[vistrails] 04/06: new upstream vistrails-src-2.2-422e1a9bbc1c

Alastair McKinstry mckinstry at moszumanska.debian.org
Mon Jun 8 14:37:16 UTC 2015


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to branch master
in repository vistrails.

commit 464132bfbccba5b1ed91f6640d34e3a439629e66
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Mon Jun 8 14:08:36 2015 +0100

    new upstream vistrails-src-2.2-422e1a9bbc1c
---
 CHANGELOG                                          |  2252 ++
 LICENSE                                            |    36 +-
 README.md                                          |    10 -
 RELEASE                                            |  2183 --
 doc/dist/instructions.txt                          |   189 -
 doc/dist/setup_build_system_windows.txt            |     9 +-
 doc/usersguide/Makefile                            |     2 +
 doc/usersguide/_static/mystyle.css                 |     6 +-
 doc/usersguide/api_documentation.rst               |   118 +
 doc/usersguide/batch.rst                           |   159 +-
 doc/usersguide/conf.py                             |    12 +-
 doc/usersguide/controlflow.rst                     |     4 +-
 doc/usersguide/creating.rst                        |     8 +-
 doc/usersguide/developer.rst                       |     2 +-
 doc/usersguide/example.rst                         |     9 +-
 doc/usersguide/example_guide.rst                   |    11 +-
 doc/usersguide/example_scikit_learn.rst            |   144 +
 doc/usersguide/example_webservices.rst             |     4 +-
 .../figures/edit_widgets/edit-widget.png           |   Bin 0 -> 27509 bytes
 .../figures/edit_widgets/edit-widgets.png          |   Bin 0 -> 272790 bytes
 .../figures/edit_widgets/enabling-edit-widgets.png |   Bin 0 -> 23965 bytes
 .../example_scikit_learn/cross_val_score.png       |   Bin 0 -> 20059 bytes
 .../figures/example_scikit_learn/grid_search.png   |   Bin 0 -> 79829 bytes
 .../figures/example_scikit_learn/manifold.png      |   Bin 0 -> 88247 bytes
 .../nested_cross_validation.png                    |   Bin 0 -> 47187 bytes
 .../figures/example_scikit_learn/pipeline.png      |   Bin 0 -> 39762 bytes
 .../example_scikit_learn/pipeline_gridsearch.png   |   Bin 0 -> 64101 bytes
 .../figures/example_scikit_learn/score.png         |   Bin 0 -> 25054 bytes
 .../example_scikit_learn/train_test_split.png      |   Bin 0 -> 21372 bytes
 .../figures/example_scikit_learn/transform.png     |   Bin 0 -> 39716 bytes
 .../list_handling/list-combine-workflow.png        |   Bin 0 -> 23044 bytes
 .../figures/list_handling/list-combine.png         |   Bin 0 -> 47264 bytes
 .../figures/packages/CustomColorShape1.png         |   Bin 24759 -> 0 bytes
 .../figures/packages/CustomColorShape2.png         |   Bin 37161 -> 0 bytes
 .../figures/packages/CustomColorShape3.png         |   Bin 21399 -> 0 bytes
 doc/usersguide/figures/packages/fancy_module1.png  |   Bin 0 -> 2787 bytes
 doc/usersguide/figures/packages/fancy_module2.png  |   Bin 0 -> 3787 bytes
 doc/usersguide/figures/packages/fancy_module3.png  |   Bin 0 -> 3862 bytes
 doc/usersguide/figures/packages/fancy_ports.png    |   Bin 0 -> 3479 bytes
 doc/usersguide/figures/persistence/base.png        |   Bin 26960 -> 0 bytes
 doc/usersguide/figures/persistence/input.png       |   Bin 10234 -> 0 bytes
 .../figures/persistence/intermediate.png           |   Bin 35945 -> 0 bytes
 doc/usersguide/figures/persistence/output.png      |   Bin 31794 -> 0 bytes
 doc/usersguide/figures/persistence/reference.png   |   Bin 84948 -> 0 bytes
 doc/usersguide/figures/persistence/versions.png    |   Bin 42233 -> 0 bytes
 .../figures/persistent_archive/contents_filter.png |   Bin 0 -> 68205 bytes
 .../persistent_archive/workflow_persistedfile.png  |   Bin 0 -> 39487 bytes
 .../persistent_archive/workflow_textquery.png      |   Bin 0 -> 29511 bytes
 doc/usersguide/intro.rst                           |    90 +-
 doc/usersguide/intro2.rst                          |    85 -
 doc/usersguide/list_handling.rst                   |   116 +
 doc/usersguide/mashups.rst                         |     4 +-
 doc/usersguide/packages.rst                        |  1214 +-
 doc/usersguide/parameter_widgets.rst               |    73 +
 doc/usersguide/persistence.rst                     |   165 -
 doc/usersguide/persistent_archive.rst              |    71 +
 doc/usersguide/preface.rst                         |     4 +-
 doc/usersguide/preliminary.rst                     |     4 -
 doc/usersguide/pythoncalc.rst                      |   287 +-
 doc/usersguide/pythoncalc_file1.rst                |    22 +
 doc/usersguide/streaming.rst                       |    94 +
 doc/usersguide/tabledata.rst                       |     4 +-
 doc/usersguide/vistrails_server.rst                |    15 +-
 doc/usersguide/vtl/README                          |     4 +-
 doc/usersguide/vtl/list-handling.vtl               |     1 +
 doc/usersguide/vtl/parameter_widgets.vtl           |     1 +
 doc/usersguide/vtl/streaming.vtl                   |     1 +
 examples-internal/XSLTSample.xsl                   |    28 -
 examples-internal/afront.xml                       |   803 -
 examples-internal/corie.xml                        |  9009 -------
 examples-internal/mummy.xml                        |   552 -
 examples/EMBOSS_webservices.vt                     |   Bin 224479 -> 0 bytes
 examples/KEGGPathway.vt                            |   Bin 57244 -> 0 bytes
 examples/KEGG_SearchEntities_webservice.vt         |   Bin 98916 -> 0 bytes
 examples/KEGG_webservices.vt                       |   Bin 11819 -> 0 bytes
 examples/api/brain_output.xml                      |   887 +
 examples/api/imagemagick.vt                        |   Bin 0 -> 10303 bytes
 examples/api/ipython-notebook.ipynb                |  1350 ++
 examples/api/out_html.xml                          |    37 +
 examples/api/outputs.vt                            |   Bin 0 -> 2778 bytes
 examples/api/simplemath.vt                         |   Bin 0 -> 12437 bytes
 examples/api/table.xml                             |    58 +
 examples/api/vistrails_logo.png                    |   Bin 0 -> 16768 bytes
 examples/chebi_webservice.vt                       |   Bin 62684 -> 269647 bytes
 examples/hadoop-nodeinfo.vt                        |   Bin 0 -> 2583 bytes
 examples/infovis.vt                                |   Bin 317911 -> 317855 bytes
 examples/list-handling.vt                          |   Bin 0 -> 2995 bytes
 examples/matplotlib/Acorr_ex8.vt                   |   Bin 30394 -> 98509 bytes
 examples/matplotlib/Arrow_ex9.vt                   |   Bin 38170 -> 106453 bytes
 examples/matplotlib/Psd.vt                         |   Bin 32554 -> 51300 bytes
 examples/matplotlib/annotate.vt                    |   Bin 32689 -> 141345 bytes
 examples/matplotlib/axhspan_ex5.vt                 |   Bin 42605 -> 242490 bytes
 examples/matplotlib/bar_ex1.vt                     |   Bin 23030 -> 80372 bytes
 examples/matplotlib/cohere.vt                      |   Bin 66159 -> 95958 bytes
 examples/matplotlib/contour.vt                     |   Bin 50196 -> 97307 bytes
 examples/matplotlib/contourf.vt                    |   Bin 38198 -> 77837 bytes
 examples/matplotlib/hist_ex1.vt                    |   Bin 18911 -> 48282 bytes
 examples/matplotlib/line2d_ex4.vt                  |   Bin 33181 -> 192632 bytes
 examples/matplotlib/line2d_ex7.vt                  |   Bin 24972 -> 65403 bytes
 examples/matplotlib/lineplot_ex3.vt                |   Bin 15631 -> 28941 bytes
 examples/matplotlib/pcolor.vt                      |   Bin 91625 -> 146370 bytes
 examples/matplotlib/pie_ex1.vt                     |   Bin 6486 -> 21895 bytes
 examples/matplotlib/polar_ex10.vt                  |   Bin 102236 -> 143313 bytes
 examples/matplotlib/scatter.vt                     |   Bin 38687 -> 97822 bytes
 examples/matplotlib/semilog.vt                     |   Bin 57219 -> 102227 bytes
 examples/mta-yankees.vt                            |   Bin 0 -> 983782 bytes
 examples/mta.vt                                    |   Bin 0 -> 195611 bytes
 examples/scripting/README                          |    11 -
 examples/scripting/brain_from_script.vt            |   Bin 5069 -> 0 bytes
 examples/scripting/brain_script.py                 |   110 -
 examples/scripting/combined_script.py              |   224 -
 examples/scripting/vtk_book_3rd_p189_script.py     |   123 -
 examples/sklearn/cross_val_score.vt                |   Bin 0 -> 85281 bytes
 examples/sklearn/dimensionality_reduction.vt       |   Bin 0 -> 288875 bytes
 examples/sklearn/grid_search.vt                    |   Bin 0 -> 221292 bytes
 examples/sklearn/pipeline.vt                       |   Bin 0 -> 169714 bytes
 examples/sklearn/roc_curve.vt                      |   Bin 0 -> 138823 bytes
 examples/sklearn/scoring.vt                        |   Bin 0 -> 91003 bytes
 examples/sklearn/support_vector_machine.vt         |   Bin 0 -> 153430 bytes
 examples/sklearn/svm_decision_function.vt          |   Bin 0 -> 410513 bytes
 examples/streaming.vt                              |   Bin 0 -> 4254 bytes
 examples/terminator.vt                             |   Bin 678956 -> 1033267 bytes
 examples/usersguide/mashups.vt                     |   Bin 540420 -> 527175 bytes
 examples/weather.vt                                |   Bin 0 -> 68849 bytes
 extensions/http/config.php.sample                  |    35 +-
 extensions/http/get_db_vistrail_list.php           |    35 +-
 extensions/http/get_vt_xml.php                     |    35 +-
 extensions/http/get_wf_pdf.php                     |    35 +-
 extensions/http/get_wf_xml.php                     |    35 +-
 extensions/http/run_vistrails.php                  |    35 +-
 extensions/latex/crowdlabs.sty                     |    35 +-
 extensions/latex/example.tex                       |    35 +-
 extensions/latex/head.tex                          |    35 +-
 extensions/latex/includecrowdlabs.py               |    35 +-
 extensions/latex/includevistrail.py                |    35 +-
 extensions/latex/vistrails.sty                     |    35 +-
 extensions/mediawiki/download.php                  |    35 +-
 extensions/mediawiki/functions.php                 |    35 +-
 extensions/mediawiki/vistrailsExtension.php        |    35 +-
 scripts/add_future_import.py                       |   152 +
 scripts/build_usersguide.py                        |   186 +-
 scripts/convert_files/convert_files.sh             |    35 +-
 scripts/convert_files/fix_file.py                  |    35 +-
 scripts/create_release_wiki_table.py               |    17 +-
 scripts/create_server_media_dir_structure.py       |    35 +-
 scripts/db_utils.py                                |    35 +-
 scripts/delete_from_db.py                          |    36 +-
 scripts/diff_package.py                            |    36 +-
 scripts/extract.py                                 |    54 +-
 scripts/force_start_vistrails.py                   |    35 +-
 scripts/force_start_vistrails_nonohup.py           |    35 +-
 scripts/gen_vtk_examples/check_diffs.py            |    35 +-
 scripts/gen_vtk_examples/colors.py                 |    35 +-
 scripts/gen_vtk_examples/convert_to_vt.py          |    35 +-
 scripts/gen_vtk_examples/copy_vtk_examples.py      |    35 +-
 scripts/gen_vtk_examples/gen_vtk_examples.py       |    35 +-
 scripts/gen_vtk_examples/get_vtk_examples.py       |    35 +-
 scripts/gen_vtk_examples/vtk_imposter.py           |    35 +-
 scripts/gen_vtk_examples/vtk_to_vt.py              |    41 +-
 scripts/generate_pkg_doc.py                        |   147 +
 scripts/get_usersguide.py                          |    98 +
 scripts/mac_update_bin.sh                          |    49 +-
 scripts/merge_vistrails.py                         |    35 +-
 scripts/module_appearance/main.py                  |    35 +-
 scripts/module_appearance/module_appearance.py     |    35 +-
 scripts/opm/opm2dot.py                             |    35 +-
 scripts/release_notes.py                           |    79 +-
 scripts/restart-vistrails-server.sh                |    35 +-
 scripts/retarget_mpl_libs.sh                       |    84 +
 scripts/run_vistrails_batch_xvfb.sh                |    35 +-
 scripts/sql_delete.py                              |    36 +-
 scripts/sql_to_xml.py                              |    36 +-
 scripts/start_vistrails.sh                         |    45 +-
 scripts/start_vistrails_xvfb.sh                    |    41 +-
 scripts/system_info.py                             |    35 +-
 scripts/unzip_vistrail.sh                          |    35 +-
 scripts/update_copyright_year.py                   |    99 +-
 scripts/update_db.py                               |    36 +-
 scripts/update_hash.py                             |    31 -
 scripts/update_to_mod_bsd_license.py               |   137 +-
 scripts/update_vistrails_command.py                |    60 +-
 scripts/watch_vistrail_servers.py                  |    35 +-
 scripts/win_update_bin.sh                          |    35 +-
 vistrails/__init__.py                              |    57 +-
 vistrails/api/__init__.py                          |    38 +-
 vistrails/core/__init__.py                         |    47 +-
 vistrails/core/analogy/__init__.py                 |    39 +-
 vistrails/core/analogy/eigen.py                    |   159 +-
 vistrails/core/analogy/pipeline_utils.py           |    39 +-
 vistrails/core/api.py                              |  1433 +-
 vistrails/core/application.py                      |   556 +-
 vistrails/core/bundles/__init__.py                 |    37 +-
 vistrails/core/bundles/installbundle.py            |    37 +-
 vistrails/core/bundles/pyimport.py                 |    68 +-
 vistrails/core/cache/__init__.py                   |    37 +-
 vistrails/core/cache/hasher.py                     |    69 +-
 vistrails/core/cache/utils.py                      |    37 +-
 vistrails/core/collection/__init__.py              |    96 +-
 vistrails/core/collection/entity.py                |    42 +-
 vistrails/core/collection/mashup.py                |    37 +-
 vistrails/core/collection/parameter_exploration.py |    37 +-
 vistrails/core/collection/schema.sql               |    35 +-
 vistrails/core/collection/search.py                |    42 +-
 vistrails/core/collection/thumbnail.py             |    37 +-
 vistrails/core/collection/vistrail.py              |    56 +-
 vistrails/core/collection/workflow.py              |    37 +-
 vistrails/core/collection/workflow_exec.py         |    37 +-
 vistrails/core/command_line.py                     |   101 -
 vistrails/core/common.py                           |    38 +-
 vistrails/core/configuration.py                    |  1933 +-
 vistrails/core/console_mode.py                     |   178 +-
 vistrails/core/data_structures/__init__.py         |    37 +-
 vistrails/core/data_structures/bijectivedict.py    |    55 +-
 vistrails/core/data_structures/graph.py            |   769 +-
 vistrails/core/data_structures/point.py            |    39 +-
 vistrails/core/data_structures/queue.py            |    41 +-
 vistrails/core/data_structures/rect.py             |    41 +-
 vistrails/core/data_structures/stack.py            |    37 +-
 vistrails/core/db/__init__.py                      |    37 +-
 vistrails/core/db/action.py                        |    37 +-
 vistrails/core/db/io.py                            |    70 +-
 vistrails/core/db/locator.py                       |    87 +-
 vistrails/core/debug.py                            |   333 +-
 vistrails/core/external_connection.py              |    53 +-
 vistrails/core/inspector.py                        |    42 +-
 vistrails/core/interpreter/__init__.py             |    37 +-
 vistrails/core/interpreter/base.py                 |    63 +-
 vistrails/core/interpreter/cached.py               |   646 +-
 vistrails/core/interpreter/default.py              |    41 +-
 vistrails/core/interpreter/noncached.py            |    46 +-
 vistrails/core/interpreter/utils.py                |    43 +-
 vistrails/core/keychain.py                         |    37 +-
 vistrails/core/layout/__init__.py                  |    37 +-
 vistrails/core/layout/tree_layout.py               |   103 +-
 vistrails/core/layout/version_tree_layout.py       |    41 +-
 vistrails/core/layout/workflow_layout.py           |    41 +-
 vistrails/core/log/__init__.py                     |    37 +-
 vistrails/core/log/controller.py                   |   563 +-
 vistrails/core/log/group_exec.py                   |    37 +-
 vistrails/core/log/log.py                          |    49 +-
 vistrails/core/log/loop_exec.py                    |    99 +-
 vistrails/core/log/machine.py                      |    37 +-
 vistrails/core/log/module_exec.py                  |    37 +-
 vistrails/core/log/opm_graph.py                    |    37 +-
 vistrails/core/log/prov_document.py                |    37 +-
 vistrails/core/log/workflow_exec.py                |    50 +-
 vistrails/core/mashup/__init__.py                  |    44 +-
 vistrails/core/mashup/action.py                    |    48 +-
 vistrails/core/mashup/action_annotation.py         |    49 +-
 vistrails/core/mashup/alias.py                     |    37 +-
 vistrails/core/mashup/component.py                 |    37 +-
 vistrails/core/mashup/controller.py                |    41 +-
 vistrails/core/mashup/mashup.py                    |    47 +-
 vistrails/core/mashup/mashup_trail.py              |    46 +-
 vistrails/core/modules/__init__.py                 |    37 +-
 vistrails/core/modules/abstraction.py              |    61 +-
 vistrails/core/modules/basic_modules.py            |  1456 +-
 vistrails/core/modules/config.py                   |   540 +
 vistrails/core/modules/constant_configuration.py   |    38 +-
 vistrails/core/modules/module_configure.py         |    38 +-
 vistrails/core/modules/module_descriptor.py        |    67 +-
 vistrails/core/modules/module_registry.py          |   808 +-
 vistrails/core/modules/module_utils.py             |    99 +-
 vistrails/core/modules/output_modules.py           |   666 +
 vistrails/core/modules/package.py                  |   228 +-
 vistrails/core/modules/paramexplore.py             |    41 +-
 vistrails/core/modules/python_source_configure.py  |    38 +-
 vistrails/core/modules/query_configuration.py      |    38 +-
 vistrails/core/modules/source_configure.py         |    38 +-
 vistrails/core/modules/sub_module.py               |   345 +-
 vistrails/core/modules/tuple_configuration.py      |    38 +-
 vistrails/core/modules/utils.py                    |    81 +-
 vistrails/core/modules/vistrails_module.py         |  1655 +-
 vistrails/core/packagemanager.py                   |   414 +-
 vistrails/core/packagerepository.py                |    51 +-
 vistrails/core/param_explore.py                    |    58 +-
 vistrails/core/paramexplore/__init__.py            |    37 +-
 vistrails/core/paramexplore/function.py            |    37 +-
 vistrails/core/paramexplore/param.py               |    37 +-
 vistrails/core/paramexplore/paramexplore.py        |    65 +-
 vistrails/core/publishing/__init__.py              |    37 +-
 vistrails/core/publishing/parse_latex.py           |    37 +-
 vistrails/core/query/__init__.py                   |    90 +-
 vistrails/core/query/combined.py                   |    44 +-
 vistrails/core/query/multiple.py                   |    43 +-
 vistrails/core/query/version.py                    |   140 +-
 vistrails/core/query/visual.py                     |    41 +-
 vistrails/core/recent_vistrails.py                 |    37 +-
 vistrails/core/repository/__init__.py              |    37 +-
 vistrails/core/repository/poster/__init__.py       |    37 +-
 vistrails/core/repository/poster/encode.py         |    41 +-
 vistrails/core/repository/poster/streaminghttp.py  |    39 +-
 vistrails/core/requirements.py                     |    57 +-
 vistrails/core/resources/default_vistrails_startup |   204 -
 .../core/resources/default_vistrails_startup_xml   |    31 +-
 vistrails/core/resources/spawned_startup_xml       |    13 -
 vistrails/core/startup.py                          |  1112 +-
 vistrails/core/system/__init__.py                  |   303 +-
 vistrails/core/system/common.py                    |   139 +
 vistrails/core/system/linux.py                     |   174 +-
 vistrails/core/system/mac_site.py                  |    37 +-
 vistrails/core/system/osx.py                       |   224 +-
 vistrails/core/system/unix.py                      |   110 +-
 vistrails/core/system/windows.py                   |   224 +-
 vistrails/core/theme.py                            |    40 +-
 vistrails/core/thumbnails.py                       |   101 +-
 vistrails/core/upgradeworkflow.py                  |   646 +-
 vistrails/core/utils/__init__.py                   |   263 +-
 vistrails/core/utils/color.py                      |    41 +-
 vistrails/core/utils/enum.py                       |    37 +-
 vistrails/core/utils/expression.py                 |    43 +-
 vistrails/core/utils/gcutils.py                    |    37 +-
 vistrails/core/utils/lockmethod.py                 |    99 -
 vistrails/core/utils/timemethod.py                 |    37 +-
 vistrails/core/utils/tracemethod.py                |    41 +-
 vistrails/core/utils/uxml.py                       |    37 +-
 vistrails/core/vistrail/__init__.py                |    37 +-
 vistrails/core/vistrail/abstraction.py             |    43 +-
 vistrails/core/vistrail/action.py                  |    61 +-
 vistrails/core/vistrail/action_annotation.py       |    37 +-
 vistrails/core/vistrail/annotation.py              |    37 +-
 vistrails/core/vistrail/connection.py              |   164 +-
 vistrails/core/vistrail/controller.py              |  1089 +-
 vistrails/core/vistrail/group.py                   |    65 +-
 vistrails/core/vistrail/job.py                     |   679 +
 vistrails/core/vistrail/location.py                |    39 +-
 vistrails/core/vistrail/module.py                  |   100 +-
 vistrails/core/vistrail/module_control_param.py    |   148 +
 vistrails/core/vistrail/module_function.py         |    44 +-
 vistrails/core/vistrail/module_param.py            |    37 +-
 vistrails/core/vistrail/operation.py               |    48 +-
 vistrails/core/vistrail/pipeline.py                |   219 +-
 vistrails/core/vistrail/plugin_data.py             |    37 +-
 vistrails/core/vistrail/port.py                    |    37 +-
 vistrails/core/vistrail/port_spec.py               |    77 +-
 vistrails/core/vistrail/port_spec_item.py          |    62 +-
 vistrails/core/vistrail/tag.py                     |    37 +-
 vistrails/core/vistrail/vistrail.py                |   264 +-
 vistrails/core/vistrail/vistrailvariable.py        |    37 +-
 vistrails/db/__init__.py                           |    37 +-
 vistrails/db/bin/__init__.py                       |    37 +-
 vistrails/db/bin/auto_gen_objects.py               |    41 +-
 vistrails/db/bin/generate.py                       |    74 +-
 vistrails/db/bin/parser.py                         |    39 +-
 vistrails/db/bin/sql_gen_objects.py                |    37 +-
 vistrails/db/bin/templates/domain.py.mako          |    37 +-
 vistrails/db/bin/templates/sql.py.mako             |    35 +-
 vistrails/db/bin/templates/sql_delete.sql.mako     |    35 +-
 vistrails/db/bin/templates/sql_schema.sql.mako     |    35 +-
 vistrails/db/bin/templates/xml.py.mako             |    35 +-
 vistrails/db/bin/templates/xml_schema.xsd.mako     |    35 +-
 vistrails/db/bin/xml_gen_objects.py                |    37 +-
 vistrails/db/domain/__init__.py                    |    40 +-
 vistrails/db/persistence/__init__.py               |    40 +-
 vistrails/db/services/__init__.py                  |    37 +-
 vistrails/db/services/abstraction.py               |    37 +-
 vistrails/db/services/action.py                    |    39 +-
 vistrails/db/services/action_chain.py              |    37 +-
 vistrails/db/services/io.py                        |   199 +-
 vistrails/db/services/locator.py                   |    53 +-
 vistrails/db/services/log.py                       |    37 +-
 vistrails/db/services/opm.py                       |    53 +-
 vistrails/db/services/prov.py                      |    42 +-
 vistrails/db/services/query.py                     |    37 +-
 vistrails/db/services/registry.py                  |    37 +-
 vistrails/db/services/vistrail.py                  |   338 +-
 vistrails/db/services/workflow.py                  |    37 +-
 vistrails/db/specs/all.xml                         |   429 +-
 vistrails/db/tests/__init__.py                     |    37 +-
 vistrails/db/tests/setup_db_tables.py              |    39 +-
 vistrails/db/tests/sql_to_xml.py                   |    43 +-
 vistrails/db/tests/xml_to_sql.py                   |    37 +-
 vistrails/db/versions/__init__.py                  |    48 +-
 vistrails/db/versions/v0_3_0/__init__.py           |    37 +-
 vistrails/db/versions/v0_3_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_3_0/domain/auto_gen.py    |    37 +-
 .../db/versions/v0_3_0/persistence/__init__.py     |    37 +-
 .../db/versions/v0_3_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_3_0/persistence/xml/auto_gen.py |    37 +-
 vistrails/db/versions/v0_3_0/persistence/xml/io.py |    37 +-
 .../db/versions/v0_3_0/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_3_0/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_3_0/specs/action.xml      |    35 +-
 .../db/versions/v0_3_0/specs/addConnection.xml     |    35 +-
 vistrails/db/versions/v0_3_0/specs/addModule.xml   |    35 +-
 .../db/versions/v0_3_0/specs/addModulePort.xml     |    35 +-
 .../db/versions/v0_3_0/specs/changeAnnotation.xml  |    35 +-
 .../db/versions/v0_3_0/specs/changeParameter.xml   |    35 +-
 .../db/versions/v0_3_0/specs/deleteAnnotation.xml  |    35 +-
 .../db/versions/v0_3_0/specs/deleteConnection.xml  |    35 +-
 .../db/versions/v0_3_0/specs/deleteFunction.xml    |    35 +-
 .../db/versions/v0_3_0/specs/deleteModule.xml      |    35 +-
 .../db/versions/v0_3_0/specs/deleteModulePort.xml  |    35 +-
 vistrails/db/versions/v0_3_0/specs/moveModule.xml  |    35 +-
 vistrails/db/versions/v0_3_0/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_3_0/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_3_1/__init__.py           |    37 +-
 vistrails/db/versions/v0_3_1/domain/__init__.py    |    37 +-
 .../db/versions/v0_3_1/persistence/__init__.py     |    37 +-
 .../db/versions/v0_3_1/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_3_1/specs/action.xml      |    35 +-
 .../db/versions/v0_3_1/specs/addConnection.xml     |    35 +-
 vistrails/db/versions/v0_3_1/specs/addModule.xml   |    35 +-
 .../db/versions/v0_3_1/specs/addModulePort.xml     |    35 +-
 .../db/versions/v0_3_1/specs/changeAnnotation.xml  |    35 +-
 .../db/versions/v0_3_1/specs/changeParameter.xml   |    35 +-
 .../db/versions/v0_3_1/specs/deleteAnnotation.xml  |    35 +-
 .../db/versions/v0_3_1/specs/deleteConnection.xml  |    35 +-
 .../db/versions/v0_3_1/specs/deleteFunction.xml    |    35 +-
 .../db/versions/v0_3_1/specs/deleteModule.xml      |    35 +-
 .../db/versions/v0_3_1/specs/deleteModulePort.xml  |    35 +-
 vistrails/db/versions/v0_3_1/specs/moveModule.xml  |    35 +-
 vistrails/db/versions/v0_3_1/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_3_1/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_3_1/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_3_1/translate/v0_3_0.py   |    37 +-
 vistrails/db/versions/v0_5_0/__init__.py           |    37 +-
 vistrails/db/versions/v0_5_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_5_0/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_5_0/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_5_0/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_5_0/domain/workflow.py    |    37 +-
 .../db/versions/v0_5_0/persistence/__init__.py     |    37 +-
 .../db/versions/v0_5_0/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_5_0/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_5_0/persistence/sql/sql_dao.py  |    48 +-
 .../db/versions/v0_5_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_5_0/persistence/xml/auto_gen.py |    37 +-
 vistrails/db/versions/v0_5_0/persistence/xml/io.py |    37 +-
 .../db/versions/v0_5_0/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_5_0/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_5_0/schemas/sql/vistrails_drop.sql |    35 +-
 vistrails/db/versions/v0_5_0/schemas/xml/log.xsd   |    33 +-
 .../db/versions/v0_5_0/schemas/xml/vistrail.xsd    |    33 +-
 .../db/versions/v0_5_0/schemas/xml/workflow.xsd    |    33 +-
 vistrails/db/versions/v0_5_0/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_5_0/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_5_0/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_5_0/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_5_0/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_5_0/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_5_0/specs/execRec.xml     |    35 +-
 vistrails/db/versions/v0_5_0/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_5_0/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_5_0/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_5_0/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_5_0/specs/macro.xml       |    35 +-
 vistrails/db/versions/v0_5_0/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_5_0/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_5_0/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_5_0/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_5_0/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_5_0/specs/session.xml     |    35 +-
 vistrails/db/versions/v0_5_0/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_5_0/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_5_0/specs/wfExec.xml      |    35 +-
 vistrails/db/versions/v0_5_0/specs/workflow.xml    |    35 +-
 vistrails/db/versions/v0_5_0/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_5_0/translate/v0_3_1.py   |    41 +-
 vistrails/db/versions/v0_6_0/__init__.py           |    37 +-
 vistrails/db/versions/v0_6_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_6_0/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_6_0/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_6_0/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_6_0/domain/workflow.py    |    37 +-
 .../db/versions/v0_6_0/persistence/__init__.py     |    37 +-
 .../db/versions/v0_6_0/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_6_0/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_6_0/persistence/sql/sql_dao.py  |    48 +-
 .../db/versions/v0_6_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_6_0/persistence/xml/auto_gen.py |    37 +-
 vistrails/db/versions/v0_6_0/persistence/xml/io.py |    37 +-
 .../db/versions/v0_6_0/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_6_0/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_6_0/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_6_0/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_6_0/specs/abstraction.xml |    35 +-
 .../db/versions/v0_6_0/specs/abstractionRef.xml    |    35 +-
 vistrails/db/versions/v0_6_0/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_6_0/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_6_0/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_6_0/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_6_0/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_6_0/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_6_0/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_6_0/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_6_0/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_6_0/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_6_0/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_6_0/specs/module_exec.xml |    35 +-
 vistrails/db/versions/v0_6_0/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_6_0/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_6_0/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_6_0/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_6_0/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_6_0/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_6_0/specs/workflow.xml    |    35 +-
 .../db/versions/v0_6_0/specs/workflow_exec.xml     |    35 +-
 vistrails/db/versions/v0_6_0/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_6_0/translate/v0_3_1.py   |    44 +-
 vistrails/db/versions/v0_6_0/translate/v0_5_0.py   |    37 +-
 vistrails/db/versions/v0_7_0/__init__.py           |    37 +-
 vistrails/db/versions/v0_7_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_7_0/domain/abstraction.py |    37 +-
 vistrails/db/versions/v0_7_0/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_7_0/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_7_0/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_7_0/domain/workflow.py    |    37 +-
 .../db/versions/v0_7_0/persistence/__init__.py     |    37 +-
 .../db/versions/v0_7_0/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_7_0/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_7_0/persistence/sql/sql_dao.py  |    48 +-
 .../db/versions/v0_7_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_7_0/persistence/xml/auto_gen.py |    37 +-
 vistrails/db/versions/v0_7_0/persistence/xml/io.py |    37 +-
 .../db/versions/v0_7_0/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_7_0/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_7_0/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_7_0/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_7_0/specs/abstraction.xml |    35 +-
 .../db/versions/v0_7_0/specs/abstractionRef.xml    |    35 +-
 vistrails/db/versions/v0_7_0/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_7_0/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_7_0/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_7_0/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_7_0/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_7_0/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_7_0/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_7_0/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_7_0/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_7_0/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_7_0/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_7_0/specs/module_exec.xml |    35 +-
 vistrails/db/versions/v0_7_0/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_7_0/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_7_0/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_7_0/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_7_0/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_7_0/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_7_0/specs/workflow.xml    |    35 +-
 .../db/versions/v0_7_0/specs/workflow_exec.xml     |    35 +-
 vistrails/db/versions/v0_7_0/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_7_0/translate/v0_6_0.py   |    37 +-
 vistrails/db/versions/v0_8_0/__init__.py           |    37 +-
 vistrails/db/versions/v0_8_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_8_0/domain/abstraction.py |    37 +-
 vistrails/db/versions/v0_8_0/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_8_0/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_8_0/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_8_0/domain/workflow.py    |    37 +-
 .../db/versions/v0_8_0/persistence/__init__.py     |    37 +-
 .../db/versions/v0_8_0/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_8_0/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_8_0/persistence/sql/sql_dao.py  |    48 +-
 .../db/versions/v0_8_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_8_0/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v0_8_0/persistence/xml/xml_dao.py  |    47 +-
 .../db/versions/v0_8_0/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_8_0/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_8_0/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_8_0/specs/abstraction.xml |    35 +-
 .../db/versions/v0_8_0/specs/abstractionRef.xml    |    35 +-
 vistrails/db/versions/v0_8_0/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_8_0/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_8_0/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_8_0/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_8_0/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_8_0/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_8_0/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_8_0/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_8_0/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_8_0/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_8_0/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_8_0/specs/module_exec.xml |    35 +-
 vistrails/db/versions/v0_8_0/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_8_0/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_8_0/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_8_0/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_8_0/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_8_0/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_8_0/specs/workflow.xml    |    35 +-
 .../db/versions/v0_8_0/specs/workflow_exec.xml     |    35 +-
 vistrails/db/versions/v0_8_0/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_8_0/translate/v0_7_0.py   |    37 +-
 vistrails/db/versions/v0_8_1/__init__.py           |    37 +-
 vistrails/db/versions/v0_8_1/domain/__init__.py    |    37 +-
 .../db/versions/v0_8_1/persistence/__init__.py     |    37 +-
 .../db/versions/v0_8_1/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_8_1/schemas/sql/vistrails.sql.bkp  |   248 -
 .../versions/v0_8_1/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_8_1/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_8_1/specs/abstraction.xml |    35 +-
 .../db/versions/v0_8_1/specs/abstractionRef.xml    |    35 +-
 vistrails/db/versions/v0_8_1/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_8_1/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_8_1/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_8_1/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_8_1/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_8_1/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_8_1/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_8_1/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_8_1/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_8_1/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_8_1/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_8_1/specs/module_exec.xml |    35 +-
 vistrails/db/versions/v0_8_1/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_8_1/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_8_1/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_8_1/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_8_1/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_8_1/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_8_1/specs/workflow.xml    |    35 +-
 .../db/versions/v0_8_1/specs/workflow_exec.xml     |    35 +-
 vistrails/db/versions/v0_8_1/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_8_1/translate/v0_8_0.py   |    37 +-
 vistrails/db/versions/v0_9_0/__init__.py           |    37 +-
 vistrails/db/versions/v0_9_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_9_0/domain/abstraction.py |    37 +-
 vistrails/db/versions/v0_9_0/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_9_0/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_9_0/domain/log.py         |    37 +-
 vistrails/db/versions/v0_9_0/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_9_0/domain/workflow.py    |    37 +-
 .../db/versions/v0_9_0/persistence/__init__.py     |    37 +-
 .../db/versions/v0_9_0/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_9_0/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_9_0/persistence/sql/sql_dao.py  |    48 +-
 .../db/versions/v0_9_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_9_0/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v0_9_0/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_9_0/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_9_0/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_9_0/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_9_0/specs/abstraction.xml |    35 +-
 .../db/versions/v0_9_0/specs/abstractionRef.xml    |    35 +-
 vistrails/db/versions/v0_9_0/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_9_0/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_9_0/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_9_0/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_9_0/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_9_0/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_9_0/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_9_0/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_9_0/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_9_0/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_9_0/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_9_0/specs/module_exec.xml |    35 +-
 vistrails/db/versions/v0_9_0/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_9_0/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_9_0/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_9_0/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_9_0/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_9_0/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_9_0/specs/workflow.xml    |    35 +-
 .../db/versions/v0_9_0/specs/workflow_exec.xml     |    35 +-
 vistrails/db/versions/v0_9_0/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_9_0/translate/v0_8_1.py   |    37 +-
 vistrails/db/versions/v0_9_1/__init__.py           |    37 +-
 vistrails/db/versions/v0_9_1/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_9_1/domain/abstraction.py |    37 +-
 vistrails/db/versions/v0_9_1/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_9_1/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_9_1/domain/log.py         |    37 +-
 vistrails/db/versions/v0_9_1/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_9_1/domain/workflow.py    |    37 +-
 .../db/versions/v0_9_1/persistence/__init__.py     |    37 +-
 .../db/versions/v0_9_1/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_9_1/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_9_1/persistence/sql/sql_dao.py  |    48 +-
 .../db/versions/v0_9_1/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_9_1/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v0_9_1/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_9_1/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_9_1/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_9_1/schemas/xml/vistrail.xsd    |    33 +-
 .../db/versions/v0_9_1/schemas/xml/vtlink.xsd      |    33 +-
 vistrails/db/versions/v0_9_1/specs/abstraction.xml |    35 +-
 .../db/versions/v0_9_1/specs/abstractionRef.xml    |    35 +-
 vistrails/db/versions/v0_9_1/specs/action.xml      |    35 +-
 vistrails/db/versions/v0_9_1/specs/add.xml         |    35 +-
 vistrails/db/versions/v0_9_1/specs/annotation.xml  |    35 +-
 vistrails/db/versions/v0_9_1/specs/change.xml      |    35 +-
 vistrails/db/versions/v0_9_1/specs/connection.xml  |    35 +-
 vistrails/db/versions/v0_9_1/specs/delete.xml      |    35 +-
 vistrails/db/versions/v0_9_1/specs/function.xml    |    35 +-
 vistrails/db/versions/v0_9_1/specs/group.xml       |    35 +-
 vistrails/db/versions/v0_9_1/specs/location.xml    |    35 +-
 vistrails/db/versions/v0_9_1/specs/log.xml         |    35 +-
 vistrails/db/versions/v0_9_1/specs/machine.xml     |    35 +-
 vistrails/db/versions/v0_9_1/specs/module.xml      |    35 +-
 vistrails/db/versions/v0_9_1/specs/module_exec.xml |    35 +-
 vistrails/db/versions/v0_9_1/specs/other.xml       |    35 +-
 vistrails/db/versions/v0_9_1/specs/parameter.xml   |    35 +-
 vistrails/db/versions/v0_9_1/specs/port.xml        |    35 +-
 vistrails/db/versions/v0_9_1/specs/portSpec.xml    |    35 +-
 vistrails/db/versions/v0_9_1/specs/tag.xml         |    35 +-
 vistrails/db/versions/v0_9_1/specs/vistrail.xml    |    35 +-
 vistrails/db/versions/v0_9_1/specs/workflow.xml    |    35 +-
 .../db/versions/v0_9_1/specs/workflow_exec.xml     |    35 +-
 vistrails/db/versions/v0_9_1/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_9_1/translate/v0_9_0.py   |    37 +-
 vistrails/db/versions/v0_9_2/__init__.py           |    37 +-
 vistrails/db/versions/v0_9_2/domain/__init__.py    |    37 +-
 .../db/versions/v0_9_2/persistence/__init__.py     |    37 +-
 vistrails/db/versions/v0_9_2/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_9_2/translate/v0_9_1.py   |    37 +-
 vistrails/db/versions/v0_9_3/__init__.py           |    37 +-
 vistrails/db/versions/v0_9_3/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_9_3/domain/abstraction.py |    37 +-
 vistrails/db/versions/v0_9_3/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_9_3/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_9_3/domain/log.py         |    37 +-
 vistrails/db/versions/v0_9_3/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_9_3/domain/workflow.py    |    37 +-
 .../db/versions/v0_9_3/persistence/__init__.py     |    37 +-
 .../db/versions/v0_9_3/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_9_3/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_9_3/persistence/sql/sql_dao.py  |    47 +-
 .../db/versions/v0_9_3/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_9_3/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v0_9_3/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_9_3/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_9_3/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_9_3/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_9_3/specs/all.xml         |    35 +-
 vistrails/db/versions/v0_9_3/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_9_3/translate/v0_9_1.py   |    37 +-
 vistrails/db/versions/v0_9_3/translate/v0_9_2.py   |    37 +-
 vistrails/db/versions/v0_9_3/translate/v0_9_4.py   |    37 +-
 vistrails/db/versions/v0_9_4/__init__.py           |    37 +-
 vistrails/db/versions/v0_9_4/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_9_4/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_9_4/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_9_4/domain/log.py         |    37 +-
 vistrails/db/versions/v0_9_4/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_9_4/domain/workflow.py    |    37 +-
 .../db/versions/v0_9_4/persistence/__init__.py     |    37 +-
 .../db/versions/v0_9_4/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_9_4/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_9_4/persistence/sql/sql_dao.py  |    47 +-
 .../db/versions/v0_9_4/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_9_4/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v0_9_4/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_9_4/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_9_4/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_9_4/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_9_4/specs/all.xml         |    35 +-
 vistrails/db/versions/v0_9_4/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_9_4/translate/v0_9_3.py   |    37 +-
 vistrails/db/versions/v0_9_4/translate/v0_9_5.py   |    37 +-
 vistrails/db/versions/v0_9_5/__init__.py           |    37 +-
 vistrails/db/versions/v0_9_5/domain/__init__.py    |    37 +-
 vistrails/db/versions/v0_9_5/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v0_9_5/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v0_9_5/domain/log.py         |    37 +-
 vistrails/db/versions/v0_9_5/domain/registry.py    |    37 +-
 vistrails/db/versions/v0_9_5/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v0_9_5/domain/workflow.py    |    37 +-
 .../db/versions/v0_9_5/persistence/__init__.py     |    37 +-
 .../db/versions/v0_9_5/persistence/sql/__init__.py |    37 +-
 .../db/versions/v0_9_5/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v0_9_5/persistence/sql/sql_dao.py  |    47 +-
 .../db/versions/v0_9_5/persistence/xml/__init__.py |    37 +-
 .../db/versions/v0_9_5/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v0_9_5/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v0_9_5/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v0_9_5/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v0_9_5/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v0_9_5/specs/all.xml         |    35 +-
 vistrails/db/versions/v0_9_5/translate/__init__.py |    37 +-
 vistrails/db/versions/v0_9_5/translate/v0_9_4.py   |    37 +-
 vistrails/db/versions/v0_9_5/translate/v1_0_0.py   |    37 +-
 vistrails/db/versions/v1_0_0/__init__.py           |    37 +-
 vistrails/db/versions/v1_0_0/domain/__init__.py    |    37 +-
 vistrails/db/versions/v1_0_0/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v1_0_0/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v1_0_0/domain/log.py         |    37 +-
 vistrails/db/versions/v1_0_0/domain/registry.py    |    37 +-
 vistrails/db/versions/v1_0_0/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v1_0_0/domain/workflow.py    |    37 +-
 .../db/versions/v1_0_0/persistence/__init__.py     |    37 +-
 .../db/versions/v1_0_0/persistence/sql/__init__.py |    37 +-
 .../db/versions/v1_0_0/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v1_0_0/persistence/sql/sql_dao.py  |    47 +-
 .../db/versions/v1_0_0/persistence/xml/__init__.py |    37 +-
 .../db/versions/v1_0_0/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v1_0_0/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v1_0_0/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v1_0_0/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v1_0_0/schemas/xml/vistrail.xsd    |    33 +-
 vistrails/db/versions/v1_0_0/specs/all.xml         |    35 +-
 vistrails/db/versions/v1_0_0/translate/__init__.py |    37 +-
 vistrails/db/versions/v1_0_0/translate/v0_9_5.py   |    37 +-
 vistrails/db/versions/v1_0_0/translate/v1_0_1.py   |    37 +-
 vistrails/db/versions/v1_0_1/__init__.py           |    37 +-
 vistrails/db/versions/v1_0_1/domain/__init__.py    |    37 +-
 vistrails/db/versions/v1_0_1/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v1_0_1/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v1_0_1/domain/log.py         |    37 +-
 vistrails/db/versions/v1_0_1/domain/registry.py    |    37 +-
 vistrails/db/versions/v1_0_1/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v1_0_1/domain/workflow.py    |    37 +-
 .../db/versions/v1_0_1/persistence/__init__.py     |    37 +-
 .../db/versions/v1_0_1/persistence/sql/__init__.py |    37 +-
 .../db/versions/v1_0_1/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v1_0_1/persistence/sql/sql_dao.py  |    47 +-
 .../db/versions/v1_0_1/persistence/xml/__init__.py |    37 +-
 .../db/versions/v1_0_1/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v1_0_1/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v1_0_1/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v1_0_1/schemas/sql/vistrails_drop.sql |    35 +-
 .../db/versions/v1_0_1/schemas/xml/vistrail.xsd    |    33 +-
 .../db/versions/v1_0_1/schemas/xml/vtlink.xsd      |    33 +-
 vistrails/db/versions/v1_0_1/specs/all.xml         |    35 +-
 vistrails/db/versions/v1_0_1/translate/__init__.py |    37 +-
 vistrails/db/versions/v1_0_1/translate/v1_0_0.py   |    37 +-
 vistrails/db/versions/v1_0_1/translate/v1_0_2.py   |    37 +-
 vistrails/db/versions/v1_0_2/__init__.py           |    37 +-
 vistrails/db/versions/v1_0_2/domain/__init__.py    |    37 +-
 vistrails/db/versions/v1_0_2/domain/auto_gen.py    |    37 +-
 vistrails/db/versions/v1_0_2/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v1_0_2/domain/log.py         |    37 +-
 vistrails/db/versions/v1_0_2/domain/registry.py    |    37 +-
 vistrails/db/versions/v1_0_2/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v1_0_2/domain/workflow.py    |    37 +-
 .../db/versions/v1_0_2/persistence/__init__.py     |    37 +-
 .../db/versions/v1_0_2/persistence/sql/__init__.py |    37 +-
 .../db/versions/v1_0_2/persistence/sql/auto_gen.py |    37 +-
 .../db/versions/v1_0_2/persistence/sql/sql_dao.py  |    49 +-
 .../db/versions/v1_0_2/persistence/xml/__init__.py |    37 +-
 .../db/versions/v1_0_2/persistence/xml/auto_gen.py |    37 +-
 .../db/versions/v1_0_2/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v1_0_2/schemas/sql/vistrails.sql   |    35 +-
 .../versions/v1_0_2/schemas/sql/vistrails_drop.sql |    35 +-
 vistrails/db/versions/v1_0_2/schemas/xml/log.xsd   |    33 +-
 .../db/versions/v1_0_2/schemas/xml/vistrail.xsd    |    33 +-
 .../db/versions/v1_0_2/schemas/xml/vtlink.xsd      |    33 +-
 .../db/versions/v1_0_2/schemas/xml/workflow.xsd    |    33 +-
 vistrails/db/versions/v1_0_2/specs/all.xml         |    35 +-
 vistrails/db/versions/v1_0_2/translate/__init__.py |    37 +-
 vistrails/db/versions/v1_0_2/translate/v1_0_1.py   |    37 +-
 vistrails/db/versions/v1_0_2/translate/v1_0_3.py   |    39 +-
 vistrails/db/versions/v1_0_3/__init__.py           |    37 +-
 vistrails/db/versions/v1_0_3/domain/__init__.py    |    37 +-
 vistrails/db/versions/v1_0_3/domain/auto_gen.py    | 23907 ++++++++++---------
 vistrails/db/versions/v1_0_3/domain/id_scope.py    |    37 +-
 vistrails/db/versions/v1_0_3/domain/log.py         |    37 +-
 vistrails/db/versions/v1_0_3/domain/registry.py    |    37 +-
 vistrails/db/versions/v1_0_3/domain/vistrail.py    |    37 +-
 vistrails/db/versions/v1_0_3/domain/workflow.py    |    37 +-
 .../db/versions/v1_0_3/persistence/__init__.py     |    37 +-
 .../db/versions/v1_0_3/persistence/sql/__init__.py |    37 +-
 .../db/versions/v1_0_3/persistence/sql/auto_gen.py |  7407 +++---
 .../db/versions/v1_0_3/persistence/sql/sql_dao.py  |    49 +-
 .../db/versions/v1_0_3/persistence/xml/__init__.py |    37 +-
 .../db/versions/v1_0_3/persistence/xml/auto_gen.py |  7277 +++---
 .../db/versions/v1_0_3/persistence/xml/xml_dao.py  |    46 +-
 .../db/versions/v1_0_3/schemas/sql/vistrails.sql   |   499 +-
 .../versions/v1_0_3/schemas/sql/vistrails_drop.sql |    37 +-
 vistrails/db/versions/v1_0_3/schemas/xml/log.xsd   |    35 +-
 .../db/versions/v1_0_3/schemas/xml/vistrail.xsd    |    35 +-
 .../db/versions/v1_0_3/schemas/xml/vtlink.xsd      |    33 +-
 .../db/versions/v1_0_3/schemas/xml/workflow.xsd    |    35 +-
 vistrails/db/versions/v1_0_3/specs/all.xml         |   217 +-
 vistrails/db/versions/v1_0_3/translate/__init__.py |    37 +-
 vistrails/db/versions/v1_0_3/translate/v1_0_2.py   |    61 +-
 vistrails/db/versions/v1_0_3/translate/v1_0_4.py   |   106 +
 vistrails/db/versions/v1_0_4/__init__.py           |    39 +
 vistrails/db/versions/v1_0_4/domain/__init__.py    |    44 +
 vistrails/db/versions/v1_0_4/domain/auto_gen.py    | 18687 +++++++++++++++
 vistrails/db/versions/v1_0_4/domain/id_scope.py    |    88 +
 vistrails/db/versions/v1_0_4/domain/log.py         |    75 +
 vistrails/db/versions/v1_0_4/domain/registry.py    |    66 +
 vistrails/db/versions/v1_0_4/domain/vistrail.py    |   223 +
 vistrails/db/versions/v1_0_4/domain/workflow.py    |   175 +
 .../db/versions/v1_0_4/persistence/__init__.py     |   475 +
 .../db/versions/v1_0_4/persistence/sql/__init__.py |    39 +
 .../db/versions/v1_0_4/persistence/sql/auto_gen.py |  8352 +++++++
 .../db/versions/v1_0_4/persistence/sql/sql_dao.py  |   262 +
 .../db/versions/v1_0_4/persistence/xml/__init__.py |    39 +
 .../db/versions/v1_0_4/persistence/xml/auto_gen.py |  6509 +++++
 .../db/versions/v1_0_4/persistence/xml/xml_dao.py  |    93 +
 .../db/versions/v1_0_4/schemas/sql/vistrails.sql   |   549 +
 .../versions/v1_0_4/schemas/sql/vistrails_drop.sql |    43 +
 vistrails/db/versions/v1_0_4/schemas/xml/log.xsd   |   157 +
 .../db/versions/v1_0_4/schemas/xml/vistrail.xsd    |   363 +
 .../db/versions/v1_0_4/schemas/xml/vtlink.xsd      |    70 +
 .../db/versions/v1_0_4/schemas/xml/workflow.xsd    |   212 +
 vistrails/db/versions/v1_0_4/specs/all.xml         |  4139 ++++
 vistrails/db/versions/v1_0_4/translate/__init__.py |    39 +
 vistrails/db/versions/v1_0_4/translate/v1_0_3.py   |   483 +
 vistrails/gui/__init__.py                          |    35 +-
 vistrails/gui/application.py                       |   308 +-
 vistrails/gui/application_server.py                |   283 +-
 vistrails/gui/base_view.py                         |    37 +-
 vistrails/gui/bundles/__init__.py                  |    35 +-
 vistrails/gui/bundles/installbundle.py             |    48 +-
 vistrails/gui/bundles/linux_debian_install.py      |    46 +-
 vistrails/gui/bundles/linux_fedora_install.py      |    42 +-
 vistrails/gui/bundles/utils.py                     |    57 +-
 vistrails/gui/collection/__init__.py               |    37 +-
 vistrails/gui/collection/explorer.py               |    64 +-
 vistrails/gui/collection/vis_log.py                |   262 +-
 vistrails/gui/collection/workspace.py              |    72 +-
 vistrails/gui/common_widgets.py                    |   286 +-
 vistrails/gui/configuration.py                     |  1109 +-
 vistrails/gui/controlflow_assist.py                |    54 +-
 vistrails/gui/debug.py                             |    50 +-
 vistrails/gui/debugger.py                          |    80 +-
 vistrails/gui/extras/__init__.py                   |    37 +-
 vistrails/gui/extras/core/__init__.py              |    37 +-
 vistrails/gui/extras/core/db/__init__.py           |    37 +-
 vistrails/gui/extras/core/db/locator.py            |    47 +-
 vistrails/gui/graphics_view.py                     |    59 +-
 vistrails/gui/job_monitor.py                       |   755 +-
 vistrails/gui/mashups/__init__.py                  |    37 +-
 vistrails/gui/mashups/alias_inspector.py           |    51 +-
 vistrails/gui/mashups/alias_list.py                |    37 +-
 vistrails/gui/mashups/alias_parameter_view.py      |    37 +-
 vistrails/gui/mashups/controller.py                |    37 +-
 vistrails/gui/mashups/mashup_app.py                |   193 +-
 vistrails/gui/mashups/mashup_view.py               |    52 +-
 vistrails/gui/mashups/mashups_inspector.py         |    37 +-
 vistrails/gui/mashups/mashups_manager.py           |    53 +-
 vistrails/gui/mashups/mashups_widgets.py           |    48 +-
 vistrails/gui/merge_gui.py                         |    39 +-
 vistrails/gui/module_annotation.py                 |    38 +-
 vistrails/gui/module_configuration.py              |    72 +-
 vistrails/gui/module_documentation.py              |    54 +-
 vistrails/gui/module_info.py                       |   163 +-
 vistrails/gui/module_options.py                    |   536 +
 vistrails/gui/module_palette.py                    |   222 +-
 vistrails/gui/modules/__init__.py                  |    64 +-
 vistrails/gui/modules/constant_configuration.py    |   951 +-
 vistrails/gui/modules/list_configuration.py        |    40 +-
 vistrails/gui/modules/module_configure.py          |    37 +-
 vistrails/gui/modules/output_configuration.py      |   414 +
 vistrails/gui/modules/paramexplore.py              |    63 +-
 vistrails/gui/modules/python_source_configure.py   |    37 +-
 vistrails/gui/modules/query_configuration.py       |    37 +-
 vistrails/gui/modules/resources/__init__.py        |    37 +-
 vistrails/gui/modules/resources/colorconfig.qrc    |     5 +
 vistrails/gui/modules/resources/colorconfig_rc.py  |    43 +-
 vistrails/gui/modules/resources/colorwheel.png     |   Bin 0 -> 28526 bytes
 vistrails/gui/modules/source_configure.py          |    63 +-
 vistrails/gui/modules/string_configure.py          |    37 +-
 .../gui/modules/stringformat_configuration.py      |    38 +
 vistrails/gui/modules/tuple_configuration.py       |    82 +-
 vistrails/gui/modules/utils.py                     |    96 +
 vistrails/gui/open_db_window.py                    |    79 +-
 vistrails/gui/paramexplore/__init__.py             |    37 +-
 vistrails/gui/paramexplore/param_view.py           |    94 +-
 vistrails/gui/paramexplore/pe_inspector.py         |    49 +-
 vistrails/gui/paramexplore/pe_pipeline.py          |    46 +-
 vistrails/gui/paramexplore/pe_tab.py               |    55 +-
 vistrails/gui/paramexplore/pe_table.py             |   107 +-
 vistrails/gui/paramexplore/pe_view.py              |    42 +-
 vistrails/gui/paramexplore/virtual_cell.py         |    57 +-
 vistrails/gui/pipeline_view.py                     |   748 +-
 vistrails/gui/pipeline_view_select.py              |    47 +-
 vistrails/gui/port_documentation.py                |    37 +-
 vistrails/gui/ports_pane.py                        |   233 +-
 vistrails/gui/preferences.py                       |   295 +-
 vistrails/gui/publishing.py                        |    41 +-
 vistrails/gui/qt.py                                |    77 +-
 vistrails/gui/query_view.py                        |    80 +-
 vistrails/gui/repository.py                        |    63 +-
 vistrails/gui/requirements.py                      |    37 +-
 vistrails/gui/resources/__init__.py                |    37 +-
 vistrails/gui/resources/images/disclaimer.png      |   Bin 265001 -> 329091 bytes
 vistrails/gui/resources/images/eye_closed.png      |   Bin 0 -> 3245 bytes
 vistrails/gui/resources/images/pencil-disabled.png |   Bin 0 -> 711 bytes
 vistrails/gui/resources/images/pencil.png          |   Bin 0 -> 465 bytes
 .../gui/resources/images/vistrails_splash.png      |   Bin 162328 -> 162012 bytes
 vistrails/gui/resources/macroicons_rc.py           |    37 +-
 vistrails/gui/shell.py                             |   931 +-
 vistrails/gui/theme.py                             |    68 +-
 vistrails/gui/utils.py                             |    39 +-
 vistrails/gui/variable_dropbox.py                  |    44 +-
 vistrails/gui/version_prop.py                      |   237 +-
 vistrails/gui/version_view.py                      |   201 +-
 vistrails/gui/view_manager.py                      |   904 -
 vistrails/gui/vis_diff.py                          |   130 +-
 vistrails/gui/vistrail_controller.py               |   639 +-
 vistrails/gui/vistrail_variables.py                |    38 +-
 vistrails/gui/vistrail_view.py                     |    96 +-
 vistrails/gui/vistrails_palette.py                 |    37 +-
 vistrails/gui/vistrails_window.py                  |   319 +-
 vistrails/packages/CLTools/README                  |    73 -
 vistrails/packages/CLTools/README.md               |    87 +
 vistrails/packages/CLTools/__init__.py             |    37 +-
 vistrails/packages/CLTools/identifiers.py          |    38 +
 vistrails/packages/CLTools/init.py                 |   261 +-
 .../packages/CLTools/test_files/test_script_1.py   |     4 +
 vistrails/packages/CLTools/wizard.py               |    81 +-
 vistrails/packages/HTTP/__init__.py                |    46 -
 vistrails/packages/HTTP/http_directory.py          |   175 -
 vistrails/packages/HTTP/init.py                    |   539 -
 vistrails/packages/ImageMagick/__init__.py         |    37 +-
 vistrails/packages/ImageMagick/init.py             |   130 +-
 vistrails/packages/JobSubmission/__init__.py       |    34 -
 .../packages/JobSubmission/common_definitions.py   |    51 -
 vistrails/packages/JobSubmission/init.py           |   315 -
 vistrails/packages/JobSubmission/machine.py        |    31 -
 vistrails/packages/RemoteQ/README                  |     2 +
 vistrails/packages/RemoteQ/__init__.py             |    56 +
 vistrails/packages/RemoteQ/base.py                 |   249 +
 vistrails/packages/RemoteQ/hdfs.py                 |   193 +
 vistrails/packages/RemoteQ/init.py                 |   549 +
 vistrails/packages/RemoteQ/streaming.py            |   244 +
 vistrails/packages/SUDSWebServices/__init__.py     |    37 +-
 vistrails/packages/SUDSWebServices/init.py         |   119 +-
 vistrails/packages/URL/__init__.py                 |    49 +
 vistrails/packages/URL/http_directory.py           |   215 +
 vistrails/packages/URL/https.py                    |   109 +
 vistrails/packages/URL/https_if_available.py       |    61 +
 vistrails/packages/URL/identifiers.py              |    53 +
 vistrails/packages/URL/init.py                     |   735 +
 vistrails/packages/__init__.py                     |    37 +-
 vistrails/packages/analytics/__init__.py           |    37 +-
 vistrails/packages/analytics/init.py               |    62 +-
 vistrails/packages/controlflow/__init__.py         |    37 +-
 vistrails/packages/controlflow/conditional.py      |   144 +-
 vistrails/packages/controlflow/fold.py             |   253 +-
 vistrails/packages/controlflow/init.py             |    47 +-
 vistrails/packages/controlflow/looping.py          |   237 +-
 vistrails/packages/controlflow/order.py            |    86 +-
 vistrails/packages/controlflow/products.py         |   138 +-
 vistrails/packages/controlflow/utils.py            |   186 +-
 vistrails/packages/dialogs/__init__.py             |    37 +-
 vistrails/packages/dialogs/continue_prompt.py      |    48 +-
 vistrails/packages/dialogs/init.py                 |    73 +-
 vistrails/packages/gmaps/__init__.py               |    55 +
 vistrails/packages/gmaps/gmap_cell.py              |   267 +
 vistrails/packages/gmaps/identifiers.py            |    41 +
 vistrails/packages/gmaps/init.py                   |   242 +
 vistrails/packages/gmaps/utils.py                  |   123 +
 vistrails/packages/gmaps/vis.py                    |   351 +
 vistrails/packages/matplotlib/__init__.py          |    40 +-
 vistrails/packages/matplotlib/artists.py           |  4877 ++--
 .../packages/matplotlib/artists_template.py.mako   |   119 +-
 vistrails/packages/matplotlib/bases.py             |   203 +-
 vistrails/packages/matplotlib/diff.py              |   119 +-
 vistrails/packages/matplotlib/figure_cell.py       |   140 +-
 vistrails/packages/matplotlib/generate.py          |    39 +
 vistrails/packages/matplotlib/identifiers.py       |    41 +-
 vistrails/packages/matplotlib/init.py              |    93 +-
 vistrails/packages/matplotlib/mixins.py            |    48 +-
 vistrails/packages/matplotlib/mpl_artists.xml      |    35 +-
 vistrails/packages/matplotlib/mpl_artists_diff.xml |    99 +
 vistrails/packages/matplotlib/mpl_plots.xml        |   468 +-
 vistrails/packages/matplotlib/mpl_plots_diff.xml   |   408 +-
 vistrails/packages/matplotlib/mpl_plots_raw.xml    |   524 +-
 vistrails/packages/matplotlib/object.py            |    20 -
 vistrails/packages/matplotlib/parse.py             |   235 +-
 vistrails/packages/matplotlib/plots.py             |  3065 +--
 .../packages/matplotlib/plots_template.py.mako     |    58 +-
 vistrails/packages/matplotlib/specs.py             |    96 +-
 vistrails/packages/matplotlib/update.py            |    38 +-
 vistrails/packages/matplotlib/widgets.py           |    38 +-
 vistrails/packages/parallelflow/__init__.py        |    38 +
 vistrails/packages/parallelflow/api.py             |    38 +
 vistrails/packages/parallelflow/engine_manager.py  |    43 +-
 vistrails/packages/parallelflow/init.py            |    38 +
 vistrails/packages/parallelflow/map.py             |   200 +-
 vistrails/packages/persistence/__init__.py         |    37 +-
 vistrails/packages/persistence/compute_hash.py     |    37 +-
 vistrails/packages/persistence/db_utils.py         |    37 +-
 vistrails/packages/persistence/find_files.py       |    37 +-
 vistrails/packages/persistence/find_workflows.py   |    37 +-
 vistrails/packages/persistence/identifiers.py      |    37 +-
 vistrails/packages/persistence/init.py             |   153 +-
 vistrails/packages/persistence/repo.py             |    38 +-
 vistrails/packages/persistence/schema.sql          |    35 +-
 vistrails/packages/persistence/widgets.py          |    61 +-
 vistrails/packages/persistent_archive/__init__.py  |    50 +
 vistrails/packages/persistent_archive/cache.py     |   141 +
 vistrails/packages/persistent_archive/common.py    |   142 +
 .../packages/persistent_archive/identifiers.py     |    40 +
 vistrails/packages/persistent_archive/init.py      |   101 +
 .../packages/persistent_archive/persistedinput.py  |   183 +
 .../packages/persistent_archive/persistedoutput.py |   142 +
 .../packages/persistent_archive/queriedinput.py    |   138 +
 vistrails/packages/persistent_archive/queries.py   |   241 +
 vistrails/packages/persistent_archive/ui.py        |   143 +
 vistrails/packages/persistent_archive/widgets.py   |   327 +
 vistrails/packages/pipelineEdit/__init__.py        |    37 +-
 vistrails/packages/pipelineEdit/init.py            |    37 +-
 vistrails/packages/pythonCalc/__init__.py          |    39 +-
 vistrails/packages/pythonCalc/init.py              |   111 +-
 vistrails/packages/pythonCalcQt/__init__.py        |    37 +-
 vistrails/packages/pythonCalcQt/init.py            |    44 +-
 vistrails/packages/qgis/__init__.py                |    37 +-
 vistrails/packages/qgis/init.py                    |    61 +-
 vistrails/packages/rpy/__init__.py                 |    37 +-
 vistrails/packages/rpy/init.py                     |   125 +-
 vistrails/packages/rpy/widgets.py                  |    37 +-
 vistrails/packages/sklearn/__init__.py             |    48 +
 vistrails/packages/sklearn/init.py                 |   423 +
 vistrails/packages/sklearn/tests.py                |   300 +
 vistrails/packages/spreadsheet/__init__.py         |    39 +-
 vistrails/packages/spreadsheet/analogy_api.py      |    73 +-
 vistrails/packages/spreadsheet/basic_widgets.py    |   295 +-
 vistrails/packages/spreadsheet/cell.qrc            |    10 +
 vistrails/packages/spreadsheet/cell_rc.py          |    43 +-
 vistrails/packages/spreadsheet/celltoolbar.qrc     |    11 +
 vistrails/packages/spreadsheet/celltoolbar_rc.py   |   314 +-
 vistrails/packages/spreadsheet/identifiers.py      |    39 +-
 .../packages/spreadsheet/images/apply_analogy.png  |   Bin 0 -> 9112 bytes
 vistrails/packages/spreadsheet/images/back.png     |   Bin 0 -> 3458 bytes
 .../spreadsheet}/images/camera.png                 |   Bin
 .../packages/spreadsheet/images/camera_mount.png   |   Bin 0 -> 2447 bytes
 .../packages/spreadsheet/images/copy_cell.png      |   Bin 0 -> 6676 bytes
 .../packages/spreadsheet/images/create_analogy.png |   Bin 0 -> 2693 bytes
 vistrails/packages/spreadsheet/images/delete.png   |   Bin 0 -> 3617 bytes
 .../packages/spreadsheet/images/deletesheet.png    |   Bin 0 -> 2549 bytes
 .../packages/spreadsheet/images/fittowindow.png    |   Bin 0 -> 1911 bytes
 vistrails/packages/spreadsheet/images/forward.png  |   Bin 0 -> 3394 bytes
 vistrails/packages/spreadsheet/images/locate.png   |   Bin 0 -> 13175 bytes
 .../packages/spreadsheet/images/move_cell.png      |   Bin 0 -> 6987 bytes
 vistrails/packages/spreadsheet/images/newsheet.png |   Bin 0 -> 1933 bytes
 .../packages/spreadsheet/images/noatunloopsong.png |   Bin 0 -> 2372 bytes
 vistrails/packages/spreadsheet/images/ok.png       |   Bin 0 -> 2040 bytes
 vistrails/packages/spreadsheet/images/open.png     |   Bin 0 -> 3703 bytes
 .../packages/spreadsheet/images/player_eject.png   |   Bin 0 -> 1509 bytes
 .../packages/spreadsheet/images/player_pause.png   |   Bin 0 -> 1201 bytes
 .../packages/spreadsheet/images/player_play.png    |   Bin 0 -> 1614 bytes
 vistrails/packages/spreadsheet/images/save.png     |   Bin 0 -> 2644 bytes
 vistrails/packages/spreadsheet/images/saveas.png   |   Bin 0 -> 2441 bytes
 vistrails/packages/spreadsheet/images/update.png   |   Bin 0 -> 11665 bytes
 .../packages/spreadsheet/images/view-refresh.png   |   Bin 0 -> 2024 bytes
 vistrails/packages/spreadsheet/init.py             |   173 +-
 vistrails/packages/spreadsheet/spreadsheet.qrc     |    14 +
 vistrails/packages/spreadsheet/spreadsheet_base.py |   125 +-
 vistrails/packages/spreadsheet/spreadsheet_cell.py |   489 +-
 .../packages/spreadsheet/spreadsheet_config.py     |    43 +-
 .../packages/spreadsheet/spreadsheet_controller.py |    65 +-
 .../packages/spreadsheet/spreadsheet_event.py      |    64 +-
 .../packages/spreadsheet/spreadsheet_execute.py    |    98 +-
 .../packages/spreadsheet/spreadsheet_helpers.py    |   107 +-
 vistrails/packages/spreadsheet/spreadsheet_rc.py   |    43 +-
 .../packages/spreadsheet/spreadsheet_registry.py   |    66 +-
 .../packages/spreadsheet/spreadsheet_sheet.py      |   332 +-
 vistrails/packages/spreadsheet/spreadsheet_tab.py  |   352 +-
 .../spreadsheet/spreadsheet_tabcontroller.py       |   246 +-
 .../packages/spreadsheet/spreadsheet_window.py     |   175 +-
 vistrails/packages/spreadsheet/widgets/__init__.py |    37 +-
 .../spreadsheet/widgets/iebrowser/__init__.py      |    37 +-
 .../spreadsheet/widgets/iebrowser/iecell.py        |    61 +-
 .../spreadsheet/widgets/imageviewer/__init__.py    |    44 +-
 .../widgets/imageviewer/images/fittocell.png       |   Bin 0 -> 1464 bytes
 .../widgets/imageviewer/images/flip.png            |   Bin 0 -> 1497 bytes
 .../widgets/imageviewer/images/rotate.png          |   Bin 0 -> 1986 bytes
 .../widgets/imageviewer/images/save.png            |   Bin 0 -> 2441 bytes
 .../spreadsheet/widgets/imageviewer/imageviewer.py |   105 +-
 .../widgets/imageviewer/imageviewer.qrc            |     8 +
 .../widgets/imageviewer/imageviewer_rc.py          |    43 +-
 .../spreadsheet/widgets/richtext/__init__.py       |    45 +-
 .../spreadsheet/widgets/richtext/richtext.py       |    89 +-
 .../packages/spreadsheet/widgets/svg/__init__.py   |    37 +-
 vistrails/packages/spreadsheet/widgets/svg/svg.py  |   115 +-
 .../spreadsheet/widgets/webview/__init__.py        |    37 +-
 .../spreadsheet/widgets/webview/webview.py         |    66 +-
 vistrails/packages/sql/__init__.py                 |    57 +-
 vistrails/packages/sql/init.py                     |   496 +-
 vistrails/packages/sql/widgets.py                  |    51 +
 vistrails/packages/tabledata/__init__.py           |    31 +-
 vistrails/packages/tabledata/common.py             |   375 +-
 vistrails/packages/tabledata/convert/__init__.py   |    37 +
 .../packages/tabledata/convert/convert_dates.py    |    97 +-
 vistrails/packages/tabledata/identifiers.py        |     4 +-
 vistrails/packages/tabledata/init.py               |    91 +-
 vistrails/packages/tabledata/operations.py         |   699 +
 vistrails/packages/tabledata/read/__init__.py      |    58 +-
 vistrails/packages/tabledata/read/read_csv.py      |   279 +-
 vistrails/packages/tabledata/read/read_excel.py    |   271 +
 vistrails/packages/tabledata/read/read_json.py     |   325 +
 vistrails/packages/tabledata/read/read_numpy.py    |    83 +-
 vistrails/packages/tabledata/test_files/xl.xls     |   Bin 0 -> 23552 bytes
 vistrails/packages/tabledata/viewer.py             |   109 +-
 vistrails/packages/tabledata/widgets.py            |   217 +
 vistrails/packages/tabledata/write/__init__.py     |   136 +
 vistrails/packages/tabledata/write/write_csv.py    |   108 +
 vistrails/packages/tabledata/write/write_excel.py  |    89 +
 vistrails/packages/tabledata/write/write_numpy.py  |   112 +
 vistrails/packages/tej/__init__.py                 |     3 +
 vistrails/packages/tej/init.py                     |   386 +
 vistrails/packages/tej/widgets.py                  |    15 +
 vistrails/packages/vtk/__init__.py                 |    37 +-
 vistrails/packages/vtk/base_module.py              |   272 -
 vistrails/packages/vtk/class_tree.py               |   303 -
 vistrails/packages/vtk/common.py                   |    88 +
 vistrails/packages/vtk/fix_classes.py              |    67 -
 vistrails/packages/vtk/hasher.py                   |    37 +-
 vistrails/packages/vtk/identifiers.py              |    40 +-
 vistrails/packages/vtk/init.py                     |  1806 +-
 vistrails/packages/vtk/inspectors.py               |   279 +-
 vistrails/packages/vtk/offscreen.py                |    70 +-
 vistrails/packages/vtk/pythonclass.py              |   232 +
 vistrails/packages/vtk/tf_widget.py                |   323 +-
 vistrails/packages/vtk/vtk_parser.py               |   548 -
 .../vtk/vtk_wrapper}/__init__.py                   |     0
 vistrails/packages/vtk/vtk_wrapper/class_tree.py   |   305 +
 vistrails/packages/vtk/vtk_wrapper/fix_classes.py  |    70 +
 vistrails/packages/vtk/vtk_wrapper/parse.py        |   931 +
 vistrails/packages/vtk/vtk_wrapper/specs.py        |   704 +
 vistrails/packages/vtk/vtk_wrapper/vtk_classes.py  |   321 +
 vistrails/packages/vtk/vtk_wrapper/vtk_module.py   |    22 +
 vistrails/packages/vtk/vtk_wrapper/vtk_parser.py   |   733 +
 vistrails/packages/vtk/vtk_wrapper/wrapper.py      |    56 +
 vistrails/packages/vtk/vtkcell.py                  |   253 +-
 vistrails/packages/vtk/vtkcell_rc.py               |   198 -
 vistrails/packages/vtk/vtkhandler.py               |   101 +-
 vistrails/packages/vtk/vtkviewcell.py              |  1045 -
 vistrails/packages/vtlcreator/__init__.py          |    37 +-
 vistrails/packages/vtlcreator/init.py              |    63 +-
 vistrails/packages/webServices/__init__.py         |    37 +-
 .../packages/webServices/enumeration_widget.py     |    92 +-
 vistrails/packages/webServices/init.py             |   139 +-
 vistrails/run.py                                   |    65 +-
 vistrails/stop_vistrails_server.py                 |    35 +-
 vistrails/tests/__init__.py                        |    51 +-
 vistrails/tests/__main__.py                        |     4 +
 vistrails/tests/resources/__init__.py              |    35 +-
 vistrails/tests/resources/console_mode_test.py     |    43 +-
 vistrails/tests/resources/dummy.xml                |    35 +-
 vistrails/tests/resources/dummy_broken.xml         |    35 +-
 vistrails/tests/resources/dummy_new.xml            |    35 +-
 vistrails/tests/resources/dynamic_module_error.xml |    35 +-
 vistrails/tests/resources/empty_bookmarks.xml      |    35 +-
 vistrails/tests/resources/import_pkg/__init__.py   |     1 +
 .../import_pkg/test_import_pkg/__init__.py         |     1 +
 .../resources/import_pkg/test_import_pkg/init.py   |     1 +
 .../import_pkg/test_import_pkg/module1.py          |     1 +
 .../import_pkg/test_import_pkg/module2.py          |     1 +
 .../tests/resources/import_targets/__init__.py     |     1 +
 vistrails/tests/resources/import_targets/test1.py  |     1 +
 vistrails/tests/resources/import_targets/test2.py  |     1 +
 vistrails/tests/resources/import_targets/test3.py  |     1 +
 vistrails/tests/resources/import_targets/test4.py  |     1 +
 vistrails/tests/resources/import_targets/test5.py  |     1 +
 vistrails/tests/resources/import_targets/test6.py  |     1 +
 vistrails/tests/resources/pythonsource.xml         |    35 +-
 vistrails/tests/resources/startup-0.1.xml.tmpl     |    63 +
 vistrails/tests/resources/test-implicit-while.vt   |   Bin 0 -> 2766 bytes
 vistrails/tests/resources/test-list-custom.vt      |   Bin 0 -> 433901 bytes
 vistrails/tests/resources/test-streaming.vt        |   Bin 0 -> 430772 bytes
 vistrails/tests/resources/test_abstraction.xml     |    72 +
 vistrails/tests/resources/test_alias.xml           |    35 +-
 vistrails/tests/resources/test_ticket_73.xml       |    35 +-
 .../resources/test_upgrades_layout/__init__.py     |     3 +
 .../tests/resources/test_upgrades_layout/init.py   |     8 +
 vistrails/tests/resources/triangle_count.vt        |   Bin 7418 -> 7188 bytes
 vistrails/tests/resources/upgrades/__init__.py     |     3 +
 vistrails/tests/resources/upgrades/init.py         |    19 +
 vistrails/tests/resources/upgrades1.xml            |   152 +
 vistrails/tests/resources/upgrades2.xml            |   133 +
 vistrails/tests/resources/vtk.xml                  |    35 +-
 vistrails/tests/run_on_mac.sh                      |    12 +-
 vistrails/tests/runtestsuite.py                    |   284 +-
 vistrails/tests/utils.py                           |   159 +-
 vistrails/vistrails_server.py                      |    41 +-
 1262 files changed, 129045 insertions(+), 74059 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..6b7cfd4
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,2252 @@
+RELEASE NOTES
+-------------
+Release Name: v2.2 build 422e1a9bbc1c from master branch
+
+Enhancements:
+ - zip/unzip binaries no longer needed (#862)
+ - new version of tabledata package (also backported to v2.1.5)
+ - new version of parallelflow package
+ - adds developer debugger (enable "developerDebugger" in expert settings)
+ - improves logging
+ - reloading a disabled package (if you changed __init__; #714)
+ - ungrouping materializes InputPort and OutputPort modules for unconnected
+   Group ports
+ - CLTools path and directory types
+ - CLTools module fails if command doesn't return 0 (#957)
+ - adds an icon for 'port not visible' (instead of blank)
+ - sql package with SQLAlchemy
+ - auto-enabling package with unmet dependencies (4a1b200b)
+ - Enhancements to job submission/monitor
+ - controlflow caches looped modules
+ - menu to export a single spreadsheet cell
+ - custom colors for version in tree
+ - export version tree to graphviz dot graph
+ - adds ReadFile module
+ - HTTP package is now URL, validates HTTPS certificates, handles ssh://
+ - fixes spreadsheet cells size resetting when resizing window
+ - loads packages from pkg_resources entry points "vistrails.packages"
+ - new persistent_archive package (#755)
+ - new sklearn package for machine learning; http://scikit-learn.org/
+ - highlight unset required ports in input ports list
+ - new user API with IPython notebook integration (#24)
+ - StandardOutput module can print a File's content
+ - output module system: same module can output to spreadsheet, file, stdout,
+   IPython, ...
+ - output port drawn from left to right (#1006)
+ - Warn when parameters have invalid values
+ - New parameter widgets for editing parameters directly on modules
+ - New list handling (deprecating the controlflow package):
+   * Typed lists (Ports can now have 'list depth')
+   * Automatic looping: Modules taking single items processes each item in
+     a list and returns a list of results
+   * Streaming support for processing one list item at a time through
+     the pipeline
+   * New control parameters for controlling looping behaviour
+ - Switching views are now faster
+ - New VTK package supporting up to VTK 6.2 (#998)
+   * Installers now contains VTK 6.2
+ - No longer show upgrade actions in version tree (optional; #1046)
+ - Associate with .vt and .vtl files on Linux
+ - Added min_conns and max_conns attribute to ports
+Bug fixes:
+ - fixes strptime on system with non-English locale
+ - fixes returning numpy arrays from PythonSource modules (3468998b)
+ - pressing ctrl+s after loading a pipeline no longer replace it with a vistrail
+ - fixed losing notes when clicking "execute" immediately from version view
+Behavior change for package developers:
+ - made Module methods python_style; updateUpstream won't work, others will
+   work but trigger warning
+ - don't use Module instances as data; pass new objects on connections
+ - module upgrades can be chained (#805)
+ - use output modules instead of cell/writer modules
+ - output port drawn from left to right; change your sort_keys
+ - constant widget use eventfilter; call installEventFilter for child widgets
+ - Improved module/parameter/widget configuration APIs
+
+From Release: v2.1.5 build 9a01936a5640 from v2.1 branch
+
+Enhancements:
+ - Tabledata package updated to version 0.1.5
+ - New google maps cell package
+ - New distribution packaging
+
+Bug fixes:
+ - Fixed problems with parameter explorations:
+   * Using more than one unset function now works
+   * Fixed update logic when switching views
+
+From Release: v2.1.4 build 269e4808eca3 from v2.1 branch
+
+Bug fixes:
+ - Pinch gesture was broken (2d5494ed1d10)
+ - Ticket 893: "Create Version" button on the spreadsheet does not work (d3db65418fad)
+ - New Parameter Exploration was created for each execution (c324acad38f9)
+ - Could not load saved Parameter Explorations (c324acad38f9)
+ - Ticket 762: Package.import_override.is_sys_pkg logic incorrect (bf5e20c923f7)
+ - Usersguide: Fixed parameter exploration vtl links (79c3021a50b3)
+ - Forces the use of PyQt4 (avoid PySide) (2460948327cc)
+ - Guess whether to use su/sudo with pip (18698fa909b3)
+
+From Release: v2.1.3 build 8262f078ed3b from v2.1 branch
+
+Bug fixes:
+ - Fixes scripting examples (8dd634391b71)
+ - Fixes Map and Filter modules outputting Variant (d597dcd6027f)
+ - Makes StringFormat handle {!r} or {:.2f} correctly (5f99a90fdc87)
+ - Fixes a test on newer pytz versions (2b4ecb3bc9bb)
+ - Displays exactly what we are going to install (214f98f478be)
+ - Fixes issue with missing PyQt4 (fbfada66f67e)
+ - Hide splashscreen when asking for file association (069c52f90130)
+
+From Release: v2.1.2 build 7d8a4ed2feeb from v2.1 branch
+
+Enhancements:
+ - Ticket 846: File Selection Dialog (78e8d01bd7ab)
+ - Ticket 824: Workflow execution output in console (8ea1231e736f)
+ - Adds PromptIsOkay module (WIP) (a1bad0cc2d46)
+ - Adds a YesNoDialog module (b267d2bed5eb)
+
+Bug fixes:
+ - Ticket 849: Autosave for existing vistrails not working (671eade8a9b8)
+ - Saving mashups to DB corrupts them (5be2ed41d33f)
+ - CLTools wizard does not show list type field (df8ef413aff4)
+ - Date error in workspace when using 8-bit characters (af83742a98ec)
+ - Ticket 850: Pipeline/history view scrollbars too sensitive (9e68064627c1)
+ - Ticket 686: Deleting a vistrail variable breaks workflows (1870f481103d)
+ - Ticket 830: Deleting a module does not delete vistrail variables connected to it (a197eba35396)
+ - Ticket 825: Vistrail Variables are not copied with modules (a197eba35396)
+ - Wrong view mode when switching between open vistrails (29bc0e1f47b7)
+ - Ticket 828: [Windows] Pinning a panel causes it to disappear (287e77ec7afd)
+ - Saving new vistrail caused view change (a95026c25968)
+ - Could not drop module in detached vistrail variables widget (63957fe80711)
+ - Vistrail Variables palette closed before it could be stickied (670f81d5eaff)
+ - Ticket 822: Exception if PyQt is installed but PyQt.QtOpenGL isn't (e4c1ded9d649)
+ - Ticket 783: Enabling packages automatically can make a different package fail (244084e837ec)
+ - Old-style imports did not work on vistrails server (eaded21310ee)
+ - Fixes adding a webservice through the context menu (d42e90689af2)
+ - Old mashuptrails were not deleted correctly in DB (5ada9ce79bcb)
+ - Mashups: Fixes alias copy bug (b5276f4c159e)
+ - SaveBundle did not copy mashups (ea12b6a1e2b3)
+ - Fixes date formatting in core.collection (1aaef5de72fb)
+ - Fixes major ImageViewerCell bug (d8ca797bf8b9)
+
+From Release: v2.1.1 build 90975fc00211 from v2.1 branch
+
+Bug fixes:
+ - Ticket 814: Parameter Exploration Broken (13da70d0b35f)
+ - Fixes early gui import in application_server (3b2f6186cea9)
+ - Ticket 816: Saved vistrail doesn't appear in 'my vistrails' (784414a617d2)
+ - Ticket Fix font issue for OS X 10.9. (22c0f0cca937)
+
+From Release: v2.1 build 179c82045907 from v2.1 branch
+
+Enhancements:
+ - Ticket 292: Add XSL support to RichTextCell (ae0126167aa8)
+ - Set file associations on Linux (579d702aaab9)
+
+Bug fixes:
+ - Ticket 610: Exporting to the database should update locator (e6c3203a2710)
+ - Ticket 809: Suspending module attached to more than one sink kills workflow execution (3b791e47c453)
+ - Save button is not disabled when file is saved (d0dc3525f334)
+ - Items in workspace were sometimes shown incorrectly (d0dc3525f334)
+ - Context Menus in workspace were missing (d0dc3525f334)
+ - Read only string widget had multi-line button (9117e5bb367e)
+ - Opening configuration window with unsaved changes fails (fa3c1335580f)
+ - Infinite loop when changing string in Mashup App (2ee81b444300)
+ - Ticket 802: Can't exit VisTrails (da5c18a8b550)
+ - Ticket 796: [JobSubmssion] Issue when resuming job from unsaved vistrail after quitting (cc3d342688fb)
+ - Temporary files for untitled locators did not work correctly (3d9df4ab5ea2)
+ - Autosave prompts when vistrail is already open (cfc06bbc1c2c)
+ - Added LinuxMint as a supported Ubuntu variant (145c4c3c16ec)
+ - Ticket 581: Latex extension: clicking on a figure on the PDF file (on acrobat) gives an error (f1a581b11929)
+ - Publishing widget did not show unsaved vistrails correctly (0a4f49d7b081)
+ - Ticket 712: Useful messages when loading abstractions (07745fca0e99)
+ - Ticket 670: Traceback in configuration window (073b57d3bfca)
+ - Ticket 709: Recursing on abstractions tracebacks (5b850844b735)
+ - Ticket 776: 'Open in New Window' feature (71147be4b5ef)
+ - Ticket 794: Exits with 'cannot connect to X server' when starting core application (3c94ccc0ac9a)
+ - Fixed DBLocator equality method (e6c3203a2710)
+ - Ticket 771: Export to DB hangs if schema is not present (c102cb8f72c8)
+ - Ticket 787: Mac color chooser locks keyboard (628fb3e773fc)
+ - Ticket 740: Double-clicking a workflow in the workspace collapses the tree (3775961debd4)
+ - Ticket 738: Double-clicking a workflow in the workspace does not select it in the history view (3775961debd4)
+ - Ticket 723: Changing view fails on Fedora (ee7b4652e845)
+ - Ticket 722: Pipeline validation doesn't check for invalid functions (47d9c6de3e45)
+ - Ticket 277: Don't always receive "enable package" dialog (802fd0de0a7e)
+ - Ticket 415: Version tree refresh after API calls (0a2f6a59d6a7)
+ - Ticket 730: help() not available warning in Mac 2.1 binary (a946e4da59c1)
+ - Ticket 683: Packages should honor -S flag (9e5b83351d2f)
+ - Ticket 649: Batch mode doesn't allow a vt without a version (b5b65892aa10)
+ - Ticket 611: Mashups relational support missing (6bf5b2b02e48)
+ - Ticket 759: QLineEdit.setPlaceholderText does not exist in Qt 4.6.3 (a57fbba44e6e)
+ - Added progress reporting to Map module (0666e24d35f5)
+ - Cannot abort execution while a vtkAlgorithm is running (6b86705c0e59)
+ - Debian install script was used on Fedora (4acca49bcf74)
+ - Ticket 751: Display history view when opening vistrail with tagged versions (f2b053cee1aa)
+ - Spreadsheet history file path was set incorrectly (1789513a3afd)
+ - Fixes slot bug in PyQt 4.7.3 (17230667d58e)
+
+From Release: v2.1 beta2 build 99faabb791a0 from v2.1 branch
+
+Bug fixes:
+ - Ticket #735: Windows dulwich install via pip fails (14d362a695df)
+ - Ticket #718: persistence can't handle directories (2a668a6e9881)
+ - Fix issue with persistent paths in Windows (2a668a6e9881)
+ - Ticket #728: Upgrading vistrail with disabled package (b28c85b718ac)
+ - Fix issue with subworkflows using disabled packages (b28c85b718ac)
+ - Fix issue with staging persistent directories (6cddde545965)
+ - Fixed module upgrades not working with dynamic packages (bf997c6bb0c6)
+ - Fix issue with transfer function widget (11213143752c)
+ - Rewrites error-prone code for GitRepo#add_commit() (c1d2f60cc10d)
+ - Persistence sets up a Git username if none is set (f37129976ba5)
+ - Fixes default values on optional Boolean ports (34365eb22800)
+ - Ticket #705: zip.exe not found in Windows binary (69a16e3c5b84)
+ - Ticket #700: Upgrades with package identifier changes fail (32f934bef698)
+ - Ticket #716: The new IPython console does not receive console output (96d65c1d0e80)
+ - Ticket #699: Base classes for parameter config widgets do not enforce defaults (6e1a5624b2ae)
+ - Fix BooleanWidget default handling (6e1a5624b2ae)
+ - Fixed tricky upgrade bug (1385b1d04f4b)
+ - Ticket #626: Passing parameters to single instance still opens second instance of VisTrails (334c743f3c33)
+ - Fix issue with package identifier changes and upgrades (32f934bef698)
+ - run.py/fix_paths was broken (16aeafb32399)
+ - Looping over a failing PythonSource caused logger to fail (2b5ff8105562)
+ - Fixes line-endings for TestUnzip (05a41335f050)
+ - Disables deleting from the persistence store (3c816e2734b8)
+ - Adds tests for type-checking, using PythonSources (3f0c602b003a)
+ - Disables type-checking for InputPort modules (4cdad5f113df)
+ - module_info now shows a module's id (0c504fe06615)
+ - Limits copy and paste in module_info (b99c674c8494)
+ - Detects cycles when computing pipeline signature (3a0fe0b5a880)
+ - Adds some more checks for persistent path type (846631436bd0)
+ - Raises a ModuleError if persisting an empty dir (d3d8b2193b5f)
+ - Makes type-checking optional (30659a8b6525)
+ - Fixes adding a directory to persistence (0c26c5b68ee6)
+ - While requires *or* ConditionPort or MaxIterations (bdcd04e3366c)
+ - Fixes a package_dependencies() crashing VisTrails (3263be2d2a52)
+ - Lets PythonSource use the default source (7684997bd888)
+ - PythonSource configuration dialog now uses default (3dff503ce8ce)
+ - Fixes StringWidget not showing default correctly (49d9dbd161f0)
+ - Restores read-only mode removed by previous merge (4bdf4705a669)
+ - Removes most of the persistence_exp package (90c70ee525e6)
+ - Fixes matplotlib not able to reuse cells (243ae02dd499)
+ - Makes UntitledLocator inherit CoreLocator (fc863650a893)
+ - Fixes looping modules (34d3029f3419)
+ - Minor changes to persistence code (96a605e0ca3f)
+ - Adds back PersistentPath#git_command() (295f9ade09cf)
+ - Fixes an issue with fix_dates() (3ad431172b47)
+ - More fixes to found_another_instance_running() (916cdeb23f6f)
+ - Makes fix_dates static in PersistentRefModel (56dec62ea2aa)
+ - Fixes persistence view (1bbb9bfb5f45)
+ - Adds tests for Unzip and UnzipDirectory (22c9d361b78b)
+ - Makes HTTPFile cacheable again (5bc3619d5cba)
+ - Fixes running the CLTools wizard standalone (77bf72286a8c)
+ - Fixes CLTools test on Windows releases (c503e4df5cf9)
+ - Fixes UnicodeDecodeErrors in DebugView (5ce4fd3515d7)
+ - Adds an UnzipDirectory module (634e6415a62e)
+ - Fixes Unzip code (10a2a3753185)
+ - Fixes runtestsuite.py ignoring *system* (b1210c5dc5c7)
+ - ImageMagick fixes (b0994f0e5684)
+ - Cleans disabled packages from cache (51a4cf021a31)
+ - Removes QPackagesWidget#erase_cache attribute (2919064fcce2)
+ - Don't expand the module palette on package load (890b6796e4a2)
+ - Re-enables type checking after all (ec6539366bbd)
+ - Fixes optional tabledata->spreadsheet dependency (511ab651ad93)
+ - Makes numpy arrays valid Lists (6425d8d7a286)
+ - Merge branch 'optimize-module' into 'master' (906a6edf8e73)
+ - Minor fixes to installers (ba9550bb44f2)
+ - Moves rgb2hsv and hsv2rgb out of paramexplore (f00a710f2424)
+ - PythonSource now sets unconnected output ports (75f4d085c57f)
+ - Adds a Delay port on the While module (07087da25339)
+ - Renames 'optimization.py' to 'looping.py' (b4b2183e3bab)
+ - Renames Optimize to While, inverts condition (0a07b43c7a2f)
+ - Adds state output/input ports (e6f57d0f4999)
+ - Adds the Optimize module to ControlFlow (ea4ebd43293c)
+ - ExecuteInOrder now uses the ControlFlow style (3d286c21a17d)
+ - Adds a Delay port on the While module (2b2648c08820)
+ - Makes log-related flags not fold-specific (954c984cca31)
+
+From Release: v2.1 beta build 16ae99d82468 from v2.1 branch
+
+Enhancements:
+
+ - Ticket #695: Parameter explorations should be migrated through upgrades if possible (29f072af3087)
+ - Start migrating parameter explorations through upgrades (29f072af3087)
+ - Ticket #690: PythonSource Port Type Completion Requires "Enter" (f19e8a6e222a)
+ - Display version id in version properties (6eb10d9e3bcf)
+ - Static mashup animations (d40c74b42abb)
+ - Animation support for Mashups (cc578f2009a7)
+ - pip should now work on all platforms where it is available (b90fdba57189)
+ - Added graphical sudo for OSX (b90fdba57189)
+ - Added IPython Console (57f54943a73d)
+ - Use PyQt API version 2 (5229204a2dce)
+ - Multi-line editor for String modules (ff7d78aa76e4)
+ - Progress Dialog for workflow execution (459f3d003393)
+ - Improve interaction between pipeline views and controller. (a3bcdf6cc7a2)
+ - Improve API (aa1dbcc5f34d)
+ - Add more robust tracking of untitled vistrails. (913ed56d9445)
+ - Add matplotlib upgrades and integrate new pkg with new identifier scehme. (79bcb5673781)
+ - Support package identifier changes. (f77b92758c07)
+ - Build up the API and refactor core application methods (de9cea46a623)
+ - More updates to matplotlib package (44dff52c4da2)
+ - Add port spec translation from schema 1.0.3 to 1.0.2 (616a1090bf4b)
+ - Incremental/Online Layout  (80cb92674de6)
+ - Spreadsheet: "Find Version" and "Save Camera" now works for unsaved, closed, and "saved as" vistrails (24243fd207fc)
+ - DB support for Mashups (4e8da08d81b1)
+ - Support backward comaptibility for packages that have not been updated to use the "vistrails." prefix when importing. (6ca1d510a773)
+ - Updated persistence package to use dulwich, a pure python implementation of git (263b6f339e50)
+ - PROV document can now be exported using the command line (script) (5f0b04c049e5)
+ - Ticket #604: Add vistrail variable support to parameter exploration (04496edc9bfd)
+ - Added PROV entities for input and output data (ae52faaadfa9)
+ - Using Dublin Core metadata for PROV document (PROV exporter) (652099fe855d)
+ - New version of the PROV exporter (03a0a2785e89)
+ - First version of PROV exporter (9d32409c7118)
+ - Serializable mixin class for modules (895fab7db230)
+ - User does not need to create IPython controller manually anymore (ba7edbc30ca4)
+ - Added support for SSH IPython engines in parallel flow (1a56f69a18e6)
+ - IPython controller is stopped when closing VisTrails or disabling the package (704658297b0f)
+ - Ongoing work on the exporter for the PROV model (704658297b0f)
+ - IPython controller and engines are now started from VisTrails (4ec53425ca92)
+ - Added information about the machine from each IPython engine (8a361420a384)
+ - Map (parallel flow) can execute an outer subworkflow in IPython engines (949f9edb24df)
+ - First version of package 'parallel flow' (ac162d9e7ccb)
+ - Module / Group executions from the IPython engines are added to the provenance (518b3a4b1129)
+ - Added some modifications in the code to allow the execution of workflow in IPython engines (d89b7f9861ee)
+ - Forward error messages when connecting to other instance (0ad89de1cb2a)
+ - Add uniform method for building descriptor, port_spec strings (9633bb6c1365)
+ - Allow selected portions of the workflow to be relaid out (6f558cc3e697)
+ - Add option to nicely layout workflows automatically (15ff124c6652)
+ - runtestsuite now returns 0 for passed test runs (5d44f2879811)
+ - Ticket #606: Copy parameter explorations between workflows (b8a25bc9bac8)
+ - Updates to parameter explorations (696b83875d73)
+ - Ticket #603: Parameter Exploration from command line (d5f554fa40e0)
+ - Ticket #545: Make unset parameters accessible from the Parameter Exploration view (7b5cbe95bbf3)
+ - Ticket #547: Migrate parameter exploration persistence to schema and controller (7b5cbe95bbf3)
+ - Unset parameters can be used in parameter explorations (7b5cbe95bbf3)
+ - New schema for parameter explorations (7b5cbe95bbf3)
+ - Parameter explorations can be named (7b5cbe95bbf3)
+ - Parameter explorations are visible in the workspace (7b5cbe95bbf3)
+ - Parameter explorations can be accessed without the gui (7b5cbe95bbf3)
+ - Improve exception message for invalid port specification (c01407d42d7c)
+ - Improve error messages during package loading (2ea29738dd9b)
+ - API: VisTrailsAPI.execute() now accepts the same parameters in core VistrailController.execute_current_workflow() (012a7e828338)
+ - LaTex Extension: Added support for relative .vtl links in pdf and relative filenames in .vtl files (2329f7e6eb10)
+ - AutoConnect: when dragging a new module into a workflow, try to connect it (5d6475919bb3)
+ - Allow port_and_port_spec_match to match two port specs (e068f2a835e2)
+ - Ticket #555: Move package-specific missing package handlers (42131938cd0f)
+ - Support enumerations for parameters (571a24363dda)
+ - Add gui support for different port shapes (9f7e54780c7b)
+ - Show when ports are set by darkening the port (9f7e54780c7b)
+ - Add visual cues for the number of connections set/needed/allowed (9f7e54780c7b)
+ - Added port docstrings to the VTK package (49aa19ba2ce3)
+ - Updated port documentation (befd489265d2)
+ - Add schema support for max/min connections for ports (befd489265d2)
+ - Native schema for Vistrail Variables (201b489e1c26)
+ - Add load_package method to API (abbc89ef42dc)
+ - Add load_workflow method to api (5786189661b2)
+ - Automatically install PyQt4 on Fedora Linux (b11e69aafe2e)
+
+Bug fixes:
+ - Fixed spreadsheet capturing keys in other windows (aad252798fe6)
+ - Fix issues with completions in port tables (f19e8a6e222a)
+ - Ticket #692: Parameter exploration schema logic invalid (44a29f0422b8)
+ - Fix translation bugs between schema versions. (6643e4dd610d)
+ - Ticket #693: Issue with PortSpecItem ids (16413b49c806)
+ - Fix ids on PortSpecItems (16413b49c806)
+ - Ticket #691: Executing a parameter exploration without the spreadsheet fails (48ccd5a64f54)
+ - Ticket #689: Mashups preview broken (3ea331e01abc)
+ - Refactor get_pipeline_name calls and remove substring hacks (3d8a9c875288)
+ - Fix QChar issue with parameter exploration (e07da85567a6)
+ - Fixed invalid current_view causing setCurrentWidget to fail (c93061c00bcb)
+ - Job Monitor: Could not run more than one job job in the same vistrail (609f09df5ce4)
+ - Job Monitor: Could not delete job other than current pipeline (609f09df5ce4)
+ - Job Monitor: Job for current pipeline was not stored on shutdown (609f09df5ce4)
+ - Looping over a failing PythonSource caused logger to fail (3bdf9620dd00)
+ - Ticket #678: Relational DB support for schema v1.0.3 broken (d54eb24cba1f)
+ - Fix issues with PortSpecItem (d54eb24cba1f)
+ - Ticket #680: Package configuration broken (20ba5b110fae)
+ - Fix broken clipboard check for paste (a6d1cc7c840c)
+ - Use codepath when identifier is not enabled when warning for old style imports (6a7f4a99a0c7)
+ - Disabling a package did not select it in the Available Packages list (8f50dcf2d941)
+ - Fixed vistrails->crowdlabs in latex/example2.tex (a95605ef12ab)
+ - Module: controller was not set in default moduleInfo (7360a90e23cd)
+ - Ticket #675: save_from_gui() is broken (482624c80e2e)
+ - Fix issue with saving untitled vistrails (482624c80e2e)
+ - Fix typo in application's convert_version (1866ec46e5ec)
+ - Logging fails when Group executed by Map fails (fcb6d4b1b637)
+ - VisTrails Server: fixed generating a pdf from a vistrail tree  (0a3d02e92b48)
+ - Ticket #668: Commit 6cf6920 broke API tests (76887e74224e)
+ - open_many_from_db should not be used with pre 1.0.2 schemas (e2b247f2c588)
+ - Updated latex example files to use crowdlabs instead of vistrails.org (0314ecf38606)
+ - Fixed generating an image of workflow graph from the command line (3f40090c5e12)
+ - Images in thumbnails are now sorted by cell location (498081d7cdc5)
+ - Errors in package dependencies method caused VisTrails to fail on startup (1adc3d25bf73)
+ - Fix issue with intermediate persistent files not being found in the store when a uuid is already assigned. (72c89f5aa6ca)
+ - Fix earlier noted issue with importing the registry in create_instance_of_type (78df1961b099)
+ - Fix some issues with Windows paths and locators. (2e2c35df7dcf)
+ - Ticket #662: VistrailController constructor does not set _current_full_graph (a3bcdf6cc7a2)
+ - Push controller constructor calls through set_vistrail (a3bcdf6cc7a2)
+ - Don't generate an error when a user attempts to drag a module into a non-pipeline view (f7abe1fd73b9)
+ - Ticket #664: Debug Message Fails with AssertionError (5008bf52a105)
+ - Ticket #661: Controller's current_version=-1 causes issues (c69b430e1701)
+ - Fix issue with inconsistencies when current_version=-1 (c69b430e1701)
+ - Ticket #590: Packages are not updated when userpackages dir is modified (88480456e2cf)
+ - Fixed bug in matplotlib cell resizing (bbe9a6078797)
+ - Vistrail Variable list was changing while being iterated over (99e60cf4dccf)
+ - Saving log to prevoius version failed (d56da92fa406)
+ - Fixed update_db script to work with master (04968e309d94)
+ - Allow reading different versions of subworkflows from DB (c5a33a0b8ead)
+ - Fixed loading wrong abstraction DB version (06a06be04889)
+ - Fixed trying to write empty workflow list to DB (06a06be04889)
+ - PipelineView: Execution exceptions were not caught which caused jobView to lock up execution (3b460bdb7c95)
+ - Mashups: controller_changed caused widget to be redrawn even when the controller did not change (801c3b8e58a8)
+ - Ticket #656: Control Flow Wizard is broken (95275d116c24)
+ - Fixed deleting mashup alias using Del/Backspace key (1d68ccf02f81)
+ - color picker widget gets orphaned in the alias inspector (1d68ccf02f81)
+ - Fixed bug on PROV exporter (f7675297ad23)
+ - Fix issue with Mac binary and the vistrails.py sys.path changes (09840f6c815b)
+ - Save log to xml action was not enabled in menu (dbc83ce34917)
+ - Ticket #641: PersistentInputFile not recognizing changes in the file contents (4f85d3d25ab9)
+ - Fix issue where file changes were not being recognized (4f85d3d25ab9)
+ - Ticket #639: Package details are not updated when a disabled package is selected in preferences panel (a251d6fe54a0)
+ - Execution of workflows in IPython engines (ba7edbc30ca4)
+ - Groups and Subworkflows can now have their execution log annotated (d89b7f9861ee)
+ - Ticket #635: Error translating from schema 1.0.2 to 1.0.3 (5fbdbe702dcb)
+ - Fix issue with whitespace between port spec items (816094bc7d64)
+ - Ticket #577: Publish window always shows grayed out snippet (fc9c5e5e11ce)
+ - Ticket #633: Automatic package download is not working on master (bce780145a5c)
+ - Ticket #626: Passing parameters to single instance still opens second instance of VisTrails (0ad89de1cb2a)
+ - CLTools: Modules were not reloaded after reloading scripts (283f8b57166b)
+ - CLTools: "env" option was not reset in wizard when loading other tool (283f8b57166b)
+ - Server mashup request need to use db user with write access (81c51908662c)
+ - MissingPackageVersion exceptions need to be tied to specific modules (5d13c3e8292b)
+ - Ticket #629: Issue with namespace (63a696d66c3b)
+ - Fixed issue with reloading packages with namespaces (63a696d66c3b)
+ - Allow only a single MissingPackage exception to be included in an InvalidPipeline container exception (a1401ec6afbb)
+ - Fixed typo with ghosted pen color (a0bdae3f8c4a)
+ - Ticket #627: Duplicate enable package messages (fb21c5c5e4b0)
+ - Fix errors in parameter exploration when viewing invalid pipelines (fb21c5c5e4b0)
+ - Do not emit errors from the query view when the selected version changes (9e1eb696ce67)
+ - Ticket #617: Hard import from the v1_0_0 schema in opm.py makes it fail with other schemas (1c7b21fab942)
+ - Fix OPM import (1c7b21fab942)
+ - Windows: Saving vistrail zip xml fails when zip.exe cannot be located (d80fbb746549)
+ - Ticket #624: unix /bin/ls check fails on fedora 17 (bcd044c4ff75)
+ - runtestsuite.py should not care about empty string arguments (f417c703c364)
+ - Fixed typo in parse/update for parameter types introduced in recent commit (133102abe14f)
+ - #623 (133102abe14f)
+ - Fixed issue with connecting tuple ports in the API (5eddcc1a9e47)
+ - Ticket #621: Hidden ports that are used in connections are not set to visible (e40295454a40)
+ - Fixed visibility of a connected port in ports panel (e40295454a40)
+ - Fixed issue when connecting modules (2811ba5d4ff3)
+ -  Fixed documentation file of CLTools that was causing a failure when building the pdf version of the usersguide  (a0c19535e7d6)
+ - Ticket #618: Open Workflow from DB missing in file menu (61619a425285)
+ - Ticket #614: test_abtraction_create fails in test suite (6885385a769d)
+ - Preferences sometimes tried to set up a removed package (5d44f2879811)
+ - SplashScreen was never deleted (5d44f2879811)
+ - Ticket #613: triangle_area.vt fails on the map operator (ad4b579121c2)
+ - Fix bug with obtaining port spec signature (ad4b579121c2)
+ - Ticket #612: User-defined parameter exploration editor is problematic (7512a2d05434)
+ - Fix issue with modified group signatures (b542543e1332)
+ - is_running_gui missing in VistrailsServerSingleton (557586218e5a)
+ - Fixed issue where OPM export could not resolve ports in parent modules (d084c5742ffb)
+ - SUDSWebServices did not handle empty configurations correctly (0cfe904c59f4)
+ - Ticket #583: CLTools: sometimes a module called CLTools is displayed (f2d755b24f53)
+ - Empty packages could not be reloaded (f2d755b24f53)
+ - PortSpecItem schema did not work on MySQL (b7556465275b)
+ - Parameter Explorations were not being converted correctly from 1.0.2 (b7556465275b)
+ - Parameter Explorations were not being loaded from database correctly (b7556465275b)
+ - Saving a Vistrail failed when package manager was not available (b7556465275b)
+ - Ticket #601: Connection port compatibility should be checked at a lower-level (f984fd5087c0)
+ - Check port compatibility at controller level (f984fd5087c0)
+ - Ticket #602: core api does not work in console (1d965a2cf952)
+ - Add missing methods to GUI application (1d965a2cf952)
+ - Ticket #599: Missing defaults cause exception when adding a function (a98e0a7962c8)
+ - Ticket #594: Defaulted booleans added twice (ef684f869d62)
+ - Fix duplicate boolean values when using defaults (ef684f869d62)
+ - Update color of cached modules correctly and reset colors on re-execute (48981ae5cfbe)
+ - Do not set module color back to active after it has been run (4f55071bb133)
+ - Ticket #591: User-decorated modules do not change color during execution (86fe5d0ad9a1)
+ - Module status brushes are checked first when setting the color of a module (86fe5d0ad9a1)
+ - Ticket #592: Dragging a Group module into a pipeline causes an invalid pipeline error (bb2f60099e4c)
+ - Guard against empty group modules (bb2f60099e4c)
+ - Spreadsheet package: Checking if the GUI is running before trying to initialize the package. (c9d20070140c)
+ - Catch exceptions when selecting invalid modules (3c3a6755adfa)
+ - Ticket #586: Selecting an invalid module raises exceptions (cb6c5b161c57)
+ - enabling/disabling package did not invalidate pipeline (1a280b63a745)
+ - Ticket #585: Failed reloading of a package does not invalidate modules (057f031ee4c3)
+ - Fixed issue where modules were not marked as invalid before validation (057f031ee4c3)
+ - Ticket #584: Enabling a package adds it to the enabled package list even if there are errors (11125174c7ff)
+ - Fix issues with package list in preferences (11125174c7ff)
+ - Unselect port on mouseReleaseEvent (56f2d9aedf37)
+ - SUDSWebServices: Offline Mode by storing WSDL in .vt file was not portable (eba546527401)
+ - SUDSWebServices: Typo in handle_missing_module caused packages with wrong names (eba546527401)
+ - Ticket #575: Vistrail variables panel has an overdraw problem (52c864c3ddb2)
+ - Ticket #576: Analogies are only displayed if we change the focus out of VisTrails to another application and back (8c023062c639)
+ - Ticket #539: Standard Module Configuration Widget asks to save when two ports are enabled (c9d5d03962b2)
+ - Configuration widgets will prompt to save only when the current module change, making it easier to copy text from another application (c9d5d03962b2)
+ - Ticket #569: Connected icon in Module Information does not disappear after removing connection (11e93fd142cb)
+ - Loading an image from workflow graph or a version tree was not working in the command line (2329f7e6eb10)
+ - Workflow results that used a VTKCell were consisting of a black screen when running in batch mode (49adb4fd6b5d)
+ - Ticket #487: isosurface script version of terminator.vt causes vistrails to crash (76de9f741635)
+ - Ticket #540: Vistrail is not always marked as changed when containing a vistrail variable (49cb21769a83)
+ - Ticket #563: Temporary connection does not appear second time you create the same connection (3bd812f9cd6c)
+ - Fix issue with temporary connection disappearing (3bd812f9cd6c)
+ - Ticket #546: Selecting a version selects the text box instead of the version ellipse (a19863118684)
+ - Ticket #550: Workspace state_changed is slow (bd734eb57838)
+ - Ticket #553: Suspended module does not execute on second run even when notcacheable (8eb9f8d11575)
+ - Parameter Exploration only worked on parameters from the Basic Modules package (75cca6574d0e)
+ - Fixed minor issue with PortSpec shape and docstring attrs (aebf4f84b052)
+ - Ticket #418: The database schema should use larger data types (75c7c6c89fdf)
+ - Bug in translation from 1.0.3 to 1.0.2 (75c7c6c89fdf)
+ - Fix issue with configure item grabbing mouse. (479a29491abc)
+ - Removed capitalized methods from ports in VTK (49aa19ba2ce3)
+ - Parameter Exploration: Changed call to update the progress bar to be thread safe (b9942f416fe1)
+ -  Mediawiki extension: fixed undefined variable  (d3d68b1c53ab)
+ - WorkflowExecution.completed were set to False in the vis_log, it should be an int. (50a2a68e177a)
+ - DBVistrail.hash*Annotation() fails when annotation values are ints (3d7f1b9cc078)
+ - Fixed path_to_figures and get_wf_graph_ calls in application_server (6df2c53cc880)
+ - Do not import VTKCell unless we have the spreadsheet (a8b7c8345ee9)
+ - HTTP Package now respects alternate dotVistrails setting (88b53249d96d)
+ - The create analogy button is too small (65be8388e906)
+ - "Show raw pipeline" and "construct from root" commands should switch to the pipeline view (dc2deb9ed6e0)
+ - Fix command_line argv dependency (5786189661b2)
+ - Mashups: slider and numericstepper widgets are only displayed for numeric aliases (3b8c4f954bce)
+ - Mashups: Validating Min Max and Step edit boxes so they accept only numbers (3b8c4f954bce)
+
+From release: v2.0.2 build 3813fdd2573b from v2.0 branch
+
+Enhancements:
+ - Added animation support to matplotlib/pylab (38fb971b6305)
+ - Job Monitor Improvements (af8f43039c94)
+ - Job Monitoring Tool View (3c43a8c5b3b7)
+ - Add support for customizing which packages are (not) reloaded (91e18f8749a0)
+ - Testing: Validate Workflows by comparing old and new thumbnails (401588f3bfdb)
+ - Added saving/loading SubWorkflows to/from the DB as part of a vistrail bundle (0704f03b2011)
+ - Ticket #628: Set the path to the vistrails tmp dir (f07b3223d16d)
+
+Bug fixes:
+ - Saving log to previous version failed (e66941c40e22)
+ - Opened vistrails were not selected (14415ac3c709)
+ - parallelflow: Do not deepcopy module dict (e66a6a3713ec)
+ - Fixed matplotlib spreadsheet cell resizing issue. (45f803f0763c)
+ - API: return result after execution (aec0ed019ac5)
+ - Job Monitor icons were set incorrectly (d5e332c4e410)
+ - Job Monitor did not delete job when vistrail was closed (d5e332c4e410)
+ - Workspace: Sometimes selecting an open vistrail does not select it (e1f57079d0fd)
+ - Ticket #651: Function remap upgrade operations performed in incorrect order (6aaa72017fa8)
+ - Fix ordering in function remap (6aaa72017fa8)
+ - Ticket #648: 'OutputPort' object has no attribute 'module_exec' (c9847fc14bb9)
+ - Ticket #647: ModuleSuspended does not work inside Groups (c9847fc14bb9)
+ - Ticket #645: Document py_import in dev guide (bf9a58708fa2)
+ - Ticket #646: Reloading packages fails in some cases (91e18f8749a0)
+ - Fix issues with package reloading (91e18f8749a0)
+ - Fixed broken mimetypes on Windows (9aa51dd35301)
+ - Ticket #643: cannot open workflow triangle_area.vt (67726aceba3b)
+ - Ticket #625: Improve crowdLabs upload interface (7389abac0902)
+ - Added DB version map 1.0.2->1.0.3 needed when downgrading the log (172301ad3858)
+ - Saving abstractions do DB was missing version translation (45ebc5afa303)
+ - Removed faulty import DBProvModel (6727b6ee2fe8)
+ - Ticket #619: Create Analogy does not work on spreadsheet (39df0813e11c)
+ - Fix issue with analogy api in the spreadsheet (39df0813e11c)
+ - Ticket #638: Re-execution of SubWorkflow is missing parameters (294574341168)
+ - Fix issue with subworkflow caching (294574341168)
+ - Ticket #634: Package Documentation says port sigstring can contain spaces (dfc9db1f4dc5)
+
+From release: v2.0.1 build 5e35e2b83b90 from v2.0 branch
+
+Enhancements:
+ - ALPS package: Updated to version 2.1.1 (4741aa04a9d7)
+ - Support import of schema v1.0.3 (94bb430fa0f0)
+ - CLTools: Preview command line arguments and module ports (6c737e297a60)
+ - CLTools: Reload modules from the wizard (6c737e297a60)
+ - CLTools: Add env port using wizard (6c737e297a60)
+ - CLTools: Extended documentation (6c737e297a60)
+ - CLTools: Ability to specify fixed environment variables for modules (6ece9152e511)
+ - CLTools: Write changes in environment variables to execution log (6ece9152e511)
+ - Added server function for seeing and enabling/disabling packages (1b7ad7717b31)
+ - CLTools: Ability to set working directory (cbf02c561ccd)
+ - CLTools: New arg type inputoutput that enables files be used as both input and output (692e3ce05961)
+ - CLTools: You can now specify file endings for output files using the suffix option (692e3ce05961)
+ - Ticket #582: CLTools: should support other types (c3b49457c3a5)
+ - Added single instance check as a configuration option and a command line option (4032ca504171)
+ - Improved exception message for invalid port specification (431802313d43)
+ - Improved error messages during package loading (4175f8c09b4d)
+
+Bug fixes:
+ - Added the missing v1_0_3 directory for schema v1_0_3 support from master branch (916cf9162df8)
+ - FileHooks for DBVistrail types should be skipped (94bb430fa0f0)
+ - Check if package has been removed before setting package information (94bb430fa0f0)
+ - CLTools: Modules were not reloaded after reloading scripts (6c737e297a60)
+ - CLTools: "env" option was not reset in wizard when loading other tool (6c737e297a60)
+ - Server mashup request need to use db user with write access (af73f32d44c0)
+ - get_vt_graph_png was broken (af73f32d44c0)
+ - Ticket #617: Hard import from the v1_0_0 schema in opm.py makes it fail with other schemas (2fefff447711)
+ - Fix OPM import (2fefff447711)
+ - Windows: Saving vistrail zip xml fails when zip.exe cannot be located (32bd4aa03c3b)
+ - Ticket #624: unix /bin/ls check fails on fedora 17 (ee2cd7d1f6c3)
+ - Ticket #621: Hidden ports that are used in connections are not set to visible (4cb7b1758bac)
+ - Fixed visibility of a connected port in ports panel (4cb7b1758bac)
+ -  Fixed documentation file of CLTools that was causing a failure when
+building the pdf version of the usersguide  (3899208009dd)
+ - is_running_gui missing in VistrailsServerSingleton (272006002712)
+ - Ticket #618: Open Workflow from DB missing in file menu (8e413fc8f504)
+ - Ticket #614: test_abtraction_create fails in test suite (2315d8e92026)
+ - Ticket #583: CLTools: sometimes a module called CLTools is displayed (11107c05a73a)
+ - Empty packages could not be reloaded (11107c05a73a)
+ - Ticket #612: User-defined parameter exploration editor is problematic (deab533c7302)
+ - Fix issue with modified group signatures (cd8e2467903b)
+ - Ticket #464: VTK Package does not support VTK 5.10 release (65462fd17800)
+ - Fixed issue where OPM export could not resolve ports in parent modules (cdc1a53bf496)
+ - Fixed issue where modifying a defaulted parameter caused a second copy of the parameter to be added (d6924b42d821)
+ - Ticket #602: core api does not work in console (ac85e1935819)
+ - Add missing methods to GUI application (ac85e1935819)
+ - Ticket #594: Defaulted booleans added twice (e90af069e58a) (d6924b42d821)
+ - Fix duplicate boolean values when using defaults (e90af069e58a)
+ - Update color of cached modules correctly and reset colors on re-execute (421ef3182f7b)
+ - Do not set module color back to active after it has been run (1f6ea4ff45e3)
+ - Ticket #591: User-decorated modules do not change color during execution (c53334a5e412)
+ - Module status brushes are checked first when setting the color of a module (c53334a5e412)
+ - Ticket #592: Dragging a Group module into a pipeline causes an invalid pipeline error (cd8b62b219a6)
+ - Guard against empty group modules (cd8b62b219a6)
+ - Spreadsheet package: Checking if the GUI is running before trying to initialize the package. (a71954b1639a)
+ - Ticket #586: Selecting an invalid module raises exceptions (225f057294dd)
+ - Catch exceptions when selecting invalid modules (225f057294dd)
+ - enabling/disabling package did not invalidate pipeline (a363ed3f0151)
+ - Ticket #585: Failed reloading of a package does not invalidate modules (46a6204cbab4)
+ - Fixed issue where modules were not marked as invalid before validation (46a6204cbab4)
+ - Ticket #584: Enabling a package adds it to the enabled package list even if there are errors (0593aad10533)
+ - Fix issues with package list in preferences (0593aad10533)
+ - SUDSWebServices: Offline Mode by storing WSDL in .vt file was not portable (6fa03241e9c6)
+ - SUDSWebServices: Typo in handle_missing_module caused packages with wrong names (6fa03241e9c6)
+
+From Release: v2.0 build 240bcab5bbcd from v2.0 branch
+
+Enhancements:
+ - Ticket #424: SUDSWebServices should store the WSDL spec in the .vt file to enable upgrades (88f616a741de)
+ - Packages can store files in .vt zip files (88f616a741de)
+ - .vt files using SUDS Web Services can now be edited offline (88f616a741de)
+ - CLTools: package menu option for reloading all scripts (3c83b7101bc0)
+ - CLTools: added Open Wizard to package menu (1f19d0a7339a)
+ - Added CLToolsWizard.command file to Mac Binary (99adfd823a2d)
+ - Ticket #430: use of absolute file names can be problematic in vtl files (2b731d8d5043)
+ - LaTex Extension: Added support for relative .vtl links in pdf and relative filenames
+   in .vtl files (2b731d8d5043)
+ - Package requirement for the job submission package (77f3f1761f92)
+ - Ticket #519: Executions in Version View that fail should change to pipeline (cea08c6e25d9)
+ - Switch to pipeline view if an execution fails (cea08c6e25d9)
+ - Ticket #557: Password dialog (f9739db121c4)
+ - Ticket #559: Persistent modules do not work in groups (4ef2b8639b6d)
+ - Allow modules in subpipelines to be cached (4ef2b8639b6d)
+ - Added alps package to VisTrails 64-bit Windows Binary  (519d862a63f5)
+
+Bug fixes:
+ - Ticket #575: Vistrail variables panel has an overdraw
+   problem (c4171c8aab63) (09815c35efb8) (7ca53292670a) (07fdeb8602a7) (45a4818a0b5c)
+ - Ticket #404: Overriding a port via add_*_port does not work (47e72744ede1)
+ - Ensure add_*_port can override ports in superclass port lists (47e72744ede1)
+ - Ticket #523: Default values for parameters not showing (e3f1b1a3253f)
+ - Add default support back in (e3f1b1a3253f)
+ - Fixed spelling in repository.py (6c2259e84214)
+ - SUDSWebServices: Wrong indentation caused vistrail save to fail (5497e50c727f)
+ - Ticket #576: Analogies are only displayed if we change the focus out of VisTrails to
+   another application and back (d782197a1cab)
+ - Fix issue with redrawing the tree after analogies (d782197a1cab)
+ - Running instance was not accepting parameters from another instance (63b58b8416d0)
+ - Ticket #464: VTK Package does not support VTK 5.10 release (3e3700900ad0)
+ - Ticket #445: mashup previews is not always shown in the main window (9111971ce8c6)
+ - Now persistent cache works after one execution (87e8ff129b88)
+ - Ticket #573: Opened vistrail fail when reloading dependent package (b1ff731d904a)
+ - SUDSWebServices: Failed Web Services could not be removed (b1ff731d904a)
+ - Execution button may hang when execution fails (b1ff731d904a)
+ - Ticket #571: Vistrail variables cannot be used in more than one workflow (02f2acee1727)
+ - Fix issue when setting a vistrail variable on multiple modules (02f2acee1727)
+ - Ticket #574: Cannot add variable to empty detached Vistrail Variables window (4ae4f3d9c582)
+ - Fixed issue with creating vistrail variables in an undocked panel (4ae4f3d9c582)
+ - Ticket #539: Standard Module Configuration Widget asks to save when two ports are
+   enabled (154525da1047)
+ - Ticket #521: Annoying PythonSource behavior (154525da1047)
+ - Configuration widgets will prompt to save only when the current
+   module change, making it easier to copy text from another application (154525da1047)
+ - QVistrailsWindow.get_current_view() was returning the wrong view sometimes (154525da1047)
+ - CLTools: IOErrors when executing process (d810075f00a6)
+ - Fix issue with analogies that also require upgrades (215ceae6ef1f)
+ - Fix typo (50da981b6938)
+ - Fix issue with remove vistrail variable modules and connections (c3183771c5ea)
+ - Ticket #569: Connected icon in Module Information does not disappear after removing
+   connection (9a68ec624c9d)
+ - Fix issue with connected indicator for ports (9a68ec624c9d)
+ - Eliminate duplicate warnings (f6020fa412bb)
+ - Use lil_matrix for analogies (f6020fa412bb)
+ - Modify logic of analogy usage to use current selected version (f6020fa412bb)
+ - Ticket #419: Analogies fail on new terminator.vt (83c7735b0d28)
+ - Change analogies to use a suitable default alpha value (83c7735b0d28)
+ - Ticket #567: CLTools has issues reading man pages on Mac OS X (cdb5368df6fc)
+ - Ticket #370: dataDirectory setting not used (73fe930b49ff)
+ - Loading an image from workflow graph or a version tree was not
+   working in the command line (2b731d8d5043)
+ - Workflow results that used a VTKCell were consisting of a black
+   screen when running in batch mode (80d55defb140)
+ - Ticket #551: Cannot access messages window when preferences window is open (cc8fa8e6ad8a)
+ - Ticket #487: isosurface script version of terminator.vt causes vistrails to
+   crash (02caf56e6c0e)
+ - Ticket #564: Invalid view warning (3b2062c17cb0)
+ - Ticket #552: No visual clue when ubuntu package finishes installing (2f78b1b1d749)
+ - Ticket #540: Vistrail is not always marked as changed when containing a vistrail
+   variable (7acddff31ff1)
+ - Ticket #566: QPixmap scaled error message (c6842a9fa320)
+ - Fixed QPixmap scaled issue (c6842a9fa320)
+ - Ticket #517: Undo menu item not working (a7b574defe31)
+ - Fix undo/redo in pipeline view (a7b574defe31)
+ - Fix issue with executions of untagged versions (36c1a73a46ae)
+ - Ticket #560: Workspace has very inefficient updates (51a4e7982bb7)
+ - Workspace: made loading mashups more efficient (51a4e7982bb7)
+ - Ticket #562: "Save as" replaces items from workspace (d8fa58ccd9c0)
+ - Ticket #560: Workspace has very inefficient updates (3dfac92ab688)
+ - Partial fix to make workspace more efficient (3dfac92ab688)
+ - Ticket #565: Version labels in query results are not gray (22e9920d1ea0)
+ - Fix colors in query results view (22e9920d1ea0)
+ - Ticket #504: The Query's refine option doesn't do anything (1fce254de2c5)
+ - Reenable refined version tree in the query view (1fce254de2c5)
+ - Ticket #532: Edit Package Abstraction Error (7c03b6999125)
+ - Fixed issue with error message for editing package subworkflows (7c03b6999125)
+ - Ticket #541: Crash when detaching ModuleInformation dockwidget on Mac (72c7afc3a95e)
+ - Fix crash on undocking module info palette on Mac OS X (72c7afc3a95e)
+ - Ticket #546: Selecting a version selects the text box instead of the version
+   ellipse (5a7df50dd899)
+ - Make version tree selection more intuitive (5a7df50dd899)
+ - Ticket #538: Pipeline Connection Drawing? (ed11bdfffa54)
+ - Fix connection drawing issue on Mac (ed11bdfffa54)
+ - Ticket #558: Group signatures cannot be based only on interface (4ef2b8639b6d)
+ - Fix issue with caching group modules (4ef2b8639b6d)
+ - Fix initial layout of matplotlib cells (3a8d5c7c3d62)
+ - Decreased level of debug message when removing elements from Thumbnails cache (18531d5fb280)
+ - Ticket #534: Mashups hang with auto-update on (1472b6ba7f32)
+ - Ticket #550: Workspace state_changed is slow (1ed823ecbb96) (b75607ea9271)
+ - Ticket #556: Path to zip.exe not set correctly (d0389bec6df6)
+ - Fix logic in identifier checks in package manager (1882ed36cd76)
+ - Ticket #554: Port labels not displayed (a9454abc238a)
+ - Add missing port labels to ports panel (a9454abc238a)
+ - Ticket #553: Suspended module does not execute on second run even when
+   notcacheable (3e22759385d3)
+ - Ticket #549: update_db.py script does not work (fb5ad0eb480a)
+ - Parameter Exploration only worked on parameters from the Basic Modules
+   package (99969b93ece2)
+ - Autoloading a SUDS Web Service no longer produce error messages (c079bd9c52db)
+ - Ticket #513: Add detachHistoryView back (08bec17e40e6)
+ - Ticket #543: Changes to persistence module configuration doesn't work (d03382c67e1d)
+ - Fix issue where reconfiguring persistent modules caused unexpected behavior. (d03382c67e1d)
+ - Show error message when trying to open a vistrail with a newer schema version (32f47804b6c7)
+ - db_log_filename was not unset correctly for db cache (8fccb74ecab3)
+ - Ticket #531: Export To Stable Version menu does not work (1b742a9f70cc)
+ - Export to DB did not work (1b742a9f70cc)
+ - Reloading a vistrail from the database gave it the name "None" (1b742a9f70cc)
+
+
+From Release: v2.0-beta build 2d428fbd26cc from v2.0 branch
+
+Enhancements:
+ - Mashup View: Added float slider (b5d481049666)
+ - New module execution state suspended added (cb47d3fc66b7)
+
+Bug fixes:
+ - Parameter Exploration: Changed call to update the progress bar to be
+   thread safe (716501f8b2fd)
+ - Fixed bug in iceCream.vt example (929ddcaa504a)
+ - MySQLdb was not being shipped correctly in Mac binary (e50f1c91b3e8)
+ - Mashup View: integer slider did not set step size correctly (b5d481049666)
+ - Cached interpreter failed when handling wrong input type (b5d481049666)
+ - Mashup View: failure when handling errors in execution that does not use the spreadsheet (b5d481049666)
+ - Fixed qt.conf problem in installer script files on Windows. (a01fabd12456)
+ - Fixed arguments of get_wf_graph_png rpc call (7cc451bdb606)
+ - updateUpstream* failed when modules did not contain the suspended attribute (256f4b4dd8a5)
+ - Mediawiki extension: fixed undefined variable  (334083cc69e1)
+ - WorkflowExecution.completed were set to False in the vis_log, it should be an int. (cb47d3fc66b7)
+
+
+From Release: v2.0-beta build 10836452c19a from v2.0 branch
+
+Bug fixes:
+ - Fix issue with deleting modules and connections (10836452c19a)
+ - VTK package: fix problem when upgrading vtkCellArray.InsertNextCell input port (e29a873af4a1)
+ - Ticket #525: The create analogy button is too small (bf61e06b0a50)
+ - Ticket #526: "Show raw pipeline" and "construct from root" commands should switch to the pipeline view (3ada5972d872)
+
+
+From Release: v2.0-beta build b074d3a4eb44 from v2.0 branch
+
+Enhancements:
+ - Added VisTrails Server documentation (611f2082f98d)
+ - Add more functionality to core.api (26c775f0a7bb)
+ - Ticket #518: Need to fix VTK ports with no parameters (9a985c40f6a2)
+ - Add separate workflow and log xml schemas (04cb36cc5305)
+ - Added support to hardcode necessary packages on startup (834e28f7cfa4)
+ - CLTools: Added enviroment variable and default directory support (5a6e1b0daba3) (7c9a113040c2)
+ - Add operation ids to messages about illegal operations (087b235e32de)
+ - Remove most PyQt4/gui dependencies in core functionality (e6ada340cc15)
+ - Ticket #55: Spreadsheet should have more shortcut icons (5f4db41dc8f2) (127037be178f)
+ - Ticket #284: Capturing Module Errors (60c055eff8f5)
+ - Display module toolTip errors in module stack trace dialog (60c055eff8f5)
+ - Wizard for CLTools - gui for wrapper creation (a7a1db436fd0)
+ - Added support for html and mediawiki extensions to
+access a remote vistrails server  (dd7456507ab4)
+
+Bug fixes:
+ - Mashups: editing an alias' values list had no effect (c485a7433dde)
+ - Mashups: slider and numericstepper widgets are only displayed for
+   numeric aliases (c485a7433dde)
+ - Mashups: Validating Min Max and Step edit boxes so they accept only
+   numbers (c485a7433dde)
+ - Accessing Module Annotate from context menu did not work (ac100b566d84)
+ - Fixed problem where unrequested vistrail temporary files were being created during test suite (445e2b68d9e6) (1a539cad8a9a)
+ - Fix issue with alternate .vistrails directory and its subdirectories (7d26c36ef77a)
+ - Fixed MissingRequirement path and ubuntu detection (11dd911b66a3)
+ - Ticket #528: Install bundle fails with the new core_no_gui changes (87f9e83772ea)
+ - Rendering version and workflow view in server failed because of new gui in 2.0 (e149aa955dd5)
+ - save_many_to_db failed when list of objects were empty (ed257eb2d523)
+ - Vistrail server need to initialize theme after core_no_gui changes (c4d2809d9a09)
+ - Fixed server mode after merge with core_no_gui (4c2cad40c30f)
+ - Ticket #522: remove_connection failure (cc038a500e3c)
+ - Fix for remove_connection issues (cc038a500e3c)
+ - Fixed issues with tabbing in the python editor (c046c86bf0af)
+ - Fixed issue with vtkInteractionHandler which was not updated when the Save/Revert changes were made to source widgets (8abbfb8a51e9)
+ - Allow zero-parameter functions to be set from ports panel (9a985c40f6a2)
+ - Fixed issue with forced versions on modules (4ae602caa09e)
+ - Fix issue with merging thumbnails (5bcaa7e75c6d)
+ - Fixed typo in core.application's register_notification (42c7ae6b0e25)
+ - Argument error caused gui/vistrail_controller test to fail (e447e02b37ca)
+ - CHEBI wsdl changed (a7f1ab43159d) (6e00beb17ce6)
+ - Removed matplotlib backend selection warning (23a6e3a89001)
+ - Dragging a version directly on a spreadsheet cell was not executing
+   the workflow (3395a01a2139) (66d49a064e59)
+ - Fixed unable to display jpeg images in the spreadsheet
+due to a wrong Qt plugins configuration (a6a1950024a7) (333456765278)
+ - Display more meaningful error when persistent inputs do not exist in a repository (1c905da96eb1)
+ - Fix issue in ModuleDescriptor.expand_descriptor_string (7b973b4a4aeb) (35f1feb4d853)
+ - Add icons to CLTools so that they not only work on X11 (a6a08bc1dd4e) (69110931c4e3)
+ - SourceConfigurationWidget silently fails when code contains
+   non-ascii characters (0c020878edf3) (768fc8ed4df5)
+ - MultiHeads configuration was not working on 2.0  (669957620bdc) (07e9672e6186)
+ - Ticket #513: Add detachHistoryView back (f238870a17fe) (38a3b95d1b5d)
+ - Added back detachHistoryView option (f238870a17fe) (38a3b95d1b5d)
+ - Removed configuration options that are only used in non-interactive mode
+   from Expert Configuration (bb0046fe6f49)
+ - Ticket #515: opening a specific version from the command line does
+   not work (20ab44a5a4ce) (468fe95d351f)
+ - Fixed opening a specific version from the command line (20ab44a5a4ce) (468fe95d351f)
+ - Ticket #512: Add how to create alias to users guide (83e49a3d487b)
+   (d56e02d30133) (a6249193e674) (f5b881191441)
+ - Ticket #421: db version import error handling (a6eb8ae65052) (6ac6c0abec6e)
+ - Detect between when a db version is missing and when it contains
+   an error (a6eb8ae65052) (6ac6c0abec6e)
+ - Ticket #391: Module colors in Visual Diff are wrong after upgrades (6b16033351a9) (c28166f2110b)
+ - diff view did not use correct brush for non-upgraded modules (6b16033351a9) (c28166f2110b)
+ - autosave feature caused "new file" action to fail (9b19a0fc5193) (6c49e4329b8a)
+ - Ticket #511: "export workflow as xml" adds extension as "..xml" (two dots) if
+   not explicitly specified (39d605e721e5) (fb2061eec506)
+ - get_save_file_locator_from_gui was adding two dots (39d605e721e5) (fb2061eec506)
+ - SpreadSheet: prompt the user to save unsaved vistrails before trying
+   to save a spreadsheet (d296dae6e508) (5e29113d0694)
+ - Ubuntu Unity did not restore menu bar after being closed (3d702340c1fa) (719ad4dd22b5)
+ - Param Exploration User-defined function did not work because of new python
+   editor interface (8354a9340944) (0f62ec4023c7)
+ - Ticket #510: The Spreadsheet can't open/save spreadsheets (9259d3b8d619) (ae73b7e48971)
+ - Ticket #194: Copy and paste duplicates aliases (7419092665c4) (27ee5e68a7e3)
+ - Ticket #480: Executions button doesn't work (c6a9a6ac15cf)
+ - Ticket #500: Double-clicking the Execute button causes VisTrails to Hang (e024a352c6ce)
+ - Double clicking execute button no longer hangs vistrails (e024a352c6ce)
+ - Ticket #508: Add port documentation back to ports panel (01f189a1a184)
+ - Ticket #505: Version notes are not always visible after an upgrade (d16b3c834c47)
+ - Issue correct version_selected signal after upgrades (d16b3c834c47)
+ - Ticket #502: change_selected_version causes key error in adjacency_list (25104a599816)
+ - Ticket #472: parameters in parameter exploration are reset if not executed (d07bcbd5104b)
+ - Parameter exploration with Color Constant was not working (b0e0da8cc61b)
+ - Ticket #462: Ungrab mouse error after editing subworkflow (2ffac0767f88)
+ - Ticket #432: Problem with labeling groups (2ffac0767f88)
+ - Allowing opening vistrail files that contain mashups. Mashups will be ignored (7d568fec386f)
+ - Ticket #454: Can't interact with TransferFunction widget using Qt 4.7.* (f897a8e68285)
+ - Fixed header placement in xml files that were causing tests to fail (a76060081c31)
+
+
+From Release: v2.0-alpha build c4e3600b6481 from v2.0 branch
+
+Enhancements:
+ - Wizard for CLTools - gui for wrapper creation (de5fbcd6144a)
+
+Bug fixes:
+ - Ticket #508: Add port documentation back to ports panel (d83b2637f5b5)
+ - Ticket #502: change_selected_version causes key error in adjacency_list (815d38ff608a)
+ - Ticket #472: parameters in parameter exploration are reset if not executed (829303e1efeb)
+ - Parameter exploration with Color Constant was not working (ecfbedcd4406)
+
+
+From Release: v2.0-alpha build 1b88c3949efd from v2.0 branch
+
+Enhancements:
+ - VisTrails now requires Python 2.7.*, Qt 4.7.*, sip 4.12.2 and PyQt4 4.8.4 to run
+ - Reworked VisTrails interface. Added Workspace palette where user's vistrails
+   are kept. Users can open multiple pipelines in different tabs that are
+   detachable.
+ - In addition to Pipeline, History, Query and Exploration Views, new views were
+   added, including Provenance and Mashup views. The Provenance view displays the
+   execution logs of a vistrail. The Mashup view allows creating simple
+   applications based on workflows by exposing only the relevant parameters.
+   See the VisTrails manual for detailed instructions.
+ - Merged the "Methods" and the "Set Methods" panel into an improved
+   "Module Information" Palette. Now port visibility, connectedness, and
+   parameters are shown in a single display. Thus, for module types without
+   special configuration widgets, there is no need for a separate configuration
+   window.
+ - CLTools - package for wrapping command line tools (3ac68958d3db)
+ - Expand search results to include all open vistrails (b2a069e38956)
+ - Opening exported mashups using Open menu will execute them automatically (48cefab0a019)
+ - Added support for exporting a mashup to a .vtl file. To export a mashup, just
+   click the "Export" button in the mashups inspector. Double-clicking the .vtl
+   file will execute the mashup in VisTrails (09203c1e12b8)
+ - Show parameters for invalid modules (7078566f7b89)
+ - Changed "Keep" button to "Tag" in the Mashups View (5ed3637c2d6f)
+ - Open subworkflow from module palette (c48a11df430f)
+ - Executions in provenance view are now given names based on the
+   "tagname + n" naming scheme (31a4a94cf967)
+ - Update executions in workspace when they are created (8b7b85229c64)
+ - Make pipeline current when selected in provenance explorer (49e93f5f789d)
+ - Remove gui dependencies for core.modules widgets (1b8487908620)
+ - Improved default query support (b9fed84af41a)
+ - Added color difference support for queries (b9fed84af41a)
+ - Mashups: made keeping the camera across updates as an option (1642d3573f62)
+ - Add extensible query support (0df170d3335d) (5d776c28b7e2)
+ - Workspace now updates Workflows and Mashups as they are created (429ceb313408)
+ - Expand Workflows/Mashups items by default (429ceb313408)
+ - Ticket #479: Dropdown boxes have white text (677a0b750762)
+ - Added support for html and mediawiki extensions to access a
+   remote vistrails server  (2eba04217a99)
+ - Displaying mashups in workspace. Double-clicking a mashup will show
+   version tree, select corresponding version and execute the mashup. (3df2af8d8cb2)
+ - Added support for multiple PythonSource configuration windows. Read-only
+   windows can be detached from the main module onfiguration window. (372c0143f6b6)
+ - Remove workspace entry when selected file has been deleted (8bdd77c78fe2)
+ - Workspace can show workflows in a tree view (c715b4a84a38)
+ - Added a Control Flow Assistant (f05f014bc778)
+ - Added Vistrail Variables support, so that modules deriving from Constant can
+   be used to create re-usable variables (a83402e0c218)
+ - Added support for cross-vistrail diffs (c300063531e8)
+ - Perform visual diff from workspace by dragging pipelines together (dd83c3f08cea)
+ - Simplify visual diff and improve parameter changes display (65849c433682)
+ - Search results show up in workspace window (f3a763972866)
+ - Improve query handling (e4b0722b1d70)
+ - Added support for opening a vistrail in a separate window (f502431ae11b)
+ - Added Expand All and Collapse All buttons to Module Palette (264410835b7)
+ - Added annotations to WorkflowExec in v1.0.2 schema (0ade1076517b)
+ - Provenance browser now shows status icon in list (fc112c4c1079)
+ - Autosort module palette (de80a5b0fb1c)
+ - Added merge by dragging vistrail to vistrail (6bb73281842a)
+ - Executable paper editing (3a96ea787a82)
+ - PythonSource editor will now indent newline to previous line (e221d10351d1)
+ - Improved PythonEditor class using QScintilla2 (d737455457db)
+ - PythonSource editor will now indent newline to previous line (d1e5d63bd715)
+ - Enhanced query capabilities (0e5f60ce0d91)
+ - Added support for interpreter to execute a pipeline with an extra list
+   of parameter values. Updating VistrailController calls to also accept
+   the new list (db6e4611305)
+ - persistence package now hides file references instead of deleting them (ae3d19282ef4)
+ - Added versioning for SUDS Web Services using content hash (47279d4246bf)
+ - Improved PythonEditor class using QScintilla2 (5ed5953f57b9)
+ - ParaView package: Added ScalarBarWidgetRepresentation to Rendering
+  namespace in modules list.  (7429a1be15cf)
+ - Add better provenance information for persistent entities (22964cfeb53b)
+ - New manager for persistent store (f0dafc611fd0)
+ - Improved efficiency of vtk workflow upgrades (3736cc9ef269)
+ - LaTex extension: Added an example for embedding local files (be50aeab59ca)
+ - Group SQL statements to enable faster DB communication (b520f1c847c8)
+ - ParaView package: Added server configuration window options to
+package configuration and loading initial values from there. Also added
+option to start paraview server when the package is initialized.  (9023c13aa76b)
+ - Ticket #408: Allow opening multiple PythonSource Editors (73e72b8419a8)
+ - Ticket #411: Support temporary directories in the FilePool (7eb29d2ba0fb)
+ - Initial version of a GIS package that uses QGIS (4cd7cc6df8db)
+
+Bug fixes:
+ - VTK Package: Call to ResetCamera() in vtkRenderer was producing wrong
+   results (d5789e5a560b)
+ - Ticket #499: Issue with BaseView.layout (9dc74870fde7)
+ - Fix issue where 'layout' was an overloaded field name (9dc74870fde7)
+ - Ticket #494: Tuple configuration is confusing and causes configuration errors (30bc134d5cdb)
+ - Ticket #498: Need to update code to show parameters for invalid modules (8da733c07199)
+ - Enable showing invalid function and show parameters in separate fields (8da733c07199)
+ - Updated version of suds python library on both Windows and Mac binary.
+ - Ticket #488: configuring webservices breaks vistrails (090a45a95f19)
+ - Ticket #456: Cannot copy/paste in detached pipelines/vistrails (970ec4ecfb42)
+ - Ignoring action updates when the view does not have the actions (970ec4ecfb42)
+ - Make provenance view read-only (9774b9e2928e)
+ - .vtl files marked to be executed when opening were not executed (09203c1e12b8)
+ - Ticket #496: Showing/hiding module ports resets module position (c073ff4bf200)
+ - Keep module position when changing visibility of ports (c073ff4bf200)
+ - Ticket #488: configuring webservices breaks vistrails (b8a935d8bbae)
+ - Ticket #495: vtkCellArray won't allow multiple points through
+   InsertCellPoint (0dcbf136aeb8)
+ - Fixed issue with ports that may have multiple functions associated with
+   them (e.g. in the vtk package) (0dcbf136aeb8)
+ - Ticket 481: Optional Output Ports collapse to non-Optional ones (7463f214023b)
+ - Fixed the issue of being unable to activate windows under Mac OS X
+   Lion. (7463f214023b)
+ - Mashups: Fixed bug introduced when removing gui
+   dependencies for core.modules widgets (76a998022666)
+ - Ticket #492: Upgrade error: signatures differ (5a70996965f8)
+ - Add upgrade for PythonSource to fix issue with 'self' port (5a70996965f8)
+ - Fixed messages during upgrades so that upgrade info is not flagged as
+   a warning (8714561fed05)
+ - Mashups: creating aliases in mashup view was not updating the alias
+   table (770f755d089d)
+ - Ticket #491: Opening a .vtl will always create a new file (3a25858be1ac)
+ - Opening vtl files: igonring showSpreadsheetOnly if execute is false (3a25858be1ac)
+ - Starting VisTrails by double-clicking a vistrail file was
+   not zooming the current pipeline view (3a25858be1ac)
+ - Can now delete from workspace using backspace key (d3f7af2868b0)
+ - Remove vistrail from workspace if removed from disk (044a841b97e9)
+ - view.is_abstraction logic fixed (044a841b97e9)
+ - sql package was not using new gui.modules.source_configure (1714703fb145)
+ - Updated VTK, Persistence and Matplolib packages to use
+   gui.modules import (f953ce4d25e4)
+ - get_current_view bug caused double-clicking a vistrail to fail (00b264c0920b)
+ - Ticket #489: VisTrails 2.0 can't open .vtl files anymore (2d450422c25b)
+ - opening .vtl files fails (2d450422c25b)
+ - Ticket #460: Subworkflow port naming errors after editing (687becdff050)
+ - Fixed issue where subworkflow edits could result in one-to-many
+   port mappings. (687becdff050)
+ - Fixed issues with multiple versions of subworkflows appearing in the
+   module palette (186d5c06a788)
+ - Do not store subworkflows in "recent files" or "My Vistrails" (17aebdbd32fa)
+ - workspace.item_selected had invalid setSelected call (3effd7a1385b)
+ - Fixed 2 detach view bugs (3f5159f5b49f)
+ - Ticket #468: Diff tab should have all modes except pipeline
+   disabled (4f691ba6ed23) (139ec1d18b22)
+ - Fixed an issue when loading a vistrail that references different versions
+   of a subworkflow that share common ancestors (4b34089abb09)
+ - Ticket #486: query execution and parameter problems (323f12916d09)
+   (0262b0410051) (d9fbb412a9b5)
+ - Added ability to open workflows from query results (323f12916d09)
+ - Ticket #484: subworkflow save causes window to change (bc100442dfe4)
+ - Fixed issues with executing queries (0262b0410051)
+ - Fixed issue where numeric comparisons were being done as
+   string compares (d9fbb412a9b5)
+ - Fixed issue where substring queries were backward (d9fbb412a9b5)
+ - Fix an issue with copy/paste to query view (b9fed84af41a)
+ - Fix issue with package subworkflows and namespaces (87c7c61f1c9e)
+ - Ticket #476: numeric stepper has wrong default value, in some cases
+   (1642d3573f62) (a08e8dc0f9c2)
+ - Ticket #485: Random Mashups Window (917b1d8b83c5)
+ - Allow return to original query in interface (0df170d3335d)
+ - Allow parameters to be set in queries (0df170d3335d)
+ - Allow return to original query in interface (5d776c28b7e2)
+ - Allow parameters to be set in queries (5d776c28b7e2)
+ - Ticket #478: Mashups updating issues (e5913008d81c)
+ - Mashups: Display Widget section was not updated when
+   switching aliases (e5913008d81c)
+ - Mashups: Mashup inspector was not updated when switching
+   vistrails using the workspace in Mashups View (e5913008d81c)
+ - Mashups: Mashup Pipeline Palette was not being updated when
+   switching mashups using the Mashup List Panel (e5913008d81c)
+ - Ticket #483: Index error when recovering a vistrail (8589b301ba13)
+ - Fixed issues with upgraded subworkflows (9c4dfcbef423)
+ - Ticket #475: Changing the background color fails in Mashup mode (31670c3e66f2)
+ - Ticket #477: opening mashup from workspace doesn't show exposed
+   parameters (429ceb313408)
+ - Sometimes closing a vistrail while closing VisTrails fails (429ceb313408)
+ - Double clicking a vistrail in file browser fails because of
+   _first_view bug (263f1947cf2c)
+ - vtkhandler did not handle new PythonEditor correctly (aa3511259f10)
+ - Ticket #443: ports are not added through Module Configuration
+   and annoying confirmation (01ed7a6566b3)
+ - Ticket #473: Cannot execute from history view immediately after
+   opening vistrail (e0ba2e97d058)
+ - Ticket #472: parameters in parameter exploration are reset if
+   not executed (63c55f11f03d)
+ - Ticket #474: Error quitting when spreadsheet is visible (afe4512b1ca9)
+   (107b24e904ea)
+ - Ticket #470: copy doesn't copy to the correct cell (c44347501d5a)
+ - Fixed issue with cell locations in spreadsheet editing mode (c44347501d5a)
+ - Ticket #471: visual diff window is missing the create analogy
+   button (14a24ea42b15)
+ - Ticket #469: locate version in editing mode selects history but shows
+   pipeline (080a2dc8b820)
+ - Opening xml vistrail from workspace showed open file dialog (069db5448e8e)
+ - Module documentation in module palette not working (647613ad637e)
+ - Ticket #467: A file is changed when test suit is run (37e0ab607139)
+ - Ticket #466: history mode selected and pipeline view shows up after
+   merging 2 trees (e22fe0a4f8b0)
+ - Ticket #459: the explore tab draws upside down (542e2cda8845)
+ - Outdated inspector.annotated_modules value caused explorer tab to be
+   drawn upside down on Mac (542e2cda8845)
+ - Ticket #446: subworkflow editing only good for one save (2ab6a92c2084)
+   (85b50d980ab1)
+ - Fixes to subworkflow upgrades and save as (2ab6a92c2084)
+ - Changes to subworkflow identification (85b50d980ab1)
+ - Ticket #465: Open Recent menu does not contain saved vistrails (a484b18b3eed)
+ - Update recent files list also when vistrail is saved (a484b18b3eed)
+ - Ticket #463: Current version not selected on open (154e9b2e8eaa)
+ - Select latest version when opening a vistrail (154e9b2e8eaa)
+ - Ticket #462: Ungrab mouse error after editing subworkflow (6aaa6bd2b526)
+ - Ticket #432: Problem with labeling groups (6aaa6bd2b526)
+ - Ticket #461: Initial history view for first vistrail is not zoomed to
+   fit (b3d8909ac0ed)
+ - Fix zoom to fit for initial vistrail (b3d8909ac0ed)
+ - Ticket #434: Can't remove tags of versions that were
+   upgraded (v2.0) (47636de1ec66)
+ - Fix issue where raw pipeline and construct from root were not
+   working (47636de1ec66)
+ - Enabled Embed version by default when selecting Publish > To Paper (8bf5e737a2c2)
+ - Ticket #456: Cannot copy/paste in detached pipelines/vistrails (0cb6ef7650af)
+ - Fixed issues with spreadsheet editing for copies and analogies (d2d4bae51a6d)
+ - Enabled Edit Configuration and Show Documentation from a module's
+   context menu  (00dcb21d22a6)
+ - File > Export > PDF was not working  (fce8cc569c14)
+ - Ticket #455: Module Information Tab stretches unnaturally when package
+   has a long name (2d07662227fd)
+ - module information stretches unnaturally (2d07662227fd)
+ - Ticket #457: PythonSource ports are not updated when configuration window
+   is saved (f6e151300476)
+ - Ticket #456: Cannot copy/paste in detached pipelines/vistrails (f9470d9fa04a)
+ - Removed missing web service (028fc4e03c62)
+ - Fixed header placement in xml files that were causing tests to fail (4db41b9e2e75)
+ - Workspace fixes for saving empty vistrail and closing detached
+   vistrail (1f798a7a0c84)
+ - Ticket #454: Can't interact with TransferFunction widget using
+   Qt 4.7.* (ea7e21dc9e01)
+ - Ticket #453: Workspace indexing error in tree mode (f8b17ab82b9b)
+ - Skip workspace make_tree when no window exist (f8b17ab82b9b)
+ - Ticket #450: Indexing failures need to be more graceful (f76532828242)
+ - Better error handling when indexing workflow (f76532828242)
+ - Ticket #452: Visual Diff Parameter Changes not detected (65849c433682)
+ - If the clipboard contained utf-8 characters, VisTrails would raise
+ an error (d7cecf541ced)
+ - QPipelineScene.addModule were calling addItem twice (d77e833f431f)
+ - Dropping vistrails variable created error (8c0b0e921201)
+ - Fixed export/import menu options (8d68b5b56ff3)
+ - Fixed parameter exploration in v2.0 (8485390429b1)
+ - Parameter exploration was not saving color parameters when they
+were being interpolated (8485390429b1)
+ - Fixed 'Diff properities' label typo (8a88bd21895a)
+ - Removed close button from Vistrails Messages view (2581ea446bad)
+ - Ticket #441: vistrail browser is not being updated (d892cd18e5b8)
+ - Correctly update collection on load/save (d892cd18e5b8)
+ - Show project selector (d892cd18e5b8)
+ - Sort default project by name (d892cd18e5b8)
+ - Ticket #435: diff result is not properly sized/centered (96c4adaa2a1a)
+ - Show executions for the current session as well (fc112c4c1079)
+ - Workspace threw exception when closing vistrails (47ae1c3c4428)
+ - Fixed crash when running VisTrails 64-bit on Windows with more than 4GB
+   of RAM (71b4bfc41a6d)
+ - 2 bugfixes to the vistrail merge code (4f05a96bcc2c)
+ - open merged vistrail in new tab and other fixes (556804ba40c4)
+ - builder_window was stealing ctrl-z/ctrl-y from PythonSource (e221d10351d1)
+ - Made new PythonEditor use correct font (2579b6f662ca)
+ - removed self reference in static method in persistence package (12e57882a72b)
+ - open merged vistrail in new tab and other fixes (971228751494)
+ - Fix menubar issue on non-Mac platforms (9d5e66156935)
+ - persistence package did not show dates correctly (357f3a55aaf5)
+ - Spreadsheet package: Fixed a typo on the usage of issubclass() which prevented
+   subclassed sheets to be used by the spreadsheet (8bcd8ac86cd4)
+ - SUDSWebServices wsdl caching in Windows need to use pickle
+   protocol=0 (4ca71139f604)
+ - SUDSWebService wsdl hash did not use the correct wsdl string (4ca71139f604)
+ - Fix issue with caching and persistent files (f56f14061d3f)
+ - ParaView package: Fixed example pipeline where it should display
+   both a box and a sphere.  (7429a1be15cf)
+ - VTK Package: Fixed bug when drawing TransferFunction widget (daaacfcedfca)
+ - Handle unnamed data when writing from manager (22964cfeb53b)
+ -  Fixed infovis example  (7d6a0dace8ca)
+ -  Fixed NOAA Web services example. NOAA had changed the urls
+for their services  (7d6a0dace8ca)
+ - Do not import MySQLdb directly in sql_dao (b1d1809c0d57)
+ - Ticket #420: VisTrails fails to install package dependencies on Ubuntu (35cd1cceeded)
+ - debug imports cause ubuntu package install to fail (35cd1cceeded)
+ - Ticket #416: The log is not copied when saving a vistrail from database to disk (1af107087fbe)
+ - Include log when copying vistrail from DB (1af107087fbe)
+ - LaTex extension: When generating LaTex command using the Embed panel,
+ make sure to enclose tag between {} so symbols are escaped. (be50aeab59ca)
+ - LaTex extension: Fixed problem when passing envrionment variables
+using \vistrailsenv{} (be50aeab59ca)
+ - Ticket #417: Database INSERT statements are not protected from overflowing (b520f1c847c8)
+ - Overflow checking for SQL datatypes (b520f1c847c8)
+ - Changed memory size to be computed in megabytes instead of bytes
+to avoid large numbers (4d21156d99f5)
+ - Ticket #414: Focus out event on Tag version edit box generates an unnecessary
+   vistrail change event (6dc3154542ba)
+ - Media wiki extension: casting returned version of a given tag to
+string before using it (6dc3154542ba)
+ - Ticket #412: Parameter exploration on File parameters fails (e54b74bb9412)
+ - Fix parameter explorations on File parameters (e54b74bb9412)
+ - Added ability to create temporary directories in the FilePool (7eb29d2ba0fb)
+ - LaTex extension: added support to work on Windows with MikTex (2bdfb94be496)
+ - LaTex extension: changed behavior of passing environment variables -
+passed variables will not replace existing ones, they will be inserted at the
+beginning (2bdfb94be496)
+ -  Removed warning when copying thumbnails fail because the files are the
+same (2bdfb94be496)
+ -  New log file was not being created on Windows when the version was
+upgraded  (2bdfb94be496)
+ - Ticket #410: Encode VTK changes as upgrades (fa2e48cedf06)
+ - Attempt to implement VTK upgrades (fa2e48cedf06)
+ - Ticket #409: Problem in workflow upgrade (5d57b4ce54b3)
+ - Fix issue with upgrading modules with null functions (no parameters) (5d57b4ce54b3)
+ - Ticket #407: Aliases in a workflow disappear after upgrade (843603916a48)
+ - Preserve aliases during upgrades (843603916a48)
+ - Replaced more GUI code that would work only on recent versions of Qt/PyQt4 (7cfcb98320ee)
+ - Replaced code that would work only on recent versions of PyQt4 (e5ca41c3fab7)
+ - Enabled with_statement for python2.5 (3ec5bdd47c3e)
+
+
+From Release: v1.7 build 325bfe1b517d from v1.7 branch
+
+Enhancements:
+ - VisTrails is now distributed under the "Modified BSD License"
+ - VisTrails binaries are now shipped with python 2.7.1, Qt 4.7.2, sip 4.12.2,
+   PyQt4 4.8.4, vtk 5.6.1, numpy 1.5.1, scipy 0.9.0 and matplotlib 1.0.1.
+Bug fixes:
+ - Importing basic_modules.py leads to import loop (325bfe1b517d)
+ - VTK Package: Fixed bug when drawing TransferFunction widget (7722fc6727aa)
+
+From Release: v1.6.2 build af4a69ad566a from v1.6 branch
+
+Enhancements:
+ - Adding pdf version of Usersguide to binaries.  (60cec4e6d858)
+ - Improved efficiency of vtk workflow upgrades (501a552cd722)
+ - LaTex extension: Added an example for embedding local files (f5976c82826f)
+
+Bug fixes:
+ - Fixed infovis example  (bd810b67daaf)
+ - Fixed NOAA Web services example. NOAA had changed the urls
+for their services  (bd810b67daaf)
+ - Added matplotlib mplot3d toolkit to Mac binary (5054da25e2e8)
+ - Ticket #410: Encode VTK changes as upgrades (aeaa56469120)
+ - Attempt to implement VTK upgrades (aeaa56469120)
+ - Ticket #420: VisTrails fails to install package dependencies on Ubuntu (5180336d429d)
+ - debug imports cause ubuntu package install to fail (5180336d429d)
+ - LaTex extension: When generating LaTex command using the Embed panel,
+ make sure to enclose tag between {} so symbols are escaped. (f5976c82826f)
+ - LaTex extension: Fixed problem when passing envrionment variables
+using \vistrailsenv{} (f5976c82826f)
+ - Changed memory size to be computed in megabytes instead of bytes
+to avoid large numbers (5f57a040c97c)
+ - Ticket #414: Focus out event on Tag version edit box generates an unnecessary vistrail change event (460836e2206e)
+ - Media wiki extension: casting returned version of a given tag to
+string before using it (460836e2206e)
+ - Ticket #412: Parameter exploration on File parameters fails (7630f10fb73c)
+ - Fix parameter explorations on File parameters (7630f10fb73c)
+ - LaTex extension: added support to work on Windows with MikTex (36322a953de2)
+ - LaTex extension: changed behavior of passing environment variables -
+passed variables will not replace existing ones, they will be inserted at the
+beginning (36322a953de2)
+ -  Removed warning when copying thumbnails fail because the files are the
+same (36322a953de2)
+ -  New log file was not being created on Windows when the version was
+upgraded  (36322a953de2)
+ - Ticket #409: Problem in workflow upgrade (040f46c2f980)
+ - Fix issue with upgrading modules with null functions (no parameters) (040f46c2f980)
+ - Ticket #407: Aliases in a workflow disappear after upgrade (5575069d2727)
+ - Preserve aliases during upgrades (5575069d2727)
+ - Replaced more GUI code that would work only on recent versions of Qt/PyQt4 (2704aa1fe222)
+ - Replaced code that would work only on recent versions of PyQt4 (50ead740f6de)
+ - Enabled with_statement for python2.5 (bec2a6498965)
+
+
+From Release: v1.6.1 build ba9616b413d2 from v1.6 branch
+
+Bug fixes:
+ - Ticket #406: Builder Window menu inconsistencies (fd46220842bf)
+ - Added support for executing workflows even if VisTrails is already
+running (useful for Latex extension) (16c1d253a63a)
+ - Added single instance limitation per user/machine instead of per
+machine. Now multiple users logged to the same system can execute their
+version of VisTrails (16c1d253a63a)
+ - VisTrails was ignoring batch mode input parameters if already running
+ (16c1d253a63a)
+ - Latex and Wiki extensions: all options can now be set from the builder. (16c1d253a63a)
+ - Ticket #405: VisTrails is not downloading unavailable packages if they are present in the packages repository (77cadf0fb8a1)
+ - VisTrails batch mode: Separated generation of the workflow graph from execution of the workflow. Added support for generating the history tree graph (77cadf0fb8a1)
+ - When generating a workflow graph VisTrails would sometimes generate a line in the borders (77cadf0fb8a1)
+ - When testing a database connection with a password=None VisTrails would crash without catching the exception (77cadf0fb8a1)
+ - When opening a vistrail from a vtl, VisTrails was ignoring the version that should be open and always opening the most recent one (77cadf0fb8a1)
+ - Latex extension: added support for running vistrails locally (15255a96e4e0)
+ - Latex extension: added support for embedding workflow and/or
+including full tree when generating vtl requests (15255a96e4e0)
+ - Wiki extension: workflows were not being embedded in .vtl file (5348cad089ba)
+ - Added title to console and debugger toolbars (b2e3bda06f62)
+ - Better error handling for duplicate module identifiers in packages (579520227409) (d5df9421d0c1)
+ - Fixed an issue where the FilePool's local copy mechanism failed in Windows (7b398b211212) (254bce86348e)
+
+
+From Release: v1.6 build e9f97c5908ac from v1.6 branch
+
+Enhancements:
+ - Added prompt for password for database access in batch mode (06c4b63434a7)
+ - Please notice that the parameter separator in the command line changed again from
+  '&&' to '$&$' so it's consistent with the server version. (35ad76515a97)
+ - VisTrails now has "Check for Updates" option in Help drop-down (b80862d8a39f)
+ - Show port_spec.sigstring in PortMismatch error message for more
+   detailed debugging (c28dad738abc)
+ - Turn off popup messages if messages window is open (62aeb9371235)
+ - add/delete Web Services from module palette for SUDSWebServices package (2e381a4394ed)
+ - Package-level context menus in the module palette (2e381a4394ed)
+ - Add preference for migrating tags and notes on upgrades (41177e74e687)
+ - Add stack trace to exception details for unexpected exceptions during
+   change_selected_version (fd3840df3c6b)
+ - Added new class Chdir to prevent users from triggering side-effects by accident
+   when using os.chdir() (4aa722db61d1)
+ - Added Open Recent to File menu (it works for vistrails in the file system or in
+   the database. The maximum number of files in the list can be configured from Advanced
+   Preferences Tab (search for maxRecentVistrails) (4aa722db61d1)
+ - Configuration object now supports bound methods as subscribers (4aa722db61d1)
+ - Debug messages now have a "details" attribute (f2911a6a6000)
+ - Buttons for filtering VisTrails messages (ebc728d49db3)
+ - Colors of message types added to theme file (ebc728d49db3)
+ - Improved log messages in the server log to also indicate the instance of the server that
+   is logging the messages (762902e79b7a)
+ - Improved handling of log messages (037568dc5960)
+ - Changed all examples using relative paths to datasets to use HTTPFile (403205442fd7)
+ - Updated head.vt and terminator.vt example to use TransferFunction widget (403205442fd7)
+ - Maintain suffixes on persistent files and directories (e9b5e906e069)
+ - Improved debug messages (9dcd1a5a2ea8)
+ - Ticket #390: Add support to Latex extension to download workflows at compilation
+   time (90ef6cee20a9)
+ - Improved error handling in vistrails.packages (a44800a88083)
+ - Improved debugging messages for vistrails.gui (25b718347ef0)
+ - Improved error handling in vistrails.core (2e095f36dc90)
+ - Debug library updated (41e3778d507e)
+ - Web Services package is now deprecated. Showing a warning message when the WebServices
+   package is loaded. Message will be shown only once. (9996bba52dd1)
+ - Ticket #375: Add GUI support for synchronizing vistrails (4efb09fbe5bd)
+ - Merge 2 Vistrails from within VisTrails (4efb09fbe5bd)
+ - Detect changes to directories so the cache can be invalidated when they change (3058d55966f2)
+ - New Web Services package that uses SUDS library (0d1d3efb99da)
+ - Add pinch gesture support to graphics views (3d01e549f849)
+ - ParaView package: Converted to new VisTrails package format (65453bd92aa5)
+ - Updated php scripts to work with Latex extension's new features (2b53ad32a374)
+ - VisTrails server: added new function to return version tree as pdf  (2b53ad32a374)
+ - Created a separate php file to store the server configuration (8d15fdbe8e1d)
+ - Added support for running crowdlabs and vistrails server on separate machines
+   (still testing) (064304a99993)
+ - Ticket #382: Improvements to Latex extension (3123297d6a1b)
+ - LaTex extension: VisTrails can now embed a workflow graph or a history tree in
+   LaTex pdf (3123297d6a1b)
+ - LaTex extension: Caching latex instructions and images for embedding images in case python
+   is not available (3123297d6a1b)
+ - Ticket #381: Split HTTPFile.compute() method to download the file in a separate
+   function (62d25dca3f3a)
+ - Add MplScatterplot and MplHistogram modules to pylab (4af6514c20d4)
+ - Ticket #295: Add Debug .command to Mac distribution (e835d69d8426)
+ - Added git executable to windows repository. It will be included in future windows
+   binaries for persistence package  (8d9931bbbe04)
+ - Updated version of the rpy package (c895125216cb)
+ - Migrating new persistence package from persistence_exp to persistence (5b6418233dea)
+ - Added methods to expand shortcut string representations for module descriptors and port
+   specs (5b6418233dea)
+ - Added support for shortcuts to remap modules/ports for upgrades (5b6418233dea)
+ - Use List for controlflow now instead of ListOfSElements (74f30460d3fe)
+ - Highlight invalidate port specs (74f30460d3fe)
+ - Improved support for work with the filesystem. Added DirectorySink module,
+    changed FileSink module to use 'overwrite'
+    instead of 'overrideFile', added support for getting the contents of a
+    directory, created a new OutputPath constant with a save-style widget
+    to select the output path, replaces OutputName on the FileSink module.
+    Added updgrade code to translate old FileSink module to new version.
+    Changed version of basic_modules and abstraction to static string
+    '1.6'. (fb30dca8a15d)
+ - HTTPFile now supports proxies. (3799edddbb62)
+
+Bug fixes:
+ - Fix issue with console mode and unit tests (a4d544eec673)
+ - Ticket #361: Cannot configure output cell layout for cells in groups in parameter
+   explorations (5807414236ba)
+ - Enable all spreadsheet cells for parameter exploration, even if they are embedded in
+   groups or subworkflows (5807414236ba)
+ - Ticket #399: Exception thrown when loading parameter exploration tab with no existing
+   exploration (4366e52c39cf)
+ - Fixed exception when loading parameter exploration tab for a workflow with no saved
+   explorations (4366e52c39cf)
+ - Ticket #154: vistrails should check for a new version being available and tell the
+   user to download it (b80862d8a39f)
+ - Ticket #398: Failure opening vtl files (filename issue) (c52ba7adc5f8)
+ - Matplotlib package: if hide toolbar parameter is set after the source
+   and there isn't an extra line at the end, the MplPlot would fail  (c52ba7adc5f8)
+ - Ticket #398: Failure opening vtl files (filename issue) (cdfa0c97493d)
+ - Added escaping to filename in unzip commandline call (cdfa0c97493d)
+ - Fixed issue where it was not possible to ungroup a subpipeline that had an InputPort
+   connected directly to an OutputPort (e1ea9b437507)
+ - Fixed problem where controlflow package would raise duplicate errors (4351b3f0102f)
+ - Fixed issue with groups and input values that evaluate to False (6fc007c0535d)
+ - Fixed ordering of PortMismatch parameters in ensure_port_specs (c28dad738abc)
+ - Fixed bug introduced on Windows platforms when changed os.chdir() calls by
+   core.utils.Chdir (0a2b8a0d50d8)
+ - Enable the Linux theme for 'Linux' system types (57dfb4a85e7a)
+ - added deletion of namespaces in module palette (2e381a4394ed)
+ - Add ability to migrate tags when upgrades are not delayed (9c49285269ca)
+ - Message filter colors does not show in linux (ee8906c91039)
+ - Ticket #397: Save execution log when in console mode (2dae96a8f004) (1afa51d895e9)
+ - Update version tree when adding delayed actions (d1dbf3005499)
+ - Subworkflows from packages that need upgrades are now moved to local.abstractions
+   in the registry and picked up for workflow upgrades (04476a172f61)
+ - Fixed issue with spreadsheet and grouped spreadsheet cells (fd3840df3c6b)
+ - Replaced svn command with git command to get current commit (if present) (4aa722db61d1)
+ - Flush delayed actions (including upgrades) to fix issues with delayed upgrades and
+   grouping upgraded workflows (79dd982e6cef)
+ - VisTrails Server: Applied fix to caching of history tree images when
+   generated as pdfs (fc0ab9f1626d)
+ - VisTrails Server: fixed problem in caching of history tree images (4862e1f7d18a)
+ - Ignoring mouse gestures when Qt version is < 4.6 (4862e1f7d18a)
+ - Ticket #394: VisTrails server is not detecting updates in vistrails loaded
+   from the database (762902e79b7a)
+ - Restoring extensions/http/run_vistrails.php to version before merge (762902e79b7a)
+ - VisTrails server was ignoring the build_always variable if it
+   found cached images (762902e79b7a)
+ - Using port to identify the instance of the server instead of virtual
+   display in script that starts vistrails server using Xvfb (762902e79b7a)
+ - Ticket #393: Latex extension doesn't handle workflow exec. errors properly (16f522c459c5)
+ - Latex extension: Making sure to convert line breaks into \MessageBreak
+   Latex commands before displaying error messages. (16f522c459c5)
+ - Forwarding force build to server so the server can also bypass
+   caching (47a1105664a0)
+ - Ticket #392: Refactor php extensions caching logic used for wf executions (3125e0eb8e81)
+ - Updated mediawiki extension to work with crowdlabs server  (3125e0eb8e81)
+ - Added workaround for RotateFileHandler problem on Windows when some
+   packages start child processes during workflow execution (e5afc47797cb)
+ - Fixed issue where named intermediate persistent files/directories were not
+   reused correctly (df3deb58a18c)
+ - Fixed git hash retrieval for persisted directories (df3deb58a18c)
+ - Pasted text in VisTrails shell was being ignored (c48e67f02ae8)
+ - Giving focus to VisTrails shell when showing it (c48e67f02ae8)
+ - Added 'VisTrails messages' button and fixed 'VisTrails debugger' button (b401b2498c74)
+ - Don't mask AttributeErrors when materializing pipelines (b5c3650e5ca6)
+ - Add upgrade path for old InputPort and OutputPort modules (8abfff56592c)
+ - Fixed an issue with groups and upgrades (720d93c8e3be)
+ - VisTrails shell was not using fixed-width font  (b521e096f879)
+ - Latex extension: delaying check for a valid url so we can include
+   cached images if there's no Internet connection (79296270cc86)
+ - Batch mode: On Windows, VisTrails was not executing workflows
+   when an absolute path to a vt file was given (81812ac04e85)
+ - Minor error fixes (45b53eef1c53)
+ - Ticket #386: Moving modules after an upgrade generates invalid actions with
+   delayed upgrades (ad9e029035f7)
+ - With delayed upgrades, moving modules after an upgrade now generates actions
+   in the correct order (ad9e029035f7)
+ - Ticket #385: Workflow instantiation fails when doing on-demand package loading (aff3408c7a51)
+ - Fix issue with on-demand package loading leaving workflows as invalid (aff3408c7a51)
+ - Casting DBLocator names to string as they can store None sometimes (9996bba52dd1)
+ - Ticket #384: Deleting version edits version tag if delete is canceled (cc05bc9e80e5)
+ - Don't delete tag text when attempting to prune (cc05bc9e80e5)
+ - Expanding port specs deals with differences between descriptor and port signatures (c5763a437606)
+ - UpgradeWorkflowError tries to trim None-value (93b3be3d2a50)
+ - Ticket #383: Unversioned modules are not upgraded (4b3fa72869f0)
+ - If a module has no version, force it to be upgraded (4b3fa72869f0)
+ - Ticket #302: Moved modules action generated when nothing changed (3e59defe4685)
+ - Fixed logic so moved modules are properly detected and positions updated. (3e59defe4685)
+ - ParaView package: Removed hardcoded path to pvserver and mpiexec
+and using configuration object for that (accessible through Menu
+Preferences -> Module Packages) (65453bd92aa5)
+ - ParaView package: Updated pv.vt example to work with current version
+of the package (65453bd92aa5)
+ - Fixed bug in some php scripts when only the tag is passed instead of
+a version number  (2b53ad32a374)
+ - Updated all php scripts in extensions/http to work with
+the current version of crowdlabs vistrails server (only local
+setup currently supported) (8d15fdbe8e1d)
+ - Fixed bug where server method get_wf_graph_png would sometimes
+fail (064304a99993)
+ - Fixed bug where although DBLocators were being cached, the
+   connections were not  (b07c22d9e93d)
+ - Ticket #359: When using VTKRenderOffscreen module VisTrails crashes (48e477f4c1d9)
+ - VTK Package doesnt work with VTK version 5.7.0 (ba5e0bdbbb16)
+ - Fixed issue with query-by-example where parameters couldn't be updated (741b1c0d7737)
+ - Error using breakpoint due to new stack trace (d4f31af05a05)
+ - LaTex extension: removed hardcoded url for downloading vt files
+upon clicking on the images in the generated pdf. It can now be set using
+the \vistrailsdownload in the latex file (3123297d6a1b)
+ - HTTP package was not handling exceptions correctly (62d25dca3f3a)
+ - Ticket #380: HTTPFile corrupts binary files on Windows (0a5ec2007878)
+ - Color Constant: Initializing Color widget with default white
+color using RGB constructor instead of QtCore.Qt.White. We assume the
+color is always a QColor object and sometimes a GlobalColor object
+was being found (8565a276a353)
+ - Persistence Package: Added code to find tar executable similar
+to the way the path to git is set up (4a2494c09ef4)
+ - Persistence Package: adapted use of tar command to work
+on Windows (430e29bcaf2e)
+ - Windows binary: Including the gnu version of tar instead
+of the one that comes with git (430e29bcaf2e)
+ - Set MplFigureCell to fill spreadsheet cell (4af6514c20d4)
+ - Ticket #302: Moved modules action generated when nothing changed (8f60ea9a4737)
+ - Dangling move actions are displayed immediately after switching versions (8f60ea9a4737)
+ - Ticket #331: ImportError when trying to import userpackages (bc27cdc4b171)
+ - "import userpackages" fixed by reordering init steps (bc27cdc4b171)
+ - Ticket #293: Shell copy & paste on Mac doesn't work (694c0a43fbda)
+ - Use git ls-files instead of cat-file to retrive hash so that we don't have issues with Windows reading from stdin (1b190225cce9)
+ - Persistence package: fixed problem where persistent files
+couldn't be found on Windows (df8a7c2ef7d1)
+ - Ticket #369: picture-in-picture setting is confused when a new vistrail is opened (7ea68b3e863f)
+ - Check PIP preference when opening vistrails (7ea68b3e863f)
+ - Allow semi-translation from abstractionRef to abstraction so
+old workflows (version <= 0.9.3) with subworkflows can be opened (50b9ce2b28fc)
+ -  Spreadsheet: fixed 'RuntimeError: underlying C/C++ object has
+been deleted' problem during EventFilter on Windows  (93884b6a47c0)
+ -  VTK Package: Fixed rendering context problem when embedding VTKCell in VisMashup on Linux (93884b6a47c0)
+ -  PathChooserToolButton was not emitting proper signals necessary for
+VisMashup (93884b6a47c0)
+ -  Persistence package: Fixed load package error on Windows (4ee8f244fc79)
+ - Change persistence package to use correct identifier for gui widgets (9dd3ad8e0b08)
+ - Ticket #378: Workflow execution log contains duplicate entries (6d65daec6089)
+ - Fixed logging so that executions are not duplicated when saving more than once per session (6d65daec6089)
+ - Ticket #377: Exporting to OPM XML fails (3ee1cc842182)
+ - Fixed OPM output capability to work with latest object layout (3ee1cc842182)
+ - Update sql package to use List instead of ListOfElements (4b08dd9018db)
+ - Fix typo with get_package_by_name (74f30460d3fe)
+ - keep selected modules after scene redraw (bb5e4e6e1f45)
+ - Optional input ports now don't show up as output ports (bb5e4e6e1f45)
+ - Ticket #376: execute_cmdline broken (bbbcf19704b8)
+ - Fixed copyright year in background image from About box (bcd3346d8865)
+ - Web Services package: fixed bug in certain Complex Types (60128ff3a89a)
+ - Ticket #374: Web service package can't be reloaded (38976729a2a9)
+ - Fixed an issue with package reloading where modules imported using the "from" syntax were not added to the imported list (38976729a2a9)
+ - HTTPFile: Fixed error when parsing the date from the file's header. (3799edddbb62)
+
+From Release: v1.5.1 build 1863
+
+Enhancements:
+ - branching is now supported when uploading to web repositories (r1853)
+ - Added ParaView package (r1850)
+ - Added Titan package (r1847)
+Bug fixes:
+ - Ticket #368: Spreadsheet: export as single image does not work (r1861)
+ - Fixed bug where RichTextCell was not displayed when running on
+   server mode (r1857)
+ - Fixed bug with thumbnails and RichTextCell (r1856)
+ - Making sure to use only image files when generating thumbnails (r1856)
+ - Fixed web repository commit bug where updated vistrail files where not
+   successfully loaded into VisTrails after being downloaded (r1853)
+ - web repository vt id annotation is now being saved (r1853)
+ - web repository cookie is now nullified if the web repository url
+   changes (r1853)
+ - VisTrails Batch mode: Changing parameter separator from '&' to '&&' so
+   urls with query urls work (r1846)
+ - Added procedure to WIndows installer script to remove VC Redist files
+   left behind (r1846)
+ - log file names are now updated according to VisTrails version (r1845)
+ - Ticket #366: VTK overloaded ports from old vistrail files are not being shown in the GUI (r1842)
+ - Fix translation of head example from old version (r1842)
+ - Ticket #367: Different port signatures when upgrading a workflow (r1841)
+ - Translate old parameter type serialization to match port/portSpecs (r1841)
+ - Ticket #364: actionAnnotation breaks view->show all (r1840)
+ - Fix issue with annotations that have the same key/value pairs (r1840)
+ - Ticket #363: Enabling the Web services package on-the-fly is broken (r1839)
+ - Spreadsheet package: SingleCellSheetReference could not be used (r1839)
+ - On Mac, the eventFilter was not being removed when finalizing
+   Vistrails and sometimes delayed events could not be processed  (r1839)
+ - ImageViewerCell: Disabling the zoom slider when playing
+   animation (r1838)
+ - Ticket #362: ImageViewerCell Animation Icons Are Not Displayed (r1837)
+ - repository_vt_id now represents the crowdlabs vistrail object id instead
+   of the vistrails db id (r1834)
+ - when merging a vistrail with one on the web repository, a check is made
+   to see if that vistrail still exists (r1834)
+
+
+From Release: v1.5 build 1832
+
+Enhancements:
+ - Upgraded libraries: VTK 5.6, Qt 4.6.3, python 2.6
+ - Adding extension files to release
+ - Add support for calling binaries in Mac bundles (r1813)
+ - New methods for cmdline execution (r1813)
+ - Better configuration for persistence package (r1813)
+ - Added scripts for manipulating the database (r1809)
+ - User may now designate permissions when uploading vistrail to web repository (r1806)
+ - More informative upload dialog that lists incompatibilities between
+   vistrail files and web repository, including PythonSource module checks (r1806)
+ - Merges with web repository now updates local vistrail version (r1806)
+ - Changed VisTrails version to 1.5 (r1805)
+ - Files produced by FileSync modules are publishable by default.
+   Use publishFile boolean to avoid publishing the files.  (r1805)
+ - Server mode: added support for executing workflows and returning
+   results as pdf files (r1804)
+ - Latex Extension: added support for embedding pdf files. See README file
+   in extensions/latex for help (r1804)
+ - Ticket #317: Add support to the spreadsheet cells also generate PDF files (r1801)
+ - Spreasheet Package: Added global configuration for controlling
+   the file type (PNG or PDF) when dumping cells (console mode). This can be set
+in the Spreadsheet configuration panel or as a
+command line option (use --pdf or -p
+for dumping files in pdf). (r1801)
+ - Added support for merging vistrails on the server side (r1798)
+ - Added support to draw workflow graphs (as png and pdf) and
+history trees (as png) (r1798)
+ - VTK Package: Added the ability to use the Transfer Funtion widget to
+create color mappings (vtkColorTransferFunction) not necessarily in
+volume property.  (r1796)
+ - Changed version of VTK Package to 0.9.2 (r1796)
+ - Added two new output ports to vtkScaledTransferFunction: vtkPiecewiseFunction and vtkColorTransferFunction (r1796)
+ - Handle upgrade and prune annotations during merge (r1792)
+ - Added gui code for the interactive vistrails merge (r1791)
+ - Interactive interface for merging two vistrails (r1789)
+ - Make actions immutable by moving mutable attributes to a higher level (r1786)
+ - Try to fix as many errors as possible in an upgrade, even if all cannot be fixed (r1777)
+ - Merging action annotations (r1771)
+ - Methods for hashing tags and annotations (r1769)
+ - Merging of vistrails files for crowdlabs. (r1762)
+ - Preferences for upgrades (r1761)
+ - Allow delaying persistence of upgrades until changes (r1761)
+ - PRELIMINARY upgrade support (r1755)
+ - view pipelines without having the packages (r1755)
+ - view invalid pipelines (r1755)
+ - improved pipeline validation (r1755)
+ - Add method to allow updates of a single port rather than all ports as updateUpstream provides (r1753)
+ - Dump non-ModuleError exceptions to the console (r1753)
+ - Improved string formating of nested InvalidPipeline exceptions (r1752)
+ - Allow QSearchBox to do non-incremental searching (r1751)
+ - Improved version selection handling (r1744)
+ - Server Mode: added support for multithreading (r1741)
+ - Decoupled the directory where the spreadsheet will dump cells from the configuration. spreadsheetDumpCells configuration is now deprecated. Now this setting can be configured in a per workflow fashion  (r1741)
+ - Added support for extra information to be passed along workflow executions. The spreadsheet now uses this mechanism instead of a global configuration for dumping cells (r1741)
+ - inital version of a VisTrails R package using rpy2 (r1723)
+ - easier namespace designation using _modules (r1722)
+ - easier constant extensibility and customization (r1721)
+ - improved List module (r1721)
+ - new Dictionary module (r1721)
+ - new SourceConfigurationWidget to make creating source configuration widget easier (r1720)
+
+Bug fixes:
+ - Sometimes matplotlib plots were not refreshed in the spreadsheet (r1828)
+ - Fixed the flickering issues of VTKCell on Windows (r1825)
+ - Updated Web services code to work with HTTP package chages (r1824)
+ - Fixed Python Wrapping issue with VTK 5.7.0 (r1818)
+ - Minor UI fixes to web repository dialog (r1817)
+ - web repository dialog now links to correct vistrail id on the web repository (r1817)
+ - Upon upload to web repository, an repository identification annotation is added automatically (r1817)
+ - Fixes for merging vistrails in server mode. (r1816)
+ - low-level merge code now allows passthrough gui references
+instead of importing them (r1812)
+ - Fix issue where annotation ids weren't properly assigned (r1809)
+ - Merging thumbnails (r1808)
+ - Fixed issue where database was saving parent id/type pairs as NULL (r1807)
+ - Fixed issue where deleted annotations were not translated to previous version (r1807)
+ - Fixed issue where deleted annotations could not be mapped back to previous schemas (r1807)
+ - Fixed issue where annotations were not set with the correct db flags (r1807)
+ -  Generating the pdf of the workflow in console mode was not
+working.  (r1805)
+ - Fixed bug in script that starts VisTrails in server mode using Xvfb (r1804)
+ - Spreadsheet package: corrected paper size of generated pdfs (r1803)
+ - Fixed Vistrail merge casting bugs (r1802)
+ -  Spreadsheet Package: Standard non-image type cells now correctly dump
+contents to file.  (r1801)
+ - Vistrail merge did not copy thumbnails (r1800)
+ - Fix issue with reading and writing the boolean parameters during persistence configuration (r1799)
+ - Fix issue when writing metadata of managed files (r1799)
+ - Ticket #358: HTTPFile header-based caching is broken (r1797)
+ - HTTPFile.is_cacheable is now implemented, and is aware of server headers. (r1797)
+ - Ticket #353: Import workflow doesn't set id scope correctly (r1790)
+ - update id scope after importing a workflow (r1790)
+ - Fix for older log files that have incorrectly moduleExec elements (r1788)
+ - Checking whether XML element is not None before trying to evaluate it as text (r1787)
+ - Fixed port spec naming in new persistence package (r1783)
+ - Fixed issue where always creating a new reference didn't generate an id (r1783)
+ - When pruning a node, make sure that node is removed from the version tree display (r1782)
+ - Fixed issue with re-saving to the database with groups (r1781)
+ - Fixed issue with upgrading groups and database persistence (r1781)
+ - References to thumbnaisl were being shared across
+different vistrails (r1780)
+ - Existing thumbnails were not being replaced by new ones (r1780)
+ - Don't automatically switch to pruned upgrade nodes (r1779)
+ - Ticket #357: Error after saving as [Errno 2] (r1778)
+ - Fixed issue with trying to upgrade groups introduced by upgrading port specs (r1777)
+ - Fix issues where pipelines are not validated after certain actions like copy-paste (r1776)
+ - Merging of vistrails did not work (r1775)
+ - Band-aid for analogies to make analogies with groups or abstractions a bit more robust (r1774)
+ - Fix error with handle_invalid_pipeline and subworkflows (r1773)
+ - Fix bugs in displaying missing dependencies in preferences (r1772)
+ - Pass module information through group to contained modules (r1770)
+ - Fix issue with upgrading module functions for user-defined ports (r1768)
+ - Fix issue with upgrading modules that have user-added ports (r1767)
+ - Change call to fix missing modules to the correct method (r1767)
+ - Merging of vistrails files for crowdlabs. (r1766)
+ - Fix issue with analogies where obselete method was being called (r1764)
+ - Fixed issue where automatic upgrades fail because a port is said to not be found even though the port does exist (r1763)
+ - Fixed issue with upgrading groups (r1761)
+ - Ticket #356: Action copy doesn't remap previous id (r1757)
+ - Pass simplify argument through in create_action_from_ops (r1756)
+ - Fixed issue with versions_increasing computation (r1752)
+ - Ticket #354: Package reloading raises duplicate package error (r1750)
+ - Fix issue with renabling packages where a signal was issued twice (r1750)
+ - VisTrails Server: the vistrail version was not being included in the .vt file generated by the server (r1746)
+ - fixed ModuleRegistry.auto_add_subworkflow so that it accepts the correct (filename, dict) format. (r1745)
+ - Server mode: Added a global variables to store information for accessing the database (r1743)
+ - Fixed a bug in the RequestHandler.get_wf_vt_zip() function. (r1742)
+ - The notes field in the History View now only supports plain text (r1741)
+ - Fixed issue where module label changes were not recognized correctly and raised an exception (r1740)
+ - Don't require a Module to a be of type __builtin__.type to
+allow boost:python, etc. classes (r1739)
+ - Differentiate between init.py not existing and init.py having ImportErrors (r1719)
+ - Ticket #346: Module Parameter Types Serialized Incorrectly (r1718)
+ - Update module parameter type serialization when containing namespaces to match port specs and ports (r1718)
+
+From Release: v1.4.2 build 1716
+
+Enhancements:
+ - Ticket #290: Reload packages without restating VisTrails (r1714)
+ - Package reloading support should now be fully functional (r1714)
+ - Enabling access to a Web package repository. (r1712)
+ - Started adding support for Qt4.6.x (r1711)
+ - Package vtlcreator: Exposing the function to create the contents
+of a .vtl file as a static method, so it can be called from other
+packages  (r1709)
+ - Added support for embedding workflows when using the Web extensions (r1709)
+ - VisTrails Server: Added support for creating a .vt file for a given
+vistrail/workflow on the DB so it can be embedded on a .vtl file (r1709)
+ - New module, RepoSync, has been added to the HTTP package, which enables data files to be synced with an online repository (crowdLabs) (r1708)
+ - Added basic online web repository (crowdLabs) user authentication dialog (r1707)
+ - Added ability to upload VisTrail files to online web repository (crowdLabs) (r1707)
+ - Improved package reloading support (r1703)
+ - Added helper methods, get_inputPort_modules and get_outputPort_modules, to get modules that connect to a given input port or output port (r1701)
+ - Added helper method, connections_to_module, that returns a list of all modules that connect into a given module (r1701)
+ - Ticket #290: Reload packages without restating VisTrails (r1697)
+ - Enable package reloading without the need to restart VisTrails. (r1697)
+ - SQL package also connects to a PostgreSQL database server (r1696)
+ - SQL package: added cacheResults parameter to SQLSource (r1696)
+ - SQL package also handles connection timeouts (r1696)
+
+Bug fixes:
+ - Package menu items (on the toolbar) are now properly removed when the package is disabled (r1714)
+ - Package lists can now be traversed with the keyboard (r1714)
+ - Fixed bug that when enabling a package dynamically sometimes VisTrails
+would say that it failed but if you just selected the version node again the
+pipeline would be loaded without problems (r1711)
+ - MAC and Qt4.6: VisTrails would fail to start when using MacBrushMetalStyle (r1711)
+ - Mac and Qt4.6: There was not text anti-aliasing in modules and version
+nodes (r1711)
+ - Qt4.6: Moving a module in the pipeline view would not move the
+connections attached to it (r1711)
+ - Qt4.6: Legend Window in Visual Diff would not properly display the
+colors (r1711)
+ - Fixed a bug with opening .vtl files that embedded workflows (r1709)
+ - Package vtlcreator: Fixed a bug that the version of the embedded
+vistrail was not being set (r1709)
+ - Fixed the Capitalization error in the VisTrails App Bundle name (r1709)
+ - Properly track all modules in the hierarchy of a module loaded by a package for correct packing reloading (r1706)
+ - Made reset query work immediately for the version search box (r1705)
+ - Stop creating empty actions (r1704)
+ - DBLocator: Removing object name from XML serialization.
+This was causing inconsistencies with caching locators because we don't
+know the name of the object before we load it  (r1702)
+ - Ticket #345: db connection edit bug (r1700)
+ - DBLocator: Serializing also db connection user so current
+permissions are not overriden by the cached version (r1700)
+ - Ticket #344: Ungroup failing (r1699)
+ - Ensure correct modules after ungrouping (r1699)
+ - Ticket #342: Method responses return None in Web Services Package (r1698)
+ - Complex types were ignoring the new 'self' input port when
+unwrapping contents (r1698)
+ - Ticket #341: On Ubuntu, VisTrails doesn't try to install MySQLdb (if not present) when accessing the database (r1695)
+ - Move Vistrail import into load_vistrail method to avoid
+circular imports. (r1694)
+
+From Release: v1.4.1 build 1693
+
+Enhancements:
+ - Code cleanup: removed unnecessary imports in a few files (r1687)
+
+Bug fixes:
+ - Using VisTrails as a library: added more imports to
+ init_for_library.py file (r1687)
+ - In the pipeline view, if you changed a module (moving it, for
+ example) and deselected the current node in the PIP view, VisTrails
+ would throw an error (r1687)
+ - Ticket #338: The DB Connection Setup Dialog opens twice (r1686)
+ - Package Web Services: expanded simple types map to include all
+ simple types defined in http://www.w3.org/2001/XMLSchema (r1685)
+ - Ticket #337: Web Services package fails to load a wsdl (r1684)
+ - Web Services package: Expanded simple types map to include missing types (r1684)
+ - Upgraded ZSI library in the binary releases to use trunk r1495
+ - Ticket #336: VisTrails fails when opening files with an older schema (r1683)
+ - Fix upgrades when module's version does not exist. (r1683)
+
+
+From Release: v1.4 build 1682
+
+Enhancements:
+ - EXPERIMENTAL: Packages can handle workflow upgrade requests. Still very much
+work-in-progress. If you want to enable this, set 'automaticallyUpgradeWorkflows'
+to True in the Expert Configuration tab in the Preferences menu.   (r1665)
+ - Module Packages tab in Preferences menu now shows package version. (r1665)
+ - Initial revision of a sql scripting package (r1664)
+ - Improve error messages when sql statements fail (r1660)
+ - Ticket #318: Add support for generating a .vtl file within a workflow (r1657)
+ - Allow persistence package to search for persistent entities
+in multiple stores (r1654)
+ - Added script that generates nightly source releases. (r1648)
+ - Better delete buttons on the parameters. (r1646)
+ - Add data provenance support for persistent files. (r1644)
+ - Removed "Tag" entry in the method palette (r1643)
+ - Ticket #276: Make method deletion more visible (r1642)
+ - Ticket #287: Allow parameters to be named (r1642)
+ - Ticket #291: Allow functions to be populated with default values (r1642)
+ - Can delete functions/methods by clicking the check box next to the name (r1642)
+ - Can define default values for parameters (r1642)
+ - Can define labels for parameters (r1642)
+ - Added script for (re)starting vistrails in server mode with Xvfb.
+ - Visual Diff now shows matches in white; modules shared by history are colored
+gray while modules shared by matching are colored white. (r1634)
+ - Added better default descriptions to version tree. (r1634)
+ - Enabled the 'SetInputArrayToProcess' method of vtkAlgorithm class to use
+for the InfoVis package. This port was disallowed earlier for some reason, so
+we have to watch if this will cause any issue. (r1632)
+ - Added support for storing logs and thumbnails on the database. (r1625)
+ - Add a new module that allows the user to control the order of execution of
+two sinks. (r1618)
+ - Use the module descriptor to do hashing instead of the module since the
+descriptor used may be a different version. (r1615)
+ - Fix so core and gui controllers both use the same change_selected_version
+logic. (r1614)
+ - Streamline error handling for workflow materialization. (r1614)
+ - Added Path and Directory constants and updated File constant
+along with configuration widgets. (r1611)
+ - Updated persistence package to support persistent directories
+and compression. (r1611)
+ - Initial version of a persistence package that aims to cache
+files across VisTrails sessions. (r1598)
+ - Adds support for viewing web documents in a WebViewCell using
+Qt's QWebView which is based on WebKit (r1596)
+ - Moved the controlflow package from packages to vistrails/packages. (r1588)
+ - Moved doc folder to root. (r1581)
+ - First version of source tree documentation. (r1580)
+ - Added the InfoVis example using the new VTKViewCell. (r1564)
+ - Enable more intuitive command-line interactions with
+pipelines (r1563)
+ - Added VTKViewCell for displaying vtkRenderView compatible with the current VTK trunk. Just connect vtkRenderView to VTKViewCell. First attempt, only tested on Linux. (r1562)
+
+Bug fixes:
+ - Ticket #334: Programmatic change_parameter problem (r1679)
+ - Add translation to new ids back after input/output remap. (r1663)
+ - Ticket #328: Backslashes in SQL Problem (r1662)
+ - Use prepared statements for the relational database
+persistence. (r1662)
+ - Ticket #330: Ungroup and save to db fails (r1661)
+ - Make sure that new objects are saved to the database. (r1661)
+ - Ticket #328: Backslashes in SQL Problem (r1660)
+ - Added prepared statement support for db version 1.0.1 (r1660)
+ - Ticket #329: Analogy port remap needs to check input/output remaps (r1659)
+ - Check the correct remap when changing ports. (r1659)
+ - Check for __init__.py in userpackages on startup. (r1656)
+ - Improve feedback for undo/redo (r1655)
+ - Ticket #327: Bug in exporting registry to DB (r1653)
+ - Removed global setting on package ids from sql spec. (r1653)
+ - Fixed exporting Log, Workflow and Registry to XML (r1652)
+ - Fixed exporting Log and Workflow to DB (r1652)
+ - tag "tag" was being ignored when "version" was empty in .vtl file (r1651)
+ - Copying DBLog objects was not working (r1650)
+ - DBVistrail.do_copy doesn't fail when log is None (r1649)
+ - Add copy methods to enhanced DBVistrail (r1645)
+ - Don't disable entire vistrails when they contain **unused**
+invalid port specs (r1641)
+ - Ticket #323: Subworkflows with version mismatches in underlying pipelines don't fail gracefully (r1640)
+ - Subworkflows that fail to load fail gracefully and print the
+exception (r1640)
+ - Ticket #321: Save As... doesn't save log (r1639)
+ - Save As and Export now save log data from files to files or
+files to db. (r1639)
+ - Ticket #259: Undo not available (r1636)
+ - Undo and redo are now available when the should be. (r1636)
+ - Execute Version Difference menu item is enabled at the correct
+times and functions correctly. (r1636)
+ - Ticket #326: Visual difference not considering namespace (r1634)
+ - Modules from different packages or namespaces no longer
+match (r1634)
+ - Groups try to match on their tag during heuristic
+matches (r1634)
+ - Ticket #325: DB version translation loses deleted entities (r1633)
+ - Translating to different database versions now transfers
+deleted entites from the old object to new object. (r1633)
+ -  wiki vistrails tags containing "tag" attributes were not executed on the wiki  (r1627)
+ - Ticket #320: Version Tree Display Inconsistent Across Serializations (r1617)
+ - Fix to make version tree layout consistent across
+serializations. (r1617)
+ - Ticket #319: Database copy/pastes saves not working correctly (r1616)
+ - Version updates now update the id scope to avoid strange
+errors when using VisTrails with an older database schema. (r1616)
+ - Copy and paste operations reset the id of a group's pipeline
+to None in order to allow the database to assign the correct
+id. (r1616)
+ - Unserialization now sets the unserialized object's is_new flag
+to True instead of allowing it to default to False. (r1616)
+ - Add version support into module signatures so that persistent
+files will be recomputed when upstream modules are updated. (r1615)
+ - Analogies now replace annotations of the same key and
+parameter values instead of adding new copies. (r1614)
+ - Bring unit tests up-to-date. (r1614)
+ - Ensure that debug messages are written in core controller. (r1614)
+ - Make code that adds parameters after executions work again. (r1614)
+ - core.system.executable_in_path now checks the correct error code from core.system.execute_cmdline() (r1613)
+ - Ticket #314: Visual Diff Broken when PythonSource loses/gains a connection (r1612)
+ - Fix issue with dynamic modules and the visual diff when ports
+have been re-typed. (r1612)
+ - Update documentation on create_action. (r1611)
+ - Ticket #311: Method palette doesn't obey port overloading (r1610)
+ - Ensure that ports are only displayed once in method palette
+and obey port overriding. (r1610)
+ - Ticket #309: Subworkflows crash on package version mismatch (r1607)
+ - Run ensure_modules, ensure_connection_specs on subworkflows
+during loading to try to avoid package version mismatch
+errors. (r1607)
+ - Ticket #308: Analogies fail on changed location (r1606)
+ - Fix bug with analogies where module's locations were added
+instead of changed causing problems when that module was
+deleted. (r1606)
+ - Fixed issue with deletes in sql persistence for versions 0.9.5
+and 1.0.0 (r1603)
+ - Ticket #307: Error messages when executing a workflow more than once (r1602)
+ - This fixes bug where error messages would be printed to the terminal when executing a pipeline with cached modules more than once (r1602)
+ - Fixed a typo in create_port, we don't need to call the vistrails_port
+object that was created. (r1601)
+ - Fixes some of the shell interaction methods. (r1600)
+ - Remove ternary operator for python 2.4 compatibility (r1599)
+ - Ticket #305: vistrails.sql script in schema v1.0.0 is broken (r1595)
+ - Fixed issues with versions 0.9.5 and 1.0.0 of the relational schema. (r1595)
+ - Ticket #304: VisTrails does not check if the connection to the database is still alive before performing an sql command (r1594)
+ -  This fixes bug where the MySQL has gone away error would show up when connected to a database and VisTrails was not being used for a while (r1594)
+ - Ticket #303: Thumbnail error when saving a vistrail (r1593)
+ -  Fixes bug that prevented a vistrail to be saved because of an error related with thumbnails. (r1593)
+ - Ticket #301: Double-clicking .vt and .vtl files does not cause them to be open by an already running VisTrails (Mac only) (r1592)
+ - Moving condition check to the right place so FileOpen events are captured correctly on a Mac (r1592)
+ - Ticket #299: Delete ops in analogies broken (r1591)
+ - Add some checks to make analogies better behaved. (r1591)
+ - Ticket #300: Null actions being added to the tree (r1590)
+ - Parameter selections don't generate null actions. (r1590)
+ - Ticket #297: MissingPort exception not raised (r1589)
+ - Fixes bug where user is never notified if a module on the
+registry is missing the requested port. (r1589)
+ - Updated VisTrails Server code in the trunk to be consistent with the server
+running in vistrails.sci.utah.edu (r1583)
+ - Fixed small bug that prevented load a vistrail from the database
+using the GUI. (r1582)
+ - Partial fix to deprecation messages. Not closing the ticket because it's
+not fixed on Windows. (r1576)
+ - Ticket #283: Fold Type Mismatch Error (r1575)
+ - Fix the type mismatch error message. (r1575)
+ - Update current list of ignored classes in vtk package. (r1573)
+ - Ticket #279: Analogies broken with namespaces (r1572)
+ - Use module's _get_module_descriptor call to get the descriptor to fix
+namespace issues with analogies. (r1572)
+ - Fixes a bug that shouldn't currently be exposed to an end-user.
+Specifically, the registry's udpate_id_scope method didn't add 1 to
+the begin id. (r1571)
+ - Fixed the pipeline execution mechanism in the spreadsheet that didn't work
+with the new interpreter interface. (r1567)
+
+From Release v1.3 build 1561
+
+Bug Fixes:
+ - Fixed bug that was preventing files from being saved on Windows
+
+
+From Release v1.3 build 1559
+
+Changes:
+ - Schema upgrade. Current version: 1.0.0.
+ - Updated VTK libs to use 5.4.2 release
+ - Removes conditional expression constructs, so that code runs on Python < 2.5.
+ - Including Gridfields python module
+ - Using only application single instance behavior if Qt 4.4 or later is
+   available
+ - Added support for SubWorkflows (with no database support yet)
+ - Added a Control Flow Package (see user's guide to see how to use it) and
+   related example files
+ - Added support for basic package repository
+ - Introduced a major reorg of the registry and related classes.  Specifically,
+   it adds serialization capabilities, and unifies the
+   core.modules.module_registry.PortSpec and
+   core.vistrail.port_spec.PortSpec classes.  In addition, all configuration and
+   drawing is done using PortSpecs (not Ports). It also includes revisions to
+   the PythonSource, and Tuple configuration dialogs, and adds controller code
+   to better support resulting updates. You can serialize the registry via the
+   "File -> Export -> Registry To ..." menu items.
+ - Added support for "registry quickstart" which allows VisTrails to boot
+   significantly faster.  It also further changes registry behavior to allow
+   VisTrails to function without having access to the actual python modules
+   behind the ModuleDescriptors.  Everything can be done by tracing the
+   descriptor hierarchy instead of the mro, but we still use the mro when we
+   have it.  Try the quickstart by starting VisTrails normally and selecting
+   "File -> Export -> Registry To XML..." and saving the resulting file.
+   Then restart VisTrails with the -q flag followed by the registry file:
+   (ie "./vistrails -q <registry_filename>")
+ - Use solid colors instead of textured backgrounds on graphics views,
+   since Qt (or pyqt) redraws much slower when these are enabled.
+ - Improved layout of modules in visual diff and analogy
+ - Added support for displaying thumbnails below the notes panel and/or as a
+   version node tooltip. See Thumbnails Preference tab for changing specific
+   options
+ - Improved menu File organization
+ - Added translate* methods for versions 0.9.3 and up, and updated code to use
+   them.  This should ensure that xml vistrails, workflows, logs, and
+   registries, can be updated when schemas change.  The idea is that you open a
+   vistrail, and if it is not in the current schema, it is translated to the
+   current schema, no matter if you're using an xml-based file or relational
+   database.  When saving the vistrail, the db code will attempt to translate
+   the vistrail to the schema of the database (even if it is an older version)
+   before saving.  For xml-based files, you may optionally specify to save the
+   file as an older version.  Currently, you are only able to translate back
+   to 0.9.3 (See menu "File -> Export -> Stable Version").
+ - Added initial support for workflow debugging
+ - Added the progress functionality allowing modules to show their progress
+   during the compute() by calling self.logging.update_progress(self, progress).
+ - The VisTrails Console is now a dockable window. Also fixed a long-standing
+   bug that hitting enter when cursor is not at EOL will carry garbage to next
+   line. Fixed also a bug where if user types fast enough in the shell, the
+   input fails.
+ - Added support for constants to generate custom hashes. The main current
+   usecase is File constants, which hash against filename and last-modified
+   times. The biggest consequence is that pipelines that use File objects will
+   now be smarter when it comes to files that change upstream, reducing the
+   number of times one has to clear the cache.
+ - Improved the initialization of packages: if package fails during call to
+   initialize(), we report failure, disable the package, and continue
+   initialization. This allows startup process to continue. Also in preferences
+   pane, when package fails to load, we now display the error message;
+   previously, it just said "error". (There's still the problem of reporting
+   packages that load ok but fail to initialize)
+ - Changed view behavior so that the initial pipeline view upon opening a
+   vistrail is reset.
+ - Added support for importing workflows that have been saved as xml.
+ - Added a function to change parameters from the api along with a function to
+   find modules by name (and package/namespace if specified). Note that the
+   param_list in change_parameter requires a list of strings---the serialized
+   representations of the parameters!
+ - Updated the gen_vtk_examples scripts to create better pipeline
+   specifications.
+ - Added pc3 package for the Third Provenance Challenge.
+ - VTK package:
+   + Added support for Picking in a VisTrails cell. By default, the
+     vtkRenderWindow contains a picker. The 'p' key activates the pick test in
+     the render window.  A new vtkPicker can be attached to the VTKCell to
+     modify the picking behavior according to the mechanism provided by VTK.
+   + All VTK Filters are registered to show their progress while executing
+   + Added support of InfoVis to VTKCell. Notice that the saving camera feature
+     does not working with InfoVis (because there are no direct SetCamera port
+     for InfoVis classes).
+   + Added support for changing the backgorund color of a vtkRenderer using
+     color widget
+ - Spreadsheet:
+   + Added exporting images and echo mode feature
+
+Bug Fixes:
+ - Fixed bug where queries with multiple sources would fail in query by example
+ - Spreadsheet:
+   + Jpg/gif/png images can be correctly displayed on the spreadsheet
+   + Fixed many interaction bugs
+   + temp files were not being correctly removed
+ - VTK state changes with statically overloaded parameters are now handled
+   correctly. Typical example is vtkTreeMapView::SetLayoutStrategy
+ - Fixes a  bug where the configuration wouldn't be setup properly for a new
+   .vistrails directory.
+ - Fixed plot.vt example to work with matplotlib version >= 0.98.5.2
+ - Catch exceptions when writing file to raise dialog box if there is an error.
+   This fixes bug that nothing was being shown to the user in case of a bad
+   write (ie, file permissions insufficient).
+ - Fixed PythonSource syntax highlighter error and (yes!) there's a line number
+   for debugging now.
+ - Fixed startup "bug" when package with dependencies fails to load
+ - Copy/paste is relative to the current canvas
+ - Shipping the GPL License in the distributions
+ - ImageMagick package:
+   + Added CombineRGBA class, configuration object, and fixed GaussianBlur bug
+   + Removed requirement check that prevented the package from loading if
+     ImageMagick was not found in the path
+ - Bug fixes in Windows installer:
+   + Installer always creates desktop shortcut and uninstaller did not remove
+     all pyc files
+ - Other minor fixes
+
+From Release v1.2.1 build 1336
+Changes:
+ - Schema upgrade. Current version: 0.9.3. If you keep vt files in a database,
+   you have to upgrade the database as well
+ - VisTrails now requires Qt 4.4 or later to run
+ - Adopted application single instance behavior (only one version of the
+   VisTrails application can be executing).
+ - Added Interactive expansion and collapsing in the version tree: the three
+   lines on edges in the version tree that used to represent multple
+   versions has been replaced by a plus symbol. Clicking this symbol
+   expands the link to show all the versions in betweeen (though this may
+   change to only a limited number later).  A minus sign appears on the
+   top of a list of untagged, non-branching, non-selected versions that
+   will collapse that list.
+ - Added descriptions to the version tree.  They show up in place of
+   a tag if one hasn't been set, but with a thinner italicized font.
+   Double-clicking on the node allows it to be changed and turned into a tag.
+   Showing a description for each action that is now displayed in the
+   properties overlay. This description is still very simple (eg.,
+   Added module), though in the future it might make sense to save off
+    more detailed descriptions for each action in the db (eg., Added
+    vtkRenderer module)
+ - Added new items to the View Menu to show and hide branches and nodes
+ - Restored the "Clear Recent Searches" in the search box in the version
+   properties
+ - Added command line options to execute workflows and show only
+   the spreadsheet when opening
+ - Logging information is now stored in .vt file
+
+ Bug fixes:
+ - Copying and Pasting dynamic modules, such as PythonSource threw an error
+ - File version was not set correctly
+ - Fixed a bug in analogies that sometimes corrupted vistrails files.
+ - Fixed some bugs and annoying behavior with autosave.  A dialog
+   now prompts the user if they want to load autosaved data.  This
+   dialog appears when opening a file or starting up vistrails.
+   Autosave data no longer is loaded when the user creates a new
+   vistrail by pressing the new button.
+ - Dragging versions to the spreadsheet is working again
+ - Dragging a spreadsheet tab created a window that couldn't be closed
+   or put back. A floating sheet can be docked back by simply closing it or
+   dragging it back the spreadsheet tab bar (if exists) or just the window
+   itself.
+ - There was no obvious way to exit full screen mode in spreadsheet. The
+   fullscreen mode can be closed either by:
+    * Pressing 'ESC', 'Ctrl-F', 'F11' or 'Alt-Enter'
+    * Right click on the fullscreen mode and unselect 'Fullscreen'
+  - Border color of selected cells in the spreadsheet is now consistent
+
+From Release: v1.2 build 1263
+Changes:
+ - Version tags can be edited directly by double-clicking the tree nodes
+ - Added basic support for package management on Fedora Core through YUM
+ - Added compatibility with Qt4.4
+ - Added support for dynamic addition of modules in packages
+ - Pipeline, Query and History views are now reset with Ctrl+R
+  (Command+R, on a Mac) so that it does not interfere with version text
+  items
+ - Add a transparent overlay to the version viewer that shows the
+   selected version's properties.  By default this is turned off, but
+   can be enabled under the view menu.
+ - Added standalone functions that help third-party applications that
+   need an API into VisTrails, located on vistrails/api directory.
+ - Improvements in the command-line for both non-interactive and interactive mode:
+   + Added support for executing more than one workflow at a time
+   + Included support for opening a vistrails from the database
+     Now a version (tag or id) can be specified in the command-line
+     together with the filename (or vistrails id when opening from the
+     database).
+ - Added support for opening special vistrails files (.vtl files) on
+   the web (wiki integration)
+ - WebServices package: added support for loading wsdl urls automatically
+   when opening a pipeline using them
+
+
+Bug fixes:
+ - Improved handling of faulty packages
+ - Vistrails having groups with annotations or functions did not open
+   correctly
+ - Query display didn't ghost module fill
+ - Query execution and reset didn't update pipeline view
+ - Connection line was drawn twice in query canvas
+ - Editing parameters in query mode was cumbersome because of
+   bad focus management
+ - Fixed database support to pipelines with groups
+ - Fixed "Add Database" dialog confusing behavior
+ - Fixed a long-standing bug on PythonCalc where ModuleError was
+   being called without the self parameter
+ - HTTP Package: slightly better error handling with malformed URLs
+ - Improved general GUI performance when changing versions, including
+   Undo/Redo
+ - Removed obsolete command-line options
+ - Refine in the search box was not working
+ - Spreadsheet: Saving a spreadsheet also included cleared cells.
+
+
+From release: v1.1 build 1143
+
+Changes:
+ - Added "Set Module Label" feature (through the configuration pop-up
+    menu of the GUI)
+ - Improved error messages
+ - Added vistrails files for many of the vtk examples
+ - Added support for packages to create menus in the builder window
+   (see spreadsheet package for an example)
+ - Modules and input ports can be automatically registered by
+   setting per-module _input_ports and _output_ports fields and
+   per-package _modules field (see teem package at www.vistrails.org)
+ - Removed graphviz dependency
+ - Ability to export workflow and history views to PDF
+ - In WevServices Package: Improved support to web services using
+   complex types
+ - Added a BooleanWidget, so Booleans are now given by a checkbox
+ - In VTK Package:
+   + Added Transfer Function Widget
+   + Added dataset inspectors, special vtk modules that allow users
+     to easily query bounds and scalar range of an object.
+   + Added support for vtkTIFFReader to allow volumetric (slice-based)
+     reads.
+ - Added support for grouping modules in pipelines
+ - Incorporated many optimizations in the code
+ - Added namespace support to packages
+
+Bug fixes:
+ - Fixed analogies
+ - Version tree was not refreshed when analogy was applied on the spreadsheet
+ - Fixed double drawing of module names and version node names on the mac
+ - Added support for running Visual Diff for pipelines with
+   PythonSources and other modules with a local registry that
+   have different input and output ports
+ - Changed the behavior of selecting new cell locations on the
+   spreadsheet when it is full (cycling vs. using always the first
+   cell)
+ - Fixed bug where options passed through the command line were
+   written to the startup.xml file
+
+----------------------------------------
+From Release v1.0.1 build 1063
+Changes:
+ - In VTK Package: Exporters now take a VTKCell as input when exporting
+   the scene
+
+Bug fixes:
+ - Caching mechanism: VTK modules didn't take the connections into account
+   when deciding whether to cache or not. This is related with the error
+   message "function expects 1 argument, got 0 instead".
+ - Fixed Parameter Exploration bugs where parameter widgets did not update
+   correctly when changes are made to the pipeline.
+
+
+From Release 1.0 build 1024
+Changes:
+ - Added a preference option to enable/disable Brushed Metal Style on Mac
+
+Bug fixes:
+ - Opening/Saving a .vt file on a path with spaces was not working on Unix
+   systems
+ - Creating/Applying analogies  on the spreadsheet
+ - Opening/Saving spreadsheets
+
+
+From Release 1.0 beta rev954:
+Changes:
+ - Added module VTKRenderOffscreen to vtk package
+
+Bug fixes:
+ - Version tags couldn't be reused
+ - Some vtk writers couldn't be dragged to the pipeline canvas
+ - Vistrails crashed when trying to copy and paste something other than
+   a serialized pipeline
+ - Modules lose focus when dragging to the pipeline canvas
+ - Modules downstream of a error module were green (as if they were executed)
+ - Select All button on the spreadsheet was not working
+ - Creating a version from the spreadsheet didn't work
+ - Tags weren't deleted when pruning the tree
+ - Booleans weren't supported in parameter exploration
+ - Fixed double-clicking on a vt file when opening vistrails on Windows
+
+From Release rev921:
+
+Changes:
+ - Interface was improved and it is now more consistent
+ - General configuration and package management accessible through menu Edit->Preferences
+ - Using a more efficient file format (*.vt)
+ - Auto saving feature
+
+--------------------------------------------------------------------
+
+
+
+
diff --git a/LICENSE b/LICENSE
index ac86225..207f77d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,27 +1,29 @@
-VisTrails is distributed under the "Modified BSD License".
-
+Copyright (c) 2014-2015, New York University
 Copyright (C) 2011-2014, NYU-Poly.
 Copyright (C) 2006-2011, University of Utah.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the
-      documentation and/or other materials provided with the distribution.
-    * Neither the name of the University of Utah nor the
-      names of its contributors may be used to endorse or promote products
-      derived from this software without specific prior written permission.
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
deleted file mode 100644
index 339e3e5..0000000
--- a/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Homepage: <http://www.vistrails.org>
-
-VisTrails is an open-source data analysis and visualization tool. It provides a comprehensive provenance infrastructure that maintains detailed history information about the steps followed and data derived in the course of an exploratory task: VisTrails maintains provenance of data products, of the computational processes that derive these products and their executions.
-
-For more information, take a look at the [documentation](http://www.vistrails.org/index.php/Documentation), the [users guide](http://www.vistrails.org/usersguide/v2.0/html/), or our [publications](http://www.vistrails.org/index.php/Publications,_Tutorials_and_Presentations).
-
-Binary releases are available on our [download](http://www.vistrails.org/index.php/Downloads) page. To report bugs, please use the github [issue](https://github.com/VisTrails/VisTrails/issues) tracker, after checking our [FAQ](http://www.vistrails.org/index.php/FAQ)
- for known issues.
-
-Who we are: <http://www.vistrails.org/index.php/People>
diff --git a/RELEASE b/RELEASE
deleted file mode 100644
index b395268..0000000
--- a/RELEASE
+++ /dev/null
@@ -1,2183 +0,0 @@
-RELEASE NOTES
--------------
-Release Name: v2.1.4 build 269e4808eca3 from v2.1 branch
-
-Bug fixes: 
- - Pinch gesture was broken (2d5494ed1d10)
- - Ticket 893: "Create Version" button on the spreadsheet does not work (d3db65418fad)
- - New Parameter Exploration was created for each execution (c324acad38f9)
- - Could not load saved Parameter Explorations (c324acad38f9)
- - Ticket 762: Package.import_override.is_sys_pkg logic incorrect (bf5e20c923f7)
- - Usersguide: Fixed parameter exploration vtl links (79c3021a50b3)
- - Forces the use of PyQt4 (avoid PySide) (2460948327cc)
- - Guess whether to use su/sudo with pip (18698fa909b3)
-
-From Release: v2.1.3 build 8262f078ed3b from v2.1 branch
-
-Bug fixes:
- - Fixes scripting examples (8dd634391b71)
- - Fixes Map and Filter modules outputting Variant (d597dcd6027f)
- - Makes StringFormat handle {!r} or {:.2f} correctly (5f99a90fdc87)
- - Fixes a test on newer pytz versions (2b4ecb3bc9bb)
- - Displays exactly what we are going to install (214f98f478be)
- - Fixes issue with missing PyQt4 (fbfada66f67e)
- - Hide splashscreen when asking for file association (069c52f90130)
-
-From Release: v2.1.2 build 7d8a4ed2feeb from v2.1 branch
-
-Enhancements: 
- - Ticket 846: File Selection Dialog (78e8d01bd7ab)
- - Ticket 824: Workflow execution output in console (8ea1231e736f)
- - Adds PromptIsOkay module (WIP) (a1bad0cc2d46)
- - Adds a YesNoDialog module (b267d2bed5eb)
-
-Bug fixes: 
- - Ticket 849: Autosave for existing vistrails not working (671eade8a9b8)
- - Saving mashups to DB corrupts them (5be2ed41d33f)
- - CLTools wizard does not show list type field (df8ef413aff4)
- - Date error in workspace when using 8-bit characters (af83742a98ec)
- - Ticket 850: Pipeline/history view scrollbars too sensitive (9e68064627c1)
- - Ticket 686: Deleting a vistrail variable breaks workflows (1870f481103d)
- - Ticket 830: Deleting a module does not delete vistrail variables connected to it (a197eba35396)
- - Ticket 825: Vistrail Variables are not copied with modules (a197eba35396)
- - Wrong view mode when switching between open vistrails (29bc0e1f47b7)
- - Ticket 828: [Windows] Pinning a panel causes it to disappear (287e77ec7afd)
- - Saving new vistrail caused view change (a95026c25968)
- - Could not drop module in detached vistrail variables widget (63957fe80711)
- - Vistrail Variables palette closed before it could be stickied (670f81d5eaff)
- - Ticket 822: Exception if PyQt is installed but PyQt.QtOpenGL isn't (e4c1ded9d649)
- - Ticket 783: Enabling packages automatically can make a different package fail (244084e837ec)
- - Old-style imports did not work on vistrails server (eaded21310ee)
- - Fixes adding a webservice through the context menu (d42e90689af2)
- - Old mashuptrails were not deleted correctly in DB (5ada9ce79bcb)
- - Mashups: Fixes alias copy bug (b5276f4c159e)
- - SaveBundle did not copy mashups (ea12b6a1e2b3)
- - Fixes date formatting in core.collection (1aaef5de72fb)
- - Fixes major ImageViewerCell bug (d8ca797bf8b9)
-
-From Release: v2.1.1 build 90975fc00211 from v2.1 branch
-
-Bug fixes: 
- - Ticket 816: Saved vistrail doesn't appear in 'my vistrails' (784414a617d2)
- - Ticket 814: Parameter Exploration Broken (13da70d0b35f)
- - Ticket Fix font issue for OS X 10.9. (22c0f0cca937)
- - Fixes early gui import in application_server (3b2f6186cea9)
-
-From Release: v2.1 build 179c82045907 from v2.1 branch
-
-Enhancements: 
- - Ticket 292: Add XSL support to RichTextCell (ae0126167aa8)
- - Set file associations on Linux (579d702aaab9)
-
-Bug fixes: 
- - Ticket 610: Exporting to the database should update locator (e6c3203a2710)
- - Ticket 809: Suspending module attached to more than one sink kills workflow execution (3b791e47c453)
- - Save button is not disabled when file is saved (d0dc3525f334)
- - Items in workspace were sometimes shown incorrectly (d0dc3525f334)
- - Context Menus in workspace were missing (d0dc3525f334)
- - Read only string widget had multi-line button (9117e5bb367e)
- - Opening configuration window with unsaved changes fails (fa3c1335580f)
- - Infinite loop when changing string in Mashup App (2ee81b444300)
- - Ticket 802: Can't exit VisTrails (da5c18a8b550)
- - Ticket 796: [JobSubmssion] Issue when resuming job from unsaved vistrail after quitting (cc3d342688fb)
- - Temporary files for untitled locators did not work correctly (3d9df4ab5ea2)
- - Autosave prompts when vistrail is already open (cfc06bbc1c2c)
- - Added LinuxMint as a supported Ubuntu variant (145c4c3c16ec)
- - Ticket 581: Latex extension: clicking on a figure on the PDF file (on acrobat) gives an error (f1a581b11929)
- - Publishing widget did not show unsaved vistrails correctly (0a4f49d7b081)
- - Ticket 712: Useful messages when loading abstractions (07745fca0e99)
- - Ticket 670: Traceback in configuration window (073b57d3bfca)
- - Ticket 709: Recursing on abstractions tracebacks (5b850844b735)
- - Ticket 776: 'Open in New Window' feature (71147be4b5ef)
- - Ticket 794: Exits with 'cannot connect to X server' when starting core application (3c94ccc0ac9a)
- - Fixed DBLocator equality method (e6c3203a2710)
- - Ticket 771: Export to DB hangs if schema is not present (c102cb8f72c8)
- - Ticket 787: Mac color chooser locks keyboard (628fb3e773fc)
- - Ticket 740: Double-clicking a workflow in the workspace collapses the tree (3775961debd4)
- - Ticket 738: Double-clicking a workflow in the workspace does not select it in the history view (3775961debd4)
- - Ticket 723: Changing view fails on Fedora (ee7b4652e845)
- - Ticket 722: Pipeline validation doesn't check for invalid functions (47d9c6de3e45)
- - Ticket 277: Don't always receive "enable package" dialog (802fd0de0a7e)
- - Ticket 415: Version tree refresh after API calls (0a2f6a59d6a7)
- - Ticket 730: help() not available warning in Mac 2.1 binary (a946e4da59c1)
- - Ticket 683: Packages should honor -S flag (9e5b83351d2f)
- - Ticket 649: Batch mode doesn't allow a vt without a version (b5b65892aa10)
- - Ticket 611: Mashups relational support missing (6bf5b2b02e48)
- - Ticket 759: QLineEdit.setPlaceholderText does not exist in Qt 4.6.3 (a57fbba44e6e)
- - Added progress reporting to Map module (0666e24d35f5)
- - Cannot abort execution while a vtkAlgorithm is running (6b86705c0e59)
- - Debian install script was used on Fedora (4acca49bcf74)
- - Ticket 751: Display history view when opening vistrail with tagged versions (f2b053cee1aa)
- - Spreadsheet history file path was set incorrectly (1789513a3afd)
- - Fixes slot bug in PyQt 4.7.3 (17230667d58e)
-
-From Release: v2.1 beta2 build 99faabb791a0 from v2.1 branch
-
-Bug fixes: 
- - Ticket #735: Windows dulwich install via pip fails (14d362a695df)
- - Ticket #718: persistence can't handle directories (2a668a6e9881)
- - Fix issue with persistent paths in Windows (2a668a6e9881)
- - Ticket #728: Upgrading vistrail with disabled package (b28c85b718ac)
- - Fix issue with subworkflows using disabled packages (b28c85b718ac)
- - Fix issue with staging persistent directories (6cddde545965)
- - Fixed module upgrades not working with dynamic packages (bf997c6bb0c6)
- - Fix issue with transfer function widget (11213143752c)
- - Rewrites error-prone code for GitRepo#add_commit() (c1d2f60cc10d)
- - Persistence sets up a Git username if none is set (f37129976ba5)
- - Fixes default values on optional Boolean ports (34365eb22800)
- - Ticket #705: zip.exe not found in Windows binary (69a16e3c5b84)
- - Ticket #700: Upgrades with package identifier changes fail (32f934bef698)
- - Ticket #716: The new IPython console does not receive console output (96d65c1d0e80)
- - Ticket #699: Base classes for parameter config widgets do not enforce defaults (6e1a5624b2ae)
- - Fix BooleanWidget default handling (6e1a5624b2ae)
- - Fixed tricky upgrade bug (1385b1d04f4b)
- - Ticket #626: Passing parameters to single instance still opens second instance of VisTrails (334c743f3c33)
- - Fix issue with package identifier changes and upgrades (32f934bef698)
- - run.py/fix_paths was broken (16aeafb32399)
- - Looping over a failing PythonSource caused logger to fail (2b5ff8105562)
- - Fixes line-endings for TestUnzip (05a41335f050)
- - Disables deleting from the persistence store (3c816e2734b8)
- - Adds tests for type-checking, using PythonSources (3f0c602b003a)
- - Disables type-checking for InputPort modules (4cdad5f113df)
- - module_info now shows a module's id (0c504fe06615)
- - Limits copy and paste in module_info (b99c674c8494)
- - Detects cycles when computing pipeline signature (3a0fe0b5a880)
- - Adds some more checks for persistent path type (846631436bd0)
- - Raises a ModuleError if persisting an empty dir (d3d8b2193b5f)
- - Makes type-checking optional (30659a8b6525)
- - Fixes adding a directory to persistence (0c26c5b68ee6)
- - While requires *or* ConditionPort or MaxIterations (bdcd04e3366c)
- - Fixes a package_dependencies() crashing VisTrails (3263be2d2a52)
- - Lets PythonSource use the default source (7684997bd888)
- - PythonSource configuration dialog now uses default (3dff503ce8ce)
- - Fixes StringWidget not showing default correctly (49d9dbd161f0)
- - Restores read-only mode removed by previous merge (4bdf4705a669)
- - Removes most of the persistence_exp package (90c70ee525e6)
- - Fixes matplotlib not able to reuse cells (243ae02dd499)
- - Makes UntitledLocator inherit CoreLocator (fc863650a893)
- - Fixes looping modules (34d3029f3419)
- - Minor changes to persistence code (96a605e0ca3f)
- - Adds back PersistentPath#git_command() (295f9ade09cf)
- - Fixes an issue with fix_dates() (3ad431172b47)
- - More fixes to found_another_instance_running() (916cdeb23f6f)
- - Makes fix_dates static in PersistentRefModel (56dec62ea2aa)
- - Fixes persistence view (1bbb9bfb5f45)
- - Adds tests for Unzip and UnzipDirectory (22c9d361b78b)
- - Makes HTTPFile cacheable again (5bc3619d5cba)
- - Fixes running the CLTools wizard standalone (77bf72286a8c)
- - Fixes CLTools test on Windows releases (c503e4df5cf9)
- - Fixes UnicodeDecodeErrors in DebugView (5ce4fd3515d7)
- - Adds an UnzipDirectory module (634e6415a62e)
- - Fixes Unzip code (10a2a3753185)
- - Fixes runtestsuite.py ignoring *system* (b1210c5dc5c7)
- - ImageMagick fixes (b0994f0e5684)
- - Cleans disabled packages from cache (51a4cf021a31)
- - Removes QPackagesWidget#erase_cache attribute (2919064fcce2)
- - Don't expand the module palette on package load (890b6796e4a2)
- - Re-enables type checking after all (ec6539366bbd)
- - Fixes optional tabledata->spreadsheet dependency (511ab651ad93)
- - Makes numpy arrays valid Lists (6425d8d7a286)
- - Merge branch 'optimize-module' into 'master' (906a6edf8e73)
- - Minor fixes to installers (ba9550bb44f2)
- - Moves rgb2hsv and hsv2rgb out of paramexplore (f00a710f2424)
- - PythonSource now sets unconnected output ports (75f4d085c57f)
- - Adds a Delay port on the While module (07087da25339)
- - Renames 'optimization.py' to 'looping.py' (b4b2183e3bab)
- - Renames Optimize to While, inverts condition (0a07b43c7a2f)
- - Adds state output/input ports (e6f57d0f4999)
- - Adds the Optimize module to ControlFlow (ea4ebd43293c)
- - ExecuteInOrder now uses the ControlFlow style (3d286c21a17d)
- - Adds a Delay port on the While module (2b2648c08820)
- - Makes log-related flags not fold-specific (954c984cca31)
-
-From Release: v2.1 beta build 16ae99d82468 from v2.1 branch
-
-Enhancements: 
-
- - Ticket #695: Parameter explorations should be migrated through upgrades if possible (29f072af3087)
- - Start migrating parameter explorations through upgrades (29f072af3087)
- - Ticket #690: PythonSource Port Type Completion Requires "Enter" (f19e8a6e222a)
- - Display version id in version properties (6eb10d9e3bcf)
- - Static mashup animations (d40c74b42abb)
- - Animation support for Mashups (cc578f2009a7)
- - pip should now work on all platforms where it is available (b90fdba57189)
- - Added graphical sudo for OSX (b90fdba57189)
- - Added IPython Console (57f54943a73d)
- - Use PyQt API version 2 (5229204a2dce)
- - Multi-line editor for String modules (ff7d78aa76e4)
- - Progress Dialog for workflow execution (459f3d003393)
- - Improve interaction between pipeline views and controller. (a3bcdf6cc7a2)
- - Improve API (aa1dbcc5f34d)
- - Add more robust tracking of untitled vistrails. (913ed56d9445)
- - Add matplotlib upgrades and integrate new pkg with new identifier scehme. (79bcb5673781)
- - Support package identifier changes. (f77b92758c07)
- - Build up the API and refactor core application methods (de9cea46a623)
- - More updates to matplotlib package (44dff52c4da2)
- - Add port spec translation from schema 1.0.3 to 1.0.2 (616a1090bf4b)
- - Incremental/Online Layout  (80cb92674de6)
- - Spreadsheet: "Find Version" and "Save Camera" now works for unsaved, closed, and "saved as" vistrails (24243fd207fc)
- - DB support for Mashups (4e8da08d81b1)
- - Support backward comaptibility for packages that have not been updated to use the "vistrails." prefix when importing. (6ca1d510a773)
- - Updated persistence package to use dulwich, a pure python implementation of git (263b6f339e50)
- - PROV document can now be exported using the command line (script) (5f0b04c049e5)
- - Ticket #604: Add vistrail variable support to parameter exploration (04496edc9bfd)
- - Added PROV entities for input and output data (ae52faaadfa9)
- - Using Dublin Core metadata for PROV document (PROV exporter) (652099fe855d)
- - New version of the PROV exporter (03a0a2785e89)
- - First version of PROV exporter (9d32409c7118)
- - Serializable mixin class for modules (895fab7db230)
- - User does not need to create IPython controller manually anymore (ba7edbc30ca4)
- - Added support for SSH IPython engines in parallel flow (1a56f69a18e6)
- - IPython controller is stopped when closing VisTrails or disabling the package (704658297b0f)
- - Ongoing work on the exporter for the PROV model (704658297b0f)
- - IPython controller and engines are now started from VisTrails (4ec53425ca92)
- - Added information about the machine from each IPython engine (8a361420a384)
- - Map (parallel flow) can execute an outer subworkflow in IPython engines (949f9edb24df)
- - First version of package 'parallel flow' (ac162d9e7ccb)
- - Module / Group executions from the IPython engines are added to the provenance (518b3a4b1129)
- - Added some modifications in the code to allow the execution of workflow in IPython engines (d89b7f9861ee)
- - Forward error messages when connecting to other instance (0ad89de1cb2a)
- - Add uniform method for building descriptor, port_spec strings (9633bb6c1365)
- - Allow selected portions of the workflow to be relaid out (6f558cc3e697)
- - Add option to nicely layout workflows automatically (15ff124c6652)
- - runtestsuite now returns 0 for passed test runs (5d44f2879811)
- - Ticket #606: Copy parameter explorations between workflows (b8a25bc9bac8)
- - Updates to parameter explorations (696b83875d73)
- - Ticket #603: Parameter Exploration from command line (d5f554fa40e0)
- - Ticket #545: Make unset parameters accessible from the Parameter Exploration view (7b5cbe95bbf3)
- - Ticket #547: Migrate parameter exploration persistence to schema and controller (7b5cbe95bbf3)
- - Unset parameters can be used in parameter explorations (7b5cbe95bbf3)
- - New schema for parameter explorations (7b5cbe95bbf3)
- - Parameter explorations can be named (7b5cbe95bbf3)
- - Parameter explorations are visible in the workspace (7b5cbe95bbf3)
- - Parameter explorations can be accessed without the gui (7b5cbe95bbf3)
- - Improve exception message for invalid port specification (c01407d42d7c)
- - Improve error messages during package loading (2ea29738dd9b)
- - API: VisTrailsAPI.execute() now accepts the same parameters in core VistrailController.execute_current_workflow() (012a7e828338)
- - LaTex Extension: Added support for relative .vtl links in pdf and relative filenames in .vtl files (2329f7e6eb10)
- - AutoConnect: when dragging a new module into a workflow, try to connect it (5d6475919bb3)
- - Allow port_and_port_spec_match to match two port specs (e068f2a835e2)
- - Ticket #555: Move package-specific missing package handlers (42131938cd0f)
- - Support enumerations for parameters (571a24363dda)
- - Add gui support for different port shapes (9f7e54780c7b)
- - Show when ports are set by darkening the port (9f7e54780c7b)
- - Add visual cues for the number of connections set/needed/allowed (9f7e54780c7b)
- - Added port docstrings to the VTK package (49aa19ba2ce3)
- - Updated port documentation (befd489265d2)
- - Add schema support for max/min connections for ports (befd489265d2)
- - Native schema for Vistrail Variables (201b489e1c26)
- - Add load_package method to API (abbc89ef42dc)
- - Add load_workflow method to api (5786189661b2)
- - Automatically install PyQt4 on Fedora Linux (b11e69aafe2e)
-
-Bug fixes: 
- - Fixed spreadsheet capturing keys in other windows (aad252798fe6)
- - Fix issues with completions in port tables (f19e8a6e222a)
- - Ticket #692: Parameter exploration schema logic invalid (44a29f0422b8)
- - Fix translation bugs between schema versions. (6643e4dd610d)
- - Ticket #693: Issue with PortSpecItem ids (16413b49c806)
- - Fix ids on PortSpecItems (16413b49c806)
- - Ticket #691: Executing a parameter exploration without the spreadsheet fails (48ccd5a64f54)
- - Ticket #689: Mashups preview broken (3ea331e01abc)
- - Refactor get_pipeline_name calls and remove substring hacks (3d8a9c875288)
- - Fix QChar issue with parameter exploration (e07da85567a6)
- - Fixed invalid current_view causing setCurrentWidget to fail (c93061c00bcb)
- - Job Monitor: Could not run more than one job job in the same vistrail (609f09df5ce4)
- - Job Monitor: Could not delete job other than current pipeline (609f09df5ce4)
- - Job Monitor: Job for current pipeline was not stored on shutdown (609f09df5ce4)
- - Looping over a failing PythonSource caused logger to fail (3bdf9620dd00)
- - Ticket #678: Relational DB support for schema v1.0.3 broken (d54eb24cba1f)
- - Fix issues with PortSpecItem (d54eb24cba1f)
- - Ticket #680: Package configuration broken (20ba5b110fae)
- - Fix broken clipboard check for paste (a6d1cc7c840c)
- - Use codepath when identifier is not enabled when warning for old style imports (6a7f4a99a0c7)
- - Disabling a package did not select it in the Available Packages list (8f50dcf2d941)
- - Fixed vistrails->crowdlabs in latex/example2.tex (a95605ef12ab)
- - Module: controller was not set in default moduleInfo (7360a90e23cd)
- - Ticket #675: save_from_gui() is broken (482624c80e2e)
- - Fix issue with saving untitled vistrails (482624c80e2e)
- - Fix typo in application's convert_version (1866ec46e5ec)
- - Logging fails when Group executed by Map fails (fcb6d4b1b637)
- - VisTrails Server: fixed generating a pdf from a vistrail tree  (0a3d02e92b48)
- - Ticket #668: Commit 6cf6920 broke API tests (76887e74224e)
- - open_many_from_db should not be used with pre 1.0.2 schemas (e2b247f2c588)
- - Updated latex example files to use crowdlabs instead of vistrails.org (0314ecf38606)
- - Fixed generating an image of workflow graph from the command line (3f40090c5e12)
- - Images in thumbnails are now sorted by cell location (498081d7cdc5)
- - Errors in package dependencies method caused VisTrails to fail on startup (1adc3d25bf73)
- - Fix issue with intermediate persistent files not being found in the store when a uuid is already assigned. (72c89f5aa6ca)
- - Fix earlier noted issue with importing the registry in create_instance_of_type (78df1961b099)
- - Fix some issues with Windows paths and locators. (2e2c35df7dcf)
- - Ticket #662: VistrailController constructor does not set _current_full_graph (a3bcdf6cc7a2)
- - Push controller constructor calls through set_vistrail (a3bcdf6cc7a2)
- - Don't generate an error when a user attempts to drag a module into a non-pipeline view (f7abe1fd73b9)
- - Ticket #664: Debug Message Fails with AssertionError (5008bf52a105)
- - Ticket #661: Controller's current_version=-1 causes issues (c69b430e1701)
- - Fix issue with inconsistencies when current_version=-1 (c69b430e1701)
- - Ticket #590: Packages are not updated when userpackages dir is modified (88480456e2cf)
- - Fixed bug in matplotlib cell resizing (bbe9a6078797)
- - Vistrail Variable list was changing while being iterated over (99e60cf4dccf)
- - Saving log to prevoius version failed (d56da92fa406)
- - Fixed update_db script to work with master (04968e309d94)
- - Allow reading different versions of subworkflows from DB (c5a33a0b8ead)
- - Fixed loading wrong abstraction DB version (06a06be04889)
- - Fixed trying to write empty workflow list to DB (06a06be04889)
- - PipelineView: Execution exceptions were not caught which caused jobView to lock up execution (3b460bdb7c95)
- - Mashups: controller_changed caused widget to be redrawn even when the controller did not change (801c3b8e58a8)
- - Ticket #656: Control Flow Wizard is broken (95275d116c24)
- - Fixed deleting mashup alias using Del/Backspace key (1d68ccf02f81)
- - color picker widget gets orphaned in the alias inspector (1d68ccf02f81)
- - Fixed bug on PROV exporter (f7675297ad23)
- - Fix issue with Mac binary and the vistrails.py sys.path changes (09840f6c815b)
- - Save log to xml action was not enabled in menu (dbc83ce34917)
- - Ticket #641: PersistentInputFile not recognizing changes in the file contents (4f85d3d25ab9)
- - Fix issue where file changes were not being recognized (4f85d3d25ab9)
- - Ticket #639: Package details are not updated when a disabled package is selected in preferences panel (a251d6fe54a0)
- - Execution of workflows in IPython engines (ba7edbc30ca4)
- - Groups and Subworkflows can now have their execution log annotated (d89b7f9861ee)
- - Ticket #635: Error translating from schema 1.0.2 to 1.0.3 (5fbdbe702dcb)
- - Fix issue with whitespace between port spec items (816094bc7d64)
- - Ticket #577: Publish window always shows grayed out snippet (fc9c5e5e11ce)
- - Ticket #633: Automatic package download is not working on master (bce780145a5c)
- - Ticket #626: Passing parameters to single instance still opens second instance of VisTrails (0ad89de1cb2a)
- - CLTools: Modules were not reloaded after reloading scripts (283f8b57166b)
- - CLTools: "env" option was not reset in wizard when loading other tool (283f8b57166b)
- - Server mashup request need to use db user with write access (81c51908662c)
- - MissingPackageVersion exceptions need to be tied to specific modules (5d13c3e8292b)
- - Ticket #629: Issue with namespace (63a696d66c3b)
- - Fixed issue with reloading packages with namespaces (63a696d66c3b)
- - Allow only a single MissingPackage exception to be included in an InvalidPipeline container exception (a1401ec6afbb)
- - Fixed typo with ghosted pen color (a0bdae3f8c4a)
- - Ticket #627: Duplicate enable package messages (fb21c5c5e4b0)
- - Fix errors in parameter exploration when viewing invalid pipelines (fb21c5c5e4b0)
- - Do not emit errors from the query view when the selected version changes (9e1eb696ce67)
- - Ticket #617: Hard import from the v1_0_0 schema in opm.py makes it fail with other schemas (1c7b21fab942)
- - Fix OPM import (1c7b21fab942)
- - Windows: Saving vistrail zip xml fails when zip.exe cannot be located (d80fbb746549)
- - Ticket #624: unix /bin/ls check fails on fedora 17 (bcd044c4ff75)
- - runtestsuite.py should not care about empty string arguments (f417c703c364)
- - Fixed typo in parse/update for parameter types introduced in recent commit (133102abe14f)
- - #623 (133102abe14f)
- - Fixed issue with connecting tuple ports in the API (5eddcc1a9e47)
- - Ticket #621: Hidden ports that are used in connections are not set to visible (e40295454a40)
- - Fixed visibility of a connected port in ports panel (e40295454a40)
- - Fixed issue when connecting modules (2811ba5d4ff3)
- -  Fixed documentation file of CLTools that was causing a failure when building the pdf version of the usersguide  (a0c19535e7d6)
- - Ticket #618: Open Workflow from DB missing in file menu (61619a425285)
- - Ticket #614: test_abtraction_create fails in test suite (6885385a769d)
- - Preferences sometimes tried to set up a removed package (5d44f2879811)
- - SplashScreen was never deleted (5d44f2879811)
- - Ticket #613: triangle_area.vt fails on the map operator (ad4b579121c2)
- - Fix bug with obtaining port spec signature (ad4b579121c2)
- - Ticket #612: User-defined parameter exploration editor is problematic (7512a2d05434)
- - Fix issue with modified group signatures (b542543e1332)
- - is_running_gui missing in VistrailsServerSingleton (557586218e5a)
- - Fixed issue where OPM export could not resolve ports in parent modules (d084c5742ffb)
- - SUDSWebServices did not handle empty configurations correctly (0cfe904c59f4)
- - Ticket #583: CLTools: sometimes a module called CLTools is displayed (f2d755b24f53)
- - Empty packages could not be reloaded (f2d755b24f53)
- - PortSpecItem schema did not work on MySQL (b7556465275b)
- - Parameter Explorations were not being converted correctly from 1.0.2 (b7556465275b)
- - Parameter Explorations were not being loaded from database correctly (b7556465275b)
- - Saving a Vistrail failed when package manager was not available (b7556465275b)
- - Ticket #601: Connection port compatibility should be checked at a lower-level (f984fd5087c0)
- - Check port compatibility at controller level (f984fd5087c0)
- - Ticket #602: core api does not work in console (1d965a2cf952)
- - Add missing methods to GUI application (1d965a2cf952)
- - Ticket #599: Missing defaults cause exception when adding a function (a98e0a7962c8)
- - Ticket #594: Defaulted booleans added twice (ef684f869d62)
- - Fix duplicate boolean values when using defaults (ef684f869d62)
- - Update color of cached modules correctly and reset colors on re-execute (48981ae5cfbe)
- - Do not set module color back to active after it has been run (4f55071bb133)
- - Ticket #591: User-decorated modules do not change color during execution (86fe5d0ad9a1)
- - Module status brushes are checked first when setting the color of a module (86fe5d0ad9a1)
- - Ticket #592: Dragging a Group module into a pipeline causes an invalid pipeline error (bb2f60099e4c)
- - Guard against empty group modules (bb2f60099e4c)
- - Spreadsheet package: Checking if the GUI is running before trying to initialize the package. (c9d20070140c)
- - Catch exceptions when selecting invalid modules (3c3a6755adfa)
- - Ticket #586: Selecting an invalid module raises exceptions (cb6c5b161c57)
- - enabling/disabling package did not invalidate pipeline (1a280b63a745)
- - Ticket #585: Failed reloading of a package does not invalidate modules (057f031ee4c3)
- - Fixed issue where modules were not marked as invalid before validation (057f031ee4c3)
- - Ticket #584: Enabling a package adds it to the enabled package list even if there are errors (11125174c7ff)
- - Fix issues with package list in preferences (11125174c7ff)
- - Unselect port on mouseReleaseEvent (56f2d9aedf37)
- - SUDSWebServices: Offline Mode by storing WSDL in .vt file was not portable (eba546527401)
- - SUDSWebServices: Typo in handle_missing_module caused packages with wrong names (eba546527401)
- - Ticket #575: Vistrail variables panel has an overdraw problem (52c864c3ddb2)
- - Ticket #576: Analogies are only displayed if we change the focus out of VisTrails to another application and back (8c023062c639)
- - Ticket #539: Standard Module Configuration Widget asks to save when two ports are enabled (c9d5d03962b2)
- - Configuration widgets will prompt to save only when the current module change, making it easier to copy text from another application (c9d5d03962b2)
- - Ticket #569: Connected icon in Module Information does not disappear after removing connection (11e93fd142cb)
- - Loading an image from workflow graph or a version tree was not working in the command line (2329f7e6eb10)
- - Workflow results that used a VTKCell were consisting of a black screen when running in batch mode (49adb4fd6b5d)
- - Ticket #487: isosurface script version of terminator.vt causes vistrails to crash (76de9f741635)
- - Ticket #540: Vistrail is not always marked as changed when containing a vistrail variable (49cb21769a83)
- - Ticket #563: Temporary connection does not appear second time you create the same connection (3bd812f9cd6c)
- - Fix issue with temporary connection disappearing (3bd812f9cd6c)
- - Ticket #546: Selecting a version selects the text box instead of the version ellipse (a19863118684)
- - Ticket #550: Workspace state_changed is slow (bd734eb57838)
- - Ticket #553: Suspended module does not execute on second run even when notcacheable (8eb9f8d11575)
- - Parameter Exploration only worked on parameters from the Basic Modules package (75cca6574d0e)
- - Fixed minor issue with PortSpec shape and docstring attrs (aebf4f84b052)
- - Ticket #418: The database schema should use larger data types (75c7c6c89fdf)
- - Bug in translation from 1.0.3 to 1.0.2 (75c7c6c89fdf)
- - Fix issue with configure item grabbing mouse. (479a29491abc)
- - Removed capitalized methods from ports in VTK (49aa19ba2ce3)
- - Parameter Exploration: Changed call to update the progress bar to be thread safe (b9942f416fe1)
- -  Mediawiki extension: fixed undefined variable  (d3d68b1c53ab)
- - WorkflowExecution.completed were set to False in the vis_log, it should be an int. (50a2a68e177a)
- - DBVistrail.hash*Annotation() fails when annotation values are ints (3d7f1b9cc078)
- - Fixed path_to_figures and get_wf_graph_ calls in application_server (6df2c53cc880)
- - Do not import VTKCell unless we have the spreadsheet (a8b7c8345ee9)
- - HTTP Package now respects alternate dotVistrails setting (88b53249d96d)
- - The create analogy button is too small (65be8388e906)
- - "Show raw pipeline" and "construct from root" commands should switch to the pipeline view (dc2deb9ed6e0)
- - Fix command_line argv dependency (5786189661b2)
- - Mashups: slider and numericstepper widgets are only displayed for numeric aliases (3b8c4f954bce)
- - Mashups: Validating Min Max and Step edit boxes so they accept only numbers (3b8c4f954bce) 
- 
-From release: v2.0.2 build 3813fdd2573b from v2.0 branch
-
-Enhancements: 
- - Added animation support to matplotlib/pylab (38fb971b6305)
- - Job Monitor Improvements (af8f43039c94)
- - Job Monitoring Tool View (3c43a8c5b3b7)
- - Add support for customizing which packages are (not) reloaded (91e18f8749a0)
- - Testing: Validate Workflows by comparing old and new thumbnails (401588f3bfdb)
- - Added saving/loading SubWorkflows to/from the DB as part of a vistrail bundle (0704f03b2011)
- - Ticket #628: Set the path to the vistrails tmp dir (f07b3223d16d)
-
-Bug fixes: 
- - Saving log to previous version failed (e66941c40e22)
- - Opened vistrails were not selected (14415ac3c709)
- - parallelflow: Do not deepcopy module dict (e66a6a3713ec)
- - Fixed matplotlib spreadsheet cell resizing issue. (45f803f0763c)
- - API: return result after execution (aec0ed019ac5)
- - Job Monitor icons were set incorrectly (d5e332c4e410)
- - Job Monitor did not delete job when vistrail was closed (d5e332c4e410)
- - Workspace: Sometimes selecting an open vistrail does not select it (e1f57079d0fd)
- - Ticket #651: Function remap upgrade operations performed in incorrect order (6aaa72017fa8)
- - Fix ordering in function remap (6aaa72017fa8)
- - Ticket #648: 'OutputPort' object has no attribute 'module_exec' (c9847fc14bb9)
- - Ticket #647: ModuleSuspended does not work inside Groups (c9847fc14bb9)
- - Ticket #645: Document py_import in dev guide (bf9a58708fa2)
- - Ticket #646: Reloading packages fails in some cases (91e18f8749a0)
- - Fix issues with package reloading (91e18f8749a0)
- - Fixed broken mimetypes on Windows (9aa51dd35301)
- - Ticket #643: cannot open workflow triangle_area.vt (67726aceba3b)
- - Ticket #625: Improve crowdLabs upload interface (7389abac0902)
- - Added DB version map 1.0.2->1.0.3 needed when downgrading the log (172301ad3858)
- - Saving abstractions do DB was missing version translation (45ebc5afa303)
- - Removed faulty import DBProvModel (6727b6ee2fe8)
- - Ticket #619: Create Analogy does not work on spreadsheet (39df0813e11c)
- - Fix issue with analogy api in the spreadsheet (39df0813e11c)
- - Ticket #638: Re-execution of SubWorkflow is missing parameters (294574341168)
- - Fix issue with subworkflow caching (294574341168)
- - Ticket #634: Package Documentation says port sigstring can contain spaces (dfc9db1f4dc5)
-
-From Release: v2.0.1 build 5e35e2b83b90 from v2.0 branch
-
-Enhancements:
- - ALPS package: Updated to version 2.1.1 (4741aa04a9d7) 
- - Support import of schema v1.0.3 (94bb430fa0f0)
- - CLTools: Preview command line arguments and module ports (6c737e297a60)
- - CLTools: Reload modules from the wizard (6c737e297a60)
- - CLTools: Add env port using wizard (6c737e297a60)
- - CLTools: Extended documentation (6c737e297a60)
- - CLTools: Ability to specify fixed environment variables for modules (6ece9152e511)
- - CLTools: Write changes in environment variables to execution log (6ece9152e511)
- - Added server function for seeing and enabling/disabling packages (1b7ad7717b31)
- - CLTools: Ability to set working directory (cbf02c561ccd)
- - CLTools: New arg type inputoutput that enables files be used as both input and output (692e3ce05961)
- - CLTools: You can now specify file endings for output files using the suffix option (692e3ce05961)
- - Ticket #582: CLTools: should support other types (c3b49457c3a5)
- - Added single instance check as a configuration option and a command line option (4032ca504171)
- - Improved exception message for invalid port specification (431802313d43)
- - Improved error messages during package loading (4175f8c09b4d)
-
-Bug fixes: 
- - Added the missing v1_0_3 directory for schema v1_0_3 support from master branch (916cf9162df8)
- - FileHooks for DBVistrail types should be skipped (94bb430fa0f0)
- - Check if package has been removed before setting package information (94bb430fa0f0)
- - CLTools: Modules were not reloaded after reloading scripts (6c737e297a60)
- - CLTools: "env" option was not reset in wizard when loading other tool (6c737e297a60)
- - Server mashup request need to use db user with write access (af73f32d44c0)
- - get_vt_graph_png was broken (af73f32d44c0)
- - Ticket #617: Hard import from the v1_0_0 schema in opm.py makes it fail with other schemas (2fefff447711)
- - Fix OPM import (2fefff447711)
- - Windows: Saving vistrail zip xml fails when zip.exe cannot be located (32bd4aa03c3b)
- - Ticket #624: unix /bin/ls check fails on fedora 17 (ee2cd7d1f6c3)
- - Ticket #621: Hidden ports that are used in connections are not set to visible (4cb7b1758bac)
- - Fixed visibility of a connected port in ports panel (4cb7b1758bac)
- -  Fixed documentation file of CLTools that was causing a failure when
-building the pdf version of the usersguide  (3899208009dd)
- - is_running_gui missing in VistrailsServerSingleton (272006002712)
- - Ticket #618: Open Workflow from DB missing in file menu (8e413fc8f504)
- - Ticket #614: test_abtraction_create fails in test suite (2315d8e92026)
- - Ticket #583: CLTools: sometimes a module called CLTools is displayed (11107c05a73a)
- - Empty packages could not be reloaded (11107c05a73a)
- - Ticket #612: User-defined parameter exploration editor is problematic (deab533c7302)
- - Fix issue with modified group signatures (cd8e2467903b)
- - Ticket #464: VTK Package does not support VTK 5.10 release (65462fd17800)
- - Fixed issue where OPM export could not resolve ports in parent modules (cdc1a53bf496)
- - Fixed issue where modifying a defaulted parameter caused a second copy of the parameter to be added (d6924b42d821)
- - Ticket #602: core api does not work in console (ac85e1935819)
- - Add missing methods to GUI application (ac85e1935819)
- - Ticket #594: Defaulted booleans added twice (e90af069e58a) (d6924b42d821)
- - Fix duplicate boolean values when using defaults (e90af069e58a)
- - Update color of cached modules correctly and reset colors on re-execute (421ef3182f7b)
- - Do not set module color back to active after it has been run (1f6ea4ff45e3)
- - Ticket #591: User-decorated modules do not change color during execution (c53334a5e412)
- - Module status brushes are checked first when setting the color of a module (c53334a5e412)
- - Ticket #592: Dragging a Group module into a pipeline causes an invalid pipeline error (cd8b62b219a6)
- - Guard against empty group modules (cd8b62b219a6)
- - Spreadsheet package: Checking if the GUI is running before trying to initialize the package. (a71954b1639a)
- - Ticket #586: Selecting an invalid module raises exceptions (225f057294dd)
- - Catch exceptions when selecting invalid modules (225f057294dd)
- - enabling/disabling package did not invalidate pipeline (a363ed3f0151)
- - Ticket #585: Failed reloading of a package does not invalidate modules (46a6204cbab4)
- - Fixed issue where modules were not marked as invalid before validation (46a6204cbab4)
- - Ticket #584: Enabling a package adds it to the enabled package list even if there are errors (0593aad10533)
- - Fix issues with package list in preferences (0593aad10533)
- - SUDSWebServices: Offline Mode by storing WSDL in .vt file was not portable (6fa03241e9c6)
- - SUDSWebServices: Typo in handle_missing_module caused packages with wrong names (6fa03241e9c6)
-
-From Release: v2.0 build 240bcab5bbcd from v2.0 branch
-
-Enhancements: 
- - Ticket #424: SUDSWebServices should store the WSDL spec in the .vt file to enable upgrades (88f616a741de)
- - Packages can store files in .vt zip files (88f616a741de)
- - .vt files using SUDS Web Services can now be edited offline (88f616a741de)
- - CLTools: package menu option for reloading all scripts (3c83b7101bc0)
- - CLTools: added Open Wizard to package menu (1f19d0a7339a)
- - Added CLToolsWizard.command file to Mac Binary (99adfd823a2d)
- - Ticket #430: use of absolute file names can be problematic in vtl files (2b731d8d5043)
- - LaTex Extension: Added support for relative .vtl links in pdf and relative filenames 
-   in .vtl files (2b731d8d5043)
- - Package requirement for the job submission package (77f3f1761f92)
- - Ticket #519: Executions in Version View that fail should change to pipeline (cea08c6e25d9)
- - Switch to pipeline view if an execution fails (cea08c6e25d9)
- - Ticket #557: Password dialog (f9739db121c4)
- - Ticket #559: Persistent modules do not work in groups (4ef2b8639b6d)
- - Allow modules in subpipelines to be cached (4ef2b8639b6d)
- - Added alps package to VisTrails 64-bit Windows Binary  (519d862a63f5)
-
-Bug fixes: 
- - Ticket #575: Vistrail variables panel has an overdraw 
-   problem (c4171c8aab63) (09815c35efb8) (7ca53292670a) (07fdeb8602a7) (45a4818a0b5c)
- - Ticket #404: Overriding a port via add_*_port does not work (47e72744ede1)
- - Ensure add_*_port can override ports in superclass port lists (47e72744ede1)
- - Ticket #523: Default values for parameters not showing (e3f1b1a3253f)
- - Add default support back in (e3f1b1a3253f)
- - Fixed spelling in repository.py (6c2259e84214)
- - SUDSWebServices: Wrong indentation caused vistrail save to fail (5497e50c727f)
- - Ticket #576: Analogies are only displayed if we change the focus out of VisTrails to 
-   another application and back (d782197a1cab)
- - Fix issue with redrawing the tree after analogies (d782197a1cab)
- - Running instance was not accepting parameters from another instance (63b58b8416d0)
- - Ticket #464: VTK Package does not support VTK 5.10 release (3e3700900ad0)
- - Ticket #445: mashup previews is not always shown in the main window (9111971ce8c6)
- - Now persistent cache works after one execution (87e8ff129b88)
- - Ticket #573: Opened vistrail fail when reloading dependent package (b1ff731d904a)
- - SUDSWebServices: Failed Web Services could not be removed (b1ff731d904a)
- - Execution button may hang when execution fails (b1ff731d904a)
- - Ticket #571: Vistrail variables cannot be used in more than one workflow (02f2acee1727)
- - Fix issue when setting a vistrail variable on multiple modules (02f2acee1727)
- - Ticket #574: Cannot add variable to empty detached Vistrail Variables window (4ae4f3d9c582)
- - Fixed issue with creating vistrail variables in an undocked panel (4ae4f3d9c582)
- - Ticket #539: Standard Module Configuration Widget asks to save when two ports are 
-   enabled (154525da1047)
- - Ticket #521: Annoying PythonSource behavior (154525da1047)
- - Configuration widgets will prompt to save only when the current
-   module change, making it easier to copy text from another application (154525da1047)
- - QVistrailsWindow.get_current_view() was returning the wrong view sometimes (154525da1047)
- - CLTools: IOErrors when executing process (d810075f00a6)
- - Fix issue with analogies that also require upgrades (215ceae6ef1f)
- - Fix typo (50da981b6938)
- - Fix issue with remove vistrail variable modules and connections (c3183771c5ea)
- - Ticket #569: Connected icon in Module Information does not disappear after removing
-   connection (9a68ec624c9d)
- - Fix issue with connected indicator for ports (9a68ec624c9d)
- - Eliminate duplicate warnings (f6020fa412bb)
- - Use lil_matrix for analogies (f6020fa412bb)
- - Modify logic of analogy usage to use current selected version (f6020fa412bb)
- - Ticket #419: Analogies fail on new terminator.vt (83c7735b0d28)
- - Change analogies to use a suitable default alpha value (83c7735b0d28)
- - Ticket #567: CLTools has issues reading man pages on Mac OS X (cdb5368df6fc)
- - Ticket #370: dataDirectory setting not used (73fe930b49ff)
- - Loading an image from workflow graph or a version tree was not
-   working in the command line (2b731d8d5043)
- - Workflow results that used a VTKCell were consisting of a black
-   screen when running in batch mode (80d55defb140)
- - Ticket #551: Cannot access messages window when preferences window is open (cc8fa8e6ad8a)
- - Ticket #487: isosurface script version of terminator.vt causes vistrails to 
-   crash (02caf56e6c0e)
- - Ticket #564: Invalid view warning (3b2062c17cb0)
- - Ticket #552: No visual clue when ubuntu package finishes installing (2f78b1b1d749)
- - Ticket #540: Vistrail is not always marked as changed when containing a vistrail 
-   variable (7acddff31ff1)
- - Ticket #566: QPixmap scaled error message (c6842a9fa320)
- - Fixed QPixmap scaled issue (c6842a9fa320)
- - Ticket #517: Undo menu item not working (a7b574defe31)
- - Fix undo/redo in pipeline view (a7b574defe31)
- - Fix issue with executions of untagged versions (36c1a73a46ae)
- - Ticket #560: Workspace has very inefficient updates (51a4e7982bb7)
- - Workspace: made loading mashups more efficient (51a4e7982bb7)
- - Ticket #562: "Save as" replaces items from workspace (d8fa58ccd9c0)
- - Ticket #560: Workspace has very inefficient updates (3dfac92ab688)
- - Partial fix to make workspace more efficient (3dfac92ab688)
- - Ticket #565: Version labels in query results are not gray (22e9920d1ea0)
- - Fix colors in query results view (22e9920d1ea0)
- - Ticket #504: The Query's refine option doesn't do anything (1fce254de2c5)
- - Reenable refined version tree in the query view (1fce254de2c5)
- - Ticket #532: Edit Package Abstraction Error (7c03b6999125)
- - Fixed issue with error message for editing package subworkflows (7c03b6999125)
- - Ticket #541: Crash when detaching ModuleInformation dockwidget on Mac (72c7afc3a95e)
- - Fix crash on undocking module info palette on Mac OS X (72c7afc3a95e)
- - Ticket #546: Selecting a version selects the text box instead of the version 
-   ellipse (5a7df50dd899)
- - Make version tree selection more intuitive (5a7df50dd899)
- - Ticket #538: Pipeline Connection Drawing? (ed11bdfffa54)
- - Fix connection drawing issue on Mac (ed11bdfffa54)
- - Ticket #558: Group signatures cannot be based only on interface (4ef2b8639b6d)
- - Fix issue with caching group modules (4ef2b8639b6d)
- - Fix initial layout of matplotlib cells (3a8d5c7c3d62)
- - Decreased level of debug message when removing elements from Thumbnails cache (18531d5fb280)
- - Ticket #534: Mashups hang with auto-update on (1472b6ba7f32)
- - Ticket #550: Workspace state_changed is slow (1ed823ecbb96) (b75607ea9271)
- - Ticket #556: Path to zip.exe not set correctly (d0389bec6df6)
- - Fix logic in identifier checks in package manager (1882ed36cd76)
- - Ticket #554: Port labels not displayed (a9454abc238a)
- - Add missing port labels to ports panel (a9454abc238a)
- - Ticket #553: Suspended module does not execute on second run even when 
-   notcacheable (3e22759385d3)
- - Ticket #549: update_db.py script does not work (fb5ad0eb480a)
- - Parameter Exploration only worked on parameters from the Basic Modules 
-   package (99969b93ece2)
- - Autoloading a SUDS Web Service no longer produce error messages (c079bd9c52db)
- - Ticket #513: Add detachHistoryView back (08bec17e40e6)
- - Ticket #543: Changes to persistence module configuration doesn't work (d03382c67e1d)
- - Fix issue where reconfiguring persistent modules caused unexpected behavior. (d03382c67e1d)
- - Show error message when trying to open a vistrail with a newer schema version (32f47804b6c7)
- - db_log_filename was not unset correctly for db cache (8fccb74ecab3)
- - Ticket #531: Export To Stable Version menu does not work (1b742a9f70cc)
- - Export to DB did not work (1b742a9f70cc)
- - Reloading a vistrail from the database gave it the name "None" (1b742a9f70cc)
-
-From Release: v2.0-beta build 716501f8b2fd from v2.0 branch
-
-Enhancements: 
- - Mashup View: Added float slider (b5d481049666)
- - New module execution state suspended added (cb47d3fc66b7)
-
-Bug fixes: 
- - Parameter Exploration: Changed call to update the progress bar to be 
-   thread safe (716501f8b2fd)
- - Fixed bug in iceCream.vt example (929ddcaa504a)
- - MySQLdb was not being shipped correctly in Mac binary (e50f1c91b3e8)
- - Mashup View: integer slider did not set step size correctly (b5d481049666)
- - Cached interpreter failed when handling wrong input type (b5d481049666)
- - Mashup View: failure when handling errors in execution that does not use the spreadsheet (b5d481049666)
- - Fixed qt.conf problem in installer script files on Windows. (a01fabd12456)
- - Fixed arguments of get_wf_graph_png rpc call (7cc451bdb606)
- - updateUpstream* failed when modules did not contain the suspended attribute (256f4b4dd8a5)
- - Mediawiki extension: fixed undefined variable  (334083cc69e1)
- - WorkflowExecution.completed were set to False in the vis_log, it
- should be an int. (cb47d3fc66b7)
-
-
-From Release: v2.0-beta build 10836452c19a from v2.0 branch
-
-Bug fixes: 
- - Fix issue with deleting modules and connections (10836452c19a)
- - VTK package: fix problem when upgrading vtkCellArray.InsertNextCell input port (e29a873af4a1)
- - Ticket #525: The create analogy button is too small (bf61e06b0a50)
- - Ticket #526: "Show raw pipeline" and "construct from root" commands should switch to the pipeline view (3ada5972d872)
-
-From Release: v2.0-beta build b074d3a4eb44 from v2.0 branch
-
-Enhancements: 
- - Added VisTrails Server documentation (611f2082f98d)
- - Add more functionality to core.api (26c775f0a7bb)
- - Ticket #518: Need to fix VTK ports with no parameters (9a985c40f6a2)
- - Add separate workflow and log xml schemas (04cb36cc5305)
- - Added support to hardcode necessary packages on startup (834e28f7cfa4)
- - CLTools: Added enviroment variable and default directory support (5a6e1b0daba3) (7c9a113040c2)
- - Add operation ids to messages about illegal operations (087b235e32de)
- - Remove most PyQt4/gui dependencies in core functionality (e6ada340cc15)
- - Ticket #55: Spreadsheet should have more shortcut icons (5f4db41dc8f2) (127037be178f)
- - Ticket #284: Capturing Module Errors (60c055eff8f5)
- - Display module toolTip errors in module stack trace dialog (60c055eff8f5)
- - Wizard for CLTools - gui for wrapper creation (a7a1db436fd0)
- - Added support for html and mediawiki extensions to
-access a remote vistrails server  (dd7456507ab4)
-
-Bug fixes: 
- - Mashups: editing an alias' values list had no effect (c485a7433dde)
- - Mashups: slider and numericstepper widgets are only displayed for 
-   numeric aliases (c485a7433dde)
- - Mashups: Validating Min Max and Step edit boxes so they accept only 
-   numbers (c485a7433dde)
- - Accessing Module Annotate from context menu did not work (ac100b566d84)
- - Fixed problem where unrequested vistrail temporary files were being created during test suite (445e2b68d9e6) (1a539cad8a9a)
- - Fix issue with alternate .vistrails directory and its subdirectories (7d26c36ef77a)
- - Fixed MissingRequirement path and ubuntu detection (11dd911b66a3)
- - Ticket #528: Install bundle fails with the new core_no_gui changes (87f9e83772ea)
- - Rendering version and workflow view in server failed because of new gui in 2.0 (e149aa955dd5)
- - save_many_to_db failed when list of objects were empty (ed257eb2d523)
- - Vistrail server need to initialize theme after core_no_gui changes (c4d2809d9a09)
- - Fixed server mode after merge with core_no_gui (4c2cad40c30f)
- - Ticket #522: remove_connection failure (cc038a500e3c)
- - Fix for remove_connection issues (cc038a500e3c)
- - Fixed issues with tabbing in the python editor (c046c86bf0af)
- - Fixed issue with vtkInteractionHandler which was not updated when the Save/Revert changes were made to source widgets (8abbfb8a51e9)
- - Allow zero-parameter functions to be set from ports panel (9a985c40f6a2)
- - Fixed issue with forced versions on modules (4ae602caa09e)
- - Fix issue with merging thumbnails (5bcaa7e75c6d)
- - Fixed typo in core.application's register_notification (42c7ae6b0e25)
- - Argument error caused gui/vistrail_controller test to fail (e447e02b37ca)
- - CHEBI wsdl changed (a7f1ab43159d) (6e00beb17ce6)
- - Removed matplotlib backend selection warning (23a6e3a89001)
- - Dragging a version directly on a spreadsheet cell was not executing 
-   the workflow (3395a01a2139) (66d49a064e59)
- - Fixed unable to display jpeg images in the spreadsheet
-due to a wrong Qt plugins configuration (a6a1950024a7) (333456765278)
- - Display more meaningful error when persistent inputs do not exist in a repository (1c905da96eb1)
- - Fix issue in ModuleDescriptor.expand_descriptor_string (7b973b4a4aeb) (35f1feb4d853)
- - Add icons to CLTools so that they not only work on X11 (a6a08bc1dd4e) (69110931c4e3)
- - SourceConfigurationWidget silently fails when code contains 
-   non-ascii characters (0c020878edf3) (768fc8ed4df5)
- - MultiHeads configuration was not working on 2.0  (669957620bdc) (07e9672e6186)
- - Ticket #513: Add detachHistoryView back (f238870a17fe) (38a3b95d1b5d)
- - Added back detachHistoryView option (f238870a17fe) (38a3b95d1b5d)
- - Removed configuration options that are only used in non-interactive mode 
-   from Expert Configuration (bb0046fe6f49)
- - Ticket #515: opening a specific version from the command line does 
-   not work (20ab44a5a4ce) (468fe95d351f)
- - Fixed opening a specific version from the command line (20ab44a5a4ce) (468fe95d351f)
- - Ticket #512: Add how to create alias to users guide (83e49a3d487b) 
-   (d56e02d30133) (a6249193e674) (f5b881191441)
- - Ticket #421: db version import error handling (a6eb8ae65052) (6ac6c0abec6e)
- - Detect between when a db version is missing and when it contains 
-   an error (a6eb8ae65052) (6ac6c0abec6e)
- - Ticket #391: Module colors in Visual Diff are wrong after upgrades (6b16033351a9) (c28166f2110b)
- - diff view did not use correct brush for non-upgraded modules (6b16033351a9) (c28166f2110b)
- - autosave feature caused "new file" action to fail (9b19a0fc5193) (6c49e4329b8a)
- - Ticket #511: "export workflow as xml" adds extension as "..xml" (two dots) if 
-   not explicitly specified (39d605e721e5) (fb2061eec506)
- - get_save_file_locator_from_gui was adding two dots (39d605e721e5) (fb2061eec506)
- - SpreadSheet: prompt the user to save unsaved vistrails before trying 
-   to save a spreadsheet (d296dae6e508) (5e29113d0694)
- - Ubuntu Unity did not restore menu bar after being closed (3d702340c1fa) (719ad4dd22b5)
- - Param Exploration User-defined function did not work because of new python 
-   editor interface (8354a9340944) (0f62ec4023c7)
- - Ticket #510: The Spreadsheet can't open/save spreadsheets (9259d3b8d619) (ae73b7e48971)
- - Ticket #194: Copy and paste duplicates aliases (7419092665c4) (27ee5e68a7e3)
- - Ticket #480: Executions button doesn't work (c6a9a6ac15cf)
- - Ticket #500: Double-clicking the Execute button causes VisTrails to Hang (e024a352c6ce)
- - Double clicking execute button no longer hangs vistrails (e024a352c6ce)
- - Ticket #508: Add port documentation back to ports panel (01f189a1a184)
- - Ticket #505: Version notes are not always visible after an upgrade (d16b3c834c47)
- - Issue correct version_selected signal after upgrades (d16b3c834c47)
- - Ticket #502: change_selected_version causes key error in adjacency_list (25104a599816)
- - Ticket #472: parameters in parameter exploration are reset if not executed (d07bcbd5104b)
- - Parameter exploration with Color Constant was not working (b0e0da8cc61b)
- - Ticket #462: Ungrab mouse error after editing subworkflow (2ffac0767f88)
- - Ticket #432: Problem with labeling groups (2ffac0767f88)
- - Allowing opening vistrail files that contain mashups. Mashups will be ignored (7d568fec386f)
- - Ticket #454: Can't interact with TransferFunction widget using Qt 4.7.* (f897a8e68285)
- - Fixed header placement in xml files that were causing tests to fail (a76060081c31)
-
-
-From Release: v2.0-alpha build c4e3600b6481 from v2.0 branch
-
-Enhancements: 
- - Wizard for CLTools - gui for wrapper creation (de5fbcd6144a)
-
-Bug fixes: 
- - Ticket #508: Add port documentation back to ports panel (d83b2637f5b5)
- - Ticket #502: change_selected_version causes key error in adjacency_list (815d38ff608a)
- - Ticket #472: parameters in parameter exploration are reset if not executed (829303e1efeb)
- - Parameter exploration with Color Constant was not working
- (ecfbedcd4406)
-
-From Release: v2.0-alpha build c4e3600b6481 from v2.0 branch
-
-Enhancements: 
- - Wizard for CLTools - gui for wrapper creation (de5fbcd6144a)
-
-Bug fixes: 
- - Ticket #508: Add port documentation back to ports panel (d83b2637f5b5)
- - Ticket #502: change_selected_version causes key error in adjacency_list (815d38ff608a)
- - Ticket #472: parameters in parameter exploration are reset if not executed (829303e1efeb)
- - Parameter exploration with Color Constant was not working
- (ecfbedcd4406)
-
-
-From Release: v2.0-alpha build 1b88c3949efd from v2.0 branch
-
-Enhancements: 
- - VisTrails now requires Python 2.7.*, Qt 4.7.*, sip 4.12.2 and PyQt4 4.8.4 to run 
- - Reworked VisTrails interface. Added Workspace palette where user's vistrails
-   are kept. Users can open multiple pipelines in different tabs that are 
-   detachable.
- - In addition to Pipeline, History, Query and Exploration Views, new views were
-   added, including Provenance and Mashup views. The Provenance view displays the
-   execution logs of a vistrail. The Mashup view allows creating simple 
-   applications based on workflows by exposing only the relevant parameters. 
-   See the VisTrails manual for detailed instructions.
- - Merged the "Methods" and the "Set Methods" panel into an improved 
-   "Module Information" Palette. Now port visibility, connectedness, and 
-   parameters are shown in a single display. Thus, for module types without 
-   special configuration widgets, there is no need for a separate configuration 
-   window.
- - CLTools - package for wrapping command line tools (3ac68958d3db)
- - Expand search results to include all open vistrails (b2a069e38956)
- - Opening exported mashups using Open menu will execute them automatically (48cefab0a019)
- - Added support for exporting a mashup to a .vtl file. To export a mashup, just 
-   click the "Export" button in the mashups inspector. Double-clicking the .vtl 
-   file will execute the mashup in VisTrails (09203c1e12b8)
- - Show parameters for invalid modules (7078566f7b89)
- - Changed "Keep" button to "Tag" in the Mashups View (5ed3637c2d6f)
- - Open subworkflow from module palette (c48a11df430f)
- - Executions in provenance view are now given names based on the 
-   "tagname + n" naming scheme (31a4a94cf967)
- - Update executions in workspace when they are created (8b7b85229c64)
- - Make pipeline current when selected in provenance explorer (49e93f5f789d)
- - Remove gui dependencies for core.modules widgets (1b8487908620)
- - Improved default query support (b9fed84af41a)
- - Added color difference support for queries (b9fed84af41a)
- - Mashups: made keeping the camera across updates as an option (1642d3573f62)
- - Add extensible query support (0df170d3335d) (5d776c28b7e2)
- - Workspace now updates Workflows and Mashups as they are created (429ceb313408)
- - Expand Workflows/Mashups items by default (429ceb313408)
- - Ticket #479: Dropdown boxes have white text (677a0b750762)
- - Added support for html and mediawiki extensions to access a 
-   remote vistrails server  (2eba04217a99)
- - Displaying mashups in workspace. Double-clicking a mashup will show 
-   version tree, select corresponding version and execute the mashup. (3df2af8d8cb2)
- - Added support for multiple PythonSource configuration windows. Read-only 
-   windows can be detached from the main module onfiguration window. (372c0143f6b6)
- - Remove workspace entry when selected file has been deleted (8bdd77c78fe2)
- - Workspace can show workflows in a tree view (c715b4a84a38)
- - Added a Control Flow Assistant (f05f014bc778)
- - Added Vistrail Variables support, so that modules deriving from Constant can 
-   be used to create re-usable variables (a83402e0c218)
- - Added support for cross-vistrail diffs (c300063531e8)
- - Perform visual diff from workspace by dragging pipelines together (dd83c3f08cea)
- - Simplify visual diff and improve parameter changes display (65849c433682)
- - Search results show up in workspace window (f3a763972866)
- - Improve query handling (e4b0722b1d70)
- - Added support for opening a vistrail in a separate window (f502431ae11b)
- - Added Expand All and Collapse All buttons to Module Palette (264410835b7)
- - Added annotations to WorkflowExec in v1.0.2 schema (0ade1076517b)
- - Provenance browser now shows status icon in list (fc112c4c1079)
- - Autosort module palette (de80a5b0fb1c)
- - Added merge by dragging vistrail to vistrail (6bb73281842a)
- - Executable paper editing (3a96ea787a82)
- - PythonSource editor will now indent newline to previous line (e221d10351d1)
- - Improved PythonEditor class using QScintilla2 (d737455457db)
- - PythonSource editor will now indent newline to previous line (d1e5d63bd715)
- - Enhanced query capabilities (0e5f60ce0d91)
- - Added support for interpreter to execute a pipeline with an extra list
-   of parameter values. Updating VistrailController calls to also accept
-   the new list (db6e4611305)
- - persistence package now hides file references instead of deleting them (ae3d19282ef4)
- - Added versioning for SUDS Web Services using content hash (47279d4246bf)
- - Improved PythonEditor class using QScintilla2 (5ed5953f57b9)
- - ParaView package: Added ScalarBarWidgetRepresentation to Rendering
-  namespace in modules list.  (7429a1be15cf)
- - Add better provenance information for persistent entities (22964cfeb53b)
- - New manager for persistent store (f0dafc611fd0)
- - Improved efficiency of vtk workflow upgrades (3736cc9ef269)
- - LaTex extension: Added an example for embedding local files (be50aeab59ca)
- - Group SQL statements to enable faster DB communication (b520f1c847c8)
- - ParaView package: Added server configuration window options to
-package configuration and loading initial values from there. Also added
-option to start paraview server when the package is initialized.  (9023c13aa76b)
- - Ticket #408: Allow opening multiple PythonSource Editors (73e72b8419a8)
- - Ticket #411: Support temporary directories in the FilePool (7eb29d2ba0fb)
- - Initial version of a GIS package that uses QGIS (4cd7cc6df8db)
-
-Bug fixes: 
- - VTK Package: Call to ResetCamera() in vtkRenderer was producing wrong 
-   results (d5789e5a560b)
- - Ticket #499: Issue with BaseView.layout (9dc74870fde7)
- - Fix issue where 'layout' was an overloaded field name (9dc74870fde7)
- - Ticket #494: Tuple configuration is confusing and causes configuration errors (30bc134d5cdb)
- - Ticket #498: Need to update code to show parameters for invalid modules (8da733c07199)
- - Enable showing invalid function and show parameters in separate fields (8da733c07199)
- - Updated version of suds python library on both Windows and Mac binary.
- - Ticket #488: configuring webservices breaks vistrails (090a45a95f19)
- - Ticket #456: Cannot copy/paste in detached pipelines/vistrails (970ec4ecfb42)
- - Ignoring action updates when the view does not have the actions (970ec4ecfb42)
- - Make provenance view read-only (9774b9e2928e)
- - .vtl files marked to be executed when opening were not executed (09203c1e12b8)
- - Ticket #496: Showing/hiding module ports resets module position (c073ff4bf200)
- - Keep module position when changing visibility of ports (c073ff4bf200)
- - Ticket #488: configuring webservices breaks vistrails (b8a935d8bbae)
- - Ticket #495: vtkCellArray won't allow multiple points through 
-   InsertCellPoint (0dcbf136aeb8)
- - Fixed issue with ports that may have multiple functions associated with 
-   them (e.g. in the vtk package) (0dcbf136aeb8)
- - Ticket 481: Optional Output Ports collapse to non-Optional ones (7463f214023b)
- - Fixed the issue of being unable to activate windows under Mac OS X 
-   Lion. (7463f214023b)
- - Mashups: Fixed bug introduced when removing gui
-   dependencies for core.modules widgets (76a998022666)
- - Ticket #492: Upgrade error: signatures differ (5a70996965f8)
- - Add upgrade for PythonSource to fix issue with 'self' port (5a70996965f8)
- - Fixed messages during upgrades so that upgrade info is not flagged as 
-   a warning (8714561fed05)
- - Mashups: creating aliases in mashup view was not updating the alias 
-   table (770f755d089d)
- - Ticket #491: Opening a .vtl will always create a new file (3a25858be1ac)
- - Opening vtl files: igonring showSpreadsheetOnly if execute is false (3a25858be1ac)
- - Starting VisTrails by double-clicking a vistrail file was
-   not zooming the current pipeline view (3a25858be1ac)
- - Can now delete from workspace using backspace key (d3f7af2868b0)
- - Remove vistrail from workspace if removed from disk (044a841b97e9)
- - view.is_abstraction logic fixed (044a841b97e9)
- - sql package was not using new gui.modules.source_configure (1714703fb145)
- - Updated VTK, Persistence and Matplolib packages to use 
-   gui.modules import (f953ce4d25e4)
- - get_current_view bug caused double-clicking a vistrail to fail (00b264c0920b)
- - Ticket #489: VisTrails 2.0 can't open .vtl files anymore (2d450422c25b)
- - opening .vtl files fails (2d450422c25b)
- - Ticket #460: Subworkflow port naming errors after editing (687becdff050)
- - Fixed issue where subworkflow edits could result in one-to-many 
-   port mappings. (687becdff050)
- - Fixed issues with multiple versions of subworkflows appearing in the 
-   module palette (186d5c06a788)
- - Do not store subworkflows in "recent files" or "My Vistrails" (17aebdbd32fa)
- - workspace.item_selected had invalid setSelected call (3effd7a1385b)
- - Fixed 2 detach view bugs (3f5159f5b49f)
- - Ticket #468: Diff tab should have all modes except pipeline 
-   disabled (4f691ba6ed23) (139ec1d18b22)
- - Fixed an issue when loading a vistrail that references different versions 
-   of a subworkflow that share common ancestors (4b34089abb09)
- - Ticket #486: query execution and parameter problems (323f12916d09) 
-   (0262b0410051) (d9fbb412a9b5)
- - Added ability to open workflows from query results (323f12916d09)
- - Ticket #484: subworkflow save causes window to change (bc100442dfe4)
- - Fixed issues with executing queries (0262b0410051)
- - Fixed issue where numeric comparisons were being done as 
-   string compares (d9fbb412a9b5)
- - Fixed issue where substring queries were backward (d9fbb412a9b5)
- - Fix an issue with copy/paste to query view (b9fed84af41a)
- - Fix issue with package subworkflows and namespaces (87c7c61f1c9e)
- - Ticket #476: numeric stepper has wrong default value, in some cases 
-   (1642d3573f62) (a08e8dc0f9c2)
- - Ticket #485: Random Mashups Window (917b1d8b83c5)
- - Allow return to original query in interface (0df170d3335d)
- - Allow parameters to be set in queries (0df170d3335d)
- - Allow return to original query in interface (5d776c28b7e2)
- - Allow parameters to be set in queries (5d776c28b7e2)
- - Ticket #478: Mashups updating issues (e5913008d81c)
- - Mashups: Display Widget section was not updated when
-   switching aliases (e5913008d81c)
- - Mashups: Mashup inspector was not updated when switching
-   vistrails using the workspace in Mashups View (e5913008d81c)
- - Mashups: Mashup Pipeline Palette was not being updated when
-   switching mashups using the Mashup List Panel (e5913008d81c)
- - Ticket #483: Index error when recovering a vistrail (8589b301ba13)
- - Fixed issues with upgraded subworkflows (9c4dfcbef423)
- - Ticket #475: Changing the background color fails in Mashup mode (31670c3e66f2)
- - Ticket #477: opening mashup from workspace doesn't show exposed 
-   parameters (429ceb313408)
- - Sometimes closing a vistrail while closing VisTrails fails (429ceb313408)
- - Double clicking a vistrail in file browser fails because of 
-   _first_view bug (263f1947cf2c)
- - vtkhandler did not handle new PythonEditor correctly (aa3511259f10)
- - Ticket #443: ports are not added through Module Configuration 
-   and annoying confirmation (01ed7a6566b3)
- - Ticket #473: Cannot execute from history view immediately after 
-   opening vistrail (e0ba2e97d058)
- - Ticket #472: parameters in parameter exploration are reset if 
-   not executed (63c55f11f03d)
- - Ticket #474: Error quitting when spreadsheet is visible (afe4512b1ca9) 
-   (107b24e904ea)
- - Ticket #470: copy doesn't copy to the correct cell (c44347501d5a)
- - Fixed issue with cell locations in spreadsheet editing mode (c44347501d5a)
- - Ticket #471: visual diff window is missing the create analogy 
-   button (14a24ea42b15)
- - Ticket #469: locate version in editing mode selects history but shows 
-   pipeline (080a2dc8b820)
- - Opening xml vistrail from workspace showed open file dialog (069db5448e8e)
- - Module documentation in module palette not working (647613ad637e)
- - Ticket #467: A file is changed when test suit is run (37e0ab607139)
- - Ticket #466: history mode selected and pipeline view shows up after 
-   merging 2 trees (e22fe0a4f8b0)
- - Ticket #459: the explore tab draws upside down (542e2cda8845)
- - Outdated inspector.annotated_modules value caused explorer tab to be 
-   drawn upside down on Mac (542e2cda8845)
- - Ticket #446: subworkflow editing only good for one save (2ab6a92c2084)
-   (85b50d980ab1)
- - Fixes to subworkflow upgrades and save as (2ab6a92c2084)
- - Changes to subworkflow identification (85b50d980ab1)
- - Ticket #465: Open Recent menu does not contain saved vistrails (a484b18b3eed)
- - Update recent files list also when vistrail is saved (a484b18b3eed)
- - Ticket #463: Current version not selected on open (154e9b2e8eaa)
- - Select latest version when opening a vistrail (154e9b2e8eaa)
- - Ticket #462: Ungrab mouse error after editing subworkflow (6aaa6bd2b526)
- - Ticket #432: Problem with labeling groups (6aaa6bd2b526)
- - Ticket #461: Initial history view for first vistrail is not zoomed to 
-   fit (b3d8909ac0ed)
- - Fix zoom to fit for initial vistrail (b3d8909ac0ed)
- - Ticket #434: Can't remove tags of versions that were 
-   upgraded (v2.0) (47636de1ec66)
- - Fix issue where raw pipeline and construct from root were not 
-   working (47636de1ec66)
- - Enabled Embed version by default when selecting Publish > To Paper (8bf5e737a2c2)
- - Ticket #456: Cannot copy/paste in detached pipelines/vistrails (0cb6ef7650af)
- - Fixed issues with spreadsheet editing for copies and analogies (d2d4bae51a6d)
- - Enabled Edit Configuration and Show Documentation from a module's
-   context menu  (00dcb21d22a6)
- - File > Export > PDF was not working  (fce8cc569c14)
- - Ticket #455: Module Information Tab stretches unnaturally when package 
-   has a long name (2d07662227fd)
- - module information stretches unnaturally (2d07662227fd)
- - Ticket #457: PythonSource ports are not updated when configuration window 
-   is saved (f6e151300476)
- - Ticket #456: Cannot copy/paste in detached pipelines/vistrails (f9470d9fa04a)
- - Removed missing web service (028fc4e03c62)
- - Fixed header placement in xml files that were causing tests to fail (4db41b9e2e75)
- - Workspace fixes for saving empty vistrail and closing detached 
-   vistrail (1f798a7a0c84)
- - Ticket #454: Can't interact with TransferFunction widget using 
-   Qt 4.7.* (ea7e21dc9e01)
- - Ticket #453: Workspace indexing error in tree mode (f8b17ab82b9b)
- - Skip workspace make_tree when no window exist (f8b17ab82b9b)
- - Ticket #450: Indexing failures need to be more graceful (f76532828242)
- - Better error handling when indexing workflow (f76532828242)
- - Ticket #452: Visual Diff Parameter Changes not detected (65849c433682)
- - If the clipboard contained utf-8 characters, VisTrails would raise
- an error (d7cecf541ced)
- - QPipelineScene.addModule were calling addItem twice (d77e833f431f)
- - Dropping vistrails variable created error (8c0b0e921201)
- - Fixed export/import menu options (8d68b5b56ff3)
- - Fixed parameter exploration in v2.0 (8485390429b1)
- - Parameter exploration was not saving color parameters when they
-were being interpolated (8485390429b1)
- - Fixed 'Diff properities' label typo (8a88bd21895a)
- - Removed close button from Vistrails Messages view (2581ea446bad)
- - Ticket #441: vistrail browser is not being updated (d892cd18e5b8)
- - Correctly update collection on load/save (d892cd18e5b8)
- - Show project selector (d892cd18e5b8)
- - Sort default project by name (d892cd18e5b8)
- - Ticket #435: diff result is not properly sized/centered (96c4adaa2a1a)
- - Show executions for the current session as well (fc112c4c1079)
- - Workspace threw exception when closing vistrails (47ae1c3c4428)
- - Fixed crash when running VisTrails 64-bit on Windows with more than 4GB 
-   of RAM (71b4bfc41a6d)
- - 2 bugfixes to the vistrail merge code (4f05a96bcc2c)
- - open merged vistrail in new tab and other fixes (556804ba40c4)
- - builder_window was stealing ctrl-z/ctrl-y from PythonSource (e221d10351d1)
- - Made new PythonEditor use correct font (2579b6f662ca)
- - removed self reference in static method in persistence package (12e57882a72b)
- - open merged vistrail in new tab and other fixes (971228751494)
- - Fix menubar issue on non-Mac platforms (9d5e66156935)
- - persistence package did not show dates correctly (357f3a55aaf5)
- - Spreadsheet package: Fixed a typo on the usage of issubclass() which prevented
-   subclassed sheets to be used by the spreadsheet (8bcd8ac86cd4)
- - SUDSWebServices wsdl caching in Windows need to use pickle 
-   protocol=0 (4ca71139f604)
- - SUDSWebService wsdl hash did not use the correct wsdl string (4ca71139f604)
- - Fix issue with caching and persistent files (f56f14061d3f)
- - ParaView package: Fixed example pipeline where it should display
-   both a box and a sphere.  (7429a1be15cf)
- - VTK Package: Fixed bug when drawing TransferFunction widget (daaacfcedfca)
- - Handle unnamed data when writing from manager (22964cfeb53b)
- -  Fixed infovis example  (7d6a0dace8ca)
- -  Fixed NOAA Web services example. NOAA had changed the urls
-for their services  (7d6a0dace8ca)
- - Do not import MySQLdb directly in sql_dao (b1d1809c0d57)
- - Ticket #420: VisTrails fails to install package dependencies on Ubuntu (35cd1cceeded)
- - debug imports cause ubuntu package install to fail (35cd1cceeded)
- - Ticket #416: The log is not copied when saving a vistrail from database to disk (1af107087fbe)
- - Include log when copying vistrail from DB (1af107087fbe)
- - LaTex extension: When generating LaTex command using the Embed panel,
- make sure to enclose tag between {} so symbols are escaped. (be50aeab59ca)
- - LaTex extension: Fixed problem when passing envrionment variables
-using \vistrailsenv{} (be50aeab59ca)
- - Ticket #417: Database INSERT statements are not protected from overflowing (b520f1c847c8)
- - Overflow checking for SQL datatypes (b520f1c847c8)
- - Changed memory size to be computed in megabytes instead of bytes
-to avoid large numbers (4d21156d99f5)
- - Ticket #414: Focus out event on Tag version edit box generates an unnecessary 
-   vistrail change event (6dc3154542ba)
- - Media wiki extension: casting returned version of a given tag to
-string before using it (6dc3154542ba)
- - Ticket #412: Parameter exploration on File parameters fails (e54b74bb9412)
- - Fix parameter explorations on File parameters (e54b74bb9412)
- - Added ability to create temporary directories in the FilePool (7eb29d2ba0fb)
- - LaTex extension: added support to work on Windows with MikTex (2bdfb94be496)
- - LaTex extension: changed behavior of passing environment variables -
-passed variables will not replace existing ones, they will be inserted at the
-beginning (2bdfb94be496)
- -  Removed warning when copying thumbnails fail because the files are the
-same (2bdfb94be496)
- -  New log file was not being created on Windows when the version was
-upgraded  (2bdfb94be496)
- - Ticket #410: Encode VTK changes as upgrades (fa2e48cedf06)
- - Attempt to implement VTK upgrades (fa2e48cedf06)
- - Ticket #409: Problem in workflow upgrade (5d57b4ce54b3)
- - Fix issue with upgrading modules with null functions (no parameters) (5d57b4ce54b3)
- - Ticket #407: Aliases in a workflow disappear after upgrade (843603916a48)
- - Preserve aliases during upgrades (843603916a48)
- - Replaced more GUI code that would work only on recent versions of Qt/PyQt4 (7cfcb98320ee)
- - Replaced code that would work only on recent versions of PyQt4 (e5ca41c3fab7)
- - Enabled with_statement for python2.5 (3ec5bdd47c3e)
-
-
-From Release: v1.7 build 325bfe1b517d from v1.7 branch
-
-Enhancements:
- - VisTrails is now distributed under the "Modified BSD License"
- - VisTrails binaries are now shipped with python 2.7.1, Qt 4.7.2, sip 4.12.2, 
-   PyQt4 4.8.4, vtk 5.6.1, numpy 1.5.1, scipy 0.9.0 and matplotlib 1.0.1. 
-Bug fixes:
- - Importing basic_modules.py leads to import loop (325bfe1b517d)
- - VTK Package: Fixed bug when drawing TransferFunction widget (7722fc6727aa)
-
-From Release: v1.6.2 build af4a69ad566a from v1.6 branch
-
-Enhancements: 
- - Adding pdf version of Usersguide to binaries.  (60cec4e6d858)
- - Improved efficiency of vtk workflow upgrades (501a552cd722)
- - LaTex extension: Added an example for embedding local files (f5976c82826f)
-
-Bug fixes: 
- - Fixed infovis example  (bd810b67daaf)
- - Fixed NOAA Web services example. NOAA had changed the urls
-for their services  (bd810b67daaf)
- - Added matplotlib mplot3d toolkit to Mac binary (5054da25e2e8)
- - Ticket #410: Encode VTK changes as upgrades (aeaa56469120)
- - Attempt to implement VTK upgrades (aeaa56469120)
- - Ticket #420: VisTrails fails to install package dependencies on Ubuntu (5180336d429d)
- - debug imports cause ubuntu package install to fail (5180336d429d)
- - LaTex extension: When generating LaTex command using the Embed panel,
- make sure to enclose tag between {} so symbols are escaped. (f5976c82826f)
- - LaTex extension: Fixed problem when passing envrionment variables
-using \vistrailsenv{} (f5976c82826f)
- - Changed memory size to be computed in megabytes instead of bytes
-to avoid large numbers (5f57a040c97c)
- - Ticket #414: Focus out event on Tag version edit box generates an unnecessary vistrail change event (460836e2206e)
- - Media wiki extension: casting returned version of a given tag to
-string before using it (460836e2206e)
- - Ticket #412: Parameter exploration on File parameters fails (7630f10fb73c)
- - Fix parameter explorations on File parameters (7630f10fb73c)
- - LaTex extension: added support to work on Windows with MikTex (36322a953de2)
- - LaTex extension: changed behavior of passing environment variables -
-passed variables will not replace existing ones, they will be inserted at the
-beginning (36322a953de2)
- -  Removed warning when copying thumbnails fail because the files are the
-same (36322a953de2)
- -  New log file was not being created on Windows when the version was
-upgraded  (36322a953de2)
- - Ticket #409: Problem in workflow upgrade (040f46c2f980)
- - Fix issue with upgrading modules with null functions (no parameters) (040f46c2f980)
- - Ticket #407: Aliases in a workflow disappear after upgrade (5575069d2727)
- - Preserve aliases during upgrades (5575069d2727)
- - Replaced more GUI code that would work only on recent versions of Qt/PyQt4 (2704aa1fe222)
- - Replaced code that would work only on recent versions of PyQt4 (50ead740f6de)
- - Enabled with_statement for python2.5 (bec2a6498965)
-
-
-From Release: v1.6.1 build ba9616b413d2 from v1.6 branch
-
-Bug fixes: 
- - Ticket #406: Builder Window menu inconsistencies (fd46220842bf)
- - Added support for executing workflows even if VisTrails is already
-running (useful for Latex extension) (16c1d253a63a)
- - Added single instance limitation per user/machine instead of per
-machine. Now multiple users logged to the same system can execute their
-version of VisTrails (16c1d253a63a)
- - VisTrails was ignoring batch mode input parameters if already running
- (16c1d253a63a)
- - Latex and Wiki extensions: all options can now be set from the builder. (16c1d253a63a)
- - Ticket #405: VisTrails is not downloading unavailable packages if they are present in the packages repository (77cadf0fb8a1)
- - VisTrails batch mode: Separated generation of the workflow graph from execution of the workflow. Added support for generating the history tree graph (77cadf0fb8a1)
- - When generating a workflow graph VisTrails would sometimes generate a line in the borders (77cadf0fb8a1)
- - When testing a database connection with a password=None VisTrails would crash without catching the exception (77cadf0fb8a1)
- - When opening a vistrail from a vtl, VisTrails was ignoring the version that should be open and always opening the most recent one (77cadf0fb8a1)
- - Latex extension: added support for running vistrails locally (15255a96e4e0)
- - Latex extension: added support for embedding workflow and/or
-including full tree when generating vtl requests (15255a96e4e0)
- - Wiki extension: workflows were not being embedded in .vtl file (5348cad089ba)
- - Added title to console and debugger toolbars (b2e3bda06f62)
- - Better error handling for duplicate module identifiers in packages (579520227409) (d5df9421d0c1)
- - Fixed an issue where the FilePool's local copy mechanism failed in Windows (7b398b211212) (254bce86348e)
-
-
-From Release: v1.6 build e9f97c5908ac from v1.6 branch
-
-Enhancements:
- - Added prompt for password for database access in batch mode (06c4b63434a7)
- - Please notice that the parameter separator in the command line changed again from 
-  '&&' to '$&$' so it's consistent with the server version. (35ad76515a97)
- - VisTrails now has "Check for Updates" option in Help drop-down (b80862d8a39f)
- - Show port_spec.sigstring in PortMismatch error message for more
-   detailed debugging (c28dad738abc)
- - Turn off popup messages if messages window is open (62aeb9371235)
- - add/delete Web Services from module palette for SUDSWebServices package (2e381a4394ed)
- - Package-level context menus in the module palette (2e381a4394ed)
- - Add preference for migrating tags and notes on upgrades (41177e74e687)
- - Add stack trace to exception details for unexpected exceptions during 
-   change_selected_version (fd3840df3c6b)
- - Added new class Chdir to prevent users from triggering side-effects by accident 
-   when using os.chdir() (4aa722db61d1)
- - Added Open Recent to File menu (it works for vistrails in the file system or in 
-   the database. The maximum number of files in the list can be configured from Advanced 
-   Preferences Tab (search for maxRecentVistrails) (4aa722db61d1)
- - Configuration object now supports bound methods as subscribers (4aa722db61d1)
- - Debug messages now have a "details" attribute (f2911a6a6000)
- - Buttons for filtering VisTrails messages (ebc728d49db3)
- - Colors of message types added to theme file (ebc728d49db3)
- - Improved log messages in the server log to also indicate the instance of the server that 
-   is logging the messages (762902e79b7a)
- - Improved handling of log messages (037568dc5960)
- - Changed all examples using relative paths to datasets to use HTTPFile (403205442fd7)
- - Updated head.vt and terminator.vt example to use TransferFunction widget (403205442fd7)
- - Maintain suffixes on persistent files and directories (e9b5e906e069)
- - Improved debug messages (9dcd1a5a2ea8)
- - Ticket #390: Add support to Latex extension to download workflows at compilation 
-   time (90ef6cee20a9)
- - Improved error handling in vistrails.packages (a44800a88083)
- - Improved debugging messages for vistrails.gui (25b718347ef0)
- - Improved error handling in vistrails.core (2e095f36dc90)
- - Debug library updated (41e3778d507e)
- - Web Services package is now deprecated. Showing a warning message when the WebServices 
-   package is loaded. Message will be shown only once. (9996bba52dd1)
- - Ticket #375: Add GUI support for synchronizing vistrails (4efb09fbe5bd)
- - Merge 2 Vistrails from within VisTrails (4efb09fbe5bd)
- - Detect changes to directories so the cache can be invalidated when they change (3058d55966f2)
- - New Web Services package that uses SUDS library (0d1d3efb99da)
- - Add pinch gesture support to graphics views (3d01e549f849)
- - ParaView package: Converted to new VisTrails package format (65453bd92aa5)
- - Updated php scripts to work with Latex extension's new features (2b53ad32a374)
- - VisTrails server: added new function to return version tree as pdf  (2b53ad32a374)
- - Created a separate php file to store the server configuration (8d15fdbe8e1d)
- - Added support for running crowdlabs and vistrails server on separate machines 
-   (still testing) (064304a99993)
- - Ticket #382: Improvements to Latex extension (3123297d6a1b)
- - LaTex extension: VisTrails can now embed a workflow graph or a history tree in 
-   LaTex pdf (3123297d6a1b)
- - LaTex extension: Caching latex instructions and images for embedding images in case python 
-   is not available (3123297d6a1b)
- - Ticket #381: Split HTTPFile.compute() method to download the file in a separate 
-   function (62d25dca3f3a)
- - Add MplScatterplot and MplHistogram modules to pylab (4af6514c20d4)
- - Ticket #295: Add Debug .command to Mac distribution (e835d69d8426)
- - Added git executable to windows repository. It will be included in future windows 
-   binaries for persistence package  (8d9931bbbe04)
- - Updated version of the rpy package (c895125216cb)
- - Migrating new persistence package from persistence_exp to persistence (5b6418233dea)
- - Added methods to expand shortcut string representations for module descriptors and port 
-   specs (5b6418233dea)
- - Added support for shortcuts to remap modules/ports for upgrades (5b6418233dea)
- - Use List for controlflow now instead of ListOfSElements (74f30460d3fe)
- - Highlight invalidate port specs (74f30460d3fe)
- - Improved support for work with the filesystem. Added DirectorySink module,
-    changed FileSink module to use 'overwrite'
-    instead of 'overrideFile', added support for getting the contents of a
-    directory, created a new OutputPath constant with a save-style widget
-    to select the output path, replaces OutputName on the FileSink module.
-    Added updgrade code to translate old FileSink module to new version.
-    Changed version of basic_modules and abstraction to static string
-    '1.6'. (fb30dca8a15d)
- - HTTPFile now supports proxies. (3799edddbb62)
-
-Bug fixes:
- - Fix issue with console mode and unit tests (a4d544eec673)
- - Ticket #361: Cannot configure output cell layout for cells in groups in parameter 
-   explorations (5807414236ba)
- - Enable all spreadsheet cells for parameter exploration, even if they are embedded in 
-   groups or subworkflows (5807414236ba)
- - Ticket #399: Exception thrown when loading parameter exploration tab with no existing 
-   exploration (4366e52c39cf)
- - Fixed exception when loading parameter exploration tab for a workflow with no saved 
-   explorations (4366e52c39cf)
- - Ticket #154: vistrails should check for a new version being available and tell the 
-   user to download it (b80862d8a39f)
- - Ticket #398: Failure opening vtl files (filename issue) (c52ba7adc5f8)
- - Matplotlib package: if hide toolbar parameter is set after the source
-   and there isn't an extra line at the end, the MplPlot would fail  (c52ba7adc5f8)
- - Ticket #398: Failure opening vtl files (filename issue) (cdfa0c97493d)
- - Added escaping to filename in unzip commandline call (cdfa0c97493d)
- - Fixed issue where it was not possible to ungroup a subpipeline that had an InputPort
-   connected directly to an OutputPort (e1ea9b437507)
- - Fixed problem where controlflow package would raise duplicate errors (4351b3f0102f)
- - Fixed issue with groups and input values that evaluate to False (6fc007c0535d)
- - Fixed ordering of PortMismatch parameters in ensure_port_specs (c28dad738abc)
- - Fixed bug introduced on Windows platforms when changed os.chdir() calls by 
-   core.utils.Chdir (0a2b8a0d50d8)
- - Enable the Linux theme for 'Linux' system types (57dfb4a85e7a)
- - added deletion of namespaces in module palette (2e381a4394ed)
- - Add ability to migrate tags when upgrades are not delayed (9c49285269ca)
- - Message filter colors does not show in linux (ee8906c91039)
- - Ticket #397: Save execution log when in console mode (2dae96a8f004) (1afa51d895e9)
- - Update version tree when adding delayed actions (d1dbf3005499)
- - Subworkflows from packages that need upgrades are now moved to local.abstractions 
-   in the registry and picked up for workflow upgrades (04476a172f61)
- - Fixed issue with spreadsheet and grouped spreadsheet cells (fd3840df3c6b)
- - Replaced svn command with git command to get current commit (if present) (4aa722db61d1)
- - Flush delayed actions (including upgrades) to fix issues with delayed upgrades and 
-   grouping upgraded workflows (79dd982e6cef)
- - VisTrails Server: Applied fix to caching of history tree images when
-   generated as pdfs (fc0ab9f1626d)
- - VisTrails Server: fixed problem in caching of history tree images (4862e1f7d18a)
- - Ignoring mouse gestures when Qt version is < 4.6 (4862e1f7d18a)
- - Ticket #394: VisTrails server is not detecting updates in vistrails loaded 
-   from the database (762902e79b7a)
- - Restoring extensions/http/run_vistrails.php to version before merge (762902e79b7a)
- - VisTrails server was ignoring the build_always variable if it
-   found cached images (762902e79b7a)
- - Using port to identify the instance of the server instead of virtual
-   display in script that starts vistrails server using Xvfb (762902e79b7a)
- - Ticket #393: Latex extension doesn't handle workflow exec. errors properly (16f522c459c5)
- - Latex extension: Making sure to convert line breaks into \MessageBreak
-   Latex commands before displaying error messages. (16f522c459c5)
- - Forwarding force build to server so the server can also bypass
-   caching (47a1105664a0)
- - Ticket #392: Refactor php extensions caching logic used for wf executions (3125e0eb8e81)
- - Updated mediawiki extension to work with crowdlabs server  (3125e0eb8e81)
- - Added workaround for RotateFileHandler problem on Windows when some
-   packages start child processes during workflow execution (e5afc47797cb)
- - Fixed issue where named intermediate persistent files/directories were not 
-   reused correctly (df3deb58a18c)
- - Fixed git hash retrieval for persisted directories (df3deb58a18c)
- - Pasted text in VisTrails shell was being ignored (c48e67f02ae8)
- - Giving focus to VisTrails shell when showing it (c48e67f02ae8)
- - Added 'VisTrails messages' button and fixed 'VisTrails debugger' button (b401b2498c74)
- - Don't mask AttributeErrors when materializing pipelines (b5c3650e5ca6)
- - Add upgrade path for old InputPort and OutputPort modules (8abfff56592c)
- - Fixed an issue with groups and upgrades (720d93c8e3be)
- - VisTrails shell was not using fixed-width font  (b521e096f879)
- - Latex extension: delaying check for a valid url so we can include
-   cached images if there's no Internet connection (79296270cc86)
- - Batch mode: On Windows, VisTrails was not executing workflows
-   when an absolute path to a vt file was given (81812ac04e85)
- - Minor error fixes (45b53eef1c53)
- - Ticket #386: Moving modules after an upgrade generates invalid actions with 
-   delayed upgrades (ad9e029035f7)
- - With delayed upgrades, moving modules after an upgrade now generates actions 
-   in the correct order (ad9e029035f7)
- - Ticket #385: Workflow instantiation fails when doing on-demand package loading (aff3408c7a51)
- - Fix issue with on-demand package loading leaving workflows as invalid (aff3408c7a51)
- - Casting DBLocator names to string as they can store None sometimes (9996bba52dd1)
- - Ticket #384: Deleting version edits version tag if delete is canceled (cc05bc9e80e5)
- - Don't delete tag text when attempting to prune (cc05bc9e80e5)
- - Expanding port specs deals with differences between descriptor and port signatures (c5763a437606)
- - UpgradeWorkflowError tries to trim None-value (93b3be3d2a50)
- - Ticket #383: Unversioned modules are not upgraded (4b3fa72869f0)
- - If a module has no version, force it to be upgraded (4b3fa72869f0)
- - Ticket #302: Moved modules action generated when nothing changed (3e59defe4685)
- - Fixed logic so moved modules are properly detected and positions updated. (3e59defe4685)
- - ParaView package: Removed hardcoded path to pvserver and mpiexec
-and using configuration object for that (accessible through Menu
-Preferences -> Module Packages) (65453bd92aa5)
- - ParaView package: Updated pv.vt example to work with current version
-of the package (65453bd92aa5)
- - Fixed bug in some php scripts when only the tag is passed instead of
-a version number  (2b53ad32a374)
- - Updated all php scripts in extensions/http to work with
-the current version of crowdlabs vistrails server (only local
-setup currently supported) (8d15fdbe8e1d)
- - Fixed bug where server method get_wf_graph_png would sometimes
-fail (064304a99993)
- - Fixed bug where although DBLocators were being cached, the 
-   connections were not  (b07c22d9e93d)
- - Ticket #359: When using VTKRenderOffscreen module VisTrails crashes (48e477f4c1d9)
- - VTK Package doesnt work with VTK version 5.7.0 (ba5e0bdbbb16)
- - Fixed issue with query-by-example where parameters couldn't be updated (741b1c0d7737)
- - Error using breakpoint due to new stack trace (d4f31af05a05)
- - LaTex extension: removed hardcoded url for downloading vt files
-upon clicking on the images in the generated pdf. It can now be set using
-the \vistrailsdownload in the latex file (3123297d6a1b)
- - HTTP package was not handling exceptions correctly (62d25dca3f3a)
- - Ticket #380: HTTPFile corrupts binary files on Windows (0a5ec2007878)
- - Color Constant: Initializing Color widget with default white
-color using RGB constructor instead of QtCore.Qt.White. We assume the
-color is always a QColor object and sometimes a GlobalColor object
-was being found (8565a276a353)
- - Persistence Package: Added code to find tar executable similar
-to the way the path to git is set up (4a2494c09ef4)
- - Persistence Package: adapted use of tar command to work
-on Windows (430e29bcaf2e)
- - Windows binary: Including the gnu version of tar instead
-of the one that comes with git (430e29bcaf2e)
- - Set MplFigureCell to fill spreadsheet cell (4af6514c20d4)
- - Ticket #302: Moved modules action generated when nothing changed (8f60ea9a4737)
- - Dangling move actions are displayed immediately after switching versions (8f60ea9a4737)
- - Ticket #331: ImportError when trying to import userpackages (bc27cdc4b171)
- - "import userpackages" fixed by reordering init steps (bc27cdc4b171)
- - Ticket #293: Shell copy & paste on Mac doesn't work (694c0a43fbda)
- - Use git ls-files instead of cat-file to retrive hash so that we don't have issues with Windows reading from stdin (1b190225cce9)
- - Persistence package: fixed problem where persistent files
-couldn't be found on Windows (df8a7c2ef7d1)
- - Ticket #369: picture-in-picture setting is confused when a new vistrail is opened (7ea68b3e863f)
- - Check PIP preference when opening vistrails (7ea68b3e863f)
- - Allow semi-translation from abstractionRef to abstraction so
-old workflows (version <= 0.9.3) with subworkflows can be opened (50b9ce2b28fc)
- -  Spreadsheet: fixed 'RuntimeError: underlying C/C++ object has
-been deleted' problem during EventFilter on Windows  (93884b6a47c0)
- -  VTK Package: Fixed rendering context problem when embedding VTKCell in VisMashup on Linux (93884b6a47c0)
- -  PathChooserToolButton was not emitting proper signals necessary for
-VisMashup (93884b6a47c0)
- -  Persistence package: Fixed load package error on Windows (4ee8f244fc79)
- - Change persistence package to use correct identifier for gui widgets (9dd3ad8e0b08)
- - Ticket #378: Workflow execution log contains duplicate entries (6d65daec6089)
- - Fixed logging so that executions are not duplicated when saving more than once per session (6d65daec6089)
- - Ticket #377: Exporting to OPM XML fails (3ee1cc842182)
- - Fixed OPM output capability to work with latest object layout (3ee1cc842182)
- - Update sql package to use List instead of ListOfElements (4b08dd9018db)
- - Fix typo with get_package_by_name (74f30460d3fe)
- - keep selected modules after scene redraw (bb5e4e6e1f45)
- - Optional input ports now don't show up as output ports (bb5e4e6e1f45)
- - Ticket #376: execute_cmdline broken (bbbcf19704b8)
- - Fixed copyright year in background image from About box (bcd3346d8865)
- - Web Services package: fixed bug in certain Complex Types (60128ff3a89a)
- - Ticket #374: Web service package can't be reloaded (38976729a2a9)
- - Fixed an issue with package reloading where modules imported using the "from" syntax were not added to the imported list (38976729a2a9)
- - HTTPFile: Fixed error when parsing the date from the file's header. (3799edddbb62)
-
-From Release: v1.5.1 build 1863
-
-Enhancements: 
- - branching is now supported when uploading to web repositories (r1853)
- - Added ParaView package (r1850)
- - Added Titan package (r1847)
-Bug fixes: 
- - Ticket #368: Spreadsheet: export as single image does not work (r1861)
- - Fixed bug where RichTextCell was not displayed when running on 
-   server mode (r1857)
- - Fixed bug with thumbnails and RichTextCell (r1856)
- - Making sure to use only image files when generating thumbnails (r1856)
- - Fixed web repository commit bug where updated vistrail files where not 
-   successfully loaded into VisTrails after being downloaded (r1853)
- - web repository vt id annotation is now being saved (r1853)
- - web repository cookie is now nullified if the web repository url 
-   changes (r1853)
- - VisTrails Batch mode: Changing parameter separator from '&' to '&&' so 
-   urls with query urls work (r1846)
- - Added procedure to WIndows installer script to remove VC Redist files 
-   left behind (r1846)
- - log file names are now updated according to VisTrails version (r1845)
- - Ticket #366: VTK overloaded ports from old vistrail files are not being shown in the GUI (r1842)
- - Fix translation of head example from old version (r1842)
- - Ticket #367: Different port signatures when upgrading a workflow (r1841)
- - Translate old parameter type serialization to match port/portSpecs (r1841)
- - Ticket #364: actionAnnotation breaks view->show all (r1840)
- - Fix issue with annotations that have the same key/value pairs (r1840)
- - Ticket #363: Enabling the Web services package on-the-fly is broken (r1839)
- - Spreadsheet package: SingleCellSheetReference could not be used (r1839)
- - On Mac, the eventFilter was not being removed when finalizing 
-   Vistrails and sometimes delayed events could not be processed  (r1839)
- - ImageViewerCell: Disabling the zoom slider when playing 
-   animation (r1838)
- - Ticket #362: ImageViewerCell Animation Icons Are Not Displayed (r1837)
- - repository_vt_id now represents the crowdlabs vistrail object id instead 
-   of the vistrails db id (r1834)
- - when merging a vistrail with one on the web repository, a check is made 
-   to see if that vistrail still exists (r1834)
-
-From Release: v1.5 build 1832
-
-Enhancements: 
- - Upgraded libraries: VTK 5.6, Qt 4.6.3, python 2.6
- - Adding extension files to release
- - Add support for calling binaries in Mac bundles (r1813)
- - New methods for cmdline execution (r1813)
- - Better configuration for persistence package (r1813)
- - Added scripts for manipulating the database (r1809)
- - User may now designate permissions when uploading vistrail to web repository (r1806)
- - More informative upload dialog that lists incompatibilities between 
-   vistrail files and web repository, including PythonSource module checks (r1806)
- - Merges with web repository now updates local vistrail version (r1806)
- - Changed VisTrails version to 1.5 (r1805)
- - Files produced by FileSync modules are publishable by default.
-   Use publishFile boolean to avoid publishing the files.  (r1805)
- - Server mode: added support for executing workflows and returning 
-   results as pdf files (r1804)
- - Latex Extension: added support for embedding pdf files. See README file
-   in extensions/latex for help (r1804)
- - Ticket #317: Add support to the spreadsheet cells also generate PDF files (r1801)
- - Spreasheet Package: Added global configuration for controlling 
-   the file type (PNG or PDF) when dumping cells (console mode). This can be set 
-in the Spreadsheet configuration panel or as a 
-command line option (use --pdf or -p 
-for dumping files in pdf). (r1801)
- - Added support for merging vistrails on the server side (r1798)
- - Added support to draw workflow graphs (as png and pdf) and 
-history trees (as png) (r1798)
- - VTK Package: Added the ability to use the Transfer Funtion widget to
-create color mappings (vtkColorTransferFunction) not necessarily in 
-volume property.  (r1796)
- - Changed version of VTK Package to 0.9.2 (r1796)
- - Added two new output ports to vtkScaledTransferFunction: vtkPiecewiseFunction and vtkColorTransferFunction (r1796)
- - Handle upgrade and prune annotations during merge (r1792)
- - Added gui code for the interactive vistrails merge (r1791)
- - Interactive interface for merging two vistrails (r1789)
- - Make actions immutable by moving mutable attributes to a higher level (r1786)
- - Try to fix as many errors as possible in an upgrade, even if all cannot be fixed (r1777)
- - Merging action annotations (r1771)
- - Methods for hashing tags and annotations (r1769)
- - Merging of vistrails files for crowdlabs. (r1762)
- - Preferences for upgrades (r1761)
- - Allow delaying persistence of upgrades until changes (r1761)
- - PRELIMINARY upgrade support (r1755)
- - view pipelines without having the packages (r1755)
- - view invalid pipelines (r1755)
- - improved pipeline validation (r1755)
- - Add method to allow updates of a single port rather than all ports as updateUpstream provides (r1753)
- - Dump non-ModuleError exceptions to the console (r1753)
- - Improved string formating of nested InvalidPipeline exceptions (r1752)
- - Allow QSearchBox to do non-incremental searching (r1751)
- - Improved version selection handling (r1744)
- - Server Mode: added support for multithreading (r1741)
- - Decoupled the directory where the spreadsheet will dump cells from the configuration. spreadsheetDumpCells configuration is now deprecated. Now this setting can be configured in a per workflow fashion  (r1741)
- - Added support for extra information to be passed along workflow executions. The spreadsheet now uses this mechanism instead of a global configuration for dumping cells (r1741)
- - inital version of a VisTrails R package using rpy2 (r1723)
- - easier namespace designation using _modules (r1722)
- - easier constant extensibility and customization (r1721)
- - improved List module (r1721)
- - new Dictionary module (r1721)
- - new SourceConfigurationWidget to make creating source configuration widget easier (r1720)
-
-Bug fixes: 
- - Sometimes matplotlib plots were not refreshed in the spreadsheet (r1828)
- - Fixed the flickering issues of VTKCell on Windows (r1825)
- - Updated Web services code to work with HTTP package chages (r1824)
- - Fixed Python Wrapping issue with VTK 5.7.0 (r1818)
- - Minor UI fixes to web repository dialog (r1817)
- - web repository dialog now links to correct vistrail id on the web repository (r1817)
- - Upon upload to web repository, an repository identification annotation is added automatically (r1817)
- - Fixes for merging vistrails in server mode. (r1816)
- - low-level merge code now allows passthrough gui references
-instead of importing them (r1812)
- - Fix issue where annotation ids weren't properly assigned (r1809)
- - Merging thumbnails (r1808)
- - Fixed issue where database was saving parent id/type pairs as NULL (r1807)
- - Fixed issue where deleted annotations were not translated to previous version (r1807)
- - Fixed issue where deleted annotations could not be mapped back to previous schemas (r1807)
- - Fixed issue where annotations were not set with the correct db flags (r1807)
- -  Generating the pdf of the workflow in console mode was not 
-working.  (r1805)
- - Fixed bug in script that starts VisTrails in server mode using Xvfb (r1804)
- - Spreadsheet package: corrected paper size of generated pdfs (r1803)
- - Fixed Vistrail merge casting bugs (r1802)
- -  Spreadsheet Package: Standard non-image type cells now correctly dump
-contents to file.  (r1801)
- - Vistrail merge did not copy thumbnails (r1800)
- - Fix issue with reading and writing the boolean parameters during persistence configuration (r1799)
- - Fix issue when writing metadata of managed files (r1799)
- - Ticket #358: HTTPFile header-based caching is broken (r1797)
- - HTTPFile.is_cacheable is now implemented, and is aware of server headers. (r1797)
- - Ticket #353: Import workflow doesn't set id scope correctly (r1790)
- - update id scope after importing a workflow (r1790)
- - Fix for older log files that have incorrectly moduleExec elements (r1788)
- - Checking whether XML element is not None before trying to evaluate it as text (r1787)
- - Fixed port spec naming in new persistence package (r1783)
- - Fixed issue where always creating a new reference didn't generate an id (r1783)
- - When pruning a node, make sure that node is removed from the version tree display (r1782)
- - Fixed issue with re-saving to the database with groups (r1781)
- - Fixed issue with upgrading groups and database persistence (r1781)
- - References to thumbnaisl were being shared across 
-different vistrails (r1780)
- - Existing thumbnails were not being replaced by new ones (r1780)
- - Don't automatically switch to pruned upgrade nodes (r1779)
- - Ticket #357: Error after saving as [Errno 2] (r1778)
- - Fixed issue with trying to upgrade groups introduced by upgrading port specs (r1777)
- - Fix issues where pipelines are not validated after certain actions like copy-paste (r1776)
- - Merging of vistrails did not work (r1775)
- - Band-aid for analogies to make analogies with groups or abstractions a bit more robust (r1774)
- - Fix error with handle_invalid_pipeline and subworkflows (r1773)
- - Fix bugs in displaying missing dependencies in preferences (r1772)
- - Pass module information through group to contained modules (r1770)
- - Fix issue with upgrading module functions for user-defined ports (r1768)
- - Fix issue with upgrading modules that have user-added ports (r1767)
- - Change call to fix missing modules to the correct method (r1767)
- - Merging of vistrails files for crowdlabs. (r1766)
- - Fix issue with analogies where obselete method was being called (r1764)
- - Fixed issue where automatic upgrades fail because a port is said to not be found even though the port does exist (r1763)
- - Fixed issue with upgrading groups (r1761)
- - Ticket #356: Action copy doesn't remap previous id (r1757)
- - Pass simplify argument through in create_action_from_ops (r1756)
- - Fixed issue with versions_increasing computation (r1752)
- - Ticket #354: Package reloading raises duplicate package error (r1750)
- - Fix issue with renabling packages where a signal was issued twice (r1750)
- - VisTrails Server: the vistrail version was not being included in the .vt file generated by the server (r1746)
- - fixed ModuleRegistry.auto_add_subworkflow so that it accepts the correct (filename, dict) format. (r1745)
- - Server mode: Added a global variables to store information for accessing the database (r1743)
- - Fixed a bug in the RequestHandler.get_wf_vt_zip() function. (r1742)
- - The notes field in the History View now only supports plain text (r1741)
- - Fixed issue where module label changes were not recognized correctly and raised an exception (r1740)
- - Don't require a Module to a be of type __builtin__.type to
-allow boost:python, etc. classes (r1739)
- - Differentiate between init.py not existing and init.py having ImportErrors (r1719)
- - Ticket #346: Module Parameter Types Serialized Incorrectly (r1718)
- - Update module parameter type serialization when containing namespaces to match port specs and ports (r1718)
-
-From Release: v1.4.2 build 1716
-
-Enhancements: 
- - Ticket #290: Reload packages without restating VisTrails (r1714)
- - Package reloading support should now be fully functional (r1714)
- - Enabling access to a Web package repository. (r1712)
- - Started adding support for Qt4.6.x (r1711)
- - Package vtlcreator: Exposing the function to create the contents
-of a .vtl file as a static method, so it can be called from other
-packages  (r1709)
- - Added support for embedding workflows when using the Web extensions (r1709)
- - VisTrails Server: Added support for creating a .vt file for a given
-vistrail/workflow on the DB so it can be embedded on a .vtl file (r1709)
- - New module, RepoSync, has been added to the HTTP package, which enables data files to be synced with an online repository (crowdLabs) (r1708)
- - Added basic online web repository (crowdLabs) user authentication dialog (r1707)
- - Added ability to upload VisTrail files to online web repository (crowdLabs) (r1707)
- - Improved package reloading support (r1703)
- - Added helper methods, get_inputPort_modules and get_outputPort_modules, to get modules that connect to a given input port or output port (r1701)
- - Added helper method, connections_to_module, that returns a list of all modules that connect into a given module (r1701)
- - Ticket #290: Reload packages without restating VisTrails (r1697)
- - Enable package reloading without the need to restart VisTrails. (r1697)
- - SQL package also connects to a PostgreSQL database server (r1696)
- - SQL package: added cacheResults parameter to SQLSource (r1696)
- - SQL package also handles connection timeouts (r1696)
-
-Bug fixes: 
- - Package menu items (on the toolbar) are now properly removed when the package is disabled (r1714)
- - Package lists can now be traversed with the keyboard (r1714)
- - Fixed bug that when enabling a package dynamically sometimes VisTrails 
-would say that it failed but if you just selected the version node again the 
-pipeline would be loaded without problems (r1711)
- - MAC and Qt4.6: VisTrails would fail to start when using MacBrushMetalStyle (r1711)
- - Mac and Qt4.6: There was not text anti-aliasing in modules and version
-nodes (r1711)
- - Qt4.6: Moving a module in the pipeline view would not move the 
-connections attached to it (r1711)
- - Qt4.6: Legend Window in Visual Diff would not properly display the
-colors (r1711)
- - Fixed a bug with opening .vtl files that embedded workflows (r1709)
- - Package vtlcreator: Fixed a bug that the version of the embedded
-vistrail was not being set (r1709)
- - Fixed the Capitalization error in the VisTrails App Bundle name (r1709)
- - Properly track all modules in the hierarchy of a module loaded by a package for correct packing reloading (r1706)
- - Made reset query work immediately for the version search box (r1705)
- - Stop creating empty actions (r1704)
- - DBLocator: Removing object name from XML serialization. 
-This was causing inconsistencies with caching locators because we don't
-know the name of the object before we load it  (r1702)
- - Ticket #345: db connection edit bug (r1700)
- - DBLocator: Serializing also db connection user so current 
-permissions are not overriden by the cached version (r1700)
- - Ticket #344: Ungroup failing (r1699)
- - Ensure correct modules after ungrouping (r1699)
- - Ticket #342: Method responses return None in Web Services Package (r1698)
- - Complex types were ignoring the new 'self' input port when 
-unwrapping contents (r1698)
- - Ticket #341: On Ubuntu, VisTrails doesn't try to install MySQLdb (if not present) when accessing the database (r1695)
- - Move Vistrail import into load_vistrail method to avoid
-circular imports. (r1694)
-
-From Release: v1.4.1 build 1693
-
-Enhancements: 
- - Code cleanup: removed unnecessary imports in a few files (r1687)
-
-Bug fixes: 
- - Using VisTrails as a library: added more imports to
- init_for_library.py file (r1687)
- - In the pipeline view, if you changed a module (moving it, for
- example) and deselected the current node in the PIP view, VisTrails
- would throw an error (r1687)
- - Ticket #338: The DB Connection Setup Dialog opens twice (r1686)
- - Package Web Services: expanded simple types map to include all
- simple types defined in http://www.w3.org/2001/XMLSchema (r1685)
- - Ticket #337: Web Services package fails to load a wsdl (r1684)
- - Web Services package: Expanded simple types map to include missing types (r1684)
- - Upgraded ZSI library in the binary releases to use trunk r1495
- - Ticket #336: VisTrails fails when opening files with an older schema (r1683)
- - Fix upgrades when module's version does not exist. (r1683)
- 
-
-From Release: v1.4 build 1682
-
-Enhancements: 
- - EXPERIMENTAL: Packages can handle workflow upgrade requests. Still very much 
-work-in-progress. If you want to enable this, set 'automaticallyUpgradeWorkflows' 
-to True in the Expert Configuration tab in the Preferences menu.   (r1665)
- - Module Packages tab in Preferences menu now shows package version. (r1665)
- - Initial revision of a sql scripting package (r1664)
- - Improve error messages when sql statements fail (r1660)
- - Ticket #318: Add support for generating a .vtl file within a workflow (r1657)
- - Allow persistence package to search for persistent entities
-in multiple stores (r1654)
- - Added script that generates nightly source releases. (r1648)
- - Better delete buttons on the parameters. (r1646)
- - Add data provenance support for persistent files. (r1644)
- - Removed "Tag" entry in the method palette (r1643)
- - Ticket #276: Make method deletion more visible (r1642)
- - Ticket #287: Allow parameters to be named (r1642)
- - Ticket #291: Allow functions to be populated with default values (r1642)
- - Can delete functions/methods by clicking the check box next to the name (r1642)
- - Can define default values for parameters (r1642)
- - Can define labels for parameters (r1642)
- - Added script for (re)starting vistrails in server mode with Xvfb.
- - Visual Diff now shows matches in white; modules shared by history are colored
-gray while modules shared by matching are colored white. (r1634)
- - Added better default descriptions to version tree. (r1634)
- - Enabled the 'SetInputArrayToProcess' method of vtkAlgorithm class to use 
-for the InfoVis package. This port was disallowed earlier for some reason, so 
-we have to watch if this will cause any issue. (r1632)
- - Added support for storing logs and thumbnails on the database. (r1625)
- - Add a new module that allows the user to control the order of execution of 
-two sinks. (r1618)
- - Use the module descriptor to do hashing instead of the module since the 
-descriptor used may be a different version. (r1615)
- - Fix so core and gui controllers both use the same change_selected_version 
-logic. (r1614)
- - Streamline error handling for workflow materialization. (r1614)
- - Added Path and Directory constants and updated File constant
-along with configuration widgets. (r1611)
- - Updated persistence package to support persistent directories
-and compression. (r1611)
- - Initial version of a persistence package that aims to cache
-files across VisTrails sessions. (r1598)
- - Adds support for viewing web documents in a WebViewCell using
-Qt's QWebView which is based on WebKit (r1596)
- - Moved the controlflow package from packages to vistrails/packages. (r1588)
- - Moved doc folder to root. (r1581)
- - First version of source tree documentation. (r1580)
- - Added the InfoVis example using the new VTKViewCell. (r1564)
- - Enable more intuitive command-line interactions with
-pipelines (r1563)
- - Added VTKViewCell for displaying vtkRenderView compatible with the current VTK trunk. Just connect vtkRenderView to VTKViewCell. First attempt, only tested on Linux. (r1562)
-
-Bug fixes: 
- - Ticket #334: Programmatic change_parameter problem (r1679)
- - Add translation to new ids back after input/output remap. (r1663)
- - Ticket #328: Backslashes in SQL Problem (r1662)
- - Use prepared statements for the relational database
-persistence. (r1662)
- - Ticket #330: Ungroup and save to db fails (r1661)
- - Make sure that new objects are saved to the database. (r1661)
- - Ticket #328: Backslashes in SQL Problem (r1660)
- - Added prepared statement support for db version 1.0.1 (r1660)
- - Ticket #329: Analogy port remap needs to check input/output remaps (r1659)
- - Check the correct remap when changing ports. (r1659)
- - Check for __init__.py in userpackages on startup. (r1656)
- - Improve feedback for undo/redo (r1655)
- - Ticket #327: Bug in exporting registry to DB (r1653)
- - Removed global setting on package ids from sql spec. (r1653)
- - Fixed exporting Log, Workflow and Registry to XML (r1652)
- - Fixed exporting Log and Workflow to DB (r1652)
- - tag "tag" was being ignored when "version" was empty in .vtl file (r1651)
- - Copying DBLog objects was not working (r1650) 
- - DBVistrail.do_copy doesn't fail when log is None (r1649)
- - Add copy methods to enhanced DBVistrail (r1645)
- - Don't disable entire vistrails when they contain **unused**
-invalid port specs (r1641)
- - Ticket #323: Subworkflows with version mismatches in underlying pipelines don't fail gracefully (r1640)
- - Subworkflows that fail to load fail gracefully and print the
-exception (r1640)
- - Ticket #321: Save As... doesn't save log (r1639)
- - Save As and Export now save log data from files to files or
-files to db. (r1639)
- - Ticket #259: Undo not available (r1636)
- - Undo and redo are now available when the should be. (r1636)
- - Execute Version Difference menu item is enabled at the correct
-times and functions correctly. (r1636)
- - Ticket #326: Visual difference not considering namespace (r1634)
- - Modules from different packages or namespaces no longer
-match (r1634)
- - Groups try to match on their tag during heuristic
-matches (r1634)
- - Ticket #325: DB version translation loses deleted entities (r1633)
- - Translating to different database versions now transfers
-deleted entites from the old object to new object. (r1633)
- -  wiki vistrails tags containing "tag" attributes were not executed on the wiki  (r1627)
- - Ticket #320: Version Tree Display Inconsistent Across Serializations (r1617)
- - Fix to make version tree layout consistent across
-serializations. (r1617)
- - Ticket #319: Database copy/pastes saves not working correctly (r1616)
- - Version updates now update the id scope to avoid strange
-errors when using VisTrails with an older database schema. (r1616)
- - Copy and paste operations reset the id of a group's pipeline
-to None in order to allow the database to assign the correct
-id. (r1616)
- - Unserialization now sets the unserialized object's is_new flag
-to True instead of allowing it to default to False. (r1616)
- - Add version support into module signatures so that persistent
-files will be recomputed when upstream modules are updated. (r1615)
- - Analogies now replace annotations of the same key and
-parameter values instead of adding new copies. (r1614)
- - Bring unit tests up-to-date. (r1614)
- - Ensure that debug messages are written in core controller. (r1614)
- - Make code that adds parameters after executions work again. (r1614)
- - core.system.executable_in_path now checks the correct error code from core.system.execute_cmdline() (r1613)
- - Ticket #314: Visual Diff Broken when PythonSource loses/gains a connection (r1612)
- - Fix issue with dynamic modules and the visual diff when ports
-have been re-typed. (r1612)
- - Update documentation on create_action. (r1611)
- - Ticket #311: Method palette doesn't obey port overloading (r1610)
- - Ensure that ports are only displayed once in method palette
-and obey port overriding. (r1610)
- - Ticket #309: Subworkflows crash on package version mismatch (r1607)
- - Run ensure_modules, ensure_connection_specs on subworkflows
-during loading to try to avoid package version mismatch
-errors. (r1607)
- - Ticket #308: Analogies fail on changed location (r1606)
- - Fix bug with analogies where module's locations were added
-instead of changed causing problems when that module was
-deleted. (r1606)
- - Fixed issue with deletes in sql persistence for versions 0.9.5
-and 1.0.0 (r1603)
- - Ticket #307: Error messages when executing a workflow more than once (r1602)
- - This fixes bug where error messages would be printed to the terminal when executing a pipeline with cached modules more than once (r1602)
- - Fixed a typo in create_port, we don't need to call the vistrails_port
-object that was created. (r1601)
- - Fixes some of the shell interaction methods. (r1600)
- - Remove ternary operator for python 2.4 compatibility (r1599)
- - Ticket #305: vistrails.sql script in schema v1.0.0 is broken (r1595)
- - Fixed issues with versions 0.9.5 and 1.0.0 of the relational schema. (r1595)
- - Ticket #304: VisTrails does not check if the connection to the database is still alive before performing an sql command (r1594)
- -  This fixes bug where the MySQL has gone away error would show up when connected to a database and VisTrails was not being used for a while (r1594)
- - Ticket #303: Thumbnail error when saving a vistrail (r1593)
- -  Fixes bug that prevented a vistrail to be saved because of an error related with thumbnails. (r1593)
- - Ticket #301: Double-clicking .vt and .vtl files does not cause them to be open by an already running VisTrails (Mac only) (r1592)
- - Moving condition check to the right place so FileOpen events are captured correctly on a Mac (r1592)
- - Ticket #299: Delete ops in analogies broken (r1591)
- - Add some checks to make analogies better behaved. (r1591)
- - Ticket #300: Null actions being added to the tree (r1590)
- - Parameter selections don't generate null actions. (r1590)
- - Ticket #297: MissingPort exception not raised (r1589)
- - Fixes bug where user is never notified if a module on the
-registry is missing the requested port. (r1589)
- - Updated VisTrails Server code in the trunk to be consistent with the server 
-running in vistrails.sci.utah.edu (r1583)
- - Fixed small bug that prevented load a vistrail from the database 
-using the GUI. (r1582)
- - Partial fix to deprecation messages. Not closing the ticket because it's 
-not fixed on Windows. (r1576)
- - Ticket #283: Fold Type Mismatch Error (r1575)
- - Fix the type mismatch error message. (r1575)
- - Update current list of ignored classes in vtk package. (r1573)
- - Ticket #279: Analogies broken with namespaces (r1572)
- - Use module's _get_module_descriptor call to get the descriptor to fix
-namespace issues with analogies. (r1572)
- - Fixes a bug that shouldn't currently be exposed to an end-user.
-Specifically, the registry's udpate_id_scope method didn't add 1 to
-the begin id. (r1571)
- - Fixed the pipeline execution mechanism in the spreadsheet that didn't work
-with the new interpreter interface. (r1567)
-
-From release v1.3 build 1561
-
-Bug Fixes:
- - Fixed bug that was preventing files from being saved on Windows
-
-
-From release: v1.3 build 1559
-
-Changes:
- - Schema upgrade. Current version: 1.0.0.
- - Updated VTK libs to use 5.4.2 release
- - Removes conditional expression constructs, so that code runs on Python < 2.5.
- - Including Gridfields python module
- - Using only application single instance behavior if Qt 4.4 or later is 
-   available
- - Added support for SubWorkflows (with no database support yet)
- - Added a Control Flow Package (see user's guide to see how to use it) and 
-   related example files
- - Added support for basic package repository
- - Introduced a major reorg of the registry and related classes.  Specifically, 
-   it adds serialization capabilities, and unifies the 
-   core.modules.module_registry.PortSpec and
-   core.vistrail.port_spec.PortSpec classes.  In addition, all configuration and
-   drawing is done using PortSpecs (not Ports). It also includes revisions to 
-   the PythonSource, and Tuple configuration dialogs, and adds controller code 
-   to better support resulting updates. You can serialize the registry via the 
-   "File -> Export -> Registry To ..." menu items.
- - Added support for "registry quickstart" which allows VisTrails to boot 
-   significantly faster.  It also further changes registry behavior to allow 
-   VisTrails to function without having access to the actual python modules 
-   behind the ModuleDescriptors.  Everything can be done by tracing the 
-   descriptor hierarchy instead of the mro, but we still use the mro when we 
-   have it.  Try the quickstart by starting VisTrails normally and selecting 
-   "File -> Export -> Registry To XML..." and saving the resulting file. 
-   Then restart VisTrails with the -q flag followed by the registry file: 
-   (ie "./vistrails -q <registry_filename>")
- - Use solid colors instead of textured backgrounds on graphics views, 
-   since Qt (or pyqt) redraws much slower when these are enabled.
- - Improved layout of modules in visual diff and analogy
- - Added support for displaying thumbnails below the notes panel and/or as a
-   version node tooltip. See Thumbnails Preference tab for changing specific
-   options
- - Improved menu File organization
- - Added translate* methods for versions 0.9.3 and up, and updated code to use 
-   them.  This should ensure that xml vistrails, workflows, logs, and 
-   registries, can be updated when schemas change.  The idea is that you open a
-   vistrail, and if it is not in the current schema, it is translated to the 
-   current schema, no matter if you're using an xml-based file or relational
-   database.  When saving the vistrail, the db code will attempt to translate 
-   the vistrail to the schema of the database (even if it is an older version) 
-   before saving.  For xml-based files, you may optionally specify to save the 
-   file as an older version.  Currently, you are only able to translate back 
-   to 0.9.3 (See menu "File -> Export -> Stable Version").
- - Added initial support for workflow debugging
- - Added the progress functionality allowing modules to show their progress 
-   during the compute() by calling self.logging.update_progress(self, progress).
- - The VisTrails Console is now a dockable window. Also fixed a long-standing 
-   bug that hitting enter when cursor is not at EOL will carry garbage to next 
-   line. Fixed also a bug where if user types fast enough in the shell, the 
-   input fails.
- - Added support for constants to generate custom hashes. The main current 
-   usecase is File constants, which hash against filename and last-modified 
-   times. The biggest consequence is that pipelines that use File objects will 
-   now be smarter when it comes to files that change upstream, reducing the 
-   number of times one has to clear the cache.
- - Improved the initialization of packages: if package fails during call to 
-   initialize(), we report failure, disable the package, and continue 
-   initialization. This allows startup process to continue. Also in preferences 
-   pane, when package fails to load, we now display the error message; 
-   previously, it just said "error". (There's still the problem of reporting 
-   packages that load ok but fail to initialize)
- - Changed view behavior so that the initial pipeline view upon opening a 
-   vistrail is reset.
- - Added support for importing workflows that have been saved as xml.
- - Added a function to change parameters from the api along with a function to 
-   find modules by name (and package/namespace if specified). Note that the 
-   param_list in change_parameter requires a list of strings---the serialized 
-   representations of the parameters!
- - Updated the gen_vtk_examples scripts to create better pipeline 
-   specifications.
- - Added pc3 package for the Third Provenance Challenge.
- - VTK package:
-   + Added support for Picking in a VisTrails cell. By default, the 
-     vtkRenderWindow contains a picker. The 'p' key activates the pick test in 
-     the render window.  A new vtkPicker can be attached to the VTKCell to 
-     modify the picking behavior according to the mechanism provided by VTK.
-   + All VTK Filters are registered to show their progress while executing
-   + Added support of InfoVis to VTKCell. Notice that the saving camera feature 
-     does not working with InfoVis (because there are no direct SetCamera port 
-     for InfoVis classes).
-   + Added support for changing the backgorund color of a vtkRenderer using 
-     color widget
- - Spreadsheet:
-   + Added exporting images and echo mode feature
-     
-Bug Fixes:
- - Fixed bug where queries with multiple sources would fail in query by example
- - Spreadsheet:
-   + Jpg/gif/png images can be correctly displayed on the spreadsheet
-   + Fixed many interaction bugs
-   + temp files were not being correctly removed
- - VTK state changes with statically overloaded parameters are now handled 
-   correctly. Typical example is vtkTreeMapView::SetLayoutStrategy
- - Fixes a  bug where the configuration wouldn't be setup properly for a new 
-   .vistrails directory.
- - Fixed plot.vt example to work with matplotlib version >= 0.98.5.2
- - Catch exceptions when writing file to raise dialog box if there is an error.  
-   This fixes bug that nothing was being shown to the user in case of a bad 
-   write (ie, file permissions insufficient).
- - Fixed PythonSource syntax highlighter error and (yes!) there's a line number 
-   for debugging now.
- - Fixed startup "bug" when package with dependencies fails to load
- - Copy/paste is relative to the current canvas
- - Shipping the GPL License in the distributions
- - ImageMagick package:
-   + Added CombineRGBA class, configuration object, and fixed GaussianBlur bug
-   + Removed requirement check that prevented the package from loading if
-     ImageMagick was not found in the path  
- - Bug fixes in Windows installer: 
-   + Installer always creates desktop shortcut and uninstaller did not remove 
-     all pyc files
- - Other minor fixes
- 
-From Release v1.2.1 build 1336
-Changes:
- - Schema upgrade. Current version: 0.9.3. If you keep vt files in a database,
-   you have to upgrade the database as well
- - VisTrails now requires Qt 4.4 or later to run
- - Adopted application single instance behavior (only one version of the
-   VisTrails application can be executing).
- - Added Interactive expansion and collapsing in the version tree: the three
-   lines on edges in the version tree that used to represent multple
-   versions has been replaced by a plus symbol. Clicking this symbol
-   expands the link to show all the versions in betweeen (though this may
-   change to only a limited number later).  A minus sign appears on the
-   top of a list of untagged, non-branching, non-selected versions that
-   will collapse that list.
- - Added descriptions to the version tree.  They show up in place of
-   a tag if one hasn't been set, but with a thinner italicized font.
-   Double-clicking on the node allows it to be changed and turned into a tag.
-   Showing a description for each action that is now displayed in the
-   properties overlay. This description is still very simple (eg.,
-   Added module), though in the future it might make sense to save off
-    more detailed descriptions for each action in the db (eg., Added
-    vtkRenderer module)
- - Added new items to the View Menu to show and hide branches and nodes
- - Restored the "Clear Recent Searches" in the search box in the version
-   properties
- - Added command line options to execute workflows and show only 
-   the spreadsheet when opening
- - Logging information is now stored in .vt file
- 
- Bug fixes:
- - Copying and Pasting dynamic modules, such as PythonSource threw an error
- - File version was not set correctly
- - Fixed a bug in analogies that sometimes corrupted vistrails files.
- - Fixed some bugs and annoying behavior with autosave.  A dialog
-   now prompts the user if they want to load autosaved data.  This
-   dialog appears when opening a file or starting up vistrails.
-   Autosave data no longer is loaded when the user creates a new
-   vistrail by pressing the new button.
- - Dragging versions to the spreadsheet is working again
- - Dragging a spreadsheet tab created a window that couldn't be closed
-   or put back. A floating sheet can be docked back by simply closing it or
-   dragging it back the spreadsheet tab bar (if exists) or just the window
-   itself.
- - There was no obvious way to exit full screen mode in spreadsheet. The
-   fullscreen mode can be closed either by:
-    * Pressing 'ESC', 'Ctrl-F', 'F11' or 'Alt-Enter'
-    * Right click on the fullscreen mode and unselect 'Fullscreen'
-  - Border color of selected cells in the spreadsheet is now consistent
- 
-From Release: v1.2 build 1263
-Changes:
- - Version tags can be edited directly by double-clicking the tree nodes
- - Added basic support for package management on Fedora Core through YUM
- - Added compatibility with Qt4.4
- - Added support for dynamic addition of modules in packages
- - Pipeline, Query and History views are now reset with Ctrl+R 
-  (Command+R, on a Mac) so that it does not interfere with version text
-  items 
- - Add a transparent overlay to the version viewer that shows the 
-   selected version's properties.  By default this is turned off, but 
-   can be enabled under the view menu.
- - Added standalone functions that help third-party applications that 
-   need an API into VisTrails, located on vistrails/api directory.
- - Improvements in the command-line for both non-interactive and interactive mode:
-   + Added support for executing more than one workflow at a time
-   + Included support for opening a vistrails from the database
-     Now a version (tag or id) can be specified in the command-line
-     together with the filename (or vistrails id when opening from the 
-     database). 
- - Added support for opening special vistrails files (.vtl files) on 
-   the web (wiki integration)
- - WebServices package: added support for loading wsdl urls automatically
-   when opening a pipeline using them
-
-
-Bug fixes:
- - Improved handling of faulty packages
- - Vistrails having groups with annotations or functions did not open
-   correctly
- - Query display didn't ghost module fill
- - Query execution and reset didn't update pipeline view
- - Connection line was drawn twice in query canvas
- - Editing parameters in query mode was cumbersome because of 
-   bad focus management
- - Fixed database support to pipelines with groups
- - Fixed "Add Database" dialog confusing behavior
- - Fixed a long-standing bug on PythonCalc where ModuleError was 
-   being called without the self parameter
- - HTTP Package: slightly better error handling with malformed URLs
- - Improved general GUI performance when changing versions, including
-   Undo/Redo
- - Removed obsolete command-line options
- - Refine in the search box was not working
- - Spreadsheet: Saving a spreadsheet also included cleared cells.
-
-
-From release: v1.1 build 1143
-
-Changes:
- - Added "Set Module Label" feature (through the configuration pop-up
-    menu of the GUI)
- - Improved error messages
- - Added vistrails files for many of the vtk examples
- - Added support for packages to create menus in the builder window
-   (see spreadsheet package for an example)
- - Modules and input ports can be automatically registered by 
-   setting per-module _input_ports and _output_ports fields and 
-   per-package _modules field (see teem package at www.vistrails.org)
- - Removed graphviz dependency
- - Ability to export workflow and history views to PDF
- - In WevServices Package: Improved support to web services using
-   complex types 
- - Added a BooleanWidget, so Booleans are now given by a checkbox 
- - In VTK Package: 
-   + Added Transfer Function Widget
-   + Added dataset inspectors, special vtk modules that allow users
-     to easily query bounds and scalar range of an object.
-   + Added support for vtkTIFFReader to allow volumetric (slice-based)
-     reads.
- - Added support for grouping modules in pipelines
- - Incorporated many optimizations in the code
- - Added namespace support to packages
-
-Bug fixes:
- - Fixed analogies
- - Version tree was not refreshed when analogy was applied on the spreadsheet
- - Fixed double drawing of module names and version node names on the mac
- - Added support for running Visual Diff for pipelines with 
-   PythonSources and other modules with a local registry that 
-   have different input and output ports
- - Changed the behavior of selecting new cell locations on the
-   spreadsheet when it is full (cycling vs. using always the first
-   cell)
- - Fixed bug where options passed through the command line were
-   written to the startup.xml file
-
-
-From Release v1.0.1 build 1063 
-Changes:
- - In VTK Package: Exporters now take a VTKCell as input when exporting 
-   the scene
- 
-Bug fixes:
- - Caching mechanism: VTK modules didn't take the connections into account 
-   when deciding whether to cache or not. This is related with the error
-   message "function expects 1 argument, got 0 instead".
- - Fixed Parameter Exploration bugs where parameter widgets did not update 
-   correctly when changes are made to the pipeline.
-
-
-From Release 1.0 build 1024
-Changes:
- - Added a preference option to enable/disable Brushed Metal Style on Mac
- 
-Bug fixes:
- - Opening/Saving a .vt file on a path with spaces was not working on Unix 
-   systems
- - Creating/Applying analogies  on the spreadsheet
- - Opening/Saving spreadsheets
-
-Release Name: v1.0 rev954
-
-Changes:
- - Added module VTKRenderOffscreen to vtk package
-
-Bug fixes:
- - Version tags couldn't be reused
- - Some vtk writers couldn't be dragged to the pipeline canvas
- - Vistrails crashed when trying to copy and paste something other than
-   a serialized pipeline
- - Modules lose focus when dragging to the pipeline canvas
- - Modules downstream of a error module were green (as if they were executed)
- - Select All button on the spreadsheet was not working
- - Creating a version from the spreadsheet didn't work
- - Tags weren't deleted when pruning the tree 
- - Booleans weren't supported in parameter exploration
- - Fixed double-clicking on a vt file when opening vistrails on Windows
-
-From Release rev921:
-
-Changes:
- - Interface was improved and it is now more consistent
- - General configuration and package management accessible through menu Edit->Preferences
- - Using a more efficient file format (*.vt)
- - Auto saving feature 
-
diff --git a/doc/dist/instructions.txt b/doc/dist/instructions.txt
deleted file mode 100644
index f6bb7b3..0000000
--- a/doc/dist/instructions.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-VisTrails Building Binary Releases
-----------------------------------
-
-1. Make sure you can run VisTrails from source on the system you will
-run these instructions. Instructions to build VisTrails from source
-are on build_from_source_mac.txt and build_from_source_windows.txt.
-
-2. Then make sure the system is prepared to package
-VisTrails. Instructions to install the required software are on
-setup_build_system_mac.txt and setup_build_system_windows.txt
-
-3. Now follow the instructions below:
-
-Binary build instructions
--------------------------
-
-== Preparation ==
-
-These work for making  both Mac and Windows releases and need to be
-done only once before generating them. I think it is easier to do on a
-Mac, commit the changes and load them on the Windows machines.
-
-=== Change in Licensing or Update the look and feel in the Mac .dmg
-file ===
-If you ever need to change the VisTrails license or need to change the
-look and feel of the .dmg file we distribute, you can do that by
-opening dist/mac/vistrails.dmgCanvas. In the project settings you can
-update the license text (that one the is displayed when you open
-the .dmg). Else you can control the background image and other
-settings.
-Usually you don't need to touch this file. So go ahead to the next steps.
-
-
-
-Updating version numbers
-
-If there is a version upgrade from 2.0 to 2.1 you need to update the
-   following files (the variable name that needs to be updated are in parentheses:
-   scripts/release_notes.py (release_name)
-   scripts/create_release_wiki_table.py (VT_VERSION)
-   vistrails/core/system/__init__.py (function vistrails_version())
-   dist/mac/setup.py (VERSION)
-   dist/windows/vistrails.iss (AppVerName)
-   dist/windows/vistrailsx64.iss (AppVerName)
-   dist/windows/custom/*.iss (AppVerName)
-   dist/source/make-vistrails-src-release.py (VT_VERSION)
-   doc/usersguide/conf.py
-   
-The splash screen also needs to be updated: 
-   vistrails/gui/resources/images/vistrails_splash.png
-
-The Adobe Illustrator source file is in the master branch, in
-dist/common/splash folder. You need to install the font file in that
-folder too before opening the .ai file. After the changes, export the
-file to a .png file. Then open it in Photoshop and resize the image to
-546x340 pixels. Then replace the file in 
-  vistrails/gui/resources/images/vistrails_splash.png
-
-Commit and push your changes.
-
-Generating the release notes
-
-Make sure scripts/release_notes.py is configured right: look for the variables inside the #### configuration #### section in the file.
-
-In particular, make sure branch has the right branch and commit_start points to the hash tag used on the last release. Also you might need to change release_name as you see fit.
-
-Then run:
-$ cd path/to/scripts
-$ python release_notes.py
-
-This will checkout the branch, process all commits and match them with the trac tickets. It will ask for your login and password on trac to do that. At the end, it will print out a release notes section. Just copy from Release Name.... down to the last item in Bug fixes. All the log messages that were not identified with <bugfix> or <feature> will be print out at the end but they can be ignored. Sometimes just take a look and see if there is something important there that should go as bu [...]
-
-You should paste the text into the dist/mac/Input/README file, just below
-RELEASE NOTES
------------------------
-
-Also take a look if there aren't repeated items... They might happen when there are merges across the branches and the commit messages got repeated.
-
-Then do the same into dist/windows/Input/releaseNotes.txt
-
-Then commit and push your changes. Now you are ready to generate the binaries on each platform.
-
-== Mac Binary Instructions ==
-ALPS
-Make sure the latest version of ALPS will be included in the binary.
-Go to http://archive.comp-phys.org/software/vistrails/ and look for the latest version and update dist/mac/make_app (ALPS_VERSION). If there were any changes, commit and push them before following next instructions.
-
-Updating revision numbers
-
-Run git log to know what is the latest hash tag on the release branch and copy the first 12 characters from it. This will be the revision number. There's probably a way to automate this but I didn't have time to look into it.
-
-Update the following files with the "revision number"
-  vistrails/core/system/__init__.py (function vistrails_revision())
-  dist/mac/Input/README (Release Name...)
-  dist/source/make-vistrails-src-release.py (VT_HASH)
-  dist/windows/Input/releaseNotes.txt
-  scripts/create_release_wiki_table.py
-  scripts/release_notes.py
-add and commit the changes. This will be the version released.
-
-Update usersguide paths
-
-Make sure the generated users guide is saved to the correct path by
-editing the following file:
-scripts/build_usersguide.py
-By default it is configured for mac
-Make sure the correct branch is used (by default in ~/code/vistrails)
-
-Now run the following:
-$ cd dist/mac/
-$ ./make_app vistrails-mac-10.6-intel-[VER]-[REV]
-where [VER] should be the vistrails version, and [REV] the revision hash.
-
-at the end you should have a file called vistrails-mac-10.6-intel-[VER]-[REV].dmg that can be tested and uploaded to SourceForge.
-You should have created the folder of the new release on source forge before running the command below
-
-$ scp vistrails-mac-10.6-intel-[VER]-[REV].dmg [SFUSER]@frs.sourceforge.net:/home/frs/project/vistrails/vistrails/v[VER]
-where [SFUSER] is your sourceforge user.
-
-== Windows 32-bit Binary Instructions ==
-Update your local copy so you get the newest changes you pushed from
-the Mac.
-VisTrails needs to be run on Windows before the release so it builds
-all the *.pyc files before hand. This can be done by running:
-$ python -m compileall .
-Also, as we are running both 32-bit and 64-bit versions on the same
-system, make sure the PATH variables are set accordingly to use the
-32-bit version of python, vtk, etc. (if you run vistrails 32-bit) or
-the 64-bit version of python, vtk, etc. (if you run vistrails 64-bit).
-
-ALPS
-Make sure the latest version of ALPS will be included in the binary.
-Go to http://archive.comp-phys.org/software/vistrails/
-Download and uncompress the alps package for windows 32 bit available on  http://archive.comp-phys.org/software/vistrails/  into dist/windows/Input/x86/alps_libs folder (it will create a bin and a vistrails folder inside it)
-
-Open dist\windows\vistrails.iss by double-clicking it
-This will launch InnoSetup
-Press the compile script button
-When it finishes a file called dist\windows\Output\vistrails-setup.exe will be created. Rename it according to the release name and create a zip file from it.
-Upload the file to sourceForge (I use WinFTP for this).
-
-Custom 32-bit builds
-For every vistrails-*.iss file in dist/windows/custom folder, run
-InnoSetup. Binaries will be generated in custom/Output folder. Rename it according to the release name and create a zip file from it.
-Upload the file to sourceForge (I use WinFTP for this). 
-
-== Windows 64-bit Binary Instructions ==
-
-ALPS
-Make sure the latest version of ALPS will be included in the binary.
-Go to http://archive.comp-phys.org/software/vistrails/
-Download and uncompress the alps package for windows 64 bit available on http://archive.comp-phys.org/software/vistrails/  into dist/windows/Input/x64/alps_libs folder (it will create a bin and a vistrails folder inside it)
-
-Open dist\windows\vistrails_x64.iss by double-clicking it
-This will launch InnoSetup
-Press the compile script button
-When it finishes a file called dist\windows\Output\vistrails-setup.exe will be created. Rename it according to the release name and create a zip file from it.
-Upload the file to sourceForge (I use WinFTP for this).
-
-Custom 64-bit builds
-For every vistrailsx64-*.iss file in dist/windows/custom folder, run
-InnoSetup. Binaries will be generated in custom/Output folder. Rename it according to the release name and create a zip file from it.
-Upload the file to sourceForge (I use WinFTP for this). 
-
-
-== Source Distribution Instructions ==
-cd path/to/dist/source
-make sure make-vistrails-src-release.py is updated with the right
-branch VT_BRANCH, VT_VERSION and VT_HASH.
-Also update the SF_USERNAME with the vistrails build username if you
-want to upload directly from the script. I usually don't because I
-don't want to commit the vistrails username to the repository so I
-skip the upload to source forge step and use the scp command line above to
-upload the file using my own user.
-
-All the files you need to upload to source forge using the vistrails
-username are in the vistrails server machine. In the cron directory,
-you can look how it is configured so the nightly builds are uploaded
-every night when there are changes.
-
-to generate the tarball:
-$ python make-vistrails-src-release.py
-It will checkout the hash code defined in the file and rename the
-tarball apropriately.
-
-== Update "Check For Updates" ==
-
-If this is a new stable version, log in to vistrails.org and update the version number in:
-/srv/wiki/vistrails/downloads/dist/release_version.txt
diff --git a/doc/dist/setup_build_system_windows.txt b/doc/dist/setup_build_system_windows.txt
index 162dc8d..d8c9b3f 100644
--- a/doc/dist/setup_build_system_windows.txt
+++ b/doc/dist/setup_build_system_windows.txt
@@ -4,14 +4,9 @@ Install InnoDB Setup
 Download and install the QuickStart Pack of Inno Setup from http://www.jrsoftware.org/isdl.php 
 
 Checkout VisTrails git repository
-In dist/windows/Input folder create a folder named x86
-Copy python27.dll 32 bit version into the x86 folder
-Inside the x86 folder create a folder called alps_libs
-
-In dist/windows/Input folder create a folder named x64
-Copy python27.dll 64 bit version into the x64 folder
-Inside the x64 folder create a folder called alps_libs
 
+Download vcredist_x86.exe and vcredist_x64.exe from microsoft.com to "C:\Users\vistrails\".
+They will be copied to the final build.
 
 == Custom Builds ==
 Inside dist/windows/custom there are scripts for custom builds.
diff --git a/doc/usersguide/Makefile b/doc/usersguide/Makefile
index 5cd524d..54f90a3 100644
--- a/doc/usersguide/Makefile
+++ b/doc/usersguide/Makefile
@@ -7,6 +7,8 @@ SPHINXBUILD   = sphinx-build
 PAPER         =
 BUILDDIR      = _build
 
+export PYTHONPATH = $(CURDIR)/../..
+
 # Internal variables.
 PAPEROPT_a4     = -D latex_paper_size=a4
 PAPEROPT_letter = -D latex_paper_size=letter
diff --git a/doc/usersguide/_static/mystyle.css b/doc/usersguide/_static/mystyle.css
index 0fe6e1a..718fb1f 100644
--- a/doc/usersguide/_static/mystyle.css
+++ b/doc/usersguide/_static/mystyle.css
@@ -2,4 +2,8 @@
 
 .red {
     color: #ff0000;
-}
\ No newline at end of file
+}
+
+th {
+    background-color: #fff;
+}
diff --git a/doc/usersguide/api_documentation.rst b/doc/usersguide/api_documentation.rst
new file mode 100644
index 0000000..a1008ea
--- /dev/null
+++ b/doc/usersguide/api_documentation.rst
@@ -0,0 +1,118 @@
+.. _chap-api-documentation:
+
+VisTrails API Documentation
+***************************
+
+Module Definition
+=================
+
+Module
+^^^^^^
+
+.. py:module:: vistrails.core.modules.vistrails_module
+
+.. autoclass:: vistrails.core.modules.vistrails_module.Module
+   :members: compute, set_output, get_input, has_input, check_input,
+	     get_input_list, force_get_input_list, force_get_input, annotate
+   :member-order: bysource
+
+   .. py:attribute:: _input_ports
+
+        Class attribute that stores the list of input ports for the module.  May include instances of :py:class:`~vistrails.core.modules.config.InputPort` and :py:class:`.CompoundInputPort`.
+
+   .. py:attribute:: _output_ports
+ 
+        Class attribute that defines the list of output ports for the module.  May include instances of :py:class:`~vistrails.core.modules.config.OutputPort` and :py:class:`.CompoundOutputPort`.
+
+   .. py:attribute:: _settings
+
+        Class attribute that stores a :py:class:`.ModuleSettings` object that controls appearance, configuration widgets, and other module settings.
+
+ModuleError
+^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.vistrails_module.ModuleError
+
+ModuleSettings
+^^^^^^^^^^^^^^
+
+.. py:module:: vistrails.core.modules.config
+
+.. autoclass:: vistrails.core.modules.config.ModuleSettings
+
+Port Specification
+==================
+
+InputPort (IPort)
+^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.InputPort
+
+.. py:class:: vistrails.core.modules.config.IPort
+
+    Synonym for :py:class:`~vistrails.core.modules.config.InputPort`
+
+
+OutputPort (OPort)
+^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.OutputPort
+
+.. py:class:: vistrails.core.modules.config.OPort
+
+    Synonym for :py:class:`~vistrails.core.modules.config.OutputPort`
+
+
+CompoundInputPort (CIPort)
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.CompoundInputPort
+
+.. py:class:: vistrails.core.modules.config.CIPort
+
+    Synonym for :py:class:`~vistrails.core.modules.config.CompoundInputPort`
+
+CompoundOutputPort (COPort)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.CompoundOutputPort
+
+.. py:class:: vistrails.core.modules.config.COPort
+
+    Synonym for :py:class:`~vistrails.core.modules.config.CompundOutputPort`
+
+InputPortItem (IPItem)
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.InputPortItem
+
+.. py:class:: vistrails.core.modules.config.IPItem
+
+    Synonym for :py:class:`~vistrails.core.modules.config.InputPortItem`
+
+OutputPortItem (OPItem)
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.OutputPortItem
+
+.. py:class:: vistrails.core.modules.config.OPItem
+
+    Synonym for :py:class:`~vistrails.core.modules.config.OutputPortItem`
+
+Parameter Widget Configuration
+==============================
+
+ConstantWidgetConfig
+^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.ConstantWidgetConfig
+
+QueryWidgetConfig
+^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.QueryWidgetConfig
+
+ParamExpWidgetConfig
+^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: vistrails.core.modules.config.ParamExpWidgetConfig
diff --git a/doc/usersguide/batch.rst b/doc/usersguide/batch.rst
index 526a954..47678b0 100644
--- a/doc/usersguide/batch.rst
+++ b/doc/usersguide/batch.rst
@@ -11,159 +11,42 @@ Starting |vistrails| via the Command Line
 
 |vistrails| supports a number of command-line arguments that let you modify certain attributes and behaviors of the program. When invoking |vistrails| from the command line, the arguments are placed after the "run.py" filename. For example,
 
-   ``python vistrails/run.py -n``
+   ``python vistrails/run.py -b``
 
-suppresses the |vistrails| splash screen. Table :ref:`table-batch-cli` contains a complete list of the command line switches supported by \vistrails. Each command line switch has both a short form and a long form. The two forms are logically equivalent, and which one you use is a matter of personal preference. The short form consists of a single minus sign "-" followed by a single letter. The longer form uses two minus signs "--" followed by a descriptive word. For example, the above com [...]
+starts |vistrails| in batch mode. Table :ref:`table-batch-cli` contains a complete list of the command line switches supported by \vistrails. Each command line switch has both a short form and a long form. The two forms are logically equivalent, and which one you use is a matter of personal preference. The short form consists of a single minus sign "-" followed by a single letter. The longer form uses two minus signs "--" followed by a descriptive word. For example, the above command for [...]
 
-   ``python vistrails/run.py --nosplash``
+   ``python vistrails/run.py --batch``
 
 
 In addition to the explicit switches listed in Table :ref:`table-batch-cli`, the |vistrails| command line also lets you indicate the filename of the vistrail you wish to open. For example, assuming your "examples" directory is one level above your current working directory, this is how you would tell |vistrails| to load the "lung.vt" example at startup:
 
-   ``python vistrails/run.py ../examples/lung.vt``
+   ``python vistrails/run.py examples/lung.vt``
 
 
 Moreover, if you want |vistrails| to start on a *specific version* of the pipeline within the vistrail, you can indicate that version's tag name on the command line. The filename and version tag should be separated by a colon. For example, to start |vistrails| with the ``colormap`` version of the "lung.vt" vistrail, use:
 
-   ``python vistrails/run.py ../examples/lung.vt:colormap``
+   ``python vistrails/run.py examples/lung.vt:colormap``
 
 
 In the event that the version you want to open contains a space in its tag name, simply surround the entire "filename:tag" pair in double quotes. For example:
 
-   ``python vistrails/run.py "../examples/lung.vt:Axial View"``
+   ``python vistrails/run.py "examples/lung.vt:Axial View"``
 
 
 You can also open up multiple vistrails at once by listing more than one vistrail file on the command line. This causes the vistrails to be opened in separate tabs, just as if you had opened them via the GUI. For example:
 
-   ``python vistrails/run.py ../examples/lung.vt ../examples/head.vt``
+   ``python vistrails/run.py examples/lung.vt examples/head.vt``
 
 
 You can specify version tags in conjunction with multiple filenames. Here is an example of an elaborate command-line invocation that opens two vistrails and sets each one to a specific version:
 
-   ``python vistrails/run.py "../examples/lung.vt:Axial View" ../examples/head.vt:bone``
+   ``python vistrails/run.py "examples/lung.vt:Axial View" examples/head.vt:bone``
 
 
-
-.. topic:: Note:
-
-   As of this writing, the |vistrails| development team is refactoring the implementation of many of the command-line switches presented in Table :ref:`table-batch-cli`. As such, depending on your version of |vistrails|, the results you achieve may not match those described. For a list of known issues with the command line switches, please refer to the |vistrails| website.
-
-.. raw::latex
-   \begin{table}
-   \caption{Command line arguments supported by VisTrails.}
-   \label{table:batch:cli}
-   \begin{center}
-   \begin{tabular}{ | l | l | p{3in} | }
-   \hline 
-   \textbf{Short form} & \textbf{Long form} & \textbf{Description} \\
-   \hline 
-     -h & -$\,$-help & Print a help message and exit. \\
-   \hline
-     -S \emph{/path} & -$\,$-startup=\emph{/path} &
-                           Set user configuration directory (default is \texttt{$\sim$/.vistrails})
-   %% (Not fully working. see Ticket 213)
-   \\
-   \hline
-     -? & &                Print a help message and exit. \\
-   \hline
-     -v & -$\,$-version &      Print version information and exit. \\
-   \hline
-     -V \emph{num} &  -$\,$-verbose=\emph{num} &
-                           Set verboseness level (0--2, default=0, higher means
-                           more verbose). \\
-   \hline
-     -b & -$\,$-noninteractive & Run in non-interactive (batch) mode. \\
-   \hline
-     -n & -$\,$-nosplash &       Do not display splash screen on startup. \\
-    \hline
-     -q \emph{file} & -$\,$-quickstart=\emph{file} &
-                             Start VisTrails using the specified static registry. \\
-   \hline
-     -c \emph{num} & -$\,$-cache=\emph{num} &
-                           Enable/disable caching (0 to disable, nonzero to enable. Default is enabled). \\
-   \hline
-     -m \emph{num} & -$\,$-movies=\emph{num} &
-                           Set automatic movie creation on spreadsheet (0 or 1,
-                           default=1). Set this to zero to work around VTK bug
-                           with offscreen renderer and OpenGL texture3D mappers. \\
-   \hline
-     -s & -$\,$-multiheads &     Display the Builder and Spreadsheet on different
-                           screens (if available).
-   \\
-   \hline
-     -x & -$\,$-maximized &      Maximize Builder and Spreadsheet windows at startup. \\
-   \hline
-     -D & -$\,$-detachHistoryView &  Detach the history view from the builder window. \\
-   \hline
-     -l & -$\,$-nologger &       Disable logging. \\
-   \hline
-     -d & -$\,$-debugsignals &   Debug Qt Signals. \\
-   \hline
-     -a \emph{params} & -$\,$-parameters=\emph{params} &
-                           Set workflow parameters (non-interactive mode only). \\
-   \hline
-     -e \emph{dir} & -$\,$-dumpcells=\emph{dir} &
-                           Set directory to dump spreadsheet cells before exiting (non-interactive mode only). \\
-   \hline
-     -G & -$\,$-workflowgraph &
-                           Save workflow graph in specified directory without running 
-			   the workflow (non-interactive mode only).
-   \hline
-     -U & -$\,$-evolutiongraph &
-                           Save evolution graph in specified directory without running
-			   any workflowDump images in pdf format (non-interactive mode only).
-  \hline
-     -p & -$\,$-pdf &
-                           Dump images in pdf format (non-interactive mode only).
-   \hline
-     -g & -$\,$-noSingleInstance &
-                           Run VisTrails without the single instance restriction. \\
-   \hline
-     -t \emph{host} & -$\,$-host=\emph{host} & Set hostname or IP address of database server. \\
-   \hline
-     -r \emph{port} & -$\,$-port=\emph{port} & Set database port. \\
-   \hline
-     -f \emph{dbName} & -$\,$-db=\emph{dbName} & Set database name. \\
-   \hline
-     -u \emph{userName} & -$\,$-user=\emph{userName} & Set database username. \\
-   \hline
-   \end{tabular}
-   \end{center}
-   \end{table}
-
-.. tabularcolumns:: |l|l|p{7.5cm}|
-   
-.. _table-batch-cli:
-
-.. csv-table:: Command line arguments supported by |vistrails|.
-   :header: **Short form**, **Long form**, **Description**
-   :widths: 10, 15, 20
-
-   -h, :math:`--`\ help, Print a help message and exit.
-   -S */path*, -\ -startup=\ */path*, Set user configuration directory (default is :math:`\sim`\ ``/.vistrails``)
-   -?, , Print a help message and exit.
-   -v, --version, Print version information and exit.
-   -V *num*, --verbose=\ *num*, "Set verboseness level (0--2, default=0, higher means more verbose)."
-   -b, --noninteractive, Run in non-interactive (batch) mode.
-   -n, --nosplash, Do not display splash screen on startup.
-   -q *file*, --quickstart=\ *file*, Start VisTrails using the specified static registry. 
-   -c *num*, --cache=\ *num*, "Enable/disable caching (0 to disable, nonzero to enable. Default is enabled)."
-   -m *num*, --movies=\ *num*, "Set automatic movie creation on spreadsheet (0 or 1, default=1). Set this to zero to work around VTK bug with offscreen renderer and OpenGL texture3D mappers."
-   -s, --multiheads, Display the Builder and Spreadsheet on different screens (if available).
-   -x, --maximized, Maximize Builder and Spreadsheet windows at startup.
-   -P, --parameterExploration, execute Parameter Exploration.
-   -l, --nologger, Disable logging.
-   -d, --debugsignals, Debug Qt Signals.
-   -a *params*, --parameters=\ *params*, Set workflow parameters (non-interactive mode only).
-   -e *dir*, --dumpcells=\ *dir*, Set directory to dump spreadsheet cells before exiting (non-interactive mode only).
-   -G, --workflowgraph, Save workflow graph in specified directory without running the workflow (non-interactive mode only).
-   -U, --evolutiongraph, Save evolution graph in specified directory without running any workflow (non-interactive mode only).
-   -p, --pdf, Dump images in pdf format (non-interactive mode only).
-   -g, --noSingleInstance, Run VisTrails without the single instance restriction. 
-   -t *host*, --host=\ *host*, Set hostname or IP address of database server.
-   -r *port*, --port=\ *port*, Set database port.
-   -f *dbName*, --db=\ *dbName*, Set database name.
-   -u *userName*, --user=\ *userName*, Set database username.
+.. argparse::
+   :module: vistrails.core.configuration
+   :func: build_sphinx_parser
+   :prog: run.py
 
 .. index:: configuration directory
 
@@ -171,7 +54,7 @@ Specifying a User Configuration Directory
 =========================================
 
 In addition to the default .vistrails directory, VisTrails allows you to create and use additional configuration directories.  First, you will need to create a new directory.  This is done by running:
- ``python vistrails/run.py -S /path_to_new_directory/new_directory_name``.  
+``python vistrails/run.py -S /path_to_new_directory/new_directory_name``.
 
 This will both create a new directory containing default configuration files and directories, and launch VisTrails, which will use the newly created files for configuration.  The user is then free to add desired configurations to the new directory.  Once a configuration directory exists, subsequent calls using the directory name (``python vistrails/run.py -S /path_to_directory/existing_directory``) will launch VisTrails using the 'existing_directory' for configuration and a new directory [...]
 
@@ -186,7 +69,7 @@ As discussed in Chapter :ref:`chap-database`, |vistrails| can read and write vis
 
 The last four rows of Table :ref:`table-batch-cli` show the command-line switches that pertain to database connectivity. Be advised that these switches were designed primarily for use by VTL files (see Section :ref:`sec-cli-vtl`) and as such, are not necessarily user-friendly. In particular, these switches are ignored unless you also specify the vistrail ID and version name on the command line. For example, to open the ``contour`` version of the the "spx" vistrail (whose ID is 5) from th [...]
 
-   ``python vistrails/run.py -t vistrails.sci.utah.edu -f vistrails -u vistrails 5:contour``
+   ``python vistrails/run.py --host=vistrails.sci.utah.edu --db=vistrails --user=vistrails 5:contour``
 
 
 Once |vistrails| opens, you will be prompted to enter the password. Upon successful authentication, the vistrail is loaded from the database and opened to the pipeline corresponding to the specified version.
@@ -218,13 +101,13 @@ Running |vistrails| in Batch Mode
    single: batch mode
    single: non-interactive mode
 
-Although |vistrails| is primarily intended to be run as an interactive, graphical client application, it also supports non-interactive use. |vistrails| can thus be invoked programmatically, \eg as part of a shell script. You can tell |vistrails| to start in non-interactive mode by using the "-b" or "--noninteractive" command line switch when launching \vistrails. [#]_
+Although |vistrails| is primarily intended to be run as an interactive, graphical client application, it also supports non-interactive use. |vistrails| can thus be invoked programmatically, \eg as part of a shell script. You can tell |vistrails| to start in non-interactive mode by using the "-b" or "--batch" command line switch when launching \vistrails. [#]_
 
 Running |vistrails| in non-interactive mode has little effect, however, without an additional command line argument indicating which vistrail to load. Since we are running |vistrails| as part of a batch process, it only makes sense to execute vistrails whose output is something tangible, such as a file. A vistrail whose only output is an interactive rendering in a ``VTKCell``, for instance, would not be well-suited for running in batch mode.
 
 Consider the following example. The "offscreen.vt" vistrail (included in the "examples" directory) has a variety of output options, depending on which version you select in the ``History`` view (Figure :ref:`The different versions of the offscreen.vt vistrail... <fig-batch-version_tree>`). The version tagged ``only vtk`` displays its output as an interactive VTK rendering. The version tagged ``html`` creates a simple web page in the Spreadsheet. The ``offscreen`` version, however, output [...]
 
-   ``python vistrails/run.py -b ../examples/offscreen.vt:offscreen``
+   ``python vistrails/run.py -b examples/offscreen.vt:offscreen``
 
 .. _fig-batch-version_tree:
 
@@ -276,17 +159,17 @@ Users can change workflow parameters that have an alias through the command line
 
 For example, offscreen pipeline in offscreen.vt always creates the file called image.png. If you want generate it with a different filename:
 
-``python vistrails/run.py -b ../examples/offscreen.vt:offscreen -a"filename=other.png"``
+``python vistrails/run.py -b examples/offscreen.vt:offscreen --parameters="filename=other.png"``
 
 filename in the example above is the alias name assigned to the parameter in the value method inside the String module. When running a pipeline from the command line, VisTrails will try to start the spreadsheet automatically if the pipeline requires it. For example, this other execution will also start the spreadsheet (attention to how $ characters are escaped when running on bash):
 
-``python vistrails/run.py -b ../examples/head.vt:aliases -a"isovalue=30\$&\$diffuse_color=0.8, 0.4, 0.2"``
+``python vistrails/run.py -b examples/head.vt:aliases --parameters="isovalue=30\$&\$diffuse_color=0.8, 0.4, 0.2"``
 
 You can also execute more than one pipeline on the command line:
 
-``python vistrails/run.py -b ../examples/head.vt:aliases ../examples/spx.vt:spx \ -a"isovalue=30"``
+``python vistrails/run.py -b examples/head.vt:aliases ../examples/spx.vt:spx \ --parameters="isovalue=30"``
 
-Use the -a parameter only once regardless the number of pipelines.
+Use --parameters only once regardless the number of pipelines.
 
 .. %TODO should we cover aliases here?
 
@@ -319,7 +202,7 @@ starts a multithreaded version of the XML-RPC server, so it will create a thread
 
 Note that this infrastructure works on Linux only. To make this work on Windows, you have to create a script similar to start_vistrails_xvfb.sh (located in the scripts folder) where you can send the number of other instances via command-line options to VisTrails. The command line options are:
 
-``python vistrails_server.py -T <ADDRESS> -R <PORT> -O<NUMBER_OF_OTHER_VISTRAILS_INSTANCES> [-M]&``
+``python vistrails_server.py --host=<ADDRESS> --port=<PORT> -O<NUMBER_OF_OTHER_VISTRAILS_INSTANCES> [-M]&``
 
 If you want the main vistrails instance to be multithreaded, use the -M at the end.
 
diff --git a/doc/usersguide/conf.py b/doc/usersguide/conf.py
index adbbffb..6b951ca 100644
--- a/doc/usersguide/conf.py
+++ b/doc/usersguide/conf.py
@@ -16,13 +16,13 @@ import sys, os
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.append(os.path.abspath('.'))
+sys.path.append(os.path.abspath('../..'))
 
 # -- General configuration -----------------------------------------------------
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.extlinks']
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.extlinks', 'sphinxarg.ext']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -45,9 +45,9 @@ copyright = u'2014, NYU Poly'
 # built documents.
 #
 # The short X.Y version.
-version = '2.1'
+version = 'master'
 # The full version, including alpha/beta/rc tags.
-release = '2.1.4'
+release = '2.2'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -86,7 +86,7 @@ pygments_style = 'sphinx'
 # A list of ignored prefixes for module index sorting.
 #modindex_common_prefix = []
 
-extlinks = {'vtl': ('http://www.vistrails.org/usersguide/v2.1/examples/%sl',
+extlinks = {'vtl': ('http://www.vistrails.org/usersguide/v2.2/examples/%sl',
                     '')}
 
 # -- Options for HTML output ---------------------------------------------------
@@ -206,3 +206,5 @@ rst_epilog = """
 .. |eg| replace:: *e.g.,*\ 
 .. |etc| replace:: *etc.*\ 
 """
+
+autoclass_content = "init"
diff --git a/doc/usersguide/controlflow.rst b/doc/usersguide/controlflow.rst
index c2b5260..abf6f03 100644
--- a/doc/usersguide/controlflow.rst
+++ b/doc/usersguide/controlflow.rst
@@ -127,7 +127,7 @@ structure.
 
   You will set some parameters now:
 
-  * ``HTTPFile``: set the parameter "url" to http://www.sci.utah.edu/~cscheid/stuff/head.120.vtk
+  * ``DownloadFile``: set the parameter "url" to http://www.sci.utah.edu/~cscheid/stuff/head.120.vtk
   * ``List``: set the parameter "value" to *[0]*
   * ``Map``: set the parameter "InputPort" to *["SetValue"]* and the parameter "OutputPort" to *GetSurfaceArea*
 
@@ -388,7 +388,7 @@ that will be executed if the input is a structure identifier.
    text = '</BODY></HTML>'
    f.write(text)
 
-   self.setResult('html', f)
+   self.set_output('html', f)
 
    f.close()
 
diff --git a/doc/usersguide/creating.rst b/doc/usersguide/creating.rst
index 12437e2..f53bea6 100644
--- a/doc/usersguide/creating.rst
+++ b/doc/usersguide/creating.rst
@@ -194,7 +194,7 @@ VisTrails supports the use of global variables, which allows the user to create
 
 .. topic:: Try it now!
 
-   Open vtk_http.vt and go to the ``Pipeline`` view of the ``Fran Cut Smoothed`` version.  Select ``Views`` :math:`\rightarrow` ``Vistrail Variables``.  Select the ``String`` module from ``Basic Modules``, drag it over to the ``Vistrail Variables`` tab, and drop it (see Figure :ref:`Create a Variable... <fig-global-create>`).  Name it 'Filename1' and assign it the following value: 'http://www.sci.utah.edu/~cscheid/stuff/vtkdata-5.0.2.zip'.  Click on ``String``, which is just below ``File [...]
+   Open vtk_http.vt and go to the ``Pipeline`` view of the ``Fran Cut Smoothed`` version.  Select ``Views`` :math:`\rightarrow` ``Vistrail Variables``.  Select the ``String`` module from ``Basic Modules``, drag it over to the ``Vistrail Variables`` tab, and drop it (see Figure :ref:`Create a Variable... <fig-global-create>`).  Name it 'Filename1' and assign it the following value: 'http://www.sci.utah.edu/~cscheid/stuff/vtkdata-5.0.2.zip'.  Click on ``String``, which is just below ``File [...]
 
 To delete a global variable, simply click on the 'X' button that appears to the right of its name.  This will remove the variable, but if any ports are assigned to it, they need to be disconnected.  You can do this by right-clicking on the port and selecting ``Disconnect Vistrail Variables`` (see Figure :ref:`Disconnect a Variable... <fig-disconnect>`).
 
@@ -235,9 +235,9 @@ Configuring Module Ports
    pair: ports; adding
    pair: ports; deleting
 
-For convenience, all the inputs and outputs of a module are not always shown in the canvas as ports.  The ports that are shown by default are defined with the method signatures of a package.
-A full list of ports is available in the ``Module Information`` panel on the right side.
-Module ports can be enabled/disabled by clicking in the left margin next to the port name in the ``Inputs`` or ``Outputs`` tabs (see Figure :ref:`Enabling the GetRadius port from the Module Information tab <fig-enabling_ports>`). When enabled, an eye icon will appear to the left of the port name.
+For convenience, all the inputs and outputs of a module are not always
+shown in the canvas as ports.  The ports that are shown by default are
+defined with the method signatures of a package.  A full list of ports is available on the ``Module Information`` panel, which is displayed on the right by default.  There, module ports can be enabled/disabled by clicking in the left margin next to the port name in the ``Inputs`` or ``Outputs`` tabs (see Figure :ref:`Enabling the GetRadius port from the Module Information tab <fig-enabling_ports>`).  When enabled, an eye icon will appear to the left of the port name.
 
 .. topic:: Try it now!
 
diff --git a/doc/usersguide/developer.rst b/doc/usersguide/developer.rst
index d2cbf9e..7589d4a 100644
--- a/doc/usersguide/developer.rst
+++ b/doc/usersguide/developer.rst
@@ -10,7 +10,7 @@ Developer's Guide
    packages
    batch
    log
-   example_itk
    controlflowdev
    parallelization
    cltools
+   api_documentation
diff --git a/doc/usersguide/example.rst b/doc/usersguide/example.rst
index 97d66c2..9f7e6cd 100644
--- a/doc/usersguide/example.rst
+++ b/doc/usersguide/example.rst
@@ -18,7 +18,7 @@ An Introduction to VisTrails
 .. toctree::
    :maxdepth: 2
 
-   intro2
+   intro
    getting_started
 
 #############################
@@ -48,11 +48,16 @@ Intermediate Concepts and VisTrails Packages
 .. toctree::
    :maxdepth: 2
 
+   parameter_widgets
    controlflow
    cfassistant
+   list_handling
+   streaming
    parallelflow
    database
    example_webservices
-   persistence
+   example_itk
+   persistent_archive
    vistrails_server
    latex
+   example_scikit_learn
diff --git a/doc/usersguide/example_guide.rst b/doc/usersguide/example_guide.rst
index 1df12af..5f9426f 100644
--- a/doc/usersguide/example_guide.rst
+++ b/doc/usersguide/example_guide.rst
@@ -9,6 +9,13 @@ Module Descriptions and Examples
 VisTrails VTK modules
 =====================
 
+Most VTK modules in VisTrails represents VTK classes. Inputs and outputs are based on class methods. A warning, in VTK it is sometimes important to call input methods in the correct order. This order is not preserved in the parameter list in VisTrails, but will still be used during execution. Method names may differ in VisTrails:
+
+* Most Set/Get prefixes have been removed.
+* SetXToY-style methods are reduced to single SetX names with a list selection.
+* Methods without parameters are replaced by booleans (that need to be set to True).
+* VTK6's SetInputData-style names are used even for VTK5.
+
 Although most VTK modules in VisTrails would be familiar to vtk users, or at least in the vtk documentation, there are a few modules that VisTrails introduces.  They are used as follows:
 
 * **PythonSource** - Although a PythonSource is in the Basic Modules list rather than VTK, it is mentioned here for convenience.  This module allows you write python statements to be executed as part of the workflow.  See Section :ref:`sec-pythonsource` for more information.
@@ -17,8 +24,6 @@ Although most VTK modules in VisTrails would be familiar to vtk users, or at lea
 
 * **VTKRenderOffscreen** - Takes the output of a vtkRenderer and produces a PNG image of size width X height.  Default values of width and height are 512.  The output can then be written to a file using a FileSink.
 
-* **VTKViewCell** - This is similar to the VTKCell except that you pass it a vtkRenderView.
-
 * **vtkInspectors: vtkDataArrayInspector, vtkDataSetAttributesInspector, vtkDataSetInspector, vtkPolyDataInspector** - These inspectors were created to allow easy access to information that is not otherwise exposed by module ports, but would be accessible through vtk objects.  This information includes: normals, scalars, tensors, and vectors as well as statistical information such as bounds, center, length, max, min.  Looking at the output ports of these inspectors gives an idea of the i [...]
 
 .. index:: vtkInteractionHandler
@@ -47,6 +52,8 @@ Modules and Corresponding Examples
 
 Here we provide a list of the .vt files in the examples directory that use the following modules:
 
+Warning, this list is out-of-date and some examples may have been removed.
+
 .. index:: 
    pair: modules; list of examples
 
diff --git a/doc/usersguide/example_scikit_learn.rst b/doc/usersguide/example_scikit_learn.rst
new file mode 100644
index 0000000..bc135fd
--- /dev/null
+++ b/doc/usersguide/example_scikit_learn.rst
@@ -0,0 +1,144 @@
+*********************
+Example: scikit-learn
+*********************
+
+Introduction to scikit-Learn
+============================
+`scikit-learn <http://scikit-learn.org>`_ is a python based open-source machine learning library.
+It provides implementations of popular machine learning algorithms together with
+evaluation and preprocessing utilities.
+For more information, refer to the `extensive documentation <http://scikit-learn.org/stable/documentation.html>`_.
+
+
+Installing scikit-learn
+=======================
+|vistrails| should be able to automatically install scikit-learn via pip.
+If this fails, try to install it manually::
+
+    pip install --user scikit-learn
+
+It this also fails, consult the `installation instructions <http://scikit-learn.org/stable/install.html>`_.
+
+
+Using scikit-learn via |vistrails|
+==================================
+
+Datasets
+^^^^^^^^
+For testing purposes and the examples, there are two multi-class classification datasets made available as |vistrails| modules,
+the Digits and the Iris datasets. These have as output ports training data and classification targets, to quickly test a pipeline.
+Both datasets are very simple toy datasets and should not be used as benchmarks.
+
+The Digits dataset consists of 1797 handwritten digits as represented as 8x8
+grey scale images, resulting in 64 features. The digits belong to the classes 0
+to 9.
+The `Iris <https://en.wikipedia.org/wiki/Iris_flower_data_set>`_ dataset
+consists of 150 data points with four features, belonging to one of three
+classes.
+
+Splitting data into training and test set
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+As machine learning is inherently about generalization from training to test data,
+it is essential to separate a data set into training and test parts.
+The ``TrainTestSplit`` module is a convenient way to do this:
+
+.. figure:: figures/example_scikit_learn/train_test_split.png
+   :align: center
+   :height: 400px
+
+   The round output ports of the Iris dataset correspond to training data and training targets,
+   which are fed into ``TrainTestSplit``. The outputs of ``TrainTestSplit`` are data and labels
+   for two subsets of the data, corresponding to the four round output ports.
+   First are training data and training labels, then test data and test
+   labels. The split is done randomly with 25% test data by default.
+
+Basic usage
+^^^^^^^^^^^
+The |vistrails| sklearn package contains most algorithms provided in scikit-learn.
+In machine learning, applying an algorithm to a dataset usually means
+training it on one part of the data, the training set, and then applying it
+to another part, the test set.
+
+Each algorithm in scikit-learn has a corresponding |vistrails| module, which has
+input ports for training data, and outputs the model that was learned (with the exception of the :ref:`manifold_module` module).
+To apply the model to new data, connect it to a ``Predict`` module (for classification and regression) or to a ``Transform`` module
+(for data transformations like feature selection and dimensionality reduction).
+
+.. figure:: figures/example_scikit_learn/transform.png
+   :align: center
+   :height: 400px
+
+It is also possible to directly compute performance metrics like the accuracy or mean squared error using the
+``Score`` module.
+
+.. figure:: figures/example_scikit_learn/score.png
+   :align: center
+   :height: 400px
+
+The resulting Scores can be output with a ``GenericOutput``, or more advanced string formatting.
+
+To make connecting the ports easier, ports that represent models are diamond shaped,
+while ports that represent data or label arrays are round. The remaining square ports
+are either parameters of the models or additional information provided as output.
+
+.. _manifold_module:
+
+Manifold learning
+^^^^^^^^^^^^^^^^^
+Manifold learning algorithms are algorithms that embed high-dimensional data
+into a lower-dimensional space, often for visualization purposes.
+Most manifold learning algorithms in scikit-learn embed data, but cannot transform new data
+using a previously learned model. Therefore, manifold learning modules will
+directly output the transformed data.
+
+.. figure:: figures/example_scikit_learn/manifold.png
+   :align: center
+   :height: 400px
+
+   The left hand side of the pipeline uses ``PCA``, which can use ``Transform`` to be applied to new data.
+   The right hand side uses the manifold learning method ``TSNE``, which cannot be applied to new data,
+   and therefore directly produces the transformed input data (in contrast to ``PCA``, which produces a model).
+
+Cross Validation and Grid Search
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+To perform a cross validation or grid search with a model,
+simply create a module for the model, without providing any training data.
+The output will be an unfitted model that can be used as input for grid search or cross validation:
+
+.. figure:: figures/example_scikit_learn/cross_val_score.png
+   :align: center
+   :height: 400px
+
+``GridSearch`` needs as additional input a dictionary of parameter values, that is best specified using a ``PythonSource`` module:
+
+.. figure:: figures/example_scikit_learn/grid_search.png
+   :align: center
+   :height: 400px
+
+``GridSearch`` itself has a model output port, so that the grid search can be used, for example, in ``CrossValScore``
+to perform a nested cross-validation.
+
+.. figure:: figures/example_scikit_learn/nested_cross_validation.png
+   :align: center
+   :height: 400px
+
+
+Pipelines of scikit-learn models
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+To perform cross validation or grid search over a chain of estimators, such
+as preprocessing followed by classification, scikit-learn provides a ``Pipeline`` module.
+Each step of a pipeline is defined by an input port specifying a model.
+All but the last model in the pipeline must be transformers, the last can be arbitrary.
+Currently the |vistrails| scikit-learn package only supports up to four steps in a pipeline.
+
+
+.. figure:: figures/example_scikit_learn/pipeline.png
+   :align: center
+   :height: 400px
+
+As any other model, a pipeline can either be fit on data and then evaluated using ``Predict``, ``Transform`` or ``Score`` modules,
+or can serve as the input model to ``CrossValScore`` or ``GridSearchCV``.
+
+.. figure:: figures/example_scikit_learn/pipeline_gridsearch.png
+   :align: center
+   :height: 400px
diff --git a/doc/usersguide/example_webservices.rst b/doc/usersguide/example_webservices.rst
index 1250685..a04711e 100644
--- a/doc/usersguide/example_webservices.rst
+++ b/doc/usersguide/example_webservices.rst
@@ -118,7 +118,7 @@ configuration dialog:
 
 .. code-block:: python
 
-   dataitemlist = self.getInputFromPort("ontologyDataItemList")
+   dataitemlist = self.get_input("ontologyDataItemList")
    output1 = self.interpreter.filePool.create_file()
    f1 = open(str(output1.name), "w")
    text = "<HTML><TITLE>Chebi WebService</TITLE><BODY BGCOLOR=#FFFFFF>"
@@ -141,7 +141,7 @@ configuration dialog:
        f1.write(line)        
    text = "</table></CENTER></BODY></HTML>"
    f1.write(text)
-   self.setResult("outfile",output1)
+   self.set_output("outfile",output1)
    f1.close()
 
 Close the dialog.  One of the ports we need to use is an optional port.  Select the ``OntologyDataItemList`` module and select the ``Outputs`` tab from the ``Module Information`` panel.  Click in the left column next to ``ListElement`` so the eye icon appears.  Now connect the modules together as shown in Figure :ref:`fig-chebi_pipeline_screenshot`.
diff --git a/doc/usersguide/figures/edit_widgets/edit-widget.png b/doc/usersguide/figures/edit_widgets/edit-widget.png
new file mode 100644
index 0000000..630d7a5
Binary files /dev/null and b/doc/usersguide/figures/edit_widgets/edit-widget.png differ
diff --git a/doc/usersguide/figures/edit_widgets/edit-widgets.png b/doc/usersguide/figures/edit_widgets/edit-widgets.png
new file mode 100644
index 0000000..4f5e372
Binary files /dev/null and b/doc/usersguide/figures/edit_widgets/edit-widgets.png differ
diff --git a/doc/usersguide/figures/edit_widgets/enabling-edit-widgets.png b/doc/usersguide/figures/edit_widgets/enabling-edit-widgets.png
new file mode 100644
index 0000000..d1a1363
Binary files /dev/null and b/doc/usersguide/figures/edit_widgets/enabling-edit-widgets.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/cross_val_score.png b/doc/usersguide/figures/example_scikit_learn/cross_val_score.png
new file mode 100644
index 0000000..2640b5d
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/cross_val_score.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/grid_search.png b/doc/usersguide/figures/example_scikit_learn/grid_search.png
new file mode 100644
index 0000000..9a787ba
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/grid_search.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/manifold.png b/doc/usersguide/figures/example_scikit_learn/manifold.png
new file mode 100644
index 0000000..af1a107
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/manifold.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/nested_cross_validation.png b/doc/usersguide/figures/example_scikit_learn/nested_cross_validation.png
new file mode 100644
index 0000000..f3e2e1e
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/nested_cross_validation.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/pipeline.png b/doc/usersguide/figures/example_scikit_learn/pipeline.png
new file mode 100644
index 0000000..767432e
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/pipeline.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/pipeline_gridsearch.png b/doc/usersguide/figures/example_scikit_learn/pipeline_gridsearch.png
new file mode 100644
index 0000000..e1a9c58
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/pipeline_gridsearch.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/score.png b/doc/usersguide/figures/example_scikit_learn/score.png
new file mode 100644
index 0000000..0096bc6
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/score.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/train_test_split.png b/doc/usersguide/figures/example_scikit_learn/train_test_split.png
new file mode 100644
index 0000000..cbf164c
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/train_test_split.png differ
diff --git a/doc/usersguide/figures/example_scikit_learn/transform.png b/doc/usersguide/figures/example_scikit_learn/transform.png
new file mode 100644
index 0000000..5c2dcf4
Binary files /dev/null and b/doc/usersguide/figures/example_scikit_learn/transform.png differ
diff --git a/doc/usersguide/figures/list_handling/list-combine-workflow.png b/doc/usersguide/figures/list_handling/list-combine-workflow.png
new file mode 100644
index 0000000..2c117fa
Binary files /dev/null and b/doc/usersguide/figures/list_handling/list-combine-workflow.png differ
diff --git a/doc/usersguide/figures/list_handling/list-combine.png b/doc/usersguide/figures/list_handling/list-combine.png
new file mode 100644
index 0000000..3f99e91
Binary files /dev/null and b/doc/usersguide/figures/list_handling/list-combine.png differ
diff --git a/doc/usersguide/figures/packages/CustomColorShape1.png b/doc/usersguide/figures/packages/CustomColorShape1.png
deleted file mode 100644
index eacfa00..0000000
Binary files a/doc/usersguide/figures/packages/CustomColorShape1.png and /dev/null differ
diff --git a/doc/usersguide/figures/packages/CustomColorShape2.png b/doc/usersguide/figures/packages/CustomColorShape2.png
deleted file mode 100644
index 2cee93c..0000000
Binary files a/doc/usersguide/figures/packages/CustomColorShape2.png and /dev/null differ
diff --git a/doc/usersguide/figures/packages/CustomColorShape3.png b/doc/usersguide/figures/packages/CustomColorShape3.png
deleted file mode 100644
index c30a590..0000000
Binary files a/doc/usersguide/figures/packages/CustomColorShape3.png and /dev/null differ
diff --git a/doc/usersguide/figures/packages/fancy_module1.png b/doc/usersguide/figures/packages/fancy_module1.png
new file mode 100644
index 0000000..7210145
Binary files /dev/null and b/doc/usersguide/figures/packages/fancy_module1.png differ
diff --git a/doc/usersguide/figures/packages/fancy_module2.png b/doc/usersguide/figures/packages/fancy_module2.png
new file mode 100644
index 0000000..4a979d4
Binary files /dev/null and b/doc/usersguide/figures/packages/fancy_module2.png differ
diff --git a/doc/usersguide/figures/packages/fancy_module3.png b/doc/usersguide/figures/packages/fancy_module3.png
new file mode 100644
index 0000000..c604b9d
Binary files /dev/null and b/doc/usersguide/figures/packages/fancy_module3.png differ
diff --git a/doc/usersguide/figures/packages/fancy_ports.png b/doc/usersguide/figures/packages/fancy_ports.png
new file mode 100644
index 0000000..3e14776
Binary files /dev/null and b/doc/usersguide/figures/packages/fancy_ports.png differ
diff --git a/doc/usersguide/figures/persistence/base.png b/doc/usersguide/figures/persistence/base.png
deleted file mode 100644
index 3663fb8..0000000
Binary files a/doc/usersguide/figures/persistence/base.png and /dev/null differ
diff --git a/doc/usersguide/figures/persistence/input.png b/doc/usersguide/figures/persistence/input.png
deleted file mode 100644
index a43116b..0000000
Binary files a/doc/usersguide/figures/persistence/input.png and /dev/null differ
diff --git a/doc/usersguide/figures/persistence/intermediate.png b/doc/usersguide/figures/persistence/intermediate.png
deleted file mode 100644
index ca49fd8..0000000
Binary files a/doc/usersguide/figures/persistence/intermediate.png and /dev/null differ
diff --git a/doc/usersguide/figures/persistence/output.png b/doc/usersguide/figures/persistence/output.png
deleted file mode 100644
index 1dbf5b3..0000000
Binary files a/doc/usersguide/figures/persistence/output.png and /dev/null differ
diff --git a/doc/usersguide/figures/persistence/reference.png b/doc/usersguide/figures/persistence/reference.png
deleted file mode 100644
index 25cabcf..0000000
Binary files a/doc/usersguide/figures/persistence/reference.png and /dev/null differ
diff --git a/doc/usersguide/figures/persistence/versions.png b/doc/usersguide/figures/persistence/versions.png
deleted file mode 100644
index 6169beb..0000000
Binary files a/doc/usersguide/figures/persistence/versions.png and /dev/null differ
diff --git a/doc/usersguide/figures/persistent_archive/contents_filter.png b/doc/usersguide/figures/persistent_archive/contents_filter.png
new file mode 100644
index 0000000..1b35615
Binary files /dev/null and b/doc/usersguide/figures/persistent_archive/contents_filter.png differ
diff --git a/doc/usersguide/figures/persistent_archive/workflow_persistedfile.png b/doc/usersguide/figures/persistent_archive/workflow_persistedfile.png
new file mode 100644
index 0000000..521b3d3
Binary files /dev/null and b/doc/usersguide/figures/persistent_archive/workflow_persistedfile.png differ
diff --git a/doc/usersguide/figures/persistent_archive/workflow_textquery.png b/doc/usersguide/figures/persistent_archive/workflow_textquery.png
new file mode 100644
index 0000000..9c679fa
Binary files /dev/null and b/doc/usersguide/figures/persistent_archive/workflow_textquery.png differ
diff --git a/doc/usersguide/intro.rst b/doc/usersguide/intro.rst
index 1076b3c..2b46796 100644
--- a/doc/usersguide/intro.rst
+++ b/doc/usersguide/intro.rst
@@ -1,9 +1,85 @@
-############################
-An Introduction to VisTrails
-############################
+******************
+What Is VisTrails?
+******************
 
-.. toctree::
-   :maxdepth: 2
+VisTrails is a new system that provides data and process management
+support for exploratory computational tasks. It combines features of
+both workflow and visualization systems. Similar to workflow systems, it allows the combination of loosely-coupled resources, specialized
+libraries, and grid and Web services. Similar to some
+visualization systems, it provides a mechanism for parameter
+exploration and comparison of different results. But unlike these other systems,
+VisTrails was designed to manage *exploratory processes* in which
+computational tasks evolve over time as a user iteratively
+formulates and tests hypotheses. A key distinguishing
+feature of VisTrails is its comprehensive provenance infrastructure that
+maintains detailed history information about the steps followed in the
+course of an exploratory task. VisTrails leverages this information to
+provide novel operations and user interfaces that streamline this
+process.
 
-   intro2
-   getting_started
+Important Features
+""""""""""""""""""
+One of our main uses for VisTrails has been exploratory visualization,
+but the system is much more general and provides many other features,
+such as:
+
+* *Flexible Provenance Architecture.* VisTrails transparently
+  tracks changes made to workflows, including all the steps followed in the
+  exploration. The system can optionally track run-time information
+  about the execution of workflows (|eg| who executed a module, on
+  which machine, elapsed time |etc|). |vistrails| also provides a
+  flexible annotation framework whereby you can specify
+  application-specific provenance information.
+
+* *Querying and Re-using History.*  The provenance
+  information is stored in a structured way. You have a choice of
+  using a relational database (such as MySQL or IBM DB2) or XML files in
+  the file system. The system provides flexible and intuitive query
+  interfaces through which you can explore and reuse provenance
+  information.  You can formulate simple keyword-based and selection
+  queries (|eg| find a visualization created by a given user) as well
+  as structured queries (|eg| find visualizations that apply
+  simplification before an isosurface computation for irregular grid
+  data sets).
+
+* *Support for collaborative exploration.*  The system can be
+  configured with a database backend that can be used as a shared
+  repository.  It also provides a synchronization facility that allows
+  multiple users to collaborate asynchronously and in a disconnected
+  fashion---you can check in and check out changes, akin to a
+  version control system (|eg| SVN: http://subversion.tigris.org).
+
+* *Extensibility.* |vistrails| provides a very simple plugin
+  functionality that can be used to dynamically add packages and
+  libraries. Neither changes to the user interface nor re-compilation
+  of the system are necessary.  Because |vistrails| is written in
+  Python, the integration of Python-wrapped libraries is
+  straightforward. For example, a single line in the VisTrails
+  start-up file is needed to import all of VTK's classes.
+* *Scalable Derivation of Data Products and Parameter Exploration.*  
+  |vistrails| supports a series of operations
+  for the simultaneous generation of multiple data products, including
+  an interface that allows you to specify sets of values for
+  different parameters in a workflow. The results of a parameter
+  exploration can be displayed side by side in the VisTrails
+  Spreadsheet for easy comparison.
+* *Task Creation by Analogy.*  Analogies are supported as
+  first-class operations to guide semi-automated changes to multiple
+  workflows, without requiring you to directly manipulate or edit
+  the workflow specifications.
+
+Obtaining the software
+""""""""""""""""""""""
+
+Visit http://www.vistrails.org to access the VisTrails community
+website. Here you will find information including instructions for
+obtaining the software, online documentation, video tutorials, and
+pointers to papers and presentations.
+
+VisTrails is available as open
+source; it is released under the GPL 2.0 license.  The pre-compiled
+versions for Windows and Mac OS X come with an installer and
+include a number of packages, including VTK, matplotlib, and Image
+Magick. Additional packages, including packages written by users, are
+also available (|eg| ITK, Matlab, Metro). Developers can easily add new
+packages using the VisTrails plugin infrastructure. 
diff --git a/doc/usersguide/intro2.rst b/doc/usersguide/intro2.rst
deleted file mode 100644
index 2b46796..0000000
--- a/doc/usersguide/intro2.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-******************
-What Is VisTrails?
-******************
-
-VisTrails is a new system that provides data and process management
-support for exploratory computational tasks. It combines features of
-both workflow and visualization systems. Similar to workflow systems, it allows the combination of loosely-coupled resources, specialized
-libraries, and grid and Web services. Similar to some
-visualization systems, it provides a mechanism for parameter
-exploration and comparison of different results. But unlike these other systems,
-VisTrails was designed to manage *exploratory processes* in which
-computational tasks evolve over time as a user iteratively
-formulates and tests hypotheses. A key distinguishing
-feature of VisTrails is its comprehensive provenance infrastructure that
-maintains detailed history information about the steps followed in the
-course of an exploratory task. VisTrails leverages this information to
-provide novel operations and user interfaces that streamline this
-process.
-
-Important Features
-""""""""""""""""""
-One of our main uses for VisTrails has been exploratory visualization,
-but the system is much more general and provides many other features,
-such as:
-
-* *Flexible Provenance Architecture.* VisTrails transparently
-  tracks changes made to workflows, including all the steps followed in the
-  exploration. The system can optionally track run-time information
-  about the execution of workflows (|eg| who executed a module, on
-  which machine, elapsed time |etc|). |vistrails| also provides a
-  flexible annotation framework whereby you can specify
-  application-specific provenance information.
-
-* *Querying and Re-using History.*  The provenance
-  information is stored in a structured way. You have a choice of
-  using a relational database (such as MySQL or IBM DB2) or XML files in
-  the file system. The system provides flexible and intuitive query
-  interfaces through which you can explore and reuse provenance
-  information.  You can formulate simple keyword-based and selection
-  queries (|eg| find a visualization created by a given user) as well
-  as structured queries (|eg| find visualizations that apply
-  simplification before an isosurface computation for irregular grid
-  data sets).
-
-* *Support for collaborative exploration.*  The system can be
-  configured with a database backend that can be used as a shared
-  repository.  It also provides a synchronization facility that allows
-  multiple users to collaborate asynchronously and in a disconnected
-  fashion---you can check in and check out changes, akin to a
-  version control system (|eg| SVN: http://subversion.tigris.org).
-
-* *Extensibility.* |vistrails| provides a very simple plugin
-  functionality that can be used to dynamically add packages and
-  libraries. Neither changes to the user interface nor re-compilation
-  of the system are necessary.  Because |vistrails| is written in
-  Python, the integration of Python-wrapped libraries is
-  straightforward. For example, a single line in the VisTrails
-  start-up file is needed to import all of VTK's classes.
-* *Scalable Derivation of Data Products and Parameter Exploration.*  
-  |vistrails| supports a series of operations
-  for the simultaneous generation of multiple data products, including
-  an interface that allows you to specify sets of values for
-  different parameters in a workflow. The results of a parameter
-  exploration can be displayed side by side in the VisTrails
-  Spreadsheet for easy comparison.
-* *Task Creation by Analogy.*  Analogies are supported as
-  first-class operations to guide semi-automated changes to multiple
-  workflows, without requiring you to directly manipulate or edit
-  the workflow specifications.
-
-Obtaining the software
-""""""""""""""""""""""
-
-Visit http://www.vistrails.org to access the VisTrails community
-website. Here you will find information including instructions for
-obtaining the software, online documentation, video tutorials, and
-pointers to papers and presentations.
-
-VisTrails is available as open
-source; it is released under the GPL 2.0 license.  The pre-compiled
-versions for Windows and Mac OS X come with an installer and
-include a number of packages, including VTK, matplotlib, and Image
-Magick. Additional packages, including packages written by users, are
-also available (|eg| ITK, Matlab, Metro). Developers can easily add new
-packages using the VisTrails plugin infrastructure. 
diff --git a/doc/usersguide/list_handling.rst b/doc/usersguide/list_handling.rst
new file mode 100644
index 0000000..a5ddc82
--- /dev/null
+++ b/doc/usersguide/list_handling.rst
@@ -0,0 +1,116 @@
+.. _chap-list_handling:
+
+**************************
+List Handling in VisTrails
+**************************
+
+In |vistrails| you can pass typed and :ref:`untyped <sec-list-type>` lists between modules. Ports on modules have a
+depth parameter specifying the  list depth it supports. 0 means no  list, 1 is a
+list, 2 is  a list of lists etc.  Port depth can be specified either by module
+developers or by using a ``PythonSource`` or similar module.
+
+It is important to know how connections of mismatching list depths are handled:
+
+* List wrapping - If the destination port has a larger list depth, the source will be wrapped in lists until the list depth is matched.
+* :ref:`sec-iterating-lists` - If the source port has a larger list depth, the destination module
+  will  be executed  once  for each  element in  the  list.
+
+.. _sec-list-type:
+
+The List type
+=============
+
+The ``List`` type represents an untyped list and can contain a list of any type. The
+vistrails ``Variant`` type matches any type and a ``List`` is equal to a
+``Variant`` of list depth 1.
+List depth specified on ``List`` types does not include the List itself: A ``List``
+type with list depth 1 are considered a ``Variant`` with list depth 2.
+
+There is one important exception: ``Variant`` connects directly to ``List``.
+This is because ``Variant`` ports are allowed to contain lists.
+
+.. _sec-iterating-lists:
+
+Iterating over lists
+====================
+
+Passing a list to  a module that does not support lists  will cause that module
+to  be executed  once  for each  element in  the  list. When  passing lists  on
+multiple input ports, the inputs  will be combined.  The default combination is
+cartesian product, where  each element in a list is  combined with each element
+in another list. This combination can be changed by selecting "Looping Options"
+in the  module menu.   The options are  ``Cartesian``, ``Pairwise``  (where the
+elements are combined pairwise), and ``Custom``.  ``Custom`` gives you complete
+control   over  how  inputs   are  combined   and  allows   you  to   use  both
+pairwise/cartesian  combiners as  well as  reordering them.   The output  of an
+iterated module  will be  an ordered  list with the  individual results  of the
+module execution. This will cause  modules downstream to also be iterated over,
+unless  they accept a  list as  input.  Iterated  modules will  have duplicated
+connections to  show that they  are being iterated  over. A list of  lists will
+have the connection triplicated etc.
+
+.. topic:: Try it Now!
+
+  Lets create a  simple example showing how to combine  strings.  First we will
+  create a  module that generates lists  of strings. Create a  new workflow and
+  add  a ``PythonSource``  module. Give  it  three output  ports named  ``s1``,
+  ``s2``, ``s3`` of  type ``String`` and set their list depth  to 1. Enter this
+  code:
+
+.. code-block:: python
+
+    s1 = ['A', 'B', 'C']
+    s2 = ['+', '-', '*']
+    s3 = ['1', '2', '3']
+
+.. topic:: Next Step!
+
+  Add  a  ``ConcatenateString``  module,  connect  ``s1->str1``,  ``s2->str2``,
+  ``s3->str3``. Notice how the connections going into ``ConcatenateString`` are
+  duplicated. This  indicates that ``ConcatenateString`` will  iterate over the
+  list    inputs.     Add    a    ``StandardOutput``   module    and    connect
+  ``ConcatenateString.value``  to  ``StandardOutput.value``.   This  connection
+  will be duplicated in both ends,  indicating they will both be iterated over.
+  Your       workflow       should       now       look       like       Figure
+  :ref:`fig-list_handling-list-combine-workflow`.
+
+.. _fig-list_handling-list-combine-workflow:
+
+.. figure:: figures/list_handling/list-combine-workflow.png
+   :align: center
+   :width: 1.8in
+
+   The complete workflow
+
+.. topic:: Next Step!
+
+  By  default ``ConcatenateString``  will  combine the  inputs using  cartesian
+  product  ``["A+1", "A+2",  "A+3", "A-1",  ...]``.  Lets  change this.   Go to
+  Module ``Menu->Looping Options``  and click custom.  Right click  in the port
+  list and  add a pairwise product. Rearrange  the ports so that  it looks like
+  Figure :ref:`fig-list_handling-list-combine`.
+
+.. _fig-list_handling-list-combine:
+
+.. figure:: figures/list_handling/list-combine.png
+   :align: center
+
+   A custom list combiner
+
+.. topic:: Finally:
+
+  ``str2`` and  ``str3`` will now be  combined pairwise and  then combined with
+  ``str1`` using cartesian product. Open  the vistrails console and execute the
+  workflow. You should see this output: :vtl:`(Open result) <list-handling.vt>`
+
+.. code-block:: python
+
+    A+1
+    A-2
+    A*3
+    B+1
+    B-2
+    B*3
+    C+1
+    C-2
+    C*3
diff --git a/doc/usersguide/mashups.rst b/doc/usersguide/mashups.rst
index dc74619..7e64219 100644
--- a/doc/usersguide/mashups.rst
+++ b/doc/usersguide/mashups.rst
@@ -23,7 +23,7 @@ Notice that a pipeline can have multiple modules of the same type or name, makin
    :width: 2.5in
    :align: center
 
-   Numbered Modules - The HTTPFile modules 1 and 2 appear in the annotated pipeline and in the parameter aliases.  The annotated pipeline also, numbers the vtkDataSetReader modules (which appear below the respective HTTPFile modules in the pipeline).  Their parameters have not been exposed to the mashup, so they do not appear in the Parameter Aliases section.
+   Numbered Modules - The DownloadFile modules 1 and 2 appear in the annotated pipeline and in the parameter aliases.  The annotated pipeline also, numbers the vtkDataSetReader modules (which appear below the respective HTTPFile modules in the pipeline).  Their parameters have not been exposed to the mashup, so they do not appear in the Parameter Aliases section.
 
 Finally, not all modules in the ``Annotated Pipeline`` will show up in the ``Parameter Aliases`` section.  Only modules whose parameters have been set in the pipeline will appear.
 
@@ -67,7 +67,7 @@ A Simple Example
 
    * Open :vtl:`brain_vistrail.vt`
    * Choose ``Save As`` and rename the file if you do not want to overwrite the original.
-   * Select the "counter 4" version
+   * Select the "contour 3" version
    * Press execute to ensure any necessary upgrades are made
    * Select ``Mashup`` from the toolbar.
    * In the Mashup Pipeline tab, look under ``vtkProperty`` :math:`\rightarrow` ``SetOpacity`` and double-click on ``Float``.  
diff --git a/doc/usersguide/packages.rst b/doc/usersguide/packages.rst
index 7b61b26..60cf393 100644
--- a/doc/usersguide/packages.rst
+++ b/doc/usersguide/packages.rst
@@ -20,7 +20,7 @@ Introduction
 plugin infrastructure to integrate user-defined functions and
 libraries. Specifically, users can incorporate their own visualization
 and simulation code into pipelines by defining custom modules (or wrappers). These
-modules are bundled in what we call *packages*. A \vistrails
+modules are bundled in what we call *packages*. A |vistrails|
 package is simply a collection of Python classes stored in one or more
 files, respecting some conventions that will be described shortly.
 Each of these classes will represent a new module. In this chapter, we
@@ -37,43 +37,52 @@ This chapter is written for developers who wish to extend |vistrails| with custo
 
 However, if you do not yet know Python but are familiar with another object-oriented language such as Java or C#, you should be able to get the gist of these examples from looking at the code and by reading our line-by-line commentaries.
 
-.. _sec-packages-simple_example:
+.. _sec-packages-example-module:
 
-A Simple Example
-================
+An Example Module
+=================
 
-Here is a simplified example of a very simple user-defined module:
+Here is the definition of a very simple module:
 
 .. code-block:: python
    :linenos:
 
    class Divide(Module):
+       _input_ports = [IPort(name='arg1',\
+                             signature='basic:Float',\
+                             label="dividend"),
+                       IPort(name='arg2',\
+		             signature='basic:Float',\
+			     label='divisor')]
+       _output_ports = [OPort(name='result',\
+                              signature='basic:Float',\
+                              label='quotient')]
+
        def compute(self):
-           arg1 = self.getInputFromPort("arg1")
-           arg2 = self.getInputFromPort("arg2")
+           arg1 = self.get_input("arg1")
+           arg2 = self.get_input("arg2")
            if arg2 == 0.0:
                raise ModuleError(self, "Division by zero")
-           self.setResult("result", arg1 / arg2)
+           self.set_output("result", arg1 / arg2)
+
+New VisTrails modules must subclass from :py:class:`~vistrails.core.modules.vistrails_module.Module`, the base class that defines basic functionality. The only required override is the :py:meth:`~vistrails.core.modules.vistrails_module.Module.compute` method, which performs the actual module computation. Input and output is specified through ports, which must be explicitly registered with |vistrails| using the :py:attr:`~.vistrails_module.Module._input_ports` and :py:attr:`~.vistrails_mo [...]
+
+.. _sec-packages-simple-example:
+
+An Example Package
+==================
 
-       _input_ports = [('arg1', '(org.vistrails.vistrails.basic:Float)',\
-                        {"labels": str(["dividend"])}),\
-                       ('arg2', '(org.vistrails.vistrails.basic:Float)',\
-                        {"labels": str(["divisor"])})]
-       _output_ports = [('result', '(org.vistrails.vistrails.basic:Float)',\
-                        {"labels": str(["quotient"])})]
+The previous section only shows the definition of a single module.  To create a full package that loads and runs in |vistrails|, a few more items are required.  In this example, we define a basic calculator package named PythonCalc.  Note that this package includes *two* files, ``__init__.py`` and ``init.py`` that live in a directory named ``pythonCalc``; each file is an important piece of a VisTrails package.
 
-   _modules = [Divide]
-   #old syntax
-   #registry.addModule(Divide)
-   #registry.addInputPort(Divide, "arg1", (basic.Float, 'dividend'))
-   #registry.addInputPort(Divide, "arg2", (basic.Float, 'divisor'))
-   #registry.addOutputPort(Divide, "result", (basic.Float, 'quotient'))
+**__init__.py**
+
+.. include:: pythoncalc_file1.rst
 
-New VisTrails modules must subclass from Module, the base class that defines basic functionality. The only required override is the compute() method, which performs the actual module computation. Input and output is specified through ports, which currently have to be explicitly registered with VisTrails. However, this is straightforward, and done through method calls to the module registry. An example of a (slightly) more complicated module follows:
+**init.py**
 
 .. include:: pythoncalc.rst
 
-To try this out in VisTrails, save the file above in the ``.vistrails/userpackages`` subdirectory of your home directory, with the filename ``pythoncalc.py``. Then, click on the ``Edit`` menu (or the ``VisTrails`` menu on Mac OS X), select the ``Preferences`` option and select the ``Module Packages`` tab.  A dialog similar to what is shown
+To create and install this package in VisTrails, first create a new directory named ``pythonCalc`` in the ``.vistrails/userpackages`` subdirectory of your home directory. Then, save the two code blocks above to the corresponding ``__init__.py`` and ``init.py`` files in the newly created ``pythonCalc`` directory.  Now, click on the ``Edit`` menu (or the ``VisTrails`` menu on Mac OS X), select the ``Preferences`` option and select the ``Module Packages`` tab.  A dialog similar to what is shown
 in Figure :ref:`All available packages... <fig-packages-enablepackage>` should appear. Select the
 ``pythonCalc`` package, then click on
 ``Enable``. This should move the package to the
@@ -104,14 +113,7 @@ will print the following on your terminal:
 
 
 
-Let's now examine how this works. The first
-two lines simply import required components. The next three lines
-give |vistrails| meta-information about the
-package. ``Version`` is simply information about the package
-version. This might be tied to the underlying library or not. The only
-recommended guideline is that compatibility is not broken across minor
-releases, but this is not enforced in any way. ``Name`` is a
-human-readable name for the package. 
+Let's now examine how this works. The ``__init__.py`` file provides metadata about the package.  ``Version`` is simply information about the package version. This might be tied to the underlying library or not. The only recommended guideline is that compatibility is not broken across minor releases, but this is not enforced in any way. ``Name`` is a human-readable name for the package. 
 
 .. %\paragraph*{Choosing a good identifier}
 
@@ -131,275 +133,123 @@ use their institution's DNS, use your own. The rationale for this is
 that the third party itself might decide to create their own |vistrails|
 package, and you do not want to introduce conflicts.
 
-Line 8 is where we actually start defining a new module.
-Every |vistrails| module corresponds
-to a Python class that ultimately derives from the ``Module`` class, which is defined in ``core.modules.vistrails_module``. Each module must implement a ``compute`` method that takes no extra parameters, such as on Line 11. This method
-represents the actual computation that happens in a module.
-This computation typically involves getting the necessary input and
-generating the output. We will now see how that works.
-
-Line 12 shows how to extract input from a
-port. Specifically, we're getting the values passed to input ports
-``value1`` and ``value2``. We then perform some
-operation with these values, and need to report the output on an
-output port, so that it is available for downstream modules. This is
-done on Line 15, where the result is set to port
-``value``.
+The ``init.py`` file contains the actual definitions of the modules. Every |vistrails| module corresponds to a Python class that ultimately derives from the :py:class:`.Module` class, which is defined in :py:mod:`vistrails.core.modules.vistrails_module`. Each module must define input ports and output ports as well as implement a :py:meth:`~.vistrails_module.Module.compute` method that takes no extra parameters.
+
+.. index:: ports
+   pair: modules; ``_input_ports``
+   pair: modules; ``_output_ports``
+
+We need to tell |vistrails| about the input and output ports we want to expose in a module.  Input ports are set in the :py:attr:`~.vistrails_module.Module._input_ports` list and output ports in the :py:attr:`~.vistrails_module.Module._output_ports` list. Each object in these lists is defined from a type from :py:mod:`vistrails.core.modules.config`.  The most basic port types are :py:class:`~.modules.config.InputPort` (aka :py:class:`~.modules.config.IPort`) and :py:class:`~.modules.conf [...]
+
+.. index::
+   pair: modules; ``compute``
+
+The compute method on Line 49 defines the actual computation that happens in a module. This computation typically involves getting the necessary input and generating the output.  Lines 53-54 shows how to extract input from a port. Specifically, we're getting the values passed to input ports ``value1`` and ``value2``. We then perform some
+operation with these values, and need to report the output on an output port, so that it is available for downstream modules. This is done on Line 62, where the result is set to port ``value``.
 
 .. index:: 
    pair: modules; ``ModuleError``
 
 Let us now look more carefully at the remainder of the class definition. Notice
 that developers are allowed to define extra helper methods, for example the ``op`` method on Line
-17. These helper methods can naturally use the ports
+64. These helper methods can naturally use the ports
 API. The other important feature of the ``op`` method is
 *error checking*. ``PythonCalc`` requires a string that
 represents the operation to be performed with the two numbers. If the
 string is invalid, it signals an error by simply raising a Python
-exception, ``ModuleError``, that is provided in
-``core.modules.vistrails_module``. This exception expects two
+exception, :py:class:`~.modules.vistrails_module.ModuleError`, that is provided in
+:py:mod:`vistrails.core.modules.vistrails_module`. This exception expects two
 parameters: the module that generated the exception (typically
-``self``) and a string describing the error. In the Pipeline view, this error message is displayed in the tooltip that appears when the user "mouses over" the ``PythonCalc`` module icon.
+``self``) and a string describing the error. In the Pipeline view, this error message is displayed in the tooltip that appears when the user moves the cursor over the ``PythonCalc`` module icon.
 
-.. index::
-   pair: packages; ``initialize``
-   pair: Module registry; ``add_Module``
-   pair: Module registry; ``add_input_port``
-   pair: Module registry; ``add_output_port``
-
-That is all that it takes in terms of module behavior. The rest of the
-code is meant to interact with |vistrails|, and let the system know
-about the modules and ports being exposed. To do that, you must
-provide a function called ``initialize`` in the main body of the
-package file (the function starting on Line
-27). The first thing is usually to register the
-module itself, such as on Line 33. Then, we need
-to tell |vistrails| about the input and output ports we want to
-expose.  Input ports are set with the ``add_input_port`` method
-in the registry, and output ports with ``add_output_port``. These calls take three parameters. The
-first parameter is the module you're adding a new port to. The second
-one is simply the name of the port, and the third one is a description
-of the parameter. In most cases, this is just a pair, where the
-first element is a |vistrails| module representing the module type
-being passed, and the second element is a string describing it.
-Notice that the
-types being used are |vistrails| modules (Line 35),
-and not Python types.
-
-.. %Later, we will see how to pass more complicated data types.
-
-That is it --- you have successfully created a new package and
-module. From now on, we will look at more complicated examples, and
-more advanced features of the package mechanism.
-
-Module documentation
-====================
+The final step is to specify the list of modules your package defines.  This is done via the ``_modules`` list which is simply a list of all the modules the package wishes to define.  Leaving a class out of that list will mean it will *not appear* as an available module for use in VisTrails.  That is it --- you have successfully created a new package and module. From now on, we will look at more complicated examples, and more advanced features of the package mechanism.
 
-The docstring you set on your Module subclass will be displayed to the user
-when he clicks on the 'Documentation' button in the 'Module Information' panel.
-Be sure to put a readable description and your usage information there.
+.. topic:: Note
 
-If you want to customize that documentation, you can provide a staticmethod or
-classmethod 'get_documentation' on your Module. The string it returns will be
-used as the documentation.
+   Older versions of VisTrails used explicit calls to the ModuleRegistry in an ``initialize()`` method.  These calls like ``ModuleRegistry.add_module()``, ``ModuleRegistry.add_input_port()``, and ``ModuleRegistry.add_output_port()`` are still supported though their use is discouraged as the new syntax places all attributes and configuration options in the module definition, making code more readable and localized.  The arguments available in the registry functions are mirrored in the new [...]
 
-.. code-block:: python
-   :linenos:
+Package Specification
+=====================
 
-   class TestMod(Module):
-       """This very simple module doesn't do anything sensible.
-       """
+Structure
+^^^^^^^^^
 
-       @classmethod
-       def get_documentation(cls, docstring, module=None):
-           return docstring.upper()
+A package should contain the following files inside a directory named for the package:
 
-The function receives two arguments: the string that was about to be used (the
-module's docstring or an empty string), and the module object from the
-pipeline if the documentation was requested for a specific instance of that
-module (else, None is passed).
+* ``__init__.py`` -- identifiers and configuration
+* ``init.py`` -- modules, other imports
 
-.. _fig-packages-custom_documentation:
+Optionally, it might also contain:
 
-.. figure:: figures/packages/custom_documentation.png
-   :align: center
+* ``identifiers.py`` -- the identifers might be specified here and imported in ``__init__.py``
+* ``widgets.py`` -- any GUI widgets the package's modules use
+* any other files and/or python submodules that the package depends on in
 
-Creating Reloadable Packages
-============================
+The reason for the separation between ``__init__.py`` and ``init.py`` is that |vistrails| inspects packages for identification, configurations, and information to populate the list of available packages, and for large packages with dependent libraries, including everything (including the subpackage imports) in ``__init__.py`` would take significant time.  Thus, we encourage package developers to define modules and include sub-imports only from ``init.py`` to speed up loading times.  The  [...]
 
-When creating or making changes to packages, it is often desirable to reload the package without having to restart |vistrails|.  To create a package that is reloadable, users should create a new directory for the package in ``userpackages`` directory.  This new directory should have the same name as the package and should contain an ``__init__.py`` file and an ``init.py`` file.  The identified, name, version, configuration, and package_dependencies fields/methods should be in ``__init__. [...]
+Most third-party packages should be installed into a user's :math:`\sim`\ ``/.vistrails/userpackages`` directory.  The package's ``codepath`` is the name of the directory in that userpackages directory.  A few third-party packages install into the ``packages`` directory of the |vistrails| codebase due to specific dependencies or to install for all users of the application.  If you are interested in such installation features, please contact us.
+
+The identifier, name, version, configuration, and package_dependencies fields/methods should be specified or imported into ``__init__.py``.  An example of ``__init__.py`` from |vistrails|' matplotlib package follows.
 
 .. code-block:: python
    :linenos:
 
    identifier = 'org.vistrails.vistrails.matplotlib'
    name = 'matplotlib'
-   version = '0.9.0'
+   version = '1.0.1'
+   old_identifiers = ['edu.utah.sci.vistrails.matplotlib']
 
    def package_dependencies():
-       import core.packagemanager
-       manager = core.packagemanager.get_package_manager()
-       if manager.has_package('org.vistrails.vistrails.spreadsheet'):
+       import vistrails.core.packagemanager
+       manager = vistrails.core.packagemanager.get_package_manager()
+       if manager.has_package('org.vistrals.vistrails.spreadsheet'):
            return ['org.vistrails.vistrails.spreadsheet']
        else:
            return []
 
    def package_requirements():
-       import core.requirements
-       if not core.requirements.python_module_exists('matplotlib'):
-           raise core.requirements.MissingRequirement('matplotlib')
-       if not core.requirements.python_module_exists('pylab'):
-           raise core.requirements.MissingRequirement('pylab')
-
-Imports (excluding core.configuration), other class definitions, and the initialize method should be in the ``init.py`` file.  Finally, to reload a package, select the ``reload`` button from the ``Preferences`` dialog's ``Module Packages`` tab.
-
-.. topic:: Note
-
-   To make the previous example :ref:`sec-packages-simple_example` reloadable, rather than having just one file ``pythoncalc.py``, one would have a ``pythoncalc`` directory with the "version", "name", and "identifier" lines in ``__init__.py`` and all other lines in ``init.py``.
-
-.. _sec-wrapping_cmdline_tools:
-
-Wrapping Command-line tools
-===========================
-
-.. index::
-   pair: packages; wrapping command-line tools
-
-Many existing programs are readily available through a command-line
-interface. Also, many existing workflows are first implemented
-through scripts, which work primarily with command-line
-tools. This section describes how to wrap command-line applications so
-they can be used with VisTrails. We will use as a running example the
-``afront`` package, which wraps ``afront``, a command-line program
-for generating 3D triangle meshes.  [#]_ We will wrap the basic
-functionality in three different modules: ``Afront``, ``AfrontIso``, and ``MeshQualityHistogram``.
-
-Each of these modules will be implemented by a Python
-class, and they will all invoke the ``afront`` binary.
-``Afront`` is the base execution module, and
-``AfrontIso`` requires extra parameters on top of the original
-ones. Because of this, we will implement ``AfrontIso`` as a
-subclass of ``Afront``. ``MeshQualityHistogram``,
-however, requires entirely different parameters, and so will not be
-a subclass of ``Afront``. A first attempt at writing this package might look something like this:
-
-.. code-block:: python
-   :linenos:
-
-   from core.modules.vistrails_module import Module
-   ... # other import statements
-
-   name = "Afront"
-   version = "0.1.0"
-   identifier = "edu.utah.vistrails.afront"
-
-   class Afront(Module):
-       def compute(self):
-           ... # invokes afront
-
-   class AfrontIso(Afront):
-       def compute(self):
-           ... # invokes afront with additional parameters
-
-   class MeshQualityHistogram(Module):
-       def compute(self):
-           ... # invokes afront with completely different parameters
-
-   def initialize():
-       ...
-
-Class Mixins
-^^^^^^^^^^^^
-
-While this approach is a good start, it does require significant duplication of effort. Each module must contain code to invoke the ``afront`` binary and pass it some parameters. Since this functionality is required by all three modules, we would like to put this code in a separate class called, say, ``AfrontRun``, and let each of our modules inherit from it. ``AfrontRun`` itself is not a module, and thus does not extend the ``Module`` class. So our three modules will inherit from *both* [...]
-
-.. %It should be clear that all three modules share some functionality (invoking ``afront``), but not all. We would like to avoid duplicate code, but there is not a single class where we can implement the base code. The solution is to create a *mixin class*, where we implement the necessary functionality, and then inherit from both classes. In the following snippets, we will highlight the changes in the code.
-
-.. raw:: latex
-
-   \definecolor{CodeEmph}{rgb}{0.8,0.1,0.1}
-   \newcommand{\important}[1]{\textsl{{\color{CodeEmph}#1}}}
-   \important{hi} hello
-
-.. code-block:: python
-   :linenos:
-
-   from core.modules.vistrails_module import Module, ModuleError
-   from core.system import list2cmdline
-   import os
-   
-   class AfrontRun(object):
-       _debug = False
-       def run(self, args):
-           cmd = ['afront', '-nogui'] + args
-           cmdline = list2cmdline(cmd)
-           if self._debug:
-               print cmdline
-           result = os.system(cmdline)
-           if result != 0:
-               raise ModuleError(self, "Execution failed")
-
-   class Afront(Module, AfrontRun):
-       ...
-
-   class MeshQualityHistogram(Module, AfrontRun):
-       ...
-
-.. .. parsed-literal::
-
-   from core.modules.vistrails_module import Module, ModuleError
-   :red:`from core.system import list2cmdline`
-   :red:`import os`
-   
-   :red:`class AfrontRun(object):`
-       :red:`_debug = False`
-       :red:`def run(self, args):`
-           :red:`cmd = ['afront', '-nogui'] + args`
-           :red:`cmdline = list2cmdline(cmd)`
-           :red:`if self._debug:`
-               :red:`print cmdline`
-           :red:`result = os.system(cmdline)`
-           :red:`if result != 0:`
-               :red:`raise ModuleError(self, "Execution failed")`
-
-   class Afront(Module, :red:`AfrontRun`):
-       ...
-
-   class MeshQualityHistogram(Module, :red:`AfrontRun`):
-       ...
+       import vistrails.core.requirements
+       if not vistrails.core.requirements.python_module_exists('matplotlib'):
+           raise vistrails.core.requirements.MissingRequirement('matplotlib')
+       if not vistrails.core.requirements.python_module_exists('pylab'):
+           raise vistrails.core.requirements.MissingRequirement('pylab')
 
-Now every module in the ``afront`` package has access to
-``run()``.  The other new feature in this snippet is
-``list2cmdline``, which turns a list of strings into a command
-line. It does this in a careful way (protecting arguments with spaces,
-for example). Notice that we use a call to a shell
-(``os.system()``) to invoke ``afront``. This is
-frequently the easiest way to get third-party functionality into |vistrails|.
+The ``old_identifiers`` field is used to identify packages whose identifiers have changed.  This allows |vistrails| to migrate old vistrails to the new packages.  Other imports (excluding vistrails.core.configuration), other class definitions, and the initialize method should be in the ``init.py`` file.
 
 .. _sec-pkg_config:
 
-Package Configuration
-^^^^^^^^^^^^^^^^^^^^^
+Configuration
+^^^^^^^^^^^^^
 
 .. index::
    pair: packages; configuration
 
-There are two obvious shortcomings in the way ``run()`` is
-implemented. First, the code assumes ``afront`` is available
-in the system path, which might not be true in practice. Second, the
-debugging variable is inaccessible from the GUI, where it could be
-very useful. |vistrails| provides a way to configure a package
-through the |vistrails| ``Preferences`` dialog. It is very simple to provide your own configuration;
-just add a ``configuration`` attribute to your package, as follows:
+In addition to "pure-python" packages, |vistrails| packages can also be
+designed to wrap existing libraries and command-line tools (see
+:ref:`sec-wrapping_cmdline_tools` for more information).  For
+command-line tools, there are often some configuration options that
+may change from machine to machine.  In addition, there may also be
+flags (e.g. for debugging) that a user may wish to toggle on or off
+depending on the situation.  |vistrails| provides the
+``configuration`` package attribute for such situations; the
+``ConfigurationObject`` stored here is accessible both during module
+computations and from the GUI in the ``Preferences`` dialog.
+
+In the following example, we have some code from a package designed to
+control runs of ``afront``, a command-line program for generating 3D
+triangle meshes. [#]_ It uses a general ``run()`` method to run each
+command, and we use the configuration object to determine where the
+executable lives and whether we should print debugging information.
 
 .. code-block:: python
    :linenos:
 
-   from core.configuration import ConfigurationObject
-   from core.modules.vistrails_module import Module, ModuleError
-   from core.system import list2cmdline
    import os
 
+   from vistrails.core.configuration import ConfigurationObject
+   from vistrails.core.modules.vistrails_module import Module, ModuleError
+   from vistrails.core.system import list2cmdline
+
    configuration = ConfigurationObject(path=(None, str),
                                        debug=False)
 
@@ -407,7 +257,7 @@ just add a ``configuration`` attribute to your package, as follows:
 
        def run(self, args):
            if configuration.check('path'): # there's a set directory
-               afront_cmd = configuration.path + '/afront'
+               afront_cmd = os.path.join(configuration.path, 'afront')
            else: # Assume afront is on path
                afront_cmd = 'afront'
            cmd = [afront_cmd, '-nogui'] + args
@@ -417,34 +267,6 @@ just add a ``configuration`` attribute to your package, as follows:
            ...
    ...
 
-.. .. parsed-literal::
-
-   :red:`from core.configuration import ConfigurationObject`
-   from core.modules.vistrails_module import Module, ModuleError
-   from core.system import list2cmdline
-   import os
-
-   .. _ref-packages=configconstructor1:
-   :red:`configuration = ConfigurationObject(path=(None, str),`
-   .. _ref-packages-configconstructor2:
-                                       :red:`debug=False)`
-
-   class AfrontRun(object):
-
-       def run(self, args):
-   .. _ref-packages-configurationcheck:
-           :red:`if configuration.check('path'): # there's a set directory`
-               :red:`afront_cmd = configuration.path + '/afront'`
-           :red:`else: # Assume afront is on path`
-               :red:`afront_cmd = 'afront'`
-           cmd = [:red:`afront_cmd`, '-nogui'] + args
-           cmdline = list2cmdline(cmd)
-   .. _ref-packages-configurationdebug:
-           :red:`if configuration.debug:` 
-               print cmdline
-           ...
-   ...
-
 .. index:: ``ConfigurationObject``
 
 Let us first look at how to specify configuration options. Named
@@ -483,86 +305,9 @@ To edit the value for a particular field, double-click on it, and change the
 value. The values set in this dialog are persistent across VisTrails
 sessions, being saved on a per-user basis.
 
-Temporary File Management
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. index::
-   pair: packages; temporary files
-   pair: packages; ``filePool``
-
-Command-line programs typically generate files as outputs. On
-complicated pipelines, many files get created and passed to other
-modules. To facilitate the use of files as communication
-objects, VisTrails provides basic infrastructure for temporary file
-management. This way, package developers do not have to worry about
-file ownership and lifetimes.
-
-To use this infrastructure, it must be possible to tell the program
-being called which filename to use as output. VisTrails can accommodate
-some filename requirements (in particular, specific
-filename extensions might be important in Windows environments, and
-these can be set), but it must be possible to direct the output to a
-certain filename.
-
-We will use ``Afront's compute()`` method to
-illustrate the feature.
-
-.. code-block:: python
-   :linenos:
-
-   ...
-   class Afront(Module, AfrontRun):
-           
-       def compute(self):
-           o = self.interpreter.filePool.create_file(suffix='.m')
-           args = []
-           if not self.hasInputFromPort("file"):
-               raise ModuleError(self, "Needs input file")
-           args.append(self.getInputFromPort("file").name)
-           if self.hasInputFromPort("rho"):
-               args.append("-rho")
-               args.append(str(self.getInputFromPort("rho")))
-           if self.hasInputFromPort("eta"):
-               args.append("-reduction")
-               args.append(str(self.getInputFromPort("eta")))
-           args.append("-outname")
-           args.append(o.name)
-           args.append("-tri")
-           self.run(args)
-           self.setResult("output", o)
-   ...
-
-Line 5 shows how to create a temporary file
-during the execution of a pipeline. There are a few new things
-happening, so let us look at them one at a time. Every module holds a
-reference to the current *interpreter*, the object responsible
-for orchestrating the execution of a pipeline. This object has a
-``filePool``, which is what we will use to create a pipeline,
-through the ``create_file`` method. This method takes
-optionally a named parameter ``suffix``, which forces the
-temporary file that will be created to have the right extension.
-
-The file pool returns an instance of ``basic_modules.File``,
-a module that is provided by the basic VisTrails packages. There are
-two important things you should know about ``File``. First, it
-has a ``name`` attribute that stores the name of the file it
-represents. In this case, it is the name of the
-recently-created temporary file. This allows you to safely use this
-file when calling a shell, as seen on Line 17.
-The other important feature is that it can be passed directly to an
-output port, so that this file can be used by subsequent modules. This
-is shown on Line 20.
-
-The above code also introduces the boolean function ``hasInputFromPort`` (see Lines 7, 10, and 13). This is a simple error-checking function that verifies that the port has incoming data before the program attempts to read from it. It is considered good practice to call this function before invoking ``getInputFromPort`` for any input port.
-
-**Accommodating badly-designed programs** Even though it is
-considered bad design for a command-line program not to allow the specification of an output
-filename, there do exist programs that lack this functionality. In this case, a possible
-workaround is to execute the command-line tool, and move the generated
-file to the name given by VisTrails.
 
-Interfacing with the |vistrails| Menu
-=====================================
+Menu Items
+^^^^^^^^^^
 
 As we saw in Section :ref:`sec-pkg_config`, using the ``ConfigurationObject`` class is one way to "hook" your custom package into the |vistrails| GUI.  However, this is not the only way to integrate your package with the user interface. |vistrails| also supports a mechanism whereby your package can add new options underneath the ``Packages`` menu (Figure :ref:`Packages can integrate their own commands... <fig-packages-package_menu>`).
 
@@ -613,8 +358,8 @@ The ``Packages`` menu is organized hierarchically, as illustrated in Figure :ref
 
 .. _sec-interpackage_dependencies:
 
-Interpackage Dependencies
-=========================
+Dependencies
+^^^^^^^^^^^^
 
 .. index::
    pair: packages; dependencies
@@ -643,8 +388,8 @@ The simple approach taken by the above code works well for the majority of cases
    :linenos:
 
    def package_dependencies():
-       import core.packagemanager
-       manager = core.packagemanager.get_package_manager()
+       import vistrails.core.packagemanager
+       manager = vistrails.core.packagemanager.get_package_manager()
        if manager.has_package('org.vistrails.vistrails.spreadsheet'):
            return ['org.vistrails.vistrails.spreadsheet']
        else:
@@ -653,13 +398,13 @@ The simple approach taken by the above code works well for the majority of cases
 
 The above code segment also demonstrates the |vistrails| API function ``has_package`` which simply verifies that a given package exists in the system.
 
-Package Requirements
-====================
+Requirements
+^^^^^^^^^^^^
 
 In Section :ref:`sec-interpackage_dependencies`\ , we saw how packages can depend on other packages. However, some packages may also depend on the presence of external libraries (in the form of Python modules) or executable files in order to run correctly.
 
-Required Python Modules
-^^^^^^^^^^^^^^^^^^^^^^^
+Python Modules
+--------------
 
 To check for the presence of a required Python module, you should add a function named ``package_requirements`` to your package. This function need not return any value; however it may raise exceptions or output error messages as necessary.
 Here is an example of the syntax of the ``package_requirements`` function, taken from the |vistrails| VTK package:
@@ -668,10 +413,10 @@ Here is an example of the syntax of the ``package_requirements`` function, taken
    :linenos:
 
    def package_requirements():
-       import core.requirements
-       if not core.requirements.python_module_exists('vtk'):
-           raise core.requirements.MissingRequirement('vtk')
-       if not core.requirements.python_module_exists('PyQt4'):
+       import vistrails.core.requirements
+       if not vistrails.core.requirements.python_module_exists('vtk'):
+           raise vistrails.core.requirements.MissingRequirement('vtk')
+       if not vistrails.core.requirements.python_module_exists('PyQt4'):
            print 'PyQt4 is not available. There will be no interaction',
            print 'between VTK and the spreadsheet.'
        import vtk
@@ -680,8 +425,8 @@ Here is an example of the syntax of the ``package_requirements`` function, taken
 A key element of ``package_requirements`` is the use of the function ``python_module_exists``  (see Lines 3 and 5), which checks whether a given module has been installed in your local Python system.
 
 
-Automatically Installing Python Modules
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Automatically Installation
+--------------------------
 
 A more advanced method is to attempt to install a python module
 automatically using a system package manager. This method currently
@@ -695,8 +440,8 @@ package names changed:
 .. code-block:: python
    :linenos:
 
-    from core.bundles import py_import
-    from core import debug
+    from vistrails.core.bundles import py_import
+    from vistrails.core import debug
     try:
         pkg_dict = {'linux-ubuntu': 'your-apt-package',
                     'linux-fedora': 'your-deb-package'}
@@ -707,8 +452,8 @@ package names changed:
 Note that, if you use this method, you should not specify it in the
 ``package_requirements``, because that would block the install attempt.
 
-Required Executables
-^^^^^^^^^^^^^^^^^^^^
+Executables
+-----------
 
 As explained in Section :ref:`sec-wrapping_cmdline_tools`, a common motivation for writing new |vistrails| modules is to wrap existing command-line tools. To this end, the |vistrails| API provides a function called ``executable_file_exists`` which checks for the presence of specific executables on the path.
 
@@ -717,37 +462,108 @@ Here is an example of its usage, taken from the ``initialize`` function of the `
 .. code-block:: python
    :linenos:
 
-   import core.requirements
+   import vistrails.core.requirements
 
    ...
 
-       if (not core.requirements.executable_file_exists('convert')):
-           raise core.requirements.MissingRequirement("ImageMagick suite")
+       if (not vistrails.core.requirements.executable_file_exists('convert')):
+           raise vistrails.core.requirements.MissingRequirement("ImageMagick suite")
 
 Note that this function is not strictly required in order to wrap third party executables into a module. Using a ``Configuration`` object (see Section :ref:`sec-pkg_config`) that lets the user specify the path to an executable may be a cleaner solution.
 
 For additional information or examples of any of the functions described above, please refer to the |vistrails| source code or contact the |vistrails| development team.
 
-Interaction with Caching
-========================
+Upgrades
+^^^^^^^^
+
+.. index::
+   pair: package; upgrades
+   single: upgrades
+
+When revising a package, it is important that workflows containing old
+modules can be translated to their corresponding new versions.  If no
+upgrade is explicitly specified, |vistrails| attempts to automatically
+upgrade the old module to the new version.  However, if a module's
+interface has changed (e.g. a port was added or removed or the name
+was changed), the automated upgrade will fail.  For such cases,
+|vistrails| provides hooks for developers to specify the upgrade
+paths.  The recommended method is to use the ``_upgrades`` attribute
+in the package to specify a dictionary where each key is a module name
+and the corresponding value is a list of potential upgrade paths for
+those modules.  The upgrade path is specified by an
+:py:class:`.UpgradeModuleRemap` instance which specifies the versions
+for which the upgrade is valid, the output version, the new module,
+and a set of remaps for module entities.  For example,
+
+.. code-block:: python
+   :linenos:
+
+   _upgrades = {"TestUpgradeA": 
+                [UpgradeModuleRemap('0.8', '0.9', '0.9', None,
+                                    function_remap={'a': 'aa'},
+                                    src_port_remap={'z': 'zz'}),
+                 UpgradeModuleRemap('0.9', '1.0', '1.0', None,
+                                    function_remap={'aa': 'aaa'},
+                                    src_port_remap={'zz': 'zzz'})]}
+
+Here, we have two upgrade paths for the module ``TestUpgradeA``.  The
+first works for version ``0.8`` through--but not including--``0.9``,
+and the second for ``0.9`` to ``1.0``.  The output versions are
+``0.9`` and ``1.0``, respectively, and both specify ``None`` as the
+new module type which means that the new module has the same name as
+the old one.  The new module type could also be a string representing
+a different module name.  There are four remap types:
+``function_remap``, ``src_port_remap``, ``dst_port_remap``, and
+``annotation_remap``.  Each one is a dictionary where the name of
+affected function, port, or annotation is the key and the value
+specifies either the output name (if this is just a name change) or a
+function to be used to perform the remap.  For example, one might
+write a method that transforms the value of a temperature parameter
+from Fahrenheit to Celsius.  Such a method should return a list of
+actions that accomplish this change.  Note that because the
+``dst_port_remap`` and ``function_remap`` both affect input ports, any
+remaps for ``dst_port_remap`` are also used for functions unless
+explicitly overridden.
+
+If you require more control over the upgrade process, you may also
+define a ``handle_module_upgrade_request`` method in the |vistrails|
+package.  It will be passed the controller, id of the module needing
+an upgrade, and the current pipeline as inputs, and should return a
+set of actions that will upgrade that single module to the latest
+version.
+
+Module Specification
+====================
+
+.. index:: 
+   pair: modules; customization
+
+In this section, we will explore different options for specifying modules and associated attributes, including those which affect their appearance and organization in the GUI.  Details about all of the options available for modules can be found in the :ref:`chap-api-documentation`. VisTrails provides the :py:class:`.ModuleSettings` class to offer a number of configuration options for modules.  A module should define the ``_settings`` attribute in the class to use these settings.
+
+Caching
+^^^^^^^
 
 .. index::
    pair: modules; caching
 
-VisTrails provides a caching mechanism, in which portions of pipelines that are common across different executions are automatically shared. However, some modules should not be shared. Caching control is therefore up to the package developer. By default, caching is enabled. So a developer that doesn't want caching to apply must make small changes to the module.  For example, look at the StandardOutput module:
+VisTrails provides a caching mechanism, in which portions of pipelines that are common across different executions are automatically shared. However, some modules should not be shared. Caching control is therefore up to the package developer. By default, caching is enabled. So a developer that doesn't want caching to apply must make small changes to the module.  For example, look at the ``StandardOutput`` module:
 
 .. code-block:: python
 
-   from core.modules.vistrails_module import Module, newModule, \
-       NotCacheable, ModuleError
-   (...)
+   from vistrails.core.modules.vistrails_module import Module, newModule, NotCacheable, ModuleError
+   from vistrails.core.modules.config import IPort
+
+   ...
+
    class StandardOutput(NotCacheable, Module):
        """StandardOutput is a VisTrails Module that simply prints the
        value connected on its port to standard output. It is intended
        mostly as a debugging device."""
     
+       _input_ports = [IPort(name="value", signature="basic:Module")]
+
        def compute(self):
-           v = self.getInputFromPort("value")
+           v = self.get_input("value")
            print v
 
 By subclassing from ``NotCacheable`` and ``Module`` (or one of its subclasses), we are telling VisTrails not to cache this module, or anything downstream from it.
@@ -759,100 +575,106 @@ VisTrails also allows a more sophisticated decision on whether or not to use cac
    class Unu1op(Unu):
    (...)
        def is_cacheable(self):
-           return not self.getInputFromPort('op') in ['rand', 'nrand']
+           return not self.get_input('op') in ['rand', 'nrand']
    (...)
 
 Notice that the module explicitly uses inputs to decide whether it should be cached. This allows reasonably fine-grained control over the process.
 
-Customizing Modules and Ports
-=============================
+Namespaces
+^^^^^^^^^^
 
-.. index:: 
-   pair: Module registry; ``-output_ports``
-   pair: Module registry; ``_input_ports``
-   pair: Module registry; ``_modules``
+.. index::
+   pair: modules; namespaces
 
-Here we will explore the options for registry initialization of modules and ports which was introduced in Section :ref:`sec-packages-simple_example`.  There is a new syntax for specifying modules in packages:
+:py:attr:`ModuleSettings.namespace` can be used to define a hierarchy for modules in a package that is used to organize the module palette. Hierarchies can be nested through the use of the '|' character.  For example,
 
 .. code-block:: python
    :linenos:
 
-   _modules = [MyModule1, (MyModule2, {'option_name' : 'value'})]
+   class MyModule1(Module):
+       _settings = ModuleSettings(namespace="MyNamespace")
+       ...
 
-Observe that ``_modules`` is assigned a list of modules to be registered, and module options can be provided as keyword arguments by specifying a tuple (class, kwargs).  Similarly, ports are defined by providing a list of tuples of the form (portName, portSignature, optional=False, sort_key=-1).  For example:
+   class MyModule2(Module):
+       _settings = ModuleSettings(namespace="ParentNamespace|\
+                                  ChildNamespace")
+       ...   
 
-.. code-block:: python
-   :linenos:
+Documentation
+^^^^^^^^^^^^^
 
-   class MyModule(Module):
-       def compute(self):
-          pass
+The docstring you set on your Module subclass will be displayed to the user
+when he clicks on the 'Documentation' button in the 'Module Information' panel.
+Be sure to put a readable description and your usage information there.
 
-       _input_ports = [('firstInput', String), ('secondInput', Integer, True)]
-       _output_ports = [('firstOutput', String), ('secondOutput', String)]
+If you want to customize that documentation, you can provide a staticmethod or
+classmethod 'get_documentation' on your Module. The string it returns will be
+used as the documentation.
 
-.. index::
-   pair: port; shortcut
+.. code-block:: python
+   :linenos:
 
-Notice that "String" and "Integer" were used for the portSignature instead of ``org.vistrails.vistrails.basic:String`` and ``org.vistrails.vistrails.basic:Integer``.  That is because the current package, ``org.vistrails.vistrails.basic`` is used by default.
+   class TestMod(Module):
+       """This very simple module doesn't do anything sensible.
+       """
 
-.. topic:: Note
+       @classmethod
+       def get_documentation(cls, docstring, module=None):
+           return docstring.upper()
 
-   The old syntax (reg.add_module(...), reg.add_input_port(...), and reg.add_output_port(...)) is still supported.
+The function receives two arguments: the string that was about to be used (the
+module's docstring or an empty string), and the module object from the
+pipeline if the documentation was requested for a specific instance of that
+module (else, None is passed).
 
-Configuring Modules
-^^^^^^^^^^^^^^^^^^^
+.. _fig-packages-custom_documentation:
+
+.. figure:: figures/packages/custom_documentation.png
+   :align: center
 
 .. index::
-   pair: packages; modules
    pair: modules; visibility
-   pair: modules; namespaces
+   pair: modules; abstract
 
-**Hierarchy and Visibility** There are a few options that assist in the organization and display of modules: ``namespace``,  ``abstract``, and ``hide_descriptor``.  The ``namespace`` option can be used to define a hierarchy in the module palette, which hierarchies can be nested through the use of the '|' character.  For example:
+Visibility
+^^^^^^^^^^
 
-.. code-block:: python
-   :linenos:
-
-   _modules = [MyModule1, (MyModule2, {'namespace': 'MyNamespace'})]
-    or
-   _modules = [MyModule1, (MyModule2, {'namespace': 'ParentNamespace|\
-               ChildNamespace'})]
-
-The other options, ``abstract`` and ``hide_descriptor`` can be used to prevent modules from appearing in the module palette.  ``Abstract`` is for use with modules that should never be instantiated in the workflow and will not add the item to the module palette.  On the other hand, ``hide-descriptor`` will add the item to the palette, but hides it.  This will prevent users from adding the module to a pipeline, but allow code to add it programmatically.  To use either of these options, ``a [...]
+:py:attr:`.ModuleSettings.abstract` and :py:attr:`.ModuleSettings.hide_descriptor` can be used to prevent modules from appearing in the module palette.  :py:attr:`~.ModuleSettings.abstract` is for use with modules that should never be instantiated in the workflow and will not add the item to the module palette.  On the other hand, :py:attr:`~.ModuleSettings.hide_descriptor` will add the item to the palette, but hides it.  This will prevent users from adding the module to a pipeline, but  [...]
 
 .. code-block:: python
    :linenos:
 
-   _modules = [AnotherModule, (InvisibleModule, {'abstract': True})]
-    or
-   _modules = [AnotherModule, (InvisibleModule, {'hide-descriptor': True})]
+   class AbstractModule(Module):
+       _settings = ModuleSettings(abstract=True)
+       ...
+
+   class InvisibleModule(Module):
+       _settings = ModuleSettings(hide_descriptor=True)
+       ...
 
 .. index::
    pair: modules; shape
    pair: modules; color
 
-**Defining Module Shapes and Colors**  VisTrails allows users to define custom colors and shapes to modules. This must be done at module registration time, by using the ``moduleColor`` and ``moduleFringe`` options. For example:
+Shape and Color
+^^^^^^^^^^^^^^^
+
+VisTrails allows users to assign custom colors and shapes to modules by using the :py:attr:`.ModuleSettings.color` and :py:attr:`.ModuleSettings.fringe` options. For example,
 
 .. code-block:: python
 
-   _modules = [(Afront, {'moduleColor' : (1.0, 0.0, 0.0), 
-                         'moduleFringe' : [(0.0, 0.0),
-                                           (0.2, 0.0),
-                                           (0.2, 0.4),
-                                           (0.0, 0.4),
-                                           (0.0, 1.0)]})]
+   class FancyModule(Module):
+       _settings = ModuleSettings(color=(1.0, 0.0, 0.0),
+                                  fringe=[(0.0, 0.0),
+                                          (0.2, 0.0),
+                                          (0.2, 0.4),
+                                          (0.0, 0.4),
+                                          (0.0, 1.0)])
   
-.. reg.addModule(Afront,
-                 moduleColor=(1.0,0.0,0.0),
-                 moduleFringe=[(0.0, 0.0),
-                               (0.2, 0.0),
-                               (0.2, 0.4),
-                               (0.0, 0.4),
-                               (0.0, 1.0)])
 
-gives:
+produces
 
-.. figure:: figures/packages/CustomColorShape1.png
+.. figure:: figures/packages/fancy_module1.png
    :align: center
    :width: 2in
 
@@ -860,161 +682,275 @@ and
 
 .. code-block:: python
 
-   _modules = [(Afront, {'moduleColor': (0.4,0.6,0.8),
-                         'moduleFringe' : [(0.0, 0.0),
-                                           (0.2, 0.0),
-                                           (0.0, 0.2),
-                                           (0.2, 0.4),
-                                           (0.0, 0.6),
-                                           (0.2, 0.8),
-                                           (0.0, 1.0)]})]
-
-..   reg = core.modules.module_registry
-..   reg.addModule(Afront,
-                 moduleColor=(0.4,0.6,0.8),
-                 moduleFringe=[(0.0, 0.0),
-                               (0.2, 0.0),
-                               (0.0, 0.2),
-                               (0.2, 0.4),
-                               (0.0, 0.6),
-                               (0.2, 0.8),
-                               (0.0, 1.0)])
-
-gives:
-
-.. figure:: figures/packages/CustomColorShape2.png
+   class FancyModule2(Module):
+       _settings = ModuleSettings(color=(0.4,0.6,0.8),
+                                  fringe=[(0.0, 0.0),
+                                          (0.2, 0.0),
+                                          (0.0, 0.2),
+                                          (0.2, 0.4),
+                                          (0.0, 0.6),
+                                          (0.2, 0.8),
+                                          (0.0, 1.0)])
+
+produces
+
+.. figure:: figures/packages/fancy_module2.png
    :align: center
    :width: 2in
 
-The moduleColor parameter must be a tuple of three floats between 0 and 1 that specify RGB colors for the module background, while moduleFringe is a list of pairs of floats that specify points as they go around a side of the module (the same one is used to go from the top-right corner to bottom-right corner, and from the bottom-left corner to the top-left one. If this is not enough, let the developers know!)
+The :py:attr:`.ModuleSettings.color` parameter must be a tuple of three floats between 0 and 1 that specify RGB colors for the module background, while :py:attr:`.ModuleSettings.fringe` is a list of pairs of floats that specify points as they go around a side of the module (the same one is used to go from the top-right corner to bottom-right corner, and from the bottom-left corner to the top-left one. If this is not enough, let the developers know!)
 
-Alternatively, you can use different fringes for the left and right borders:
+Alternatively, you may use different fringes for the left and right borders:
 
 .. code-block:: python
 
-   _modules = [(Afront, {'moduleColor': (1.0,0.8,0.6),
-                         'moduleLeftFringe' : [(0.0, 0.0),
+   class FancyModule3(Module):
+       _settings = ModuleSettings(color=(1.0,0.8,0.6),
+                                  left_fringe=[(0.0, 0.0),
                                                (-0.2, 0.0),
                                                (0.0, 1.0)],
-                         'moduleRightFringe' : [(0.0, 0.0),
+                                  right_fringe=[(0.0, 0.0),
                                                 (0.2, 1.0),
-                                                (0.0, 1.0)]})]
-
-
-..   reg.addModule(Afront,
-                 moduleColor=(1.0,0.8,0.6),
-                 moduleLeftFringe=[(0.0, 0.0),
-                                   (-0.2, 0.0),
-                                   (0.0, 1.0)],
-                 moduleRightFringe=[(0.0, 0.0),
-                                    (0.2, 1.0),
-                                    (0.0, 1.0)])
+                                                (0.0, 1.0)])
 
-.. figure:: figures/packages/CustomColorShape3.png
+.. figure:: figures/packages/fancy_module3.png
    :align: center
    :width: 2in
 
-Configuring Ports
-^^^^^^^^^^^^^^^^^
+.. _sec-configuration-widgets:
+
+Configuration Widgets
+^^^^^^^^^^^^^^^^^^^^^
+
+.. index::
+   pair: modules; widgets
+   pair: modules; configuration
+
+
+There are two types of widgets that are associated with modules.  The first, the *module configuration widget*, is available to all modules regardless of inheritance.  This type of widget allows users to configure modules in ways other than with the ports list in the Module Information panel.  For example, the ``PythonSource`` module uses a special widget that allows users to add ports as well as write code in a editor with line numbers and highlighting features.  Developers wishing to c [...]
+
+The second type of widget is the *constant configuration widget* which can only be defined for constant modules, that is those which subclass from ``vistrails.core.modules.basic_modules.Constant``.  When such a module is used as the type of an input port, the user is allowed to edit the value in the ports list of the Module Information panel.  The constant configuration widget is used to display and allow the user to edit the value of a parameter.  The default widget is a simple line edi [...]
+
+Creation
+--------
+
+Developers may build new constant configuration widgets using the ``vistrails.gui.modules.constant_configuration.ConstantWidgetBase`` or ``vistrails.gui.modules.constant_configuration.ConstantEnumWidgetBase`` base classes.  **Note** that these base classes should be the *second* base class listed; the first should be a *QWidget* subclass.  ``ConstantWidgetBase`` is intended for use with "normal"  while ``ConstantEnumWidgetBase`` is intended for use with ports where the possible values ar [...]
+
+As an example, consider the following widget:
+
+.. code-block:: python
+    :linenos:
+
+    from PyQt4 import QtCore, QtGui
+    from vistrails.gui.modules.constant_configuration import ConstantEnumWidgetBase
+
+    class NumericSliderWidget(QtGui.QSlider, ConstantEnumWidgetBase):
+        def __init__(self, param, parent=None):
+            QtGui.QSlider.__init__(self, parent)
+            self.setOrientation(QtCore.Qt.Horizontal)
+            self.setTracking(False)
+            self.setTickPosition(QtGui.QSlider.TicksBelow)
+            ConstantEnumWidgetBase.__init__(self, param)
+            self.connect(self, QtCore.SIGNAL("valueChanged(int)"),
+                         self.update_parent)
+
+        def setValues(self, values):
+            self.setMinimum(int(values[0]))
+            self.setMaximum(int(values[1]))
+
+        def contents(self):
+            return unicode(self.value())
+
+        def setContents(self, contents, silent=True):
+            if contents:
+                self.setValue(int(contents))
+                if not silent:
+                    self.update_parent()
+
+Registration
+------------
+
+To make |vistrails| aware of these new widgets, developers should specifying them in the :py:class:`.ModuleSettings` options.  For example,
+
+.. code-block:: python
+    :linenos:
+    
+    class TestWidgets(Constant):
+        _settings = ModuleSettings(configure_widget="widgets:MyWidget",
+	                           constant_widget="widgets:ConstWgt")
+
+Note that the ``PathString`` is best specified relative to the base path of the package.  **Important:** If ``MyWidget`` is defined in the ``widgets`` module of the ``test_widgets`` package in ``userpackages``, its full path might be ``userpackages.test_widgets.widgets:MyWidget``, but we only include the inner path (``widgets:MyWidget``).  (The full path is used for internal packages, but this should be avoided for third-party packages.)
+
+For constant widgets, |vistrails| allows users to associate different widgets with different *uses*.  A widget used for query may differ from the default display & edit widget, and developers may specify different widgets for these uses.  Current uses include "query" and "paramexp" (parameter exploration). In addition, individual ports may specify different constant widgets using the :py:attr:`.InputPort.entry_type` setting.  These specifications are tied to the widget's *type*.  To spec [...]
+
+.. code-block:: python
+    :linenos:
+
+    class TestWidgets(Constant):
+        _settings = ModuleSettings(constant_widgets=[
+            ConstantWidgetConfig(widget="widgets:MyEnumWidget",
+                                 widget_type="enum"),
+            QueryWidgetConfig(widget="widgets:MyQueryWidget")])
+
+Note that if a query or parameter exploration widget is not specified, |vistrails| will generically adapt the default widget for those uses so you do not need to create a widget for each use.  
+
+Port Specification
+==================
 
 .. index::
    pair: packages; ports
    pair: ports; default values
    pair: ports; labels
 
-**Default Values and Labels** In versions 1.4 and greater, package developers can add labels and default values for parameters. To add this functionality, you need to use the defaults and labels keyword arguments and pass the values as strings. For example,
+Defaults and Labels
+^^^^^^^^^^^^^^^^^^^
+
+In versions 2.0 and greater, package developers can add labels and default values for parameters. To add this functionality, you need to use the default(s) and label(s) keyword arguments. For example,
 
 .. code-block:: python
    :linenos:
 
    class TestDefaults(Module):
-      _input_ports = [('f1', '(org.vistrails.vistrails.basic:Float,\
-                               org.vistrails.vistrails.basic:String)',
-                       {"defaults": str([1.23, "abc"]), 
-                        "labels": str(["temp", "name"])})]
-   _modules = [TestDefaults]
-
-or in the older syntax,
+      _input_ports = [IPort('word', 'basic:String',
+                            default="Hello",
+                            label="greeting"),
+                      CIPort('center', 'basic:Float, basic:Float',
+                             defaults=[10.0, 10.0], labels=["x", "y"])]
 
-.. code-block:: python
-   :linenos:
-
-   def initialize():
-     reg = core.modules.module_registry.get_module_registry()
-     reg.add_module(TestDefaults)
-     reg.add_input_port(TestDefaults, "f1", [Float, String], 
-                        defaults=str([1.23, "abc"]), 
-                        labels=str(["temp", "name"]))
+Note that simple ports use the singular :py:attr:`.InputPort.default` and :py:attr:`.InputPort.label` kwargs while compound input ports use *plural* forms, :py:attr:`.CompoundInputPort.defaults` and :py:attr:`.CompoundInputPort.labels`.
 
 .. index::
    pair: ports; optional
 
-**Making a Port Optional**  To add a port that is optional, set the optional flag to true:
+Optional Ports
+^^^^^^^^^^^^^^
+
+An optional port is one that will not be visible by default in the module shape.  For modules with many ports, developers might less-used ports optional to reduce clutter.  To make a port optional, set the :py:attr:`~.config.InputPort.optional` flag to true:
 
 .. code-block:: python
    :linenos:
+   
+   class ModuleWithManyPorts(Module):
+        _input_ports = [IPort('Port14', 'basic:String',
+                              optional=True)]
+
+.. index::
+   pair: ports; cardinality
 
-   _input_ports = [('MyPort', '(org.vistrails.vistrails.basic:String)',
-                       {"optional": True})]
+Cardinality
+^^^^^^^^^^^
 
-   reg.add_input_port(MyModule, "MyPort", 
-                      "(org.vistrails.vistrails.basic:String)", 
-                      optional=True)
+By default, ports will accept any number of connections or parameters.  However, the :py:meth:`.Module.get_input` method will only access *one* of the inputs, and which one is not well-defined.  To access *all* of the inputs, developers should use the :py:meth:`.Module.get_input_list` method.  The spreadsheet package uses this feature, so look there for usage examples (vistrails/packages/spreadsheet/basic_widgets.py)
 
+In addition, VisTrails 2.1 introduced new port configuration arguments :py:attr:`~.config.InputPort.min_conns` and :py:attr:`~.config.InputPort.max_conns` that allow developers to enforce specific cardinalities on their ports.  For example, a port that required at least two inputs could set ``min_conns=2``, and a port that does not accept more than a single input could set ``max_conns=1``.  Currently, the values for :py:attr:`~.config.InputPort.min_conns` and :py:attr:`~.config.InputPort [...]
 
 .. index::
-   pair: ports; multiple inputs
+   pair: ports; shape
 
-**Multiple Inputs** For compatibility reasons, we do need to allow multiple connections to an input port. However, most package developers should never have to use this, and so we do our best to hide it. the default behavior for getting inputs from a port, then, is to always return a single input.
+Shape
+^^^^^
 
-If on your module you need multiple inputs connected to a single port, use the 'forceGetInputListFromPort' method. It will return a list of all the data items coming through the port. The spreadsheet package uses this feature, so look there for usage examples (vistrails/packages/spreadsheet/basic_widgets.py)
+As with modules, port shape can also be customized.  There are three basic types besides the default square, "triangle", "circle", and "diamond".  Such types are specified as string values to the :py:attr:`~.config.InputPort.shape` setting.  In addition, the triangle may be rotated by appending the degree of rotation (90, 180, or 270 only!) in the string.  Finally, custom shapes are supported in a similar fashion to the module fringe.  The shape should be defined in the [0,1] x [0,1] dom [...]
+
+.. code-block:: python
+    :linenos:
+
+    class FancyPorts(Module):
+        _input_ports = [IPort("normal", "basic:Float"),
+                        IPort("triangle", "basic:Float",
+                              shape="triangle"),
+                        IPort("triangle90", "basic:Float",
+                              shape="triangle90"),
+                        IPort("circle", "basic:Float",
+                              shape="circle"),
+                        IPort("diamond", "basic:Float",
+                              shape="diamond"),
+                        IPort("pentagon", "basic:Float",
+                              shape=[(0.0, 0.0), (0.0, 0.66), 
+			             (0.5, 1.0), (1.0, 0.66), 
+				     (1.0, 0.0)])]
+
+This produces a module with ports that look like the following figure:
+
+.. figure:: figures/packages/fancy_ports.png
+   :align: center
+   :width: 2in
 
 .. index::
-   pair: ports; port types
+   pair: ports; signatures
 
-**Port Types** To define ports to be of types that are not imported into the package, pass and identifier string as the portSignature:
+Signatures
+^^^^^^^^^^
+
+We recommend using strings to define ports, but we still allow the actual classes to be used instead for backward compatibility.  For example,
 
 .. code-block:: python
    :linenos:
 
-   <module_string> := <package_identifier>:[<namespace>|]<module_name>,
-   <port_signature> := (<module_string>*)
+   from vistrails.core.modules.basic_modules import String
 
-For example,
+   class MyModule(Module):
+       _input_ports = [IPort("a", String)]
+
+
+This is **not recommended** for non-basic types due to the required import of the dependent package modules.  If a package develoepr wants to use a module from another package, they must determine where in that package the module is defined, import that specific module, and then hope that future versions of that package do not change the location of that module.  String-based signatures do not face the same issues as code reorganization is independent of the package definition.  The gram [...]
 
 .. code-block:: python
+   :linenos:
 
-   registry.add_input_port(MyModule, 'myInputPort', \
-                           '(org.vistrails.vistrails.basic:String)')
+   <module_string> := <package_identifier>:[<namespace>|]<module_name>
+   <port_signature> := "<module_string>"
 
-or
+and for a compound port:
 
 .. code-block:: python
+   :linenos:
 
-   _input_ports = [('myInputPort', '(org.vistrails.vistrails.basic:String)')]
+   <compound_string> := ,<module_string>
+   <port_signature> := "<module_string><compound_string>*"
+
+
+For example,
+
+.. code-block:: python
+
+   class MyModule(Module):
+       _input_ports = ("myInputPort", "org.suborg.pkg_name:Namespace|ModuleB")
 
 .. index::
-   pair: ports; input dependency
+   pair: ports; variant
+
+Variable Output
+^^^^^^^^^^^^^^^
 
-**Varying Output According to the Input** There are a few ways to tackle this - each has it's own benefits and pitfalls. Firstly, module connections do respect class hierarchies as we're familiar with in object oriented languages. For instance, A module can output a Constant of which String, Float, Integer, etc are specifications. In this way, you can have a subclass of something like MyData be passed out of the module and the connections will be established regardless of the sub-type. T [...]
+There may be cases where a port may output values of different types. There are a few ways to tackle this--each has its own benefits and pitfalls. Because |vistrails| modules obey inheritance principles, a port of a given type may produce/accept subclasses of itself.  For example, an output port of type ``Constant`` may output ``String``, ``Float``, or ``Integer`` values since all are subclasses of ``Constant``.  For input ports, ``Module`` (the base class for all modules) is the most ge [...]
+
+.. code-block:: python
+    :linenos:
 
-A second method that is employed in several different packages is the idea of a container class. For instance, the NumSciPy package uses a relatively generic container "Numpy Array" to encapsulate the data. Of course, these encapsulating objects can store dictionaries that other modules can easily access and understand how to operate on. Although this method is slightly more work, the benefits of a stricter typing of ports is beneficial - particularly upon interfacing with other packages [...]
+    class GetItem(Module):
+        _input_ports = [IPort("list", "basic:List"),
+	                IPort("index", "basic:Integer")]
+        _output_ports = [OPort("value", "basic:Variant")]
 
 .. index::
-   pair: ports; module connectivity
+   pair: ports; connectivity
 
-**Determining Whether or Not a Module is Attached to an Output Port** The outputPorts dictionary of the base Module stores connection information. Thus, you should be able to check
+Connectivity
+^^^^^^^^^^^^
+
+In some cases, it may be desirable to know which outputs are used before running a computation.  The ``outputPorts`` dictionary of the module stores connection information. Thus, you should be able to check
 
 ``("myPortName" in self.outputPorts)``
 
-on the parent module to check if there are any downstream connections from the port "myPortName". This might be used, for example, to only set results for output ports that will be used. **Note**, however, that the caching algorithm assumes that all outputs are set so adding a new connection to a previously unconnected output port will not work as desired if that module is cached. For this reason, I would currently recommend making such a module not cacheable. Another possibility is over [...]
+on the parent module to check if there are any downstream connections from the port "myPortName". **Note**, however, that the caching algorithm assumes that all outputs are computed so adding a new connection to a previously unconnected output port will not work as desired if that module is cached. For this reason, we would currently recommend making such a module not cacheable. Another possibility is overriding the ``update()`` method to check the output ports and set the ``upToDate`` f [...]
 
 .. code-block:: python
    :linenos:
 
    class TestModule(Module):
-       _output_ports = [('a1', '(org.vistrails.vistrails.basic:String)'),
-                        ('a2', '(org.vistrails.vistrails.basic:String)')]
+       _output_ports = [('a1', 'basic:String'),
+                        ('a2', 'basic:String')]
        def __init__(self):
            Module.__init__(self)
            self._cached_output_ports = set()
@@ -1026,9 +962,9 @@ on the parent module to check if there are any downstream connections from the p
     
        def compute(self):
            if "a1" in self.outputPorts:
-               self.setResult("a1", "test")
+               self.set_output("a1", "test")
            if "a2" in self.outputPorts:
-               self.setResult("a2", "test2")
+               self.set_output("a2", "test2")
            self._cached_output_ports = set(self.outputPorts)
 
 Generating Modules Dynamically
@@ -1044,9 +980,9 @@ When wrapping existing libraries or trying to generate modules in a more procedu
 .. code-block:: python
    :linenos:
 
-   from core.configuration import ConfigurationObject
+   from vistrails.core.configuration import ConfigurationObject
  
-   identifier = "org.vistrails.dakoop.auto_example"
+   identifier = "org.vistrails.examples.auto_example"
    version = "0.0.1"
    name = "AutoExample"
  
@@ -1059,9 +995,9 @@ The expand_ports and build_modules methods are functions to help the constructio
 .. code-block:: python
    :linenos:
 
-   from core.modules.vistrails_module import new_module, Module
+   from vistrails.core.modules.vistrails_module import new_module, Module
  
-   identifier = "org.vistrails.dakoop.auto_example"
+   identifier = "org.vistrails.examples.auto_example"
  
    def expand_ports(port_list):
        new_port_list = []
@@ -1130,13 +1066,13 @@ The expand_ports and build_modules methods are functions to help the constructio
    def initialize():
        global _modules
        def a_compute(self):
-           a = self.getInputFromPort("a")
+           a = self.get_input("a")
            i = 0
-           if self.hasInputFromPort("i"):
-               i = self.getInputFromPort("i")
+           if self.has_input("i"):
+               i = self.get_input("i")
            if a == "abc":
                i += 100
-           self.setResult("b", i)
+           self.set_output("b", i)
  
        module_descs = [("ModuleA", {"_inputs": [("a", "basic:String")],
                                     "_outputs": [("b", "basic:Integer")],
@@ -1155,13 +1091,217 @@ The expand_ports and build_modules methods are functions to help the constructio
  
    _modules = []
 
+.. _sec-wrapping_cmdline_tools:
+
+Wrapping Command-line tools
+===========================
+
+.. index::
+   pair: packages; wrapping command-line tools
+
+Many existing programs are readily available through a command-line
+interface. Also, many existing workflows are first implemented
+through scripts, which work primarily with command-line
+tools. This section describes how to wrap command-line applications so
+they can be used with VisTrails. We will use as a running example the
+``afront`` package, which wraps ``afront``, a command-line program
+for generating 3D triangle meshes.  We will wrap the basic
+functionality in three different modules: ``Afront``, ``AfrontIso``, and ``MeshQualityHistogram``.
+
+Each of these modules will be implemented by a Python
+class, and they will all invoke the ``afront`` binary.
+``Afront`` is the base execution module, and
+``AfrontIso`` requires extra parameters on top of the original
+ones. Because of this, we will implement ``AfrontIso`` as a
+subclass of ``Afront``. ``MeshQualityHistogram``,
+however, requires entirely different parameters, and so will not be
+a subclass of ``Afront``. A first attempt at writing this package might look something like this:
+
+**__init__.py**
+
+.. code-block:: python
+   :linenos:
+
+   name = "Afront"
+   version = "0.1.0"
+   identifier = "edu.utah.sci.vistrails.afront"
+
+**init.py**
+
+.. code-block:: python
+   :linenos:
+
+   from vistrails.core.modules.vistrails_module import Module
+   ... # other import statements
+
+   class Afront(Module):
+       def compute(self):
+           ... # invokes afront
+
+   class AfrontIso(Afront):
+       def compute(self):
+           ... # invokes afront with additional parameters
+
+   class MeshQualityHistogram(Module):
+       def compute(self):
+           ... # invokes afront with completely different parameters
+
+   _modules = [Afront, AfrontIso, MeshQualityHistogram, ...]
+
+Class Mixins
+^^^^^^^^^^^^
+
+While this approach is a good start, it does require significant duplication of effort. Each module must contain code to invoke the ``afront`` binary and pass it some parameters. Since this functionality is required by all three modules, we would like to put this code in a separate class called, say, ``AfrontRun``, and let each of our modules inherit from it. ``AfrontRun`` itself is not a module, and thus does not extend the ``Module`` class. So our three modules will inherit from *both* [...]
+
+.. %It should be clear that all three modules share some functionality (invoking ``afront``), but not all. We would like to avoid duplicate code, but there is not a single class where we can implement the base code. The solution is to create a *mixin class*, where we implement the necessary functionality, and then inherit from both classes. In the following snippets, we will highlight the changes in the code.
+
+.. raw:: latex
+
+   \definecolor{CodeEmph}{rgb}{0.8,0.1,0.1}
+   \newcommand{\important}[1]{\textsl{{\color{CodeEmph}#1}}}
+   \important{hi} hello
+
+.. code-block:: python
+   :linenos:
+
+   from vistrails.core.modules.vistrails_module import Module, ModuleError
+   from vistrails.core.system import list2cmdline
+   import os
+   
+   class AfrontRun(object):
+       _debug = False
+       def run(self, args):
+           cmd = ['afront', '-nogui'] + args
+           cmdline = list2cmdline(cmd)
+           if self._debug:
+               print cmdline
+           result = os.system(cmdline)
+           if result != 0:
+               raise ModuleError(self, "Execution failed")
+
+   class Afront(Module, AfrontRun):
+       ...
+
+   class MeshQualityHistogram(Module, AfrontRun):
+       ...
+
+.. .. parsed-literal::
+
+   from vistrails.core.modules.vistrails_module import Module, ModuleError
+   :red:`from vistrails.core.system import list2cmdline`
+   :red:`import os`
+   
+   :red:`class AfrontRun(object):`
+       :red:`_debug = False`
+       :red:`def run(self, args):`
+           :red:`cmd = ['afront', '-nogui'] + args`
+           :red:`cmdline = list2cmdline(cmd)`
+           :red:`if self._debug:`
+               :red:`print cmdline`
+           :red:`result = os.system(cmdline)`
+           :red:`if result != 0:`
+               :red:`raise ModuleError(self, "Execution failed")`
+
+   class Afront(Module, :red:`AfrontRun`):
+       ...
+
+   class MeshQualityHistogram(Module, :red:`AfrontRun`):
+       ...
+
+Now every module in the ``afront`` package has access to
+``run()``.  The other new feature in this snippet is
+``list2cmdline``, which turns a list of strings into a command
+line. It does this in a careful way (protecting arguments with spaces,
+for example). Notice that we use a call to a shell
+(``os.system()``) to invoke ``afront``. This is
+frequently the easiest way to get third-party functionality into |vistrails|.
+
+Temporary File Management
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. index::
+   pair: packages; temporary files
+   pair: packages; ``filePool``
+
+Command-line programs typically generate files as outputs. On
+complicated pipelines, many files get created and passed to other
+modules. To facilitate the use of files as communication
+objects, VisTrails provides basic infrastructure for temporary file
+management. This way, package developers do not have to worry about
+file ownership and lifetimes.
+
+To use this infrastructure, it must be possible to tell the program
+being called which filename to use as output. VisTrails can accommodate
+some filename requirements (in particular, specific
+filename extensions might be important in Windows environments, and
+these can be set), but it must be possible to direct the output to a
+certain filename.
+
+We will use ``Afront's compute()`` method to
+illustrate the feature.
+
+.. code-block:: python
+   :linenos:
+
+   ...
+   class Afront(Module, AfrontRun):
+           
+       def compute(self):
+           o = self.interpreter.filePool.create_file(suffix='.m')
+           args = []
+           if not self.has_input("file"):
+               raise ModuleError(self, "Needs input file")
+           args.append(self.get_input("file").name)
+           if self.has_input("rho"):
+               args.append("-rho")
+               args.append(str(self.get_input("rho")))
+           if self.has_input("eta"):
+               args.append("-reduction")
+               args.append(str(self.get_input("eta")))
+           args.append("-outname")
+           args.append(o.name)
+           args.append("-tri")
+           self.run(args)
+           self.set_output("output", o)
+   ...
+
+Line 5 shows how to create a temporary file
+during the execution of a pipeline. There are a few new things
+happening, so let us look at them one at a time. Every module holds a
+reference to the current *interpreter*, the object responsible
+for orchestrating the execution of a pipeline. This object has a
+``filePool``, which is what we will use to create a pipeline,
+through the ``create_file`` method. This method takes
+optionally a named parameter ``suffix``, which forces the
+temporary file that will be created to have the right extension.
+
+The file pool returns an instance of ``basic_modules.File``,
+a module that is provided by the basic VisTrails packages. There are
+two important things you should know about ``File``. First, it
+has a ``name`` attribute that stores the name of the file it
+represents. In this case, it is the name of the
+recently-created temporary file. This allows you to safely use this
+file when calling a shell, as seen on Line 17.
+The other important feature is that it can be passed directly to an
+output port, so that this file can be used by subsequent modules. This
+is shown on Line 20.
+
+The above code also introduces the boolean function ``has_input`` (see Lines 7, 10, and 13). This is a simple error-checking function that verifies that the port has incoming data before the program attempts to read from it. It is considered good practice to call this function before invoking ``get_input`` for any input port.
+
+**Accommodating badly-designed programs** Even though it is
+considered bad design for a command-line program not to allow the specification of an output
+filename, there do exist programs that lack this functionality. In this case, a possible
+workaround is to execute the command-line tool, and move the generated
+file to the name given by VisTrails.
+
+
 For System Administrators
 =========================
 Most users will want to put their custom packages in their
 
  :math:`\sim`\ ``/.vistrails/userpackages``
 
-directory, as described in Section :ref:`sec-packages-simple_example`. This makes the package available to the current user only. However, if you are a power user or a system administrator, you may wish to make certain packages available to all users of a |vistrails| installation. To do this, copy the appropriate package files and/or directories to the
+directory, as described in Section :ref:`sec-packages-simple-example`. This makes the package available to the current user only. However, if you are a power user or a system administrator, you may wish to make certain packages available to all users of a |vistrails| installation. To do this, copy the appropriate package files and/or directories to the
 
  ``vistrails/packages``
 
diff --git a/doc/usersguide/parameter_widgets.rst b/doc/usersguide/parameter_widgets.rst
new file mode 100644
index 0000000..dfb4922
--- /dev/null
+++ b/doc/usersguide/parameter_widgets.rst
@@ -0,0 +1,73 @@
+.. _chap-parameter-widgets:
+
+*****************
+Parameter Widgets
+*****************
+
+.. index::  parameter widgets
+
+Introduction to Parameter Widgets
+=================================
+
+Parameter widgets are editable parameters inside modules in the pipeline
+view. They can be used to give an overview of the parameters in a workflow, or to
+quickly edit parameters without the usual clicking on a module and selecting
+the parameter in the 'Module Info' panel.
+:ref:`Figure 1 <fig-edit-widgets-example>` shows a complete workflow
+using parameter widgets. :vtl:`(open in vistrails) <parameter_widgets.vt>`
+
+.. _fig-edit-widgets-example:
+
+.. figure:: figures/edit_widgets/edit-widgets.png
+   :align: center
+   :width: 100%
+
+   Figure 1 - Complex Workflow with Parameter Widgets.
+
+Enabling Parameter Widgets
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Parameter widgets are hidden by default, but can be enabled by toggling the
+pencil icon in the 'Module Info' panel (See :ref:`Figure 2 <fig-enabling-edit-widgets>`).
+This will show all existing parameter widgets as well as the pencil icons
+in 'Module Info' for adding new ones.
+
+.. _fig-enabling-edit-widgets:
+
+.. figure:: figures/edit_widgets/enabling-edit-widgets.png
+   :align: center
+   :width: 30%
+
+   Figure 2 - How to enable/disable the Parameter Widgets mode.
+
+Adding a parameter widget to a module
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A parameter widget can be enabled or disabled in the 'Module Info' panel by
+toggling the pencil icon (See :ref:`Figure 3 <fig-edit-widget>`). Only
+parameters of constant type that have widgets for editing can be added.
+
+Constant modules such as String and Integer show a parameter widget for 'value'
+by default, but it can be removed using the 'Module Info' panel if needed.
+
+.. _fig-edit-widget:
+
+.. figure:: figures/edit_widgets/edit-widget.png
+   :align: center
+   :width: 60%
+
+   Figure 3 - How to add/remove Parameter Widgets from modules.
+
+Limitations
+^^^^^^^^^^^
+
+On some platforms (Such as Mac) some parameter widgets may look unsharp or
+pixelated. This is because no widget for that type has been created for use
+in the pipeline view, and the default one from the 'Module Info' pane has been used instead.
+
+Only one parameter widget per port can be visible right now. In the 'Module Info' pane it is
+possible to specify several function parameters for each port.
+
+Zooming out will hide all the edit widgets for performance reasons, it would also
+be difficult to edit anything in that size.
+
diff --git a/doc/usersguide/persistence.rst b/doc/usersguide/persistence.rst
deleted file mode 100644
index f65570a..0000000
--- a/doc/usersguide/persistence.rst
+++ /dev/null
@@ -1,165 +0,0 @@
-.. _chap-persistence:
-
-*************************
-Persistence in VisTrails
-*************************
-
-.. index::persistence
-
-The ``Persistence`` package in Vistrails helps improve reproducibility by associating versions of data files with their provenance, and minimize the need to rerun lengthy executions by keeping intermediate persistent files. 
-Although, we will focus primarily on the use of persistent files, persistent directories are used in the same manner.  The difference is that a persistent directory deals with multiple files within a directory rather than a single file.
-
-Getting Started With Persistence
-================================
-
-A persistent file is simply a file that is kept in a repository and identified by an id and version string and annotated with a signature and content hash.  To begin, notice that there are three persistent file/directory types: input, intermediate, and output. It is helpful to understand the differences among these files as well as their distinguishing characteristics and configuration options.
-
-Input Files
-^^^^^^^^^^^
-
-.. index::
-   pair: persistent files; input
-
-To use a persistent input file, after dragging it onto the canvas, it is necessary to edit the configuration (Ctrl+E).  For an input file, one can either create a new reference to an existing local file, or use a file that exists in the database.  To create a new reference, select ``Create New Reference`` and either enter the path to the file, or select the folder icon on the right to browse local directories for a file.  Then, give the file a name and any appropriate tags to help identi [...]
-
-.. topic:: Note
-
-   A new version of a persistent file is created each time its contents change.  A persistent input file will always use the most recent version of a file if it is assigned to the root of the file tree.
-
-The ``PersitentInputFile`` module can also be used to read or write data directly from or to a local file.  To use this feature, you will need to set ``localPath`` to point to a local file.  This can be done in the Set Methods Panel, the Configuration Dialog, or by connecting a file to the localPath input port.  Then, the local file will be read when readLocal is set to true and written when writeLocal is set to true.  To do this using the Configuration Dialog, select ``Keep Local Versio [...]
-
-Output Files
-^^^^^^^^^^^^
-
-.. index::
-   pair: persistent files; output
-
-To use a persistent output file, after dragging it onto the canvas, it is necessary to edit the configuration (Ctrl+E).  Notice that the Configuration Dialog for the output file is the same as that of the input file except that an option to ``Always Create New Reference`` exists.  Selecting this new option will cause a new file to be created and added to the persistent store each time the workflow is executed.  The new file does not get a name or tag, so it can be difficult to identify t [...]
-
-If you prefer to have a new version of the file created each time the workflow is changed rather than executed, you should choose either of the other options (``Create New Reference``, or ``Use Existing Reference``).  The other two options and the option to read from or write to a local path are used in the same manner as with the input file.  However, when the input file is read from a local path, it is not also read from the persistent store.  In contrast, when an output file is writte [...]
-
-Intermediate Files
-^^^^^^^^^^^^^^^^^^
-
-.. index::
-   pair: persistent files; intermediate
-
-An intermediate file is the same as the output file except that its contents can be used in further calculations.  Thus, lengthy computations upstream of the intermediate file will only be recalculated when the upstream workflow changes, but will not need to be rerun when only the downstream workflow changes.  Intermediate files by default are set to always create a new reference.  Since these files do not need to be manually annotated or named, configuration is optional, but is the same [...]
-
-Using the Output of One Workflow as Input for Another
-=====================================================
-
-You need to configure the persistence modules using the module's configuration dialog. After adding a PersistentOutputFile to the workflow, click on the triangle in the upper-right corner of the PersistentOutputFile, and select "Edit Configuration" from the menu that appears. In this dialog, select "Create New Reference" and give the reference a name (and any space-delimited tags). Upon running that workflow, the data will be written to the persistent store. In the second workflow where  [...]
-
-Managing Files in the Store
-===========================
-
-You may manage the files in the store by selecting ``Packages -> Persistence -> Manage Store``.  You are then free to save files from the store to local files, or delete files from the store.  However, please be aware that files deleted from the store are not recoverable.  Also, for versioned files, a specific version of a file can not be deleted without deleting all versions of that file.  To delete all versions of the file, select the root version and press ``Delete``.
-
-Examples
-========
-
-.. topic:: Try it Now!
-
-   **Base Workflow**
-
-   1) Drag the following modules to the canvas and connect them in the order in which they are named:  ``HTTPFile``, ``vtkUnstructuredGridReader``, ``vtkDataSetMapper``, ``vtkActor``, ``vtkRenderer``, ``VTKRenderOffscreen``.  Refer to Figure :ref:`Example 1.1 <fig-pers-example-base>` to ensure connections are correct.
-
-   2) Select the ``HTTPFile`` module and set the url to: 
-      
-      http://www.vistrails.org/download/download.php?type=DATA&id=spx.vtk
-
-   3) (Optional) Select the ``vtkRenderer`` module and select ``SetBackgroungWidget`` from the ``Module Information's`` ``Inputs`` tab.  Select the background color of your choice.
-
-   **Persistent Output**
-
-   4) Switch to the ``History`` view and tag the current version as "Base Workflow".  Then, switch back to the pipeline view.
-
-   5) Enable the persistence package.
-
-   6) Drag the ``PersistentOutputFile`` module to the canvas and connect the output from ``VTKRenderOffscreen`` to its value port. See Figure :ref:`Example 1.2 <fig-pers-example-output>`.
-
-   7) With the ``PersistentOutputFile`` module selected, press Ctrl-E to edit the module configuration. 
-
-   8) Select ``Create New Reference``, name it "persistence1_1", and give it a "Persistent Output" tag.  Select ``Save``.
-
-   9) Execute the workflow.
-
-   **Persistent Input**
-
-   10) Switch to the History view again and tag the current version as "Persistent Output".  Then, select the root of the version tree and go back to the pipeline view.
-
-   11) Drag the ``PersistentInputFile`` and ``ImageViewerCell`` modules to the canvas and connect them. See Figure :ref:`Example 1.3 <fig-pers-example-input>`.
-
-   12) Edit the configuration of the ``PersitentInputFile``.  Select "Use Existing Reference" and select the file named "persistence1_1" with the "Persistent Output" tag.  Select ``Save``. See Figure :ref:`Example 1.4 <fig-pers-example-conf>`.
-
-   13) Execute the workflow.  An image should be displayed in the VisTrails spreadsheet.
-
-   **Persistent Intermediate**
-
-   14) Switch to the ``History`` view and tag the version with "Persistent Input", then select the "Base Workflow" version and switch to the pipeline view again.
-
-   15) Drag the ``PersistentIntermediateFile`` and ``ImageViewerCell`` modules to the canvas and connect them as shown in Figure :ref:`Example 1.5 <fig-pers-example-intermediate>`.
-
-   16) Execute the workflow.
-
-   17) In the History view, tag the version with "Persistent Intermediate".  See Figure :ref:`Example 1.6 <fig-pers-example-ver>`.
-
-   **Experimentation**
-
-   You can now change the background color in the "Persistent Output" version and execute the pipeline.  The changes should show up when you execute the pipeline of the "Persistent Input" version.  You can also change the background color in the "Persistent Intermediate" version, but this example merely demonstrates how to use the module.  Performance increase will not be seen here due to the lack of lengthy computations.
-
-.. _fig-pers-example-base:
-
-.. |fig1| image:: figures/persistence/base.png
-   :align: top
-
-.. _fig-pers-example-output:
-
-.. |fig2| image:: figures/persistence/output.png
-   :align: top
-
-+-----------------------+------------------------------------+
-| |fig1|                |  |fig2|                            |
-+-----------------------+------------------------------------+
-| Example 1.1 - Base    |  Example 1.2 - Persistent Output   |
-| Workflow - An example |  File                              |
-| pipeline without      |                                    |
-| persistence.          |                                    |
-+-----------------------+------------------------------------+
-
-
-.. _fig-pers-example-input:
-
-.. figure:: figures/persistence/input.png
-   :align: center
-   :width: 30%
-
-   Example 1.3 - Persistent Input File
-
-
-.. _fig-pers-example-conf:
-
-.. figure:: figures/persistence/reference.png
-   :align: center
-   :width: 100%
-
-   Example 1.4 - Selecting an existing reference
-
-
-.. _fig-pers-example-intermediate:
-
-.. figure:: figures/persistence/intermediate.png
-   :align: center
-   :width: 40%
-
-   Example 1.5 - Persistent Intermediate File
-
-
-.. _fig-pers-example-ver:
-
-.. figure:: figures/persistence/versions.png
-   :align: center
-   :width: 70%
-
-   Example 1.6 - The History Tree
diff --git a/doc/usersguide/persistent_archive.rst b/doc/usersguide/persistent_archive.rst
new file mode 100644
index 0000000..03177ba
--- /dev/null
+++ b/doc/usersguide/persistent_archive.rst
@@ -0,0 +1,71 @@
+.. _chap-persistence:
+
+*************************
+Persistence in VisTrails
+*************************
+
+.. index::persistence
+
+The ``Persistent Archive`` package in |vistrails| provides a persistent file store with searchable metadata. It makes it easy for users to store files permanently with meaningful information so that they can be retrieved and exploited later, without having to manually organize and reference them.
+
+At the simplest level, you can use it to cache files to disk, so that your pipelines can retrieve them later and avoid lengthy recomputations by inserting a ``CachedFile`` module.
+
+Getting Started With Persistence
+================================
+
+This package builds upon the `file_archive tool <https://github.com/remram44/file_archive>`_. Should you need to insert or extract files from the store from outside VisTrails, you will find the store in ``~/.vistrails/file_archive``.
+
+Files are stored uncompressed in the store, along with metadata in the form of key-value pairs. |vistrails| stores the generating module location and signature in their, but you can add all the meaningful metadata you might need for later identification.
+
+|vistrails| provides 4 types of modules:
+
+PersistedInputDir and PersistedInputFile
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This allows you to persist an input file inside the store. It will use the matching file from the store, unless a new file is provided and differs from the store.
+
+Use it for example to record the result of a computation, or to keep track of your experiment's input for later reference even though you might change or delete the original.
+
+PersistedDir and PersistedFile
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These modules insert data into the store, along with metadata. Additionally, if an entry can be found for the signature of the upstream subpipeline, the module will simply use that file, skipping the execution of these upstream modules.
+
+Use it for example to persistent an important result that is part of your pipeline.
+
+CachedDir and CachedFile
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+These are variants of PersistedDir and PersistedFile that don't accept additional metadata. Files will be marked as cache files and won't be shown by default in the viewer. You can use this for unimportant pieces of data that you only persist to speed up your pipeline.
+
+QueriedInputDir and QueriedInputFile
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These simply get a previous result, or any entry from the store, from conditions on the metadata. It accepts more general queries than PersistedInputFile which only compares for equality of the metadata.
+
+Use it for example to analyse previous results.
+
+Managing the store
+==================
+
+All the files currently stored in the archive can be listed by clicking on the *Packages* menu > *Persistent Archive* > *Show archive content*.
+
+Examples
+========
+
+.. figure:: figures/persistent_archive/workflow_persistedfile.png
+   :align: center
+
+   Example: Using PersistedFile in a workflow with metadata. Upstream is not re-executed.
+
+
+.. figure:: figures/persistent_archive/workflow_textquery.png
+   :align: center
+
+   Example: Querying a file from the archive with text conditions.
+
+
+.. figure:: figures/persistent_archive/contents_filter.png
+   :align: center
+
+   Example: Searching for archive entries with the *Show archive content* dialog.
diff --git a/doc/usersguide/preface.rst b/doc/usersguide/preface.rst
index 507dca6..87bf805 100644
--- a/doc/usersguide/preface.rst
+++ b/doc/usersguide/preface.rst
@@ -14,8 +14,8 @@ VisTrails community. The easiest way to get started is to sign up for
 the VisTrails Users mailing list. Instructions for doing this can be
 found on the VisTrails web site: www.vistrails.org.
 
-This book is divided into four parts. The first part, :doc:`Introduction
-to VisTrails </intro>`, provides instructions on how to download and install
+This book is divided into four parts. The first part, :doc:`Getting started
+</getting_started>`, provides instructions on how to download and install
 the VisTrails software, and introduces you to its user interface. The
 second and longest part, "Learning VisTrails by Example," consists
 of a number of tutorial chapters that guide you, step by step, through
diff --git a/doc/usersguide/preliminary.rst b/doc/usersguide/preliminary.rst
deleted file mode 100644
index 5321777..0000000
--- a/doc/usersguide/preliminary.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-.. toctree::
-   :maxdepth: 1
-
-   preface
diff --git a/doc/usersguide/pythoncalc.rst b/doc/usersguide/pythoncalc.rst
index cbc0758..c4cf2ec 100644
--- a/doc/usersguide/pythoncalc.rst
+++ b/doc/usersguide/pythoncalc.rst
@@ -1,208 +1,95 @@
 .. % NB: Please don't break any of the long lines - Verbatim is picky about line breaks
 
 .. index::
-   pair: Module registry; ``addModule``
-   pair: packages; ``initialize``
-   pair: Module registry; ``addInputPort``
-   pair: Module registry; ``addOutputPort``
+   pair: packages; ``_modules``
+   pair: modules; ``_input_ports``
+   pair: modules; ``_output_ports``
    pair: modules; ``ModuleError``
 
 .. role:: red
 
 .. code-block:: python
-   :linenos:
-
-   import core.modules.module_registry
-   from core.modules.vistrails_module import Module, ModuleError
-
-   version = "0.9.0"
-   name = "PythonCalc"
-   identifier = "org.vistrails.vistrails.pythoncalc"
-
-   class PythonCalc(Module):
-       """PythonCalc is a module that performs simple arithmetic operations on its inputs."""
-
-       def compute(self):
-           v1 = self.getInputFromPort("value1")
-           v2 = self.getInputFromPort("value2")
-           result = self.op(v1, v2)
-           self.setResult("value", result)
-
-       def op(self, v1, v2):
-           op = self.getInputFromPort("op")
-           if op == '+': return v1 + v2
-           elif op == '-': return v1 - v2
-           elif op == '*': return v1 * v2
-           elif op == '/': return v1 / v2
-           else: raise ModuleError(self, "unrecognized operation: '%s'" % op)
-
-   ###############################################################################
-
-   def initialize(*args, **keywords):
-
-       # We'll first create a local alias for the module registry so that
-       # we can refer to it in a shorter way.
-       reg = core.modules.module_registry.registry
-
-       # VisTrails cannot currently automatically detect your derived
-       # classes, and the ports that they support as input and
-       # output. Because of this, you as a module developer need to let
-       # VisTrails know that you created a new module. This is done by calling
-       # function addModule:
-       reg.add_module(PythonCalc)
-
-       # In a similar way, you need to report the ports the module wants
-       # to make available. This is done by calling addInputPort and
-       # addOutputPort appropriately. These calls only show how to set up
-       # one-parameter ports. We'll see in later tutorials how to set up
-       # multiple-parameter plots.
-       reg.add_input_port(PythonCalc, "value1", 
-                          (core.modules.basic_modules.Float, 'the first argument'))
-       reg.add_input_port(PythonCalc, "value2",
-                          (core.modules.basic_modules.Float, 'the second argument'))
-       # We declare this port as an enum, so that the user may only select one of
-       # the listed values
-       reg.add_input_port(PythonCalc, "op",
-                          (core.modules.basic_modules.String, 'the operation'),
-                          entry_types=['enum'], values=["['+', '-', '*', '/']"])
-       reg.add_output_port(PythonCalc, "value",
-                          (core.modules.basic_modules.Float, 'the result'))
-
-.. .. code-block:: python
-   :linenos:
-
-   ###############################################################################
-   ##
-   ## Copyright (C) 2011-2014, NYU-Poly.
-   ## Copyright (C) 2006-2011, University of Utah.
-   ## All rights reserved.
-   ## Contact: contact at vistrails.org
-   ##
-   ## This file is part of VisTrails.
-   ##
-   ## "Redistribution and use in source and binary forms, with or without 
-   ## modification, are permitted provided that the following conditions are met:
-   ##
-   ##  - Redistributions of source code must retain the above copyright notice, 
-   ##    this list of conditions and the following disclaimer.
-   ##  - Redistributions in binary form must reproduce the above copyright 
-   ##    notice, this list of conditions and the following disclaimer in the 
-   ##    documentation and/or other materials provided with the distribution.
-   ##  - Neither the name of the University of Utah nor the names of its 
-   ##    contributors may be used to endorse or promote products derived from 
-   ##    this software without specific prior written permission.
-   ##
-   ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-   ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-   ## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-   ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-   ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-   ## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-   ## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-   ## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-   ## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-   ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-   ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-   ##
-   ###############################################################################
-   """This package implements a very simple VisTrails module called
-   PythonCalc. This is intended as a simple example that can be referred
-   to by users to create their own packages and modules later.
-
-   If you're interested in developing new modules for VisTrails, you
-   should also consult the documentation in
-   core/modules/vistrails_module.py.
-   """
-
-   import core.modules
-   import core.modules.module_registry
-   from core.modules.vistrails_module import Module, ModuleError
-
-   ###############################################################################
-   # PythonCalc
-   #
-   # A VisTrails package is simply a Python class that subclasses from
-   # Module.  For this class to be executable, it must define a method
-   # compute(self) that will perform the appropriate computations and set
-   # the results.
-   #
-   # Extra helper methods can be defined, as usual. In this case, we're
-   # using a helper method op(self, v1, v2) that performs the right
-   # operations.
-
-   class PythonCalc(Module):
-       """PythonCalc is a module that performs simple arithmetic operations
-       on its inputs."""
-
-       # This constructor is strictly unnecessary. However, some modules
-       # might want to initialize per-object data. When implementing your
-       # own constructor, remember that it must not take any extra
-       # parameters.
-       def __init__(self):
-           Module.__init__(self)
-
-       # This is the method you should implement in every module that
-       # will be executed directly. VisTrails does not use the return
-       # value of this method.
-       def compute(self):
-           # getInputFromPort is a method defined in Module that returns
-           # the value stored at an input port. If there's no value
-           # stored on the port, the method will return None.
-           v1 = self.getInputFromPort("value1")
-           v2 = self.getInputFromPort("value2")
-
-           # You should call setResult to store the appropriate results
-           # on the ports.  In this case, we are only storing a
-           # floating-point result, so we can use the number types
-           # directly. For more complicated data, you should
-           # return an instance of a VisTrails Module. This will be made
-           # clear in further examples that use these more complicated data.
-           self.setResult("value", self.op(v1, v2))
-
-       def op(self, v1, v2):
-           op = self.getInputFromPort("op")
-           if op == '+':
-               return v1 + v2
-           elif op == '-':
-               return v1 - v2
-           elif op == '*':
-               return v1 * v2
-           elif op == '/':
-               return v1 / v2
-           # If a module wants to report an error to VisTrails, it should raise
-           # ModuleError with a descriptive error. This allows the interpreter
-           # to capture the error and report it to the caller of the evaluation
-           # function.
-           raise ModuleError(self, "unrecognized operation: '%s'" % op)
-
-   ###############################################################################
-   # the function initialize is called for each package, after all
-   # packages have been loaded. It it used to register the module with
-   # the VisTrails runtime.
-
-   def initialize(*args, **keywords):
-
-       # We'll first create a local alias for the module_registry so that
-       # we can refer to it in a shorter way.
-       reg = core.modules.module_registry
-
-       # VisTrails cannot currently automatically detect your derived
-       # classes, and the ports that they support as input and
-       # output. Because of this, you as a module developer need to let
-       # VisTrails know that you created a new module. This is done by calling
-       # function addModule:
-       reg.addModule(PythonCalc)
-
-       # In a similar way, you need to report the ports the module wants
-       # to make available. This is done by calling addInputPort and
-       # addOutputPort appropriately. These calls only show how to set up
-       # one-parameter ports. We'll see in later tutorials how to set up
-       # multiple-parameter plots.
-       reg.addInputPort(PythonCalc, "value1",
-                        (core.modules.basic_modules.Float, 'the first argument'))
-       reg.addInputPort(PythonCalc, "value2",
-                        (core.modules.basic_modules.Float, 'the second argument'))
-       reg.addInputPort(PythonCalc, "op",
-                        (core.modules.basic_modules.String, 'the operation'))
-       reg.addOutputPort(PythonCalc, "value",
-                         (core.modules.basic_modules.Float, 'the result'))
+    :linenos:
+
+    ###############################################################################
+    # PythonCalc
+    #
+    # A VisTrails package is simply a Python class that subclasses from
+    # Module.  For this class to be executable, it must define a method
+    # compute(self) that will perform the appropriate computations and set
+    # the results.
+    #
+    # Extra helper methods can be defined, as usual. In this case, we're
+    # using a helper method op(self, v1, v2) that performs the right
+    # operations.
+
+    from vistrails.core.modules.vistrails_module import Module, ModuleError
+    from vistrails.core.modules.config import IPort, OPort
+
+    class PythonCalc(Module):
+        """PythonCalc is a module that performs simple arithmetic operations
+    on its inputs."""
+
+        # You need to report the ports the module wants to make
+        # available. This is done by creating _input_ports and
+        # _output_ports lists composed of InputPort (IPort) and OutputPort
+        # (OPort) objects. These are simple ports that take only one
+        # value. We'll see in later tutorials how to create compound ports
+        # which can take a tuple of values.  Each port must specify its
+        # name and signature.  The signature specifies the package
+        # (e.g. "basic" which is shorthand for
+        # "org.vistrails.vistrails.basic") and module (e.g. "Float").
+        # Note that the third input port (op) has two other arguments.
+        # The "enum" entry_type specifies that there are a set of options
+        # the user should choose from, and the values then specifies those
+        # options.
+        _input_ports = [IPort(name="value1", signature="basic:Float"),
+                        IPort(name="value2", signature="basic:Float"),
+                        IPort(name="op", signature="basic:String",
+                              entry_type="enum", values=["+", "-", "*", "/"])]
+        _output_ports = [OPort(name="value", signature="basic:Float")]
+
+        # This constructor is strictly unnecessary. However, some modules
+        # might want to initialize per-object data. When implementing your
+        # own constructor, remember that it must not take any extra
+        # parameters.
+        def __init__(self):
+            Module.__init__(self)
+
+        # This is the method you should implement in every module that
+        # will be executed directly. VisTrails does not use the return
+        # value of this method.
+        def compute(self):
+            # get_input is a method defined in Module that returns
+            # the value stored at an input port. If there's no value
+            # stored on the port, the method will return None.
+            v1 = self.get_input("value1")
+            v2 = self.get_input("value2")
+
+            # You should call set_output to store the appropriate results
+            # on the ports.  In this case, we are only storing a
+            # floating-point result, so we can use the number types
+            # directly. For more complicated data, you should
+            # return an instance of a VisTrails Module. This will be made
+            # clear in further examples that use these more complicated data.
+            self.set_output("value", self.op(v1, v2))
+
+        def op(self, v1, v2):
+            op = self.get_input("op")
+            if op == '+':
+                return v1 + v2
+            elif op == '-':
+                return v1 - v2
+            elif op == '*':
+                return v1 * v2
+            elif op == '/':
+                return v1 / v2
+            # If a module wants to report an error to VisTrails, it should raise
+            # ModuleError with a descriptive error. This allows the interpreter
+            # to capture the error and report it to the caller of the evaluation
+            # function.
+            raise ModuleError(self, "unrecognized operation: '%s'" % op)
+
+    # VisTrails will only load the modules specified in the _modules list.
+    # This list contains all of the modules a package defines.
+    _modules = [PythonCalc,]
diff --git a/doc/usersguide/pythoncalc_file1.rst b/doc/usersguide/pythoncalc_file1.rst
new file mode 100644
index 0000000..f0b0561
--- /dev/null
+++ b/doc/usersguide/pythoncalc_file1.rst
@@ -0,0 +1,22 @@
+.. index::
+   pair: packages; ``identifier``
+   pair: packages; ``name``
+   pair: packages; ``version``
+
+.. role:: red
+
+.. code-block:: python
+    :linenos:
+
+    """This package implements a very simple VisTrails module called
+    PythonCalc. This is intended as a simple example that can be referred
+    to by users to create their own packages and modules later.
+
+    If you're interested in developing new modules for VisTrails, you
+    should also consult the documentation in the User's Guide and in
+    core/modules/vistrails_module.py.
+    """
+
+    identifier = 'org.vistrails.vistrails.pythoncalc'
+    name = 'PythonCalc'
+    version = '0.9.2'
diff --git a/doc/usersguide/streaming.rst b/doc/usersguide/streaming.rst
new file mode 100644
index 0000000..987ee7a
--- /dev/null
+++ b/doc/usersguide/streaming.rst
@@ -0,0 +1,94 @@
+.. _chap-streaming:
+
+**********************
+Streaming in VisTrails
+**********************
+
+Streaming data may be useful for  a number of reasons, such as to incrementally
+update  a  visualization,  or  to  process  more data  than  fit  into  memory.
+VisTrails supports streaming data through the workflow. By implementing modules
+that supports streaming,  data items will be passed  through the whole workflow
+one at a time.
+
+Using Streaming
+===============
+
+Streaming     is     similar      to     list     handling     (see     Chapter
+:ref:`chap-list_handling`). Modules  that create  streams should output  a port
+with list depth 1. Downstream modules that do not accept lists will be executed
+once for  each item  in the  stream. Modules with  multiple input  streams will
+combine them  pairwise. For  this reason the  input streams should  contain the
+same number of items (or ben unlimited).
+
+Modules accepting  a type with  list depth 1,  but does not  support streaming,
+will convert input streams to lists and execute after the streaming have ended.
+
+.. topic:: Try it Now!
+
+  Lets use PythonSources to create  a simple example that incrementally sums up
+  a  sequence of  numbers.  First  we  will create  a module  that streams  the
+  natural  numbers  up  to  some  value.   Create a  new  workflow  and  add  a
+  ``PythonSource``  module. Give  it an  input  port named  ``inputs`` of  type
+  Integer, which  will specify the maxim  number to stream, and  an output port
+  named ``out`` of type ``Integer`` with list depth 1, which will be the output
+  stream.      An    output     stream    can     be    created     by    using
+  ``self.set_streaming_output``, which takes the port name, an iterator object,
+  and an optional length of the  input items.  To create an integer iterator we
+  can use xrange. Add this to the PythonSource:
+
+.. code-block:: python
+
+   self.set_streaming_output('out',
+                             xrange(inputs).__iter__(),
+                             inputs)
+
+.. topic:: Next Step!
+
+  Now lets create a  module that captures the item in the  string. Add a second
+  ``PythonSource`` module  below the  first one.  Give  it an input  port named
+  ``integerStream`` of  type Integer and  list depth 1  that will be  our input
+  stream.   An  input  stream  can  be  captured by  adding  the  magic  string
+  ``#STREAMING``  to the PYthonSource  code and  calling ``self.set_streaming``
+  with a  generator method as argument.   The generator method  should take the
+  module as  an input.  It should first  initialize its value, in  our case set
+  ``intsum=0``.  Then it should receive the inputs in a loop ending with yield.
+  In each iteration  the module will be  updated to contain a new  input in the
+  stream. Similar to a normal module, the loop should:
+
+  1. get inputs
+  2. compute outputs
+  3. set outputs
+  4. call ``yield``
+  
+  Below is the complete example. Add it to the PythonSource.
+
+.. code-block:: python
+
+  #STREAMING - This tag is magic, do not change.
+
+  def generator(module):
+      intsum = 0
+      while 1:
+          i = module.get_input('integerStream')
+          intsum += i
+          print "Sum so far:", intsum
+          yield
+
+  self.set_streaming(generator)
+
+.. topic:: Finally:
+
+  Connect  the  two  PythonSource's,  set   ``inputs``  to  100  in  the  first
+  PythonSource, open the  vistrails console and execute. See  how the output is
+  printed to  the console  while the stream  runs and  how the progress  of the
+  modules increase. The output should  look like this: :vtl:`(open in vistrails)
+  <streaming.vt>`
+
+.. code-block:: python
+  
+  Sum so far: 0
+  Sum so far: 1
+  Sum so far: 3
+  ...
+  Sum so far: 4851
+  Sum so far: 4950
diff --git a/doc/usersguide/tabledata.rst b/doc/usersguide/tabledata.rst
index fe1fe7d..29f3212 100644
--- a/doc/usersguide/tabledata.rst
+++ b/doc/usersguide/tabledata.rst
@@ -20,7 +20,7 @@ plain binary files) and extract or convert columns.
 
   Start by dragging the following modules to the canvas:
 
-   * ``HTTPFile`` (from the HTTP package)
+   * ``DownloadFile`` (from the URL package)
    * ``CSVFile`` (under ``read/csv``)
    * ``TableCell``
    * Two ``ExtractColumn`` modules
@@ -41,7 +41,7 @@ plain binary files) and extract or convert columns.
 
 .. topic:: Next Step!
 
-  Set the 'url' input of HTTPFile to ``http://www.vistrails.org/download/download.php?type=DATA&id=citibike_from_launch.csv``.
+  Set the 'url' input of DownloadFile to ``http://www.vistrails.org/download/download.php?type=DATA&id=citibike_from_launch.csv``.
   Make sure 'header_present' is checked on CSVFile.
 
   Set the 'column_name' parameters on both ExtractColumn modules to ``Date`` (for the one on the left) and ``Miles traveled today (midnight to 11:59 pm)`` (for the one on the right). Alternatively, you can set column_index to 0 and 3.
diff --git a/doc/usersguide/vistrails_server.rst b/doc/usersguide/vistrails_server.rst
index 3ae0f9e..39241ac 100644
--- a/doc/usersguide/vistrails_server.rst
+++ b/doc/usersguide/vistrails_server.rst
@@ -1,10 +1,10 @@
 .. _chap-vistrails-server:
 
-***********************
+**********************
 VisTrails Server Setup
-***********************
+**********************
 
-.. index:: server 
+.. index:: server
 
 * lets assume that everything is going to be put in the /server dir::
 
@@ -34,12 +34,12 @@ VisTrails Server Setup
 
 * Determine how you will start the vistrails server. You have a choice of using Xvfb or not. If you use it, /server/vistrails/git/scripts/start_vistrails_xvfb.sh is what you will use, otherwise, use start_vistrails.sh
 
-Using Xvfb is slower and not recommended if your workflows will make use of volume rendering or other graphics-card intensive techniques. 
+Using Xvfb is slower and not recommended if your workflows will make use of volume rendering or other graphics-card intensive techniques.
 
 .. _sec-server-using-xvfb:
 
 Using Xvfb
-===========
+==========
 
 * edit /server/vistrails/git/scripts/start_vistrails_xvfb.sh file and make sure it is consistent with your system setup::
 
@@ -53,7 +53,7 @@ Using Xvfb
     NUMBER_OF_OTHER_VISTRAILS_INSTANCES="1"
     MULTI_OPTION="-M" #execute the main instance multithreaded
 
-* The setup above will execute 2 instances of the server. You can add more instances by changing the variable NUMBER_OF_OTHER_VISTRAILS_INSTANCES. When using multiple instances, the ports and virtual displays will be used incrementally, so if the main instance is using port 8081 and virtual display :6, the next instance will use port 8082 and virtual display :7, and so on. 
+* The setup above will execute 2 instances of the server. You can add more instances by changing the variable NUMBER_OF_OTHER_VISTRAILS_INSTANCES. When using multiple instances, the ports and virtual displays will be used incrementally, so if the main instance is using port 8081 and virtual display :6, the next instance will use port 8082 and virtual display :7, and so on.
 
 .. _sec-server-using-x-directly:
 
@@ -70,7 +70,7 @@ Connecting to X server directly
     NUMBER_OF_OTHER_VISTRAILS_INSTANCES="2"
     MULTI_OPTION="-M" #execute the main instance multithreaded
 
-* The setup above will execute 3 instances of the server. You can add or remove more instances by changing the variable NUMBER_OF_OTHER_VISTRAILS_INSTANCES. When using multiple instances, the ports will be used incrementally, so if the main instance is using port 8081, the next instance will use port 8082, and so on. 
+* The setup above will execute 3 instances of the server. You can add or remove more instances by changing the variable NUMBER_OF_OTHER_VISTRAILS_INSTANCES. When using multiple instances, the ports will be used incrementally, so if the main instance is using port 8081, the next instance will use port 8082, and so on.
 
 .. _sec-server-basic-configuration:
 
@@ -103,7 +103,6 @@ Basic Configuration
     [access]
     permitted_addresses = localhost, 127.0.0.1, <crowdlabs-server-address>
 
-
 * Add the password for the full permission mysql user::
 
     write_user = <write user>
diff --git a/doc/usersguide/vtl/README b/doc/usersguide/vtl/README
index 7bd4c34..3c09363 100644
--- a/doc/usersguide/vtl/README
+++ b/doc/usersguide/vtl/README
@@ -15,7 +15,7 @@ To create  a link to an example:
    Using macro with custom title:
        :vtl:`(Open result) <global_variables.vt>`
    Raw version:
-   `(Open result) <http://www.vistrails.org/usersguide/v2.1/examples/global_variables.vtl>`_
+   `(Open result) <http://www.vistrails.org/usersguide/v2.2/examples/global_variables.vtl>`_
 
 4. Copy the new vtl files to the server:
-    scp doc/usersguide/vtl/* vistrails.org:/srv/wiki/vistrails/usersguide/v2.1/examples/
\ No newline at end of file
+    scp doc/usersguide/vtl/* vistrails.org:/srv/wiki/vistrails/usersguide/v2.2/examples/
\ No newline at end of file
diff --git a/doc/usersguide/vtl/list-handling.vtl b/doc/usersguide/vtl/list-handling.vtl
new file mode 100644
index 0000000..0b24449
--- /dev/null
+++ b/doc/usersguide/vtl/list-handling.vtl
@@ -0,0 +1 @@
+<vtlink filename="@examples/list-handling.vt" version="combine lists"/>
diff --git a/doc/usersguide/vtl/parameter_widgets.vtl b/doc/usersguide/vtl/parameter_widgets.vtl
new file mode 100644
index 0000000..82668c6
--- /dev/null
+++ b/doc/usersguide/vtl/parameter_widgets.vtl
@@ -0,0 +1 @@
+<vtlink filename="@examples/terminator.vt" version="parameter widgets"/>
diff --git a/doc/usersguide/vtl/streaming.vtl b/doc/usersguide/vtl/streaming.vtl
new file mode 100644
index 0000000..09d5d54
--- /dev/null
+++ b/doc/usersguide/vtl/streaming.vtl
@@ -0,0 +1 @@
+<vtlink filename="@examples/streaming.vt" version="add numbers"/>
diff --git a/examples-internal/XSLTSample.xsl b/examples-internal/XSLTSample.xsl
deleted file mode 100644
index d291c4a..0000000
--- a/examples-internal/XSLTSample.xsl
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet
-  version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-  <xsl:output method="xml" encoding="UTF-8"/>
-  <xsl:template match="/">
-    <html>
-      <head><title>XSLT Sample</title></head>
-      <body>
-         <h2>The Sequence for the Given Gene is: </h2>
-                <ul>
-                  <li>
-        <xsl:value-of select="DDBJXML/SEQUENCE"/> 
-                  </li>
-                </ul>
-<h3>Please fill in the following inputs and Submit:</h3>
-<xsl:text disable-output-escaping="yes"><![CDATA[
-  <form method="post" action="http://geon01.sdsc.edu:8164/pt2/jsp/ptf.jsp">      
-                <b>Program: </b><input name="program" size="20" type="text"><BR>
-                <b>Database: </b><input name="database" size="20" type="text"><BR>
-                <b>Query: </b><input name="query" size="20" type="text"><BR>
-                <INPUT TYPE="submit" VALUE="Make BLAST search using the specified inputs">        
-</form>
-]]></xsl:text>   
-      </body>
-    </html>
-  </xsl:template>
-</xsl:stylesheet>
diff --git a/examples-internal/afront.xml b/examples-internal/afront.xml
deleted file mode 100644
index ad95b2b..0000000
--- a/examples-internal/afront.xml
+++ /dev/null
@@ -1,803 +0,0 @@
-  <visTrail version="0.3.0">
-    <action date="01 Mar 2007 17:56:06" parent="0" time="1" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="0" name="Afront" x="9.0" y="273.0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:12" parent="1" time="2" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-46.0" dy="-38.0" id="0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:12" parent="2" time="3" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="1" name="File" x="-58.0" y="381.0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:16" parent="3" time="4" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="10.0" dy="-84.0" id="0"/>
-      <move dx="30.0" dy="-45.0" id="1"/>
-    </action>
-    <action date="01 Mar 2007 17:56:16" parent="4" time="5" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="name" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="01 Mar 2007 17:56:24" parent="5" time="6" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="name" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="/home/cscheid/cscheid_old/meshes/bunny.off"/>
-    </action>
-    <action date="01 Mar 2007 17:56:25" parent="6" time="7" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="name" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="/home/cscheid/cscheid_old/meshes/bunny.off"/>
-    </action>
-    <action date="01 Mar 2007 17:56:29" parent="7" time="8" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="eta" functionId="0" moduleId="0" parameter="eta" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:32" parent="8" time="9" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="eta" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Float" value="0.8"/>
-    </action>
-    <action date="01 Mar 2007 17:56:34" parent="9" time="10" user="cscheid" what="deleteFunction">
-      <notes>
-        None
-      </notes>
-      <function functionId="0" moduleId="0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:35" parent="10" time="11" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="rho" functionId="0" moduleId="0" parameter="rho" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:37" parent="11" time="12" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="rho" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Float" value="0.8"/>
-    </action>
-    <action date="01 Mar 2007 17:56:38" parent="12" time="13" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="rho" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Float" value="0.8"/>
-    </action>
-    <action date="01 Mar 2007 17:56:41" parent="13" time="14" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="0" destinationModule="Afront" destinationPort="file(File)" id="0" sourceId="1" sourceModule="File" sourcePort="self(File)"/>
-    </action>
-    <action date="01 Mar 2007 17:56:50" parent="14" time="15" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="5.0" dy="26.0" id="0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:50" parent="15" time="16" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="2" name="MeshQualityHistogram" x="35.0" y="46.0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:53" parent="16" time="17" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-23.0" dy="25.0" id="0"/>
-    </action>
-    <action date="01 Mar 2007 17:56:53" parent="17" time="18" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="2" destinationModule="MeshQualityHistogram" destinationPort="file(File)" id="1" sourceId="0" sourceModule="Afront" sourcePort="output(File)"/>
-    </action>
-    <action date="01 Mar 2007 17:56:57" parent="18" time="19" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-53.0" dy="26.0" id="2"/>
-    </action>
-    <action date="01 Mar 2007 17:56:57" parent="19" time="20" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="3" name="PythonSource" x="-30.0" y="-86.0"/>
-    </action>
-    <action date="01 Mar 2007 17:58:52" parent="20" time="21" user="cscheid" what="addModulePort">
-      <notes>
-        None
-      </notes>
-      <addPort moduleId="3" portName="input" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="01 Mar 2007 17:58:52" parent="21" time="22" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="3" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20self.getInputFromPort%28%27input%27%29%0A%0Av%20%3D%201.0%0Afor%20l%20in%20f.readlines%28%29%3A%0A%20%20%20v%20-%3D%20float%28l%29%20/%20100.0%0A%0Aprint%20%22mesh%20quality%3A%20%22%2C%20v"/>
-    </action>
-    <action date="01 Mar 2007 17:58:54" parent="22" time="23" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="3" destinationModule="PythonSource" destinationPort="input(File)" id="2" sourceId="2" sourceModule="MeshQualityHistogram" sourcePort="output(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:00:32" parent="23" time="24" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="3" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20self.getInputFromPort%28%27input%27%29%0A%0Av%20%3D%201.0%0Afor%20l%20in%20file%28f.name%29.readlines%28%29%3A%0A%20%20%20v%20-%3D%20float%28l%29%20/%20100.0%0A%0Aprint%20%22mesh%20quality%3A%20%22%2C%20v"/>
-    </action>
-    <action date="01 Mar 2007 18:00:48" parent="24" time="25" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="3" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20self.getInputFromPort%28%27input%27%29%0A%0Av%20%3D%201.0%0Afor%20l%20in%20file%28f.name%29.readlines%28%29%3A%0A%20%20%20print%20l%0A%20%20%20v%20-%3D%20float%28l%29%20/%20100.0%0A%0Aprint%20%22mesh%20quality%3A%20%22%2C%20v"/>
-    </action>
-    <action date="01 Mar 2007 18:09:13" parent="25" time="26" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="3" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20self.getInputFromPort%28%27input%27%29%0A%0Av%20%3D%201.0%0Afor%20l%20in%20file%28f.name%29.readlines%28%29%3A%0A%20%20%20v%20-%3D%20float%28l%29%20/%20100.0%0A%0Aprint%20%22mesh%20quality%3A%20%22%2C%20v"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="0" time="27" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="0" name="vtkDataSetReader" x="50.4689536324" y="-75.039097946"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="27" time="28" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="1" name="OutputPort" x="66.5683979218" y="-176.342434481"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="28" time="29" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="2" name="InputPort" x="72.8614246679" y="145.860534924"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="29" time="30" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="3" name="PythonSource" x="50.127651043" y="23.962638969"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="30" time="31" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="0" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="31" time="32" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="1" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="32" time="33" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="name" functionId="0" moduleId="2" parameter="<no description>" parameterId="0" type="String" value="input_file"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="33" time="34" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="2" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="34" time="35" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="3" parameter="<no description>" parameterId="0" type="String" value="%23%20Extracts%20the%20internal%20file%20name%20so%20VTK%20can%20use%20it%0A%23%20Also%2C%20makes%20local%20copy%20so%20that%20the%20file%20survives%20filepool%0A%23%20cleanup.%0Afrom%20packages.spreadsheet.spreadsheet_controller%20import%20spreadsheetController%0Aself.checkInputPort%28%22file%22%29%0Awindow%20%3D%20spreadsheetController.findSpreadshee [...]
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="35" time="36" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="3" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="36" time="37" user="cscheid" what="addModulePort">
-      <notes>
-        None
-      </notes>
-      <addPort moduleId="3" portName="file" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="37" time="38" user="cscheid" what="addModulePort">
-      <notes>
-        None
-      </notes>
-      <addPort moduleId="3" portName="name" portSpec="(String)" portType="output"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="38" time="39" user="cscheid" what="addModulePort">
-      <notes>
-        None
-      </notes>
-      <addPort moduleId="3" portName="file" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="39" time="40" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="1" destinationModule="OutputPort" destinationPort="InternalPipe(Module)" id="0" sourceId="0" sourceModule="vtkDataSetReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="40" time="41" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="0" destinationModule="vtkDataReader" destinationPort="SetFileName(String)" id="1" sourceId="3" sourceModule="PythonSource" sourcePort="name(String)"/>
-    </action>
-    <action date="01 Mar 2007 18:09:26" parent="41" time="42" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="3" destinationModule="PythonSource" destinationPort="file(File)" id="2" sourceId="2" sourceModule="InputPort" sourcePort="InternalPipe(Variant)"/>
-    </action>
-    <action date="01 Mar 2007 18:10:45" parent="26" time="43" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="4" name="MeshFilter" x="-260.146183261" y="3.39321108601"/>
-    </action>
-    <action date="01 Mar 2007 18:10:48" parent="43" time="44" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="output_format" functionId="0" moduleId="4" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:12:31" parent="44" time="45" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="output_format" functionId="0" moduleId="4" parameter="<no description>" parameterId="0" type="String" value=".vtk"/>
-    </action>
-    <action date="01 Mar 2007 18:12:34" parent="45" time="46" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="4" destinationModule="MeshFilter" destinationPort="input_file(File)" id="3" sourceId="0" sourceModule="Afront" sourcePort="output(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:13:38" parent="46" time="47" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="5" name="vtkVistrailsFileReader" x="-272.292020374" y="-128.719864177"/>
-    </action>
-    <action date="01 Mar 2007 18:13:41" parent="47" time="48" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="5" destinationModule="vtkVistrailsFileReader" destinationPort="input_file(File)" id="4" sourceId="4" sourceModule="MeshFilter" sourcePort="output_file(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="48" time="49" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="6" name="VTKCell" x="-180.664206774" y="-165.520338043"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="49" time="50" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="7" name="vtkDataSetMapper" x="-237.282186703" y="301.998142802"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="50" time="51" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="8" name="vtkRenderer" x="-220.460112232" y="-3.1201219181"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="51" time="52" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="9" name="vtkActor" x="-258.041526728" y="119.069528254"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="52" time="53" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="6" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="53" time="54" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="ScalarVisibilityOn" functionId="0" moduleId="7" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="54" time="55" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="7" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="55" time="56" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="8" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="56" time="57" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="9" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="57" time="58" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="6" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="5" sourceId="8" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="58" time="59" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="9" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="6" sourceId="7" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:08" parent="59" time="60" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="8" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="7" sourceId="9" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:14" parent="60" time="61" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-39.0229417805" dy="-559.894382068" id="6"/>
-      <move dx="-39.0229417805" dy="-559.894382068" id="7"/>
-      <move dx="-39.0229417805" dy="-559.894382068" id="8"/>
-      <move dx="-39.0229417805" dy="-559.894382068" id="9"/>
-    </action>
-    <action date="01 Mar 2007 18:14:14" parent="61" time="62" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="7" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="8" sourceId="5" sourceModule="vtkVistrailsFileReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="0" time="63" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="0" name="VTKCell" x="-209.687148555" y="-715.414720111"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="63" time="64" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="1" name="vtkActor" x="-287.064468509" y="-430.824853814"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="64" time="65" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="2" name="vtkVistrailsFileReader" x="-262.292020374" y="-118.719864177"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="65" time="66" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="3" name="vtkRenderer" x="-249.483054013" y="-553.014503986"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="66" time="67" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="4" name="vtkDataSetMapper" x="-266.305128484" y="-247.896239266"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="67" time="68" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="0" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="68" time="69" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="1" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="69" time="70" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="2" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="70" time="71" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="3" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="71" time="72" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="ScalarVisibilityOn" functionId="0" moduleId="4" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="72" time="73" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="4" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="73" time="74" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="0" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="0" sourceId="3" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="74" time="75" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="1" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="1" sourceId="4" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="75" time="76" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="3" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="2" sourceId="1" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:33" parent="76" time="77" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="4" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="3" sourceId="2" sourceModule="vtkVistrailsFileReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:41" parent="77" time="78" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="5" name="InputPort" x="-312.960721232" y="26.921352364"/>
-    </action>
-    <action date="01 Mar 2007 18:14:42" parent="78" time="79" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="2" destinationModule="vtkVistrailsFileReader" destinationPort="input_file(File)" id="4" sourceId="5" sourceModule="InputPort" sourcePort="InternalPipe(Variant)"/>
-    </action>
-    <action date="01 Mar 2007 18:14:56" parent="62" time="80" user="cscheid" what="deleteConnection">
-      <notes>
-        None
-      </notes>
-      <connection connectionId="5"/>
-      <connection connectionId="7"/>
-      <connection connectionId="8"/>
-      <connection connectionId="4"/>
-      <connection connectionId="6"/>
-    </action>
-    <action date="01 Mar 2007 18:14:56" parent="80" time="81" user="cscheid" what="deleteModule">
-      <notes>
-        None
-      </notes>
-      <module moduleId="8"/>
-      <module moduleId="5"/>
-      <module moduleId="7"/>
-      <module moduleId="9"/>
-      <module moduleId="6"/>
-    </action>
-    <action date="01 Mar 2007 18:15:01" parent="81" time="82" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="10" name="MeshCell" x="-269.411673235" y="-189.161387591"/>
-    </action>
-    <action date="01 Mar 2007 18:15:04" parent="82" time="83" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="10" destinationModule="MeshCell" destinationPort="input_file(File)" id="9" sourceId="4" sourceModule="MeshFilter" sourcePort="output_file(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:15:10" parent="83" time="84" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="74.5181223843" dy="-45.8573060826" id="2"/>
-      <move dx="74.5181223843" dy="-45.8573060826" id="3"/>
-      <move dx="11.4643265207" dy="82.1610067314" id="10"/>
-    </action>
-    <action date="01 Mar 2007 18:15:10" parent="84" time="85" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="11" name="MeshFilter" x="-250.146183261" y="13.393211086"/>
-    </action>
-    <action date="01 Mar 2007 18:15:10" parent="85" time="86" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="output_format" functionId="0" moduleId="11" parameter="<no description>" parameterId="0" type="String" value=".vtk"/>
-    </action>
-    <action date="01 Mar 2007 18:15:10" parent="86" time="87" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="11" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:15:13" parent="87" time="88" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-87.8931699917" dy="179.607782157" id="11"/>
-    </action>
-    <action date="01 Mar 2007 18:15:13" parent="88" time="89" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="11" destinationModule="MeshFilter" destinationPort="input_file(File)" id="10" sourceId="1" sourceModule="File" sourcePort="self(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:15:14" parent="89" time="90" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="12" name="MeshCell" x="-247.947346715" y="-97.000380859"/>
-    </action>
-    <action date="01 Mar 2007 18:15:14" parent="90" time="91" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="12" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:15:17" parent="91" time="92" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-187.250666504" dy="141.393360421" id="12"/>
-    </action>
-    <action date="01 Mar 2007 18:15:17" parent="92" time="93" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="12" destinationModule="MeshCell" destinationPort="input_file(File)" id="11" sourceId="11" sourceModule="MeshFilter" sourcePort="output_file(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="93" time="94" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-265.590231062" dy="-26.7500952149" id="1"/>
-      <move dx="-107.000380859" dy="-204.447156285" id="11"/>
-      <move dx="-11.4643265207" dy="-152.857686942" id="12"/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="94" time="95" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="13" name="MplFigureCell" x="37.0688549561" y="-60.0259508645"/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="95" time="96" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="14" name="MplPlot" x="-104.504769347" y="212.057733157"/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="96" time="97" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="15" name="MplFigure" x="-2.3575207408" y="92.971924974"/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="97" time="98" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="13" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="98" time="99" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0Afig%20%3D%20gcf%28%29%0A%0Aax3d%20%3D%20axes3d.Axes3D%28fig%29%0Aplt%20%3D%20fig.axes.append%28ax3d%29%0A%0Adelta%20%3D%20pi%20/%20199.0%0Au%20%3D%20arange%280%2C%202%2Api%2B%28delta%2A2%29%2C%20delta%2A2%29%0Av%20%3D%20arange%280%2C%20pi%2Bdelta%2C%20delta%29%0A%0Ax%20%3D%20outer%28cos%28u%29%2Csin%28v%29 [...]
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="99" time="100" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="14" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="100" time="101" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="15" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:16:57" parent="101" time="102" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="13" destinationModule="MplFigureCell" destinationPort="FigureManager(MplFigureManager)" id="12" sourceId="15" sourceModule="MplFigure" sourcePort="FigureManager(MplFigureManager)"/>
-    </action>
-    <action date="01 Mar 2007 18:16:58" parent="102" time="103" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="15" destinationModule="MplFigure" destinationPort="Script(String)" id="13" sourceId="14" sourceModule="MplPlot" sourcePort="source(String)"/>
-    </action>
-    <action date="01 Mar 2007 18:19:45" parent="103" time="104" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-187.250666504" dy="-460.483781913" id="13"/>
-      <move dx="-89.8038910785" dy="-443.287292132" id="14"/>
-      <move dx="-171.96489781" dy="-433.733686698" id="15"/>
-    </action>
-    <action date="01 Mar 2007 18:19:45" parent="104" time="105" user="cscheid" what="addModulePort">
-      <notes>
-        None
-      </notes>
-      <addPort moduleId="14" portName="inputFile" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="01 Mar 2007 18:19:45" parent="105" time="106" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0Afig%20%3D%20gcf%28%29%0A%0Aplot%28array%28%5B0%2C%201%2C%202%2C%203%5D%29%2C%20array%28%5B1%2C%203%2C%201%2C%203%5D%29%29%0A"/>
-    </action>
-    <action date="01 Mar 2007 18:19:52" parent="106" time="107" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="14" destinationModule="MplPlot" destinationPort="inputFile(File)" id="14" sourceId="2" sourceModule="MeshQualityHistogram" sourcePort="output(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:19:53" parent="107" time="108" user="cscheid" what="deleteConnection">
-      <notes>
-        None
-      </notes>
-      <connection connectionId="2"/>
-    </action>
-    <action date="01 Mar 2007 18:19:53" parent="108" time="109" user="cscheid" what="deleteModule">
-      <notes>
-        None
-      </notes>
-      <module moduleId="3"/>
-    </action>
-    <action date="01 Mar 2007 18:21:37" parent="109" time="110" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0Afig%20%3D%20gcf%28%29%0A%0Ax%20%3D%20arange%280.0%2C%201.0%2C%201.0/100.0%29%0Ay%20%3D%20array%28%5Bfloat%28x%29%20for%20x%20in%20file%28inputFile.name%29%5D%29%0A%0Aplot%28x%2C%20y%29%0A"/>
-    </action>
-    <action date="01 Mar 2007 18:23:36" parent="110" time="111" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0AinputFile%20%3D%20self.getInputFromPort%28%27inputFile%27%29%0A%0Afig%20%3D%20gcf%28%29%0A%0Ax%20%3D%20arange%280.0%2C%201.0%2C%201.0/100.0%29%0Ay%20%3D%20array%28%5Bfloat%28x%29%20for%20x%20in%20file%28inputFile.name%29%5D%29%0A%0Aplot%28x%2C%20y%29%0A"/>
-    </action>
-    <action date="01 Mar 2007 18:24:06" parent="111" time="112" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0AinputFile%20%3D%20self.getInputFromPort%28%27inputFile%27%29%0A%0Afig%20%3D%20gcf%28%29%0A%0Ax%20%3D%20arange%280.0%2C%201.0%2C%201.0/100.0%29%0Ay%20%3D%20array%28%5Bfloat%28x%29%20for%20x%20in%20file%28inputFile.name%29%5D%29%0A%0Aprint%20x%0A%0Aprint%20y%0A%0Aplot%28x%2C%20y%29%0A"/>
-    </action>
-    <action date="01 Mar 2007 18:24:38" parent="112" time="113" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0AinputFile%20%3D%20self.getInputFromPort%28%27inputFile%27%29%0A%0Afig%20%3D%20gcf%28%29%0A%0Ax%20%3D%20arange%280.0%2C%201.0%2C%201.0/100.0%29%0Ay%20%3D%20array%28%5Bfloat%28v%29%20for%20v%20in%20file%28inputFile.name%29%5D%29%0A%0Aprint%20x%0A%0Aprint%20y%0A%0Aplot%28x%2C%20y%29%0A"/>
-    </action>
-    <action date="01 Mar 2007 18:25:09" parent="113" time="114" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="244.572299107" dy="150.946965855" id="13"/>
-      <move dx="244.572299107" dy="150.946965855" id="14"/>
-      <move dx="244.572299107" dy="150.946965855" id="15"/>
-    </action>
-    <action date="01 Mar 2007 18:25:09" parent="114" time="115" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="16" name="MplFigure" x="-164.322418551" y="-330.761761724"/>
-    </action>
-    <action date="01 Mar 2007 18:25:09" parent="115" time="116" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="17" name="MplFigureCell" x="-140.181811548" y="-510.509732778"/>
-    </action>
-    <action date="01 Mar 2007 18:25:09" parent="116" time="117" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="18" name="MplPlot" x="-184.308660425" y="-221.229558975"/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="117" time="118" user="cscheid" what="addModule">
-      <notes>
-        None
-      </notes>
-      <object cache="0" id="19" name="MeshQualityHistogram" x="66.5181223843" y="36.1426939174"/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="118" time="119" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="16" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="119" time="120" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="17" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="120" time="121" user="cscheid" what="changeParameter">
-      <notes>
-        None
-      </notes>
-      <set alias="" function="source" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="String" value="import%20matplotlib.axes3d%20as%20axes3d%0A%0AinputFile%20%3D%20self.getInputFromPort%28%27inputFile%27%29%0A%0Afig%20%3D%20gcf%28%29%0A%0Ax%20%3D%20arange%280.0%2C%201.0%2C%201.0/100.0%29%0Ay%20%3D%20array%28%5Bfloat%28v%29%20for%20v%20in%20file%28inputFile.name%29%5D%29%0A%0Aprint%20x%0A%0Aprint%20y%0A%0Aplot%28x%2C%20y%29%0A"/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="121" time="122" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="18" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="122" time="123" user="cscheid" what="addModulePort">
-      <notes>
-        None
-      </notes>
-      <addPort moduleId="18" portName="inputFile" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="123" time="124" user="cscheid" what="changeAnnotation">
-      <notes>
-        None
-      </notes>
-      <set key="" moduleId="19" value=""/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="124" time="125" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="17" destinationModule="MplFigureCell" destinationPort="FigureManager(MplFigureManager)" id="15" sourceId="16" sourceModule="MplFigure" sourcePort="FigureManager(MplFigureManager)"/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="125" time="126" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="16" destinationModule="MplFigure" destinationPort="Script(String)" id="16" sourceId="18" sourceModule="MplPlot" sourcePort="source(String)"/>
-    </action>
-    <action date="01 Mar 2007 18:25:10" parent="126" time="127" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="18" destinationModule="MplPlot" destinationPort="inputFile(File)" id="17" sourceId="19" sourceModule="MeshQualityHistogram" sourcePort="output(File)"/>
-    </action>
-    <action date="01 Mar 2007 18:25:24" parent="127" time="128" user="cscheid" what="moveModule">
-      <notes>
-        None
-      </notes>
-      <move dx="-196.804271938" dy="49.6787482562" id="11"/>
-      <move dx="-196.804271938" dy="49.6787482562" id="12"/>
-      <move dx="-168.143455636" dy="-225.46508824" id="16"/>
-      <move dx="-168.143455636" dy="-225.46508824" id="17"/>
-      <move dx="-168.143455636" dy="-225.46508824" id="18"/>
-      <move dx="-397.429986049" dy="-385.965659529" id="19"/>
-    </action>
-    <action date="01 Mar 2007 18:25:24" parent="128" time="129" user="cscheid" what="addConnection">
-      <notes>
-        None
-      </notes>
-      <connect destinationId="19" destinationModule="MeshQualityHistogram" destinationPort="file(File)" id="18" sourceId="1" sourceModule="File" sourcePort="self(File)"/>
-    </action>
-    <tag name="MeshCell" time="79"/>
-    <tag name="vtkVistrailsFileReader" time="42"/>
-  </visTrail>
diff --git a/examples-internal/corie.xml b/examples-internal/corie.xml
deleted file mode 100644
index 8640a5c..0000000
--- a/examples-internal/corie.xml
+++ /dev/null
@@ -1,9009 +0,0 @@
-  <visTrail version="0.3.1">
-    <action date="20 Feb 2007 22:50:33" parent="0" time="1" user="emanuele" what="addModule">
-      <object cache="1" id="0" name="vtkCornerAnnotation" x="1034.11991838" y="-58.3393925256"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="1" time="2" user="emanuele" what="addModule">
-      <object cache="1" id="1" name="vtkActor" x="1527.32015179" y="-249.262640518"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="2" time="3" user="emanuele" what="addModule">
-      <object cache="1" id="2" name="vtkColorTransferFunction" x="688.135907588" y="231.58177416"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="3" time="4" user="emanuele" what="addModule">
-      <object cache="1" id="3" name="VTKCell" x="1391.97591862" y="-567.894434513"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="4" time="5" user="emanuele" what="addModule">
-      <object cache="1" id="4" name="vtkConeSource" x="1529.10671562" y="277.773705378"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="5" time="6" user="emanuele" what="addModule">
-      <object cache="1" id="5" name="vtkRenderer" x="1126.59136348" y="-482.339603991"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="6" time="7" user="emanuele" what="addModule">
-      <object cache="1" id="6" name="vtkCORIEUnstructuredGridReader" x="418.239165751" y="151.010904512"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="7" time="8" user="emanuele" what="addModule">
-      <object cache="1" id="7" name="vtkScalarBarActor" x="836.37112053" y="-202.13140985"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="8" time="9" user="emanuele" what="addModule">
-      <object cache="1" id="8" name="vtkUnstructuredGrid" x="1091.15098771" y="524.040867763"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="9" time="10" user="emanuele" what="addModule">
-      <object cache="1" id="9" name="vtkProbeFilter" x="1202.33440979" y="271.24222817"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="10" time="11" user="emanuele" what="addModule">
-      <object cache="1" id="10" name="vtkGlyph2D" x="1364.74284306" y="104.477008592"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="11" time="12" user="emanuele" what="addModule">
-      <object cache="1" id="11" name="vtkPoints" x="689.885161439" y="565.332955628"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="12" time="13" user="emanuele" what="addModule">
-      <object cache="1" id="12" name="vtkTextProperty" x="848.94125449" y="320.68414913"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="13" time="14" user="emanuele" what="addModule">
-      <object cache="1" id="13" name="vtkDataSetMapper" x="1383.08800066" y="-67.4334562647"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="14" time="15" user="emanuele" what="addModule">
-      <object cache="1" id="14" name="vtkProperty" x="1604.14239657" y="86.6113697478"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="15" time="16" user="emanuele" what="addModule">
-      <object cache="1" id="15" name="vtkActor" x="664.542307966" y="-301.817763707"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="16" time="17" user="emanuele" what="addModule">
-      <object cache="1" id="16" name="vtkCORIEUnstructuredGridReader" x="817.54781389" y="409.941849195"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="17" time="18" user="emanuele" what="addModule">
-      <object cache="1" id="17" name="vtkProperty" x="451.377069242" y="-140.384892112"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="18" time="19" user="emanuele" what="addModule">
-      <object cache="1" id="18" name="CellLocation" x="1425.54504314" y="-424.279517609"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="19" time="20" user="emanuele" what="addModule">
-      <object cache="1" id="19" name="vtkDataSetMapper" x="578.36256334" y="-46.76947102"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="20" time="21" user="emanuele" what="addModule">
-      <object cache="1" id="20" name="vtkCamera" x="1311.70460535" y="-224.351717051"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="21" time="22" user="emanuele" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 21:00:00"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="22" time="23" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="0" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="23" time="24" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="1" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="24" time="25" user="emanuele" what="changeParameter">
-      <set alias="" function="SetColorSpaceToRGB" functionId="0" moduleId="2" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="25" time="26" user="emanuele" what="changeParameter">
-      <set alias="" function="ClampingOn" functionId="1" moduleId="2" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="26" time="27" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.47"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="27" time="28" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.81"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="28" time="29" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="20"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.15"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.43"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="29" time="30" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="24"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.15"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.72"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="30" time="31" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="28"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.16"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="31" time="32" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="30"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.16"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.73"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="32" time="33" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.73"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.31"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="33" time="34" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31.4"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.45"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="34" time="35" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31.8"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.93"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="35" time="36" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.75"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="36" time="37" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.2"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.56"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="37" time="38" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.4"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.37"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="38" time="39" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.6"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.88"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="39" time="40" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.8"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.68"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="40" time="41" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="33.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.49"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="41" time="42" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.49"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="42" time="43" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="2" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="43" time="44" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="3" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="44" time="45" user="emanuele" what="changeParameter">
-      <set alias="" function="CappingOn" functionId="0" moduleId="4" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="45" time="46" user="emanuele" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="1" moduleId="4" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="46" time="47" user="emanuele" what="changeParameter">
-      <set alias="" function="SetHeight" functionId="2" moduleId="4" parameter="<no description>" parameterId="0" type="Float" value="3000"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="47" time="48" user="emanuele" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="3" moduleId="4" parameter="<no description>" parameterId="0" type="Float" value="300"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="48" time="49" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="4" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="49" time="50" user="emanuele" what="changeParameter">
-      <set alias="" function="SetBackground" functionId="0" moduleId="5" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="5" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="5" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="50" time="51" user="emanuele" what="changeParameter">
-      <set alias="" function="ResetCameraClippingRange" functionId="1" moduleId="5" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="51" time="52" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="5" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="52" time="53" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFileName" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="../examples/data/1_salt.63"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="53" time="54" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="95"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="54" time="55" user="emanuele" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="2" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="55" time="56" user="emanuele" what="changeParameter">
-      <set alias="" function="SetVerticalShift" functionId="3" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="-100"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="56" time="57" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="6" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="57" time="58" user="emanuele" what="changeParameter">
-      <set alias="" function="SetNumberOfLabels" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Integer" value="8"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="58" time="59" user="emanuele" what="changeParameter">
-      <set alias="" function="SetHeight" functionId="1" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="0.6"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="59" time="60" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="7" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="60" time="61" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="8" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="61" time="62" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="9" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="62" time="63" user="emanuele" what="changeParameter">
-      <set alias="" function="OrientOn" functionId="0" moduleId="10" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="63" time="64" user="emanuele" what="changeParameter">
-      <set alias="" function="SetVectorModeToUseVector" functionId="1" moduleId="10" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="64" time="65" user="emanuele" what="changeParameter">
-      <set alias="" function="SetColorModeToColorByScalar" functionId="2" moduleId="10" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="65" time="66" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="10" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="66" time="67" user="emanuele" what="changeParameter">
-      <set alias="" function="InsertNextPoint" functionId="0" moduleId="11" parameter="<no description>" parameterId="0" type="Float" value="113734.609286"/>
-      <set alias="" function="InsertNextPoint" functionId="0" moduleId="11" parameter="<no description>" parameterId="1" type="Float" value="165718.376885"/>
-      <set alias="" function="InsertNextPoint" functionId="0" moduleId="11" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="67" time="68" user="emanuele" what="changeParameter">
-      <set alias="" function="InsertNextPoint" functionId="1" moduleId="11" parameter="<no description>" parameterId="0" type="Float" value="99973.093896"/>
-      <set alias="" function="InsertNextPoint" functionId="1" moduleId="11" parameter="<no description>" parameterId="1" type="Float" value="304108.195791"/>
-      <set alias="" function="InsertNextPoint" functionId="1" moduleId="11" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="68" time="69" user="emanuele" what="changeParameter">
-      <set alias="" function="InsertNextPoint" functionId="2" moduleId="11" parameter="<no description>" parameterId="0" type="Float" value="96696.997373"/>
-      <set alias="" function="InsertNextPoint" functionId="2" moduleId="11" parameter="<no description>" parameterId="1" type="Float" value="441862.953096"/>
-      <set alias="" function="InsertNextPoint" functionId="2" moduleId="11" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="69" time="70" user="emanuele" what="changeParameter">
-      <set alias="" function="InsertNextPoint" functionId="3" moduleId="11" parameter="<no description>" parameterId="0" type="Float" value="290740.998481"/>
-      <set alias="" function="InsertNextPoint" functionId="3" moduleId="11" parameter="<no description>" parameterId="1" type="Float" value="149131.407453"/>
-      <set alias="" function="InsertNextPoint" functionId="3" moduleId="11" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="70" time="71" user="emanuele" what="changeParameter">
-      <set alias="" function="InsertNextPoint" functionId="4" moduleId="11" parameter="<no description>" parameterId="0" type="Float" value="255945.317532"/>
-      <set alias="" function="InsertNextPoint" functionId="4" moduleId="11" parameter="<no description>" parameterId="1" type="Float" value="433511.203416"/>
-      <set alias="" function="InsertNextPoint" functionId="4" moduleId="11" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="71" time="72" user="emanuele" what="changeParameter">
-      <set alias="" function="InsertNextPoint" functionId="5" moduleId="11" parameter="<no description>" parameterId="0" type="Float" value="278171.046176"/>
-      <set alias="" function="InsertNextPoint" functionId="5" moduleId="11" parameter="<no description>" parameterId="1" type="Float" value="291109.255391"/>
-      <set alias="" function="InsertNextPoint" functionId="5" moduleId="11" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="72" time="73" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="11" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="73" time="74" user="emanuele" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="12" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="12" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="12" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="74" time="75" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFontFamilyToArial" functionId="1" moduleId="12" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="75" time="76" user="emanuele" what="changeParameter">
-      <set alias="" function="ShadowOff" functionId="2" moduleId="12" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="76" time="77" user="emanuele" what="changeParameter">
-      <set alias="" function="BoldOff" functionId="3" moduleId="12" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="77" time="78" user="emanuele" what="changeParameter">
-      <set alias="" function="ItalicOff" functionId="4" moduleId="12" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="78" time="79" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="12" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="79" time="80" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="13" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="80" time="81" user="emanuele" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="14" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="14" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="81" time="82" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="14" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="82" time="83" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="15" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="83" time="84" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFileName" functionId="0" moduleId="16" parameter="<no description>" parameterId="0" type="String" value="../examples/data/1_wind.62"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="84" time="85" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="1" moduleId="16" parameter="<no description>" parameterId="0" type="Integer" value="95"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="85" time="86" user="emanuele" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="2" moduleId="16" parameter="<no description>" parameterId="0" type="Float" value="1.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="86" time="87" user="emanuele" what="changeParameter">
-      <set alias="" function="SetVerticalShift" functionId="3" moduleId="16" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="87" time="88" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="16" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="88" time="89" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="17" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="89" time="90" user="emanuele" what="changeParameter">
-      <set alias="" function="ColumnRowAddress" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="String" value="A1"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="90" time="91" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="18" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="91" time="92" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="19" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="92" time="93" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="288871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="823378.928288"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="93" time="94" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="288871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="94" time="95" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="95" time="96" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="20" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="96" time="97" user="emanuele" what="addConnection">
-      <connect destinationId="0" destinationModule="vtkCornerAnnotation" destinationPort="SetTextProperty(vtkTextProperty)" id="0" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="97" time="98" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="1" sourceId="0" sourceModule="vtkCornerAnnotation" sourcePort="self(vtkCornerAnnotation)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="98" time="99" user="emanuele" what="addConnection">
-      <connect destinationId="1" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="2" sourceId="14" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="99" time="100" user="emanuele" what="addConnection">
-      <connect destinationId="1" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="3" sourceId="13" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="100" time="101" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="4" sourceId="1" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="101" time="102" user="emanuele" what="addConnection">
-      <connect destinationId="19" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="5" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="102" time="103" user="emanuele" what="addConnection">
-      <connect destinationId="7" destinationModule="vtkScalarBarActor" destinationPort="SetLookupTable(vtkScalarsToColors)" id="6" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="103" time="104" user="emanuele" what="addConnection">
-      <connect destinationId="3" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="7" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="104" time="105" user="emanuele" what="addConnection">
-      <connect destinationId="3" destinationModule="VTKCell" destinationPort="Location(CellLocation)" id="8" sourceId="18" sourceModule="CellLocation" sourcePort="self(CellLocation)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="105" time="106" user="emanuele" what="addConnection">
-      <connect destinationId="10" destinationModule="vtkGlyph2D" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="9" sourceId="4" sourceModule="vtkConeSource" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="106" time="107" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="10" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="107" time="108" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="11" sourceId="7" sourceModule="vtkScalarBarActor" sourcePort="self(vtkScalarBarActor)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="108" time="109" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="SetActiveCamera(vtkCamera)" id="12" sourceId="20" sourceModule="vtkCamera" sourcePort="self(vtkCamera)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="109" time="110" user="emanuele" what="addConnection">
-      <connect destinationId="19" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="13" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="110" time="111" user="emanuele" what="addConnection">
-      <connect destinationId="7" destinationModule="vtkScalarBarActor" destinationPort="SetTitleTextProperty(vtkTextProperty)" id="14" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="111" time="112" user="emanuele" what="addConnection">
-      <connect destinationId="8" destinationModule="vtkPointSet" destinationPort="SetPoints(vtkPoints)" id="15" sourceId="11" sourceModule="vtkPoints" sourcePort="self(vtkPoints)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="112" time="113" user="emanuele" what="addConnection">
-      <connect destinationId="9" destinationModule="vtkDataSetAlgorithm" destinationPort="SetInput(vtkDataObject)" id="16" sourceId="8" sourceModule="vtkUnstructuredGrid" sourcePort="self(vtkUnstructuredGrid)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="113" time="114" user="emanuele" what="addConnection">
-      <connect destinationId="9" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="17" sourceId="16" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="114" time="115" user="emanuele" what="addConnection">
-      <connect destinationId="10" destinationModule="vtkGlyph2D" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="18" sourceId="9" sourceModule="vtkProbeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="115" time="116" user="emanuele" what="addConnection">
-      <connect destinationId="13" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="19" sourceId="10" sourceModule="vtkGlyph2D" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="116" time="117" user="emanuele" what="addConnection">
-      <connect destinationId="15" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="20" sourceId="19" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="20 Feb 2007 22:50:33" parent="117" time="118" user="emanuele" what="addConnection">
-      <connect destinationId="15" destinationModule="vtkActor" destinationPort="SetBackfaceProperty(vtkProperty)" id="21" sourceId="17" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="118" time="119" user="emanuele" what="addModule">
-      <object cache="1" id="21" name="HTTPFile" x="510.751822568" y="760.282758217"/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="119" time="120" user="emanuele" what="addModule">
-      <object cache="1" id="22" name="Unzip" x="520.597962218" y="675.192654404"/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="120" time="121" user="emanuele" what="changeParameter">
-      <set alias="" function="url" functionId="0" moduleId="21" parameter="<no description>" parameterId="0" type="String" value="http://www.vistrails.org/data/1_wind.62.zip"/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="121" time="122" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="21" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="122" time="123" user="emanuele" what="changeParameter">
-      <set alias="" function="filename_in_archive" functionId="0" moduleId="22" parameter="<no description>" parameterId="0" type="String" value="1_wind.62"/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="123" time="124" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="22" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:51:50" parent="124" time="125" user="emanuele" what="addConnection">
-      <connect destinationId="22" destinationModule="Unzip" destinationPort="archive_file(File)" id="22" sourceId="21" sourceModule="HTTPFile" sourcePort="file(File)"/>
-    </action>
-    <action date="20 Feb 2007 22:52:18" parent="125" time="126" user="emanuele" what="moveModule">
-      <move dx="314.808975907" dy="43.959811951" id="11"/>
-      <move dx="225.471293555" dy="-56.7223380013" id="21"/>
-      <move dx="225.471293555" dy="-56.7223380013" id="22"/>
-    </action>
-    <action date="20 Feb 2007 22:52:18" parent="126" time="127" user="emanuele" what="addModule">
-      <object cache="1" id="23" name="PythonSource" x="498.129984085" y="582.910364636"/>
-    </action>
-    <action date="20 Feb 2007 22:52:19" parent="127" time="128" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="23" parameter="<no description>" parameterId="0" type="String" value="%23%20Extracts%20the%20internal%20file%20name%20so%20VTK%20can%20use%20it%0A%23%20Also%2C%20makes%20local%20copy%20so%20that%20the%20file%20survives%20filepool%0A%23%20cleanup.%0Afrom%20packages.spreadsheet.spreadsheet_controller%20import%20spreadsheetController%0Aself.checkInputPort%28%22file%22%29%0Awindow%20%3D%20spreadsheetController.findSpreadshe [...]
-    </action>
-    <action date="20 Feb 2007 22:52:19" parent="128" time="129" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="23" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:52:35" parent="129" time="130" user="emanuele" what="moveModule">
-      <move dx="269.431105506" dy="-55.3042795513" id="23"/>
-    </action>
-    <action date="20 Feb 2007 22:52:35" parent="130" time="131" user="emanuele" what="deleteFunction">
-      <function functionId="0" moduleId="16"/>
-    </action>
-    <action date="20 Feb 2007 22:53:03" parent="131" time="132" user="emanuele" what="addModulePort">
-      <addPort moduleId="23" portName="file" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 22:53:03" parent="132" time="133" user="emanuele" what="addModulePort">
-      <addPort moduleId="23" portName="name" portSpec="(String)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 22:53:15" parent="133" time="134" user="emanuele" what="addModulePort">
-      <addPort moduleId="23" portName="file" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 22:53:19" parent="134" time="135" user="emanuele" what="addConnection">
-      <connect destinationId="23" destinationModule="PythonSource" destinationPort="file(File)" id="23" sourceId="22" sourceModule="Unzip" sourcePort="file(File)"/>
-    </action>
-    <action date="20 Feb 2007 22:53:28" parent="135" time="136" user="emanuele" what="moveModule">
-      <move dx="0.0" dy="-1.41805845003" id="16"/>
-    </action>
-    <action date="20 Feb 2007 22:53:31" parent="136" time="137" user="emanuele" what="addConnection">
-      <connect destinationId="16" destinationModule="vtkDataReader" destinationPort="SetFileName(String)" id="24" sourceId="23" sourceModule="PythonSource" sourcePort="name(String)"/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="137" time="138" user="emanuele" what="addModule">
-      <object cache="1" id="24" name="Unzip" x="756.069255773" y="628.470316403"/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="138" time="139" user="emanuele" what="addModule">
-      <object cache="1" id="25" name="HTTPFile" x="746.223116123" y="713.560420216"/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="139" time="140" user="emanuele" what="changeParameter">
-      <set alias="" function="filename_in_archive" functionId="0" moduleId="24" parameter="<no description>" parameterId="0" type="String" value="1_wind.62"/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="140" time="141" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="24" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="141" time="142" user="emanuele" what="changeParameter">
-      <set alias="" function="url" functionId="0" moduleId="25" parameter="<no description>" parameterId="0" type="String" value="http://www.vistrails.org/data/1_wind.62.zip"/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="142" time="143" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="25" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:55:16" parent="143" time="144" user="emanuele" what="addConnection">
-      <connect destinationId="24" destinationModule="Unzip" destinationPort="archive_file(File)" id="25" sourceId="25" sourceModule="HTTPFile" sourcePort="file(File)"/>
-    </action>
-    <action date="20 Feb 2007 22:55:34" parent="144" time="145" user="emanuele" what="moveModule">
-      <move dx="-393.264654737" dy="-294.948491053" id="24"/>
-      <move dx="-393.264654737" dy="-294.948491053" id="25"/>
-    </action>
-    <action date="20 Feb 2007 22:55:34" parent="145" time="146" user="emanuele" what="changeParameter">
-      <set alias="" function="url" functionId="0" moduleId="25" parameter="<no description>" parameterId="0" type="String" value="http://www.vistrails.org/data/1_salt.63.zip"/>
-    </action>
-    <action date="20 Feb 2007 22:55:44" parent="146" time="147" user="emanuele" what="changeParameter">
-      <set alias="" function="filename_in_archive" functionId="0" moduleId="24" parameter="<no description>" parameterId="0" type="String" value="1_salt.63"/>
-    </action>
-    <action date="20 Feb 2007 22:55:52" parent="147" time="148" user="emanuele" what="addModule">
-      <object cache="1" id="26" name="PythonSource" x="777.561089591" y="537.606085085"/>
-    </action>
-    <action date="20 Feb 2007 22:55:52" parent="148" time="149" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="26" parameter="<no description>" parameterId="0" type="String" value="%23%20Extracts%20the%20internal%20file%20name%20so%20VTK%20can%20use%20it%0A%23%20Also%2C%20makes%20local%20copy%20so%20that%20the%20file%20survives%20filepool%0A%23%20cleanup.%0Afrom%20packages.spreadsheet.spreadsheet_controller%20import%20spreadsheetController%0Aself.checkInputPort%28%22file%22%29%0Awindow%20%3D%20spreadsheetController.findSpreadshe [...]
-    </action>
-    <action date="20 Feb 2007 22:55:52" parent="149" time="150" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="26" value=""/>
-    </action>
-    <action date="20 Feb 2007 22:56:26" parent="150" time="151" user="emanuele" what="moveModule">
-      <move dx="-400.827436559" dy="-283.60431832" id="26"/>
-    </action>
-    <action date="20 Feb 2007 22:56:26" parent="151" time="152" user="emanuele" what="addModulePort">
-      <addPort moduleId="26" portName="file" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 22:56:26" parent="152" time="153" user="emanuele" what="addModulePort">
-      <addPort moduleId="26" portName="name" portSpec="(String)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 22:56:27" parent="153" time="154" user="emanuele" what="addModulePort">
-      <addPort moduleId="26" portName="file" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 22:56:45" parent="154" time="155" user="emanuele" what="deleteFunction">
-      <function functionId="0" moduleId="6"/>
-    </action>
-    <action date="20 Feb 2007 22:56:57" parent="155" time="156" user="emanuele" what="addConnection">
-      <connect destinationId="6" destinationModule="vtkDataReader" destinationPort="SetFileName(String)" id="26" sourceId="26" sourceModule="PythonSource" sourcePort="name(String)"/>
-    </action>
-    <action date="20 Feb 2007 22:57:00" parent="156" time="157" user="emanuele" what="addConnection">
-      <connect destinationId="26" destinationModule="PythonSource" destinationPort="file(File)" id="27" sourceId="24" sourceModule="Unzip" sourcePort="file(File)"/>
-    </action>
-    <action date="20 Feb 2007 22:58:53" parent="157" time="158" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="16" parameter="<no description>" parameterId="0" type="Integer" value="60"/>
-    </action>
-    <action date="20 Feb 2007 22:59:01" parent="158" time="159" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="60"/>
-    </action>
-    <action date="20 Feb 2007 23:00:33" parent="159" time="160" user="emanuele" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Oct-11 18:00:00"/>
-    </action>
-    <action date="20 Feb 2007 23:01:17" parent="160" time="161" user="emanuele" what="changeParameter">
-      <set alias="" function="ColumnRowAddress" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="String" value="B1"/>
-    </action>
-    <action date="20 Feb 2007 23:02:57" parent="157" time="162" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="16" parameter="<no description>" parameterId="0" type="Integer" value="30"/>
-    </action>
-    <action date="20 Feb 2007 23:03:02" parent="162" time="163" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="30"/>
-    </action>
-    <action date="20 Feb 2007 23:03:16" parent="163" time="164" user="emanuele" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Oct-11 12:00:00"/>
-    </action>
-    <action date="20 Feb 2007 23:04:39" parent="157" time="165" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="16" parameter="<no description>" parameterId="0" type="Integer" value="90"/>
-    </action>
-    <action date="20 Feb 2007 23:04:44" parent="165" time="166" user="emanuele" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="90"/>
-    </action>
-    <action date="20 Feb 2007 23:05:01" parent="166" time="167" user="emanuele" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Oct-11 24:00:00"/>
-    </action>
-    <action date="20 Feb 2007 23:05:07" parent="167" time="168" user="emanuele" what="changeParameter">
-      <set alias="" function="ColumnRowAddress" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="String" value="C1"/>
-    </action>
-    <action date="20 Feb 2007 23:06:32" parent="164" time="169" user="emanuele" what="deleteConnection">
-      <connection connectionId="7"/>
-      <connection connectionId="8"/>
-    </action>
-    <action date="20 Feb 2007 23:06:32" parent="169" time="170" user="emanuele" what="deleteModule">
-      <module moduleId="3"/>
-    </action>
-    <action date="20 Feb 2007 23:07:04" parent="170" time="171" user="emanuele" what="moveModule">
-      <move dx="-87.2343489712" dy="46.0403508459" id="5"/>
-    </action>
-    <action date="20 Feb 2007 23:07:04" parent="171" time="172" user="emanuele" what="addModule">
-      <object cache="1" id="27" name="SheetReference" x="845.30516105" y="-1059.21860426"/>
-    </action>
-    <action date="20 Feb 2007 23:07:04" parent="172" time="173" user="emanuele" what="addModule">
-      <object cache="1" id="28" name="RichTextCell" x="832.724802472" y="-850.069864812"/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="173" time="174" user="emanuele" what="addModule">
-      <object cache="1" id="29" name="CellLocation" x="840.504976386" y="-955.819381689"/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="174" time="175" user="emanuele" what="changeParameter">
-      <set alias="" function="MinColumnCount" functionId="0" moduleId="27" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="175" time="176" user="emanuele" what="changeParameter">
-      <set alias="" function="MinRowCount" functionId="1" moduleId="27" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="176" time="177" user="emanuele" what="changeParameter">
-      <set alias="" function="SheetName" functionId="2" moduleId="27" parameter="<no description>" parameterId="0" type="String" value="Salinity 60"/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="177" time="178" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="27" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="178" time="179" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="28" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:07:05" parent="179" time="180" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="29" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:07:06" parent="180" time="181" user="emanuele" what="addConnection">
-      <connect destinationId="29" destinationModule="CellLocation" destinationPort="SheetReference(SheetReference)" id="28" sourceId="27" sourceModule="SheetReference" sourcePort="self(SheetReference)"/>
-    </action>
-    <action date="20 Feb 2007 23:07:06" parent="181" time="182" user="emanuele" what="addConnection">
-      <connect destinationId="28" destinationModule="RichTextCell" destinationPort="Location(CellLocation)" id="29" sourceId="29" sourceModule="CellLocation" sourcePort="self(CellLocation)"/>
-    </action>
-    <action date="20 Feb 2007 23:07:46" parent="182" time="183" user="emanuele" what="moveModule">
-      <move dx="-25.3348992958" dy="250.182130546" id="27"/>
-      <move dx="-25.3348992958" dy="250.182130546" id="28"/>
-      <move dx="-25.3348992958" dy="250.182130546" id="29"/>
-    </action>
-    <action date="20 Feb 2007 23:07:46" parent="183" time="184" user="emanuele" what="addModule">
-      <object cache="1" id="30" name="PythonSource" x="754.625002262" y="-594.276667201"/>
-    </action>
-    <action date="20 Feb 2007 23:07:46" parent="184" time="185" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Awindow%20%3D%20vtk.vtkRenderWindow%28%29%0Ar%20%3D%20self.getInputFromPort%28%22renderer%22%29.vtkInstance%0Ar.ResetCamera%28%29%0Awindow.AddRenderer%28r%29%0Awindow.OffScreenRenderingOn%28%29%0Awindow.Start%28%29%0Awindow.Render%28%29%0Awin2image%20%3D%20vtk.vtkWindowToImageFilter%28%29%0Awin2image.SetInput%28window%29%0Awin2image.Upda [...]
-    </action>
-    <action date="20 Feb 2007 23:07:46" parent="185" time="186" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="30" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:08:32" parent="186" time="187" user="emanuele" what="moveModule">
-      <move dx="-19.0011744719" dy="129.841358891" id="30"/>
-    </action>
-    <action date="20 Feb 2007 23:08:32" parent="187" time="188" user="emanuele" what="addModulePort">
-      <addPort moduleId="30" portName="renderer" portSpec="(vtkRenderer)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 23:08:33" parent="188" time="189" user="emanuele" what="addModulePort">
-      <addPort moduleId="30" portName="image" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 23:08:53" parent="189" time="190" user="emanuele" what="moveModule">
-      <move dx="-129.841358891" dy="31.6686241198" id="30"/>
-    </action>
-    <action date="20 Feb 2007 23:08:53" parent="190" time="191" user="emanuele" what="addModule">
-      <object cache="1" id="31" name="PythonSource" x="836.780897749" y="-721.414679071"/>
-    </action>
-    <action date="20 Feb 2007 23:08:53" parent="191" time="192" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="31" parameter="<no description>" parameterId="0" type="String" value="imageFile%20%3D%20self.getInputFromPort%28%22imageFile%22%29%0A%0Atext%20%3D%20%27%3CHTML%3E%3CTITLE%3EElcirc%20run%20todaydev%3C/TITLE%3E%3CBODY%20BGCOLOR%3D%22%23FFFFFF%22%3E%3CTABLE%20WIDTH%3D%22100%25%22%20BORDER%3D%221%22%20BGCOLOR%3D%22%23FFFFFF%22%20CELLPADDING%3D%224%22%3E%20%27%0Atext%20%2B%3D%20%27%3CTR%3E%3CTD%3EToday%20Salinity%3CBR%3Esali [...]
-    </action>
-    <action date="20 Feb 2007 23:08:53" parent="192" time="193" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="31" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:09:32" parent="193" time="194" user="emanuele" what="moveModule">
-      <move dx="0.0" dy="-38.0023489437" id="27"/>
-      <move dx="0.0" dy="-28.5017617078" id="28"/>
-      <move dx="6.33372482396" dy="-25.3348992958" id="29"/>
-      <move dx="376.856627025" dy="-88.6721475354" id="30"/>
-      <move dx="-123.507634067" dy="202.679194367" id="31"/>
-    </action>
-    <action date="20 Feb 2007 23:09:32" parent="194" time="195" user="emanuele" what="addModulePort">
-      <addPort moduleId="31" portName="imageFile" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 23:09:32" parent="195" time="196" user="emanuele" what="addModulePort">
-      <addPort moduleId="31" portName="htmlFile" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 23:09:42" parent="196" time="197" user="emanuele" what="moveModule">
-      <move dx="-53.8366610036" dy="38.0023489437" id="5"/>
-    </action>
-    <action date="20 Feb 2007 23:09:42" parent="197" time="198" user="emanuele" what="addConnection">
-      <connect destinationId="30" destinationModule="PythonSource" destinationPort="renderer(vtkRenderer)" id="30" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="20 Feb 2007 23:09:52" parent="198" time="199" user="emanuele" what="moveModule">
-      <move dx="-32.3332087983" dy="36.6443033047" id="30"/>
-      <move dx="347.043107768" dy="-62.5108703433" id="31"/>
-    </action>
-    <action date="20 Feb 2007 23:09:52" parent="199" time="200" user="emanuele" what="addConnection">
-      <connect destinationId="31" destinationModule="PythonSource" destinationPort="imageFile(File)" id="31" sourceId="30" sourceModule="PythonSource" sourcePort="image(File)"/>
-    </action>
-    <action date="20 Feb 2007 23:09:55" parent="200" time="201" user="emanuele" what="addConnection">
-      <connect destinationId="28" destinationModule="RichTextCell" destinationPort="File(File)" id="32" sourceId="31" sourceModule="PythonSource" sourcePort="htmlFile(File)"/>
-    </action>
-    <action date="20 Feb 2007 23:11:52" parent="201" time="202" user="emanuele" what="changeParameter">
-      <set alias="" function="SheetName" functionId="2" moduleId="27" parameter="<no description>" parameterId="0" type="String" value="Salinity30"/>
-    </action>
-    <action date="20 Feb 2007 23:11:55" parent="202" time="203" user="emanuele" what="changeParameter">
-      <set alias="" function="SheetName" functionId="2" moduleId="27" parameter="<no description>" parameterId="0" type="String" value="Salinity 30"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="161" time="204" user="emanuele" what="addModule">
-      <object cache="1" id="27" name="SheetReference" x="845.30516105" y="-1059.21860426"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="204" time="205" user="emanuele" what="addModule">
-      <object cache="1" id="28" name="RichTextCell" x="832.724802472" y="-850.069864812"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="205" time="206" user="emanuele" what="addModule">
-      <object cache="1" id="29" name="CellLocation" x="840.504976386" y="-955.819381689"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="206" time="207" user="emanuele" what="changeParameter">
-      <set alias="" function="MinColumnCount" functionId="0" moduleId="27" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="207" time="208" user="emanuele" what="changeParameter">
-      <set alias="" function="MinRowCount" functionId="1" moduleId="27" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="208" time="209" user="emanuele" what="changeParameter">
-      <set alias="" function="SheetName" functionId="2" moduleId="27" parameter="<no description>" parameterId="0" type="String" value="Salinity 60"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="209" time="210" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="27" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="210" time="211" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="28" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="211" time="212" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="29" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="212" time="213" user="emanuele" what="addConnection">
-      <connect destinationId="29" destinationModule="CellLocation" destinationPort="SheetReference(SheetReference)" id="28" sourceId="27" sourceModule="SheetReference" sourcePort="self(SheetReference)"/>
-    </action>
-    <action date="20 Feb 2007 23:13:20" parent="213" time="214" user="emanuele" what="addConnection">
-      <connect destinationId="28" destinationModule="RichTextCell" destinationPort="Location(CellLocation)" id="29" sourceId="29" sourceModule="CellLocation" sourcePort="self(CellLocation)"/>
-    </action>
-    <action date="20 Feb 2007 23:13:47" parent="214" time="215" user="emanuele" what="addModule">
-      <object cache="1" id="30" name="PythonSource" x="960.305887126" y="-474.794528421"/>
-    </action>
-    <action date="20 Feb 2007 23:13:47" parent="215" time="216" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Awindow%20%3D%20vtk.vtkRenderWindow%28%29%0Ar%20%3D%20self.getInputFromPort%28%22renderer%22%29.vtkInstance%0Ar.ResetCamera%28%29%0Awindow.AddRenderer%28r%29%0Awindow.OffScreenRenderingOn%28%29%0Awindow.Start%28%29%0Awindow.Render%28%29%0Awin2image%20%3D%20vtk.vtkWindowToImageFilter%28%29%0Awin2image.SetInput%28window%29%0Awin2image.Upda [...]
-    </action>
-    <action date="20 Feb 2007 23:13:47" parent="216" time="217" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="30" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:14:06" parent="217" time="218" user="emanuele" what="addModule">
-      <object cache="1" id="31" name="PythonSource" x="1070.31637145" y="-571.246355048"/>
-    </action>
-    <action date="20 Feb 2007 23:14:06" parent="218" time="219" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="31" parameter="<no description>" parameterId="0" type="String" value="imageFile%20%3D%20self.getInputFromPort%28%22imageFile%22%29%0A%0Atext%20%3D%20%27%3CHTML%3E%3CTITLE%3EElcirc%20run%20todaydev%3C/TITLE%3E%3CBODY%20BGCOLOR%3D%22%23FFFFFF%22%3E%3CTABLE%20WIDTH%3D%22100%25%22%20BORDER%3D%221%22%20BGCOLOR%3D%22%23FFFFFF%22%20CELLPADDING%3D%224%22%3E%20%27%0Atext%20%2B%3D%20%27%3CTR%3E%3CTD%3EToday%20Salinity%3CBR%3Esali [...]
-    </action>
-    <action date="20 Feb 2007 23:14:06" parent="219" time="220" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="31" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:14:39" parent="220" time="221" user="emanuele" what="moveModule">
-      <move dx="-278.683892254" dy="-41.1692113557" id="31"/>
-    </action>
-    <action date="20 Feb 2007 23:14:39" parent="221" time="222" user="emanuele" what="addModulePort">
-      <addPort moduleId="31" portName="imageFile" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 23:14:40" parent="222" time="223" user="emanuele" what="addModulePort">
-      <addPort moduleId="31" portName="htmlFile" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 23:14:46" parent="223" time="224" user="emanuele" what="addConnection">
-      <connect destinationId="28" destinationModule="RichTextCell" destinationPort="File(File)" id="30" sourceId="31" sourceModule="PythonSource" sourcePort="htmlFile(File)"/>
-    </action>
-    <action date="20 Feb 2007 23:15:31" parent="224" time="225" user="emanuele" what="moveModule">
-      <move dx="47.5029361797" dy="-117.173909243" id="30"/>
-      <move dx="107.673322007" dy="-53.8366610036" id="31"/>
-    </action>
-    <action date="20 Feb 2007 23:15:31" parent="225" time="226" user="emanuele" what="addModulePort">
-      <addPort moduleId="30" portName="renderer" portSpec="(vtkRenderer)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 23:15:31" parent="226" time="227" user="emanuele" what="addModulePort">
-      <addPort moduleId="30" portName="image" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 23:15:37" parent="227" time="228" user="emanuele" what="deleteConnection">
-      <connection connectionId="7"/>
-      <connection connectionId="8"/>
-    </action>
-    <action date="20 Feb 2007 23:15:37" parent="228" time="229" user="emanuele" what="deleteModule">
-      <module moduleId="3"/>
-    </action>
-    <action date="20 Feb 2007 23:15:41" parent="229" time="230" user="emanuele" what="deleteConnection"/>
-    <action date="20 Feb 2007 23:15:41" parent="230" time="231" user="emanuele" what="deleteModule">
-      <module moduleId="18"/>
-    </action>
-    <action date="20 Feb 2007 23:15:46" parent="231" time="232" user="emanuele" what="addConnection">
-      <connect destinationId="30" destinationModule="PythonSource" destinationPort="renderer(vtkRenderer)" id="31" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="20 Feb 2007 23:15:54" parent="232" time="233" user="emanuele" what="moveModule">
-      <move dx="28.5017617078" dy="3.16686241198" id="30"/>
-    </action>
-    <action date="20 Feb 2007 23:15:54" parent="233" time="234" user="emanuele" what="addConnection">
-      <connect destinationId="31" destinationModule="PythonSource" destinationPort="imageFile(File)" id="32" sourceId="30" sourceModule="PythonSource" sourcePort="image(File)"/>
-    </action>
-    <action date="20 Feb 2007 23:16:19" parent="203" time="235" user="emanuele" what="moveModule">
-      <move dx="2.79721122452" dy="0.0" id="18"/>
-    </action>
-    <action date="20 Feb 2007 23:16:19" parent="235" time="236" user="emanuele" what="deleteConnection"/>
-    <action date="20 Feb 2007 23:16:19" parent="236" time="237" user="emanuele" what="deleteModule">
-      <module moduleId="18"/>
-    </action>
-    <action date="20 Feb 2007 23:17:09" parent="168" time="238" user="emanuele" what="deleteConnection">
-      <connection connectionId="7"/>
-      <connection connectionId="8"/>
-    </action>
-    <action date="20 Feb 2007 23:17:09" parent="238" time="239" user="emanuele" what="deleteModule">
-      <module moduleId="3"/>
-    </action>
-    <action date="20 Feb 2007 23:17:11" parent="239" time="240" user="emanuele" what="deleteConnection"/>
-    <action date="20 Feb 2007 23:17:11" parent="240" time="241" user="emanuele" what="deleteModule">
-      <module moduleId="18"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="241" time="242" user="emanuele" what="addModule">
-      <object cache="1" id="27" name="SheetReference" x="865.30516105" y="-1039.21860426"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="242" time="243" user="emanuele" what="addModule">
-      <object cache="1" id="28" name="CellLocation" x="770.569532929" y="-897.275620359"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="243" time="244" user="emanuele" what="addModule">
-      <object cache="1" id="29" name="RichTextCell" x="849.512822349" y="-775.466202927"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="244" time="245" user="emanuele" what="changeParameter">
-      <set alias="" function="MinColumnCount" functionId="0" moduleId="27" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="245" time="246" user="emanuele" what="changeParameter">
-      <set alias="" function="MinRowCount" functionId="1" moduleId="27" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="246" time="247" user="emanuele" what="changeParameter">
-      <set alias="" function="SheetName" functionId="2" moduleId="27" parameter="<no description>" parameterId="0" type="String" value="Salinity 90"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="247" time="248" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="27" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="248" time="249" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="28" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="249" time="250" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="29" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="250" time="251" user="emanuele" what="addConnection">
-      <connect destinationId="28" destinationModule="CellLocation" destinationPort="SheetReference(SheetReference)" id="28" sourceId="27" sourceModule="SheetReference" sourcePort="self(SheetReference)"/>
-    </action>
-    <action date="20 Feb 2007 23:17:12" parent="251" time="252" user="emanuele" what="addConnection">
-      <connect destinationId="29" destinationModule="RichTextCell" destinationPort="Location(CellLocation)" id="29" sourceId="28" sourceModule="CellLocation" sourcePort="self(CellLocation)"/>
-    </action>
-    <action date="20 Feb 2007 23:17:37" parent="252" time="253" user="emanuele" what="addModule">
-      <object cache="1" id="30" name="PythonSource" x="1070.31637145" y="-571.246355048"/>
-    </action>
-    <action date="20 Feb 2007 23:17:37" parent="253" time="254" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="String" value="imageFile%20%3D%20self.getInputFromPort%28%22imageFile%22%29%0A%0Atext%20%3D%20%27%3CHTML%3E%3CTITLE%3EElcirc%20run%20todaydev%3C/TITLE%3E%3CBODY%20BGCOLOR%3D%22%23FFFFFF%22%3E%3CTABLE%20WIDTH%3D%22100%25%22%20BORDER%3D%221%22%20BGCOLOR%3D%22%23FFFFFF%22%20CELLPADDING%3D%224%22%3E%20%27%0Atext%20%2B%3D%20%27%3CTR%3E%3CTD%3EToday%20Salinity%3CBR%3Esali [...]
-    </action>
-    <action date="20 Feb 2007 23:17:37" parent="254" time="255" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="30" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:17:55" parent="255" time="256" user="emanuele" what="addModule">
-      <object cache="1" id="31" name="PythonSource" x="960.305887126" y="-474.794528421"/>
-    </action>
-    <action date="20 Feb 2007 23:17:55" parent="256" time="257" user="emanuele" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="31" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Awindow%20%3D%20vtk.vtkRenderWindow%28%29%0Ar%20%3D%20self.getInputFromPort%28%22renderer%22%29.vtkInstance%0Ar.ResetCamera%28%29%0Awindow.AddRenderer%28r%29%0Awindow.OffScreenRenderingOn%28%29%0Awindow.Start%28%29%0Awindow.Render%28%29%0Awin2image%20%3D%20vtk.vtkWindowToImageFilter%28%29%0Awin2image.SetInput%28window%29%0Awin2image.Upda [...]
-    </action>
-    <action date="20 Feb 2007 23:17:55" parent="257" time="258" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="31" value=""/>
-    </action>
-    <action date="20 Feb 2007 23:18:47" parent="258" time="259" user="emanuele" what="moveModule">
-      <move dx="-50.1123073025" dy="-84.5645185729" id="30"/>
-      <move dx="-28.1881728576" dy="-81.4324993665" id="31"/>
-    </action>
-    <action date="20 Feb 2007 23:18:47" parent="259" time="260" user="emanuele" what="addModulePort">
-      <addPort moduleId="31" portName="renderer" portSpec="(vtkRenderer)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 23:18:47" parent="260" time="261" user="emanuele" what="addModulePort">
-      <addPort moduleId="31" portName="image" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 23:19:09" parent="261" time="262" user="emanuele" what="addModulePort">
-      <addPort moduleId="30" portName="imageFile" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="20 Feb 2007 23:19:10" parent="262" time="263" user="emanuele" what="addModulePort">
-      <addPort moduleId="30" portName="htmlFile" portSpec="(File)" portType="output"/>
-    </action>
-    <action date="20 Feb 2007 23:19:15" parent="263" time="264" user="emanuele" what="moveModule">
-      <move dx="-12.5280768256" dy="3.1320192064" id="31"/>
-    </action>
-    <action date="20 Feb 2007 23:19:15" parent="264" time="265" user="emanuele" what="addConnection">
-      <connect destinationId="30" destinationModule="PythonSource" destinationPort="imageFile(File)" id="30" sourceId="31" sourceModule="PythonSource" sourcePort="image(File)"/>
-    </action>
-    <action date="20 Feb 2007 23:19:20" parent="265" time="266" user="emanuele" what="addConnection">
-      <connect destinationId="29" destinationModule="RichTextCell" destinationPort="File(File)" id="31" sourceId="30" sourceModule="PythonSource" sourcePort="htmlFile(File)"/>
-    </action>
-    <action date="20 Feb 2007 23:19:33" parent="266" time="267" user="emanuele" what="moveModule">
-      <move dx="-43.8482688897" dy="53.2443265089" id="5"/>
-    </action>
-    <action date="20 Feb 2007 23:19:33" parent="267" time="268" user="emanuele" what="addConnection">
-      <connect destinationId="31" destinationModule="PythonSource" destinationPort="renderer(vtkRenderer)" id="32" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="07 Mar 2007 12:57:29" parent="157" time="269" user="hvo" what="moveModule">
-      <move dx="24.1926213319" dy="-39.8466704291" id="18"/>
-    </action>
-    <action date="07 Mar 2007 12:57:29" parent="269" time="270" user="hvo" what="addModule">
-      <object cache="1" id="27" name="SingleCellSheetReference" x="1461.51894752" y="-330.158126412"/>
-    </action>
-    <action date="07 Mar 2007 12:57:32" parent="270" time="271" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="CellLocation" destinationPort="SheetReference(SheetReference)" id="28" sourceId="27" sourceModule="SingleCellSheetReference" sourcePort="self(SingleCellSheetReference)"/>
-    </action>
-    <action date="07 Mar 2007 12:58:11" parent="271" time="272" user="hvo" what="deleteConnection">
-      <connection connectionId="21"/>
-    </action>
-    <action date="07 Mar 2007 12:58:11" parent="272" time="273" user="hvo" what="deleteModule">
-      <module moduleId="17"/>
-    </action>
-    <action date="07 Mar 2007 13:18:35" parent="273" time="274" user="hvo" what="addModule">
-      <object cache="1" id="28" name="vtkCylinder" x="342.965984764" y="-210.618115125"/>
-    </action>
-    <action date="07 Mar 2007 13:19:26" parent="274" time="275" user="hvo" what="moveModule">
-      <move dx="-1.42309537247" dy="1.42309537247" id="26"/>
-      <move dx="155.117395599" dy="24.1926213319" id="28"/>
-    </action>
-    <action date="07 Mar 2007 13:20:47" parent="275" time="276" user="hvo" what="moveModule">
-      <move dx="108.155248307" dy="-68.3085778784" id="0"/>
-      <move dx="-1.42309537247" dy="0.0" id="6"/>
-      <move dx="91.0781038379" dy="-183.579303048" id="12"/>
-    </action>
-    <action date="07 Mar 2007 13:21:09" parent="276" time="277" user="hvo" what="moveModule">
-      <move dx="-95.3473899553" dy="227.695259595" id="28"/>
-    </action>
-    <action date="07 Mar 2007 13:21:09" parent="277" time="278" user="hvo" what="addModule">
-      <object cache="1" id="29" name="vtkCutter" x="397.043608918" y="-187.848589166"/>
-    </action>
-    <action date="07 Mar 2007 13:21:18" parent="278" time="279" user="hvo" what="moveModule">
-      <move dx="-9.96166760727" dy="116.693820542" id="29"/>
-    </action>
-    <action date="07 Mar 2007 13:21:18" parent="279" time="280" user="hvo" what="addConnection">
-      <connect destinationId="29" destinationModule="vtkCutter" destinationPort="SetCutFunction(vtkImplicitFunction)" id="29" sourceId="28" sourceModule="vtkCylinder" sourcePort="self(vtkCylinder)"/>
-    </action>
-    <action date="07 Mar 2007 13:21:41" parent="280" time="281" user="hvo" what="moveModule">
-      <move dx="-4.2692861174" dy="-152.271204854" id="19"/>
-      <move dx="-41.2697658015" dy="28.4619074493" id="28"/>
-      <move dx="85.385722348" dy="29.8850028218" id="29"/>
-    </action>
-    <action date="07 Mar 2007 13:21:41" parent="281" time="282" user="hvo" what="addConnection">
-      <connect destinationId="19" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="30" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:21:44" parent="282" time="283" user="hvo" what="deleteConnection">
-      <connection connectionId="13"/>
-    </action>
-    <action date="07 Mar 2007 13:21:53" parent="283" time="284" user="hvo" what="moveModule">
-      <move dx="-29.8850028218" dy="-42.692861174" id="28"/>
-      <move dx="55.5007195262" dy="4.2692861174" id="29"/>
-    </action>
-    <action date="07 Mar 2007 13:21:53" parent="284" time="285" user="hvo" what="addConnection">
-      <connect destinationId="29" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="31" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:22:20" parent="285" time="286" user="hvo" what="moveModule">
-      <move dx="243.349308692" dy="12.8078583522" id="2"/>
-      <move dx="99.6166760727" dy="-1.42309537247" id="7"/>
-      <move dx="214.887401242" dy="-21.346430587" id="12"/>
-      <move dx="130.924774267" dy="18.5002398421" id="15"/>
-      <move dx="108.155248307" dy="68.3085778784" id="19"/>
-      <move dx="428.351707113" dy="128.078583522" id="28"/>
-      <move dx="24.1926213319" dy="39.8466704291" id="29"/>
-    </action>
-    <action date="07 Mar 2007 13:22:20" parent="286" time="287" user="hvo" what="changeParameter">
-      <set alias="" function="GenerateCutScalarsOn" functionId="0" moduleId="29" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:22:40" parent="287" time="288" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:25:25" parent="288" time="289" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:25:29" parent="289" time="290" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="297794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:25:33" parent="290" time="291" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="297794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:25:35" parent="291" time="292" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="1" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:25:43" parent="292" time="293" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="1" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="100000"/>
-    </action>
-    <action date="07 Mar 2007 13:25:44" parent="293" time="294" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="1" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="100000"/>
-    </action>
-    <action date="07 Mar 2007 13:35:32" parent="294" time="295" user="hvo" what="addModule">
-      <object cache="1" id="30" name="vtkGeneralTransform" x="663.819690788" y="276.354120199"/>
-    </action>
-    <action date="07 Mar 2007 13:35:35" parent="295" time="296" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="32" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 13:39:06" parent="296" time="297" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:39:18" parent="297" time="298" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="89"/>
-    </action>
-    <action date="07 Mar 2007 13:39:20" parent="298" time="299" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 13:39:21" parent="299" time="300" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 13:40:02" parent="300" time="301" user="hvo" what="moveModule">
-      <move dx="-1.42450577422" dy="-1.42450577422" id="29"/>
-    </action>
-    <action date="07 Mar 2007 13:40:02" parent="301" time="302" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="287794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:40:02" parent="302" time="303" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="287794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:40:14" parent="303" time="304" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:40:15" parent="304" time="305" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:11" parent="305" time="306" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:13" parent="306" time="307" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:20" parent="307" time="308" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="107794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:21" parent="308" time="309" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="107794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:27" parent="309" time="310" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="203246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="107794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:29" parent="310" time="311" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="203246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="107794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:41:36" parent="311" time="312" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="203246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="107794"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:41:41" parent="312" time="313" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="203246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:41:42" parent="313" time="314" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="203246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:41:47" parent="314" time="315" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:41:49" parent="315" time="316" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:41:54" parent="316" time="317" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:41:56" parent="317" time="318" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:42:02" parent="318" time="319" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="303246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:42:04" parent="319" time="320" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="323246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:42:05" parent="320" time="321" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="323246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:42:12" parent="321" time="322" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:42:13" parent="322" time="323" user="hvo" what="changeParameter">
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetCenter" functionId="0" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:42:46" parent="323" time="324" user="hvo" what="moveModule">
-      <move dx="15.6695635165" dy="-45.5841847752" id="19"/>
-      <move dx="126.781013906" dy="29.9146212587" id="29"/>
-    </action>
-    <action date="07 Mar 2007 13:42:46" parent="324" time="325" user="hvo" what="addModule">
-      <object cache="1" id="31" name="vtkActor" x="805.467082233" y="-273.317523865"/>
-    </action>
-    <action date="07 Mar 2007 13:42:47" parent="325" time="326" user="hvo" what="addModule">
-      <object cache="1" id="32" name="vtkDataSetMapper" x="692.24852553" y="-120.732097996"/>
-    </action>
-    <action date="07 Mar 2007 13:42:47" parent="326" time="327" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="31" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:42:47" parent="327" time="328" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="32" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:42:47" parent="328" time="329" user="hvo" what="addConnection">
-      <connect destinationId="31" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="33" sourceId="32" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="07 Mar 2007 13:42:58" parent="329" time="330" user="hvo" what="moveModule">
-      <move dx="9.97154041956" dy="-9.97154041956" id="15"/>
-      <move dx="-277.778625974" dy="-25.641103936" id="31"/>
-      <move dx="-237.892464295" dy="-34.1881385814" id="32"/>
-    </action>
-    <action date="07 Mar 2007 13:42:58" parent="330" time="331" user="hvo" what="addConnection">
-      <connect destinationId="32" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="34" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:43:02" parent="331" time="332" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="35" sourceId="31" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 13:43:27" parent="332" time="333" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.84901154845" id="6"/>
-    </action>
-    <action date="07 Mar 2007 13:43:27" parent="333" time="334" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="2.0"/>
-    </action>
-    <action date="07 Mar 2007 13:43:30" parent="334" time="335" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-    </action>
-    <action date="07 Mar 2007 13:43:30" parent="335" time="336" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-    </action>
-    <action date="07 Mar 2007 13:43:59" parent="336" time="337" user="hvo" what="moveModule">
-      <move dx="1.42450577422" dy="0.0" id="6"/>
-      <move dx="1.42450577422" dy="0.0" id="15"/>
-    </action>
-    <action date="07 Mar 2007 13:43:59" parent="337" time="338" user="hvo" what="deleteConnection">
-      <connection connectionId="10"/>
-    </action>
-    <action date="07 Mar 2007 13:44:32" parent="338" time="339" user="hvo" what="addConnection">
-      <connect destinationId="32" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="36" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="07 Mar 2007 13:44:38" parent="339" time="340" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="37" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 13:47:30" parent="340" time="341" user="hvo" what="addModule">
-      <object cache="1" id="33" name="vtkDiskSource" x="487.180974784" y="450.143824655"/>
-    </action>
-    <action date="07 Mar 2007 13:47:37" parent="341" time="342" user="hvo" what="moveModule">
-      <move dx="437.323272687" dy="-414.531180299" id="33"/>
-    </action>
-    <action date="07 Mar 2007 13:47:37" parent="342" time="343" user="hvo" what="changeParameter">
-      <set alias="" function="SetInnerRadius" functionId="0" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:47:47" parent="343" time="344" user="hvo" what="changeParameter">
-      <set alias="" function="SetInnerRadius" functionId="0" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="100000"/>
-    </action>
-    <action date="07 Mar 2007 13:47:51" parent="344" time="345" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="1" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:47:59" parent="345" time="346" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="1" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="110000"/>
-    </action>
-    <action date="07 Mar 2007 13:48:01" parent="346" time="347" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="1" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="110000"/>
-    </action>
-    <action date="07 Mar 2007 13:50:12" parent="347" time="348" user="hvo" what="addConnection">
-      <connect destinationId="19" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="38" sourceId="33" sourceModule="vtkDiskSource" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:50:14" parent="348" time="349" user="hvo" what="deleteConnection">
-      <connection connectionId="38"/>
-    </action>
-    <action date="07 Mar 2007 13:50:18" parent="349" time="350" user="hvo" what="addModule">
-      <object cache="1" id="34" name="vtkActor" x="537.688456259" y="-288.958627801"/>
-    </action>
-    <action date="07 Mar 2007 13:50:18" parent="350" time="351" user="hvo" what="addModule">
-      <object cache="1" id="35" name="vtkDataSetMapper" x="464.356061235" y="-144.920236577"/>
-    </action>
-    <action date="07 Mar 2007 13:50:18" parent="351" time="352" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="34" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:50:18" parent="352" time="353" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="35" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:50:18" parent="353" time="354" user="hvo" what="addConnection">
-      <connect destinationId="34" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="39" sourceId="35" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="07 Mar 2007 13:50:28" parent="354" time="355" user="hvo" what="moveModule">
-      <move dx="-460.115365074" dy="-424.502720719" id="33"/>
-      <move dx="343.305891588" dy="-334.758856943" id="34"/>
-      <move dx="343.305891588" dy="-334.758856943" id="35"/>
-    </action>
-    <action date="07 Mar 2007 13:50:28" parent="355" time="356" user="hvo" what="addConnection">
-      <connect destinationId="35" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="40" sourceId="33" sourceModule="vtkDiskSource" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:50:32" parent="356" time="357" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="41" sourceId="34" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 13:51:29" parent="357" time="358" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42450577422" id="33"/>
-    </action>
-    <action date="07 Mar 2007 13:51:29" parent="358" time="359" user="hvo" what="changeParameter">
-      <set alias="" function="SetCircumferentialResolution" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="07 Mar 2007 13:51:30" parent="359" time="360" user="hvo" what="changeParameter">
-      <set alias="" function="SetCircumferentialResolution" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="20"/>
-    </action>
-    <action date="07 Mar 2007 13:51:31" parent="360" time="361" user="hvo" what="changeParameter">
-      <set alias="" function="SetCircumferentialResolution" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="20"/>
-    </action>
-    <action date="07 Mar 2007 13:51:43" parent="361" time="362" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:51:50" parent="362" time="363" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 13:51:55" parent="363" time="364" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.84901154845" id="30"/>
-    </action>
-    <action date="07 Mar 2007 13:51:55" parent="364" time="365" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:51:59" parent="365" time="366" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="28"/>
-    </action>
-    <action date="07 Mar 2007 13:54:11" parent="366" time="367" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadialResolution" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="07 Mar 2007 13:54:12" parent="367" time="368" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadialResolution" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:54:13" parent="368" time="369" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadialResolution" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="1\"/>
-    </action>
-    <action date="07 Mar 2007 13:54:15" parent="369" time="370" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadialResolution" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="1\"/>
-    </action>
-    <action date="07 Mar 2007 13:54:26" parent="370" time="371" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadialResolution" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:54:27" parent="371" time="372" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadialResolution" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="07 Mar 2007 13:55:16" parent="372" time="373" user="hvo" what="changeParameter">
-      <set alias="" function="SetCircumferentialResolution" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-    </action>
-    <action date="07 Mar 2007 13:55:20" parent="373" time="374" user="hvo" what="changeParameter">
-      <set alias="" function="SetCircumferentialResolution" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-    </action>
-    <action date="07 Mar 2007 13:55:50" parent="374" time="375" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="35"/>
-    </action>
-    <action date="07 Mar 2007 13:56:32" parent="375" time="376" user="hvo" what="addModule">
-      <object cache="1" id="36" name="vtkTransformPolyDataFilter" x="552.160462162" y="-481.00576343"/>
-    </action>
-    <action date="07 Mar 2007 13:56:40" parent="376" time="377" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-7.11546987323" id="30"/>
-      <move dx="-78.2701686055" dy="83.9625445041" id="33"/>
-      <move dx="-25.6156915436" dy="14.2309397465" id="36"/>
-    </action>
-    <action date="07 Mar 2007 13:56:40" parent="377" time="378" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="42" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 13:56:44" parent="378" time="379" user="hvo" what="moveModule">
-      <move dx="9.96165782252" dy="51.2313830872" id="36"/>
-    </action>
-    <action date="07 Mar 2007 13:56:44" parent="379" time="380" user="hvo" what="deleteConnection">
-      <connection connectionId="40"/>
-    </action>
-    <action date="07 Mar 2007 13:56:47" parent="380" time="381" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="43" sourceId="33" sourceModule="vtkDiskSource" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:56:49" parent="381" time="382" user="hvo" what="addConnection">
-      <connect destinationId="35" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="44" sourceId="36" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:56:53" parent="382" time="383" user="hvo" what="deleteConnection">
-      <connection connectionId="39"/>
-      <connection connectionId="44"/>
-    </action>
-    <action date="07 Mar 2007 13:56:53" parent="383" time="384" user="hvo" what="deleteModule">
-      <module moduleId="35"/>
-    </action>
-    <action date="07 Mar 2007 13:56:57" parent="384" time="385" user="hvo" what="addModule">
-      <object cache="1" id="37" name="vtkDataSetMapper" x="464.356061235" y="-144.920236577"/>
-    </action>
-    <action date="07 Mar 2007 13:56:57" parent="385" time="386" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="37" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:57:02" parent="386" time="387" user="hvo" what="moveModule">
-      <move dx="347.234929813" dy="-372.850621357" id="37"/>
-    </action>
-    <action date="07 Mar 2007 13:57:02" parent="387" time="388" user="hvo" what="addConnection">
-      <connect destinationId="37" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="45" sourceId="36" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 13:57:07" parent="388" time="389" user="hvo" what="addConnection">
-      <connect destinationId="34" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="46" sourceId="37" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="07 Mar 2007 13:57:36" parent="389" time="390" user="hvo" what="addModule">
-      <object cache="1" id="38" name="vtkGeneralTransform" x="673.819690788" y="276.389638777"/>
-    </action>
-    <action date="07 Mar 2007 13:57:36" parent="390" time="391" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 13:57:36" parent="391" time="392" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 13:57:36" parent="392" time="393" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="38" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:57:41" parent="393" time="394" user="hvo" what="moveModule">
-      <move dx="-192.117686577" dy="135.193927591" id="38"/>
-    </action>
-    <action date="07 Mar 2007 13:57:41" parent="394" time="395" user="hvo" what="addConnection">
-      <connect destinationId="30" destinationModule="vtkAbstractTransform" destinationPort="SetInverse(vtkAbstractTransform)" id="47" sourceId="38" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 13:57:45" parent="395" time="396" user="hvo" what="deleteConnection">
-      <connection connectionId="47"/>
-    </action>
-    <action date="07 Mar 2007 13:57:47" parent="396" time="397" user="hvo" what="addConnection">
-      <connect destinationId="30" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="48" sourceId="38" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 13:58:00" parent="397" time="398" user="hvo" what="moveModule">
-      <move dx="58.3468529605" dy="-15.6540337211" id="38"/>
-    </action>
-    <action date="07 Mar 2007 13:58:00" parent="398" time="399" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="38"/>
-    </action>
-    <action date="07 Mar 2007 13:58:03" parent="399" time="400" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="30"/>
-    </action>
-    <action date="07 Mar 2007 13:58:07" parent="400" time="401" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:58:09" parent="401" time="402" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 13:58:10" parent="402" time="403" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 13:58:12" parent="403" time="404" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 13:58:19" parent="404" time="405" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="49" sourceId="38" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 13:58:21" parent="405" time="406" user="hvo" what="deleteConnection">
-      <connection connectionId="42"/>
-    </action>
-    <action date="07 Mar 2007 13:59:02" parent="406" time="407" user="hvo" what="moveModule">
-      <move dx="-24.192597569" dy="58.3468529605" id="32"/>
-    </action>
-    <action date="07 Mar 2007 13:59:02" parent="407" time="408" user="hvo" what="deleteConnection">
-      <connection connectionId="37"/>
-    </action>
-    <action date="07 Mar 2007 13:59:25" parent="408" time="409" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="1" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="101000"/>
-    </action>
-    <action date="07 Mar 2007 13:59:26" parent="409" time="410" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="1" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="101000"/>
-    </action>
-    <action date="07 Mar 2007 13:59:42" parent="410" time="411" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="50" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 13:59:44" parent="411" time="412" user="hvo" what="deleteConnection">
-      <connection connectionId="35"/>
-    </action>
-    <action date="07 Mar 2007 14:00:20" parent="412" time="413" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="38"/>
-    </action>
-    <action date="07 Mar 2007 14:00:20" parent="413" time="414" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:00:21" parent="414" time="415" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:00:23" parent="415" time="416" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:00:24" parent="416" time="417" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:00:40" parent="417" time="418" user="hvo" what="moveModule">
-      <move dx="18.5002216704" dy="-41.2697252647" id="38"/>
-    </action>
-    <action date="07 Mar 2007 14:00:40" parent="418" time="419" user="hvo" what="deleteConnection">
-      <connection connectionId="49"/>
-    </action>
-    <action date="07 Mar 2007 14:00:43" parent="419" time="420" user="hvo" what="moveModule">
-      <move dx="-52.6544770619" dy="41.2697252647" id="38"/>
-    </action>
-    <action date="07 Mar 2007 14:00:43" parent="420" time="421" user="hvo" what="deleteConnection">
-      <connection connectionId="48"/>
-    </action>
-    <action date="07 Mar 2007 14:00:46" parent="421" time="422" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="51" sourceId="38" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:00:47" parent="422" time="423" user="hvo" what="deleteConnection">
-      <connection connectionId="32"/>
-    </action>
-    <action date="07 Mar 2007 14:00:49" parent="423" time="424" user="hvo" what="addConnection">
-      <connect destinationId="38" destinationModule="vtkAbstractTransform" destinationPort="SetInverse(vtkAbstractTransform)" id="52" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:00:52" parent="424" time="425" user="hvo" what="moveModule">
-      <move dx="83.9625445041" dy="-27.0387855183" id="38"/>
-    </action>
-    <action date="07 Mar 2007 14:00:52" parent="425" time="426" user="hvo" what="deleteConnection">
-      <connection connectionId="52"/>
-    </action>
-    <action date="07 Mar 2007 14:00:54" parent="426" time="427" user="hvo" what="addConnection">
-      <connect destinationId="38" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="53" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:01:15" parent="427" time="428" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:01:23" parent="428" time="429" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:01:27" parent="429" time="430" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:01:30" parent="430" time="431" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="38"/>
-    </action>
-    <action date="07 Mar 2007 14:01:30" parent="431" time="432" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="0" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="38" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:01:35" parent="432" time="433" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:01:35" parent="433" time="434" user="hvo" what="deleteConnection">
-      <connection connectionId="51"/>
-      <connection connectionId="53"/>
-    </action>
-    <action date="07 Mar 2007 14:01:35" parent="434" time="435" user="hvo" what="deleteModule">
-      <module moduleId="38"/>
-    </action>
-    <action date="07 Mar 2007 14:01:39" parent="435" time="436" user="hvo" what="moveModule">
-      <move dx="15.6540337211" dy="52.6544770619" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:01:39" parent="436" time="437" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="54" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:02:04" parent="437" time="438" user="hvo" what="moveModule">
-      <move dx="-49.8082891126" dy="-59.7699469351" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:02:04" parent="438" time="439" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:02:07" parent="439" time="440" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:02:08" parent="440" time="441" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:02:09" parent="441" time="442" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:04:00" parent="442" time="443" user="hvo" what="moveModule">
-      <move dx="61.1930409098" dy="-4.26928192394" id="31"/>
-    </action>
-    <action date="07 Mar 2007 14:04:00" parent="443" time="444" user="hvo" what="deleteConnection">
-      <connection connectionId="41"/>
-    </action>
-    <action date="07 Mar 2007 14:04:16" parent="444" time="445" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:04:16" parent="445" time="446" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:04:18" parent="446" time="447" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:04:21" parent="447" time="448" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="313246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:04:38" parent="448" time="449" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.42309397465" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:04:38" parent="449" time="450" user="hvo" what="deleteConnection">
-      <connection connectionId="34"/>
-    </action>
-    <action date="07 Mar 2007 14:05:18" parent="450" time="451" user="hvo" what="moveModule">
-      <move dx="1.42309397465" dy="0.0" id="29"/>
-    </action>
-    <action date="07 Mar 2007 14:05:18" parent="451" time="452" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:05:19" parent="452" time="453" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:05:28" parent="453" time="454" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="1" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="307794"/>
-    </action>
-    <action date="07 Mar 2007 14:05:41" parent="454" time="455" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="30"/>
-    </action>
-    <action date="07 Mar 2007 14:05:47" parent="455" time="456" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:05:49" parent="456" time="457" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="207794"/>
-    </action>
-    <action date="07 Mar 2007 14:05:50" parent="457" time="458" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:05:53" parent="458" time="459" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:05:53" parent="459" time="460" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="1" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:06:09" parent="460" time="461" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:06:11" parent="461" time="462" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:06:12" parent="462" time="463" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:06:12" parent="463" time="464" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="333246"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:06:34" parent="464" time="465" user="hvo" what="addConnection">
-      <connect destinationId="32" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="55" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 14:06:36" parent="465" time="466" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkViewport" destinationPort="AddActor2D(vtkProp)" id="56" sourceId="31" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 14:06:41" parent="466" time="467" user="hvo" what="deleteConnection">
-      <connection connectionId="56"/>
-    </action>
-    <action date="07 Mar 2007 14:06:43" parent="467" time="468" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="57" sourceId="31" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 14:07:43" parent="468" time="469" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="207794"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:07:44" parent="469" time="470" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="30"/>
-    </action>
-    <action date="07 Mar 2007 14:08:52" parent="470" time="471" user="hvo" what="deleteConnection">
-      <connection connectionId="57"/>
-    </action>
-    <action date="07 Mar 2007 14:09:09" parent="471" time="472" user="hvo" what="moveModule">
-      <move dx="1.42309397465" dy="0.0" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:09:09" parent="472" time="473" user="hvo" what="addModule">
-      <object cache="1" id="39" name="vtkGeneralTransform" x="639.665435397" y="269.274168904"/>
-    </action>
-    <action date="07 Mar 2007 14:09:09" parent="473" time="474" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="39" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:09:09" parent="474" time="475" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="39" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:09:13" parent="475" time="476" user="hvo" what="moveModule">
-      <move dx="-37.0004433408" dy="81.1163565548" id="39"/>
-    </action>
-    <action date="07 Mar 2007 14:09:13" parent="476" time="477" user="hvo" what="addConnection">
-      <connect destinationId="30" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="58" sourceId="39" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:09:16" parent="477" time="478" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="39"/>
-    </action>
-    <action date="07 Mar 2007 14:09:20" parent="478" time="479" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:09:23" parent="479" time="480" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:09:24" parent="480" time="481" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:09:26" parent="481" time="482" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="39" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:09:36" parent="482" time="483" user="hvo" what="deleteConnection">
-      <connection connectionId="58"/>
-    </action>
-    <action date="07 Mar 2007 14:09:36" parent="483" time="484" user="hvo" what="deleteModule">
-      <module moduleId="39"/>
-    </action>
-    <action date="07 Mar 2007 14:09:40" parent="484" time="485" user="hvo" what="moveModule">
-      <move dx="-7.11546987323" dy="86.8087324534" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:09:40" parent="485" time="486" user="hvo" what="deleteConnection">
-      <connection connectionId="54"/>
-    </action>
-    <action date="07 Mar 2007 14:09:41" parent="486" time="487" user="hvo" what="addModule">
-      <object cache="1" id="40" name="vtkGeneralTransform" x="639.665435397" y="269.274168904"/>
-    </action>
-    <action date="07 Mar 2007 14:09:41" parent="487" time="488" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:09:41" parent="488" time="489" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="40" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:09:44" parent="489" time="490" user="hvo" what="addConnection">
-      <connect destinationId="40" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="59" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:09:46" parent="490" time="491" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="60" sourceId="40" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:09:48" parent="491" time="492" user="hvo" what="moveModule">
-      <move dx="31.3080674422" dy="-46.9621011633" id="40"/>
-    </action>
-    <action date="07 Mar 2007 14:09:48" parent="492" time="493" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="40"/>
-    </action>
-    <action date="07 Mar 2007 14:09:54" parent="493" time="494" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:09:58" parent="494" time="495" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:09:58" parent="495" time="496" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:09:59" parent="496" time="497" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:13" parent="497" time="498" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:14" parent="498" time="499" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:28" parent="499" time="500" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:29" parent="500" time="501" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:38" parent="501" time="502" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:38" parent="502" time="503" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:43" parent="503" time="504" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:44" parent="504" time="505" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:10:53" parent="505" time="506" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:11:06" parent="506" time="507" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:11:10" parent="507" time="508" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:11:11" parent="508" time="509" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:11:16" parent="509" time="510" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:11:16" parent="510" time="511" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="40" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:11:58" parent="511" time="512" user="hvo" what="moveModule">
-      <move dx="7.11546987323" dy="-62.6161348844" id="29"/>
-    </action>
-    <action date="07 Mar 2007 14:11:58" parent="512" time="513" user="hvo" what="deleteConnection">
-      <connection connectionId="60"/>
-      <connection connectionId="59"/>
-    </action>
-    <action date="07 Mar 2007 14:11:58" parent="513" time="514" user="hvo" what="deleteModule">
-      <module moduleId="40"/>
-    </action>
-    <action date="07 Mar 2007 14:12:01" parent="514" time="515" user="hvo" what="moveModule">
-      <move dx="22.7695035943" dy="-81.1163565548" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:12:01" parent="515" time="516" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="61" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:12:01" parent="516" time="517" user="hvo" what="addModule">
-      <object cache="1" id="41" name="vtkGeneralTransform" x="680.973502839" y="232.312067741"/>
-    </action>
-    <action date="07 Mar 2007 14:12:01" parent="517" time="518" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:12:01" parent="518" time="519" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="41" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:12:07" parent="519" time="520" user="hvo" what="moveModule">
-      <move dx="-9.96165782252" dy="-15.6540337211" id="30"/>
-      <move dx="-85.3856384787" dy="109.578236048" id="41"/>
-    </action>
-    <action date="07 Mar 2007 14:12:07" parent="520" time="521" user="hvo" what="addConnection">
-      <connect destinationId="30" destinationModule="vtkAbstractTransform" destinationPort="SetInverse(vtkAbstractTransform)" id="62" sourceId="41" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:12:11" parent="521" time="522" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:12:12" parent="522" time="523" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:12:14" parent="523" time="524" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:12:24" parent="524" time="525" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:12:25" parent="525" time="526" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:12:26" parent="526" time="527" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:12:37" parent="527" time="528" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="-300000"/>
-    </action>
-    <action date="07 Mar 2007 14:12:39" parent="528" time="529" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="-300000"/>
-    </action>
-    <action date="07 Mar 2007 14:12:41" parent="529" time="530" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="-300000"/>
-    </action>
-    <action date="07 Mar 2007 14:12:42" parent="530" time="531" user="hvo" what="deleteConnection">
-      <connection connectionId="62"/>
-    </action>
-    <action date="07 Mar 2007 14:12:44" parent="531" time="532" user="hvo" what="addConnection">
-      <connect destinationId="30" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="63" sourceId="41" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:13:00" parent="532" time="533" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.42309397465" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:13:00" parent="533" time="534" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-90"/>
-    </action>
-    <action date="07 Mar 2007 14:13:01" parent="534" time="535" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-90"/>
-    </action>
-    <action date="07 Mar 2007 14:13:03" parent="535" time="536" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="-300000"/>
-    </action>
-    <action date="07 Mar 2007 14:13:04" parent="536" time="537" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:13:05" parent="537" time="538" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:13:14" parent="538" time="539" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:13:16" parent="539" time="540" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="-300000"/>
-    </action>
-    <action date="07 Mar 2007 14:13:17" parent="540" time="541" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="-300000"/>
-    </action>
-    <action date="07 Mar 2007 14:13:25" parent="541" time="542" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:13:26" parent="542" time="543" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:13:27" parent="543" time="544" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:13:28" parent="544" time="545" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:13:38" parent="545" time="546" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-3000000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:13:40" parent="546" time="547" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-3000000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-3000000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:13:41" parent="547" time="548" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-3000000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-3000000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:13:46" parent="548" time="549" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="-3000000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:13:52" parent="549" time="550" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:40:25" parent="550" time="551" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="29"/>
-    </action>
-    <action date="07 Mar 2007 14:40:27" parent="551" time="552" user="hvo" what="changeParameter">
-      <set alias="" function="GenerateCutScalarsOff" functionId="0" moduleId="29" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:40:45" parent="552" time="553" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="41"/>
-    </action>
-    <action date="07 Mar 2007 14:40:45" parent="553" time="554" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="600000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:40:46" parent="554" time="555" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="600000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:40:53" parent="555" time="556" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:40:54" parent="556" time="557" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="41" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:41:18" parent="557" time="558" user="hvo" what="deleteConnection">
-      <connection connectionId="63"/>
-    </action>
-    <action date="07 Mar 2007 14:41:18" parent="558" time="559" user="hvo" what="deleteModule">
-      <module moduleId="41"/>
-    </action>
-    <action date="07 Mar 2007 14:41:21" parent="559" time="560" user="hvo" what="moveModule">
-      <move dx="15.6540337211" dy="102.462766174" id="30"/>
-    </action>
-    <action date="07 Mar 2007 14:41:21" parent="560" time="561" user="hvo" what="deleteConnection">
-      <connection connectionId="61"/>
-    </action>
-    <action date="07 Mar 2007 14:41:25" parent="561" time="562" user="hvo" what="addModule">
-      <object cache="1" id="42" name="vtkGeneralTransform" x="662.434938991" y="363.198371231"/>
-    </action>
-    <action date="07 Mar 2007 14:41:25" parent="562" time="563" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="-90"/>
-    </action>
-    <action date="07 Mar 2007 14:41:25" parent="563" time="564" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="42" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:41:30" parent="564" time="565" user="hvo" what="moveModule">
-      <move dx="-11.3847517972" dy="-108.155142073" id="42"/>
-    </action>
-    <action date="07 Mar 2007 14:41:30" parent="565" time="566" user="hvo" what="addConnection">
-      <connect destinationId="42" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="64" sourceId="30" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:41:33" parent="566" time="567" user="hvo" what="moveModule">
-      <move dx="1.42309397465" dy="-2.84618794929" id="42"/>
-    </action>
-    <action date="07 Mar 2007 14:41:33" parent="567" time="568" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="65" sourceId="42" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:43:58" parent="568" time="569" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.42309397465" id="30"/>
-      <move dx="1.42309397465" dy="0.0" id="33"/>
-      <move dx="0.0" dy="1.42309397465" id="42"/>
-    </action>
-    <action date="07 Mar 2007 14:43:58" parent="569" time="570" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="30"/>
-    </action>
-    <action date="07 Mar 2007 14:44:01" parent="570" time="571" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:44:05" parent="571" time="572" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:44:07" parent="572" time="573" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="600000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:44:08" parent="573" time="574" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="600000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:44:08" parent="574" time="575" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="600000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:44:13" parent="575" time="576" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:44:18" parent="576" time="577" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:44:20" parent="577" time="578" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:44:55" parent="578" time="579" user="hvo" what="deleteConnection">
-      <connection connectionId="64"/>
-    </action>
-    <action date="07 Mar 2007 14:44:55" parent="579" time="580" user="hvo" what="deleteModule">
-      <module moduleId="30"/>
-    </action>
-    <action date="07 Mar 2007 14:44:58" parent="580" time="581" user="hvo" what="moveModule">
-      <move dx="-4.26928192394" dy="82.5394505294" id="42"/>
-    </action>
-    <action date="07 Mar 2007 14:44:58" parent="581" time="582" user="hvo" what="addModule">
-      <object cache="1" id="43" name="vtkGeneralTransform" x="662.473281168" y="263.620135183"/>
-    </action>
-    <action date="07 Mar 2007 14:44:58" parent="582" time="583" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-90"/>
-    </action>
-    <action date="07 Mar 2007 14:44:58" parent="583" time="584" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="43" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:45:02" parent="584" time="585" user="hvo" what="addConnection">
-      <connect destinationId="43" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="66" sourceId="42" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:45:04" parent="585" time="586" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkImplicitFunction" destinationPort="SetTransform(vtkAbstractTransform)" id="67" sourceId="43" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:45:05" parent="586" time="587" user="hvo" what="deleteConnection">
-      <connection connectionId="65"/>
-    </action>
-    <action date="07 Mar 2007 14:45:08" parent="587" time="588" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="43"/>
-    </action>
-    <action date="07 Mar 2007 14:45:08" parent="588" time="589" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="43"/>
-    </action>
-    <action date="07 Mar 2007 14:45:10" parent="589" time="590" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:45:14" parent="590" time="591" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:45:15" parent="591" time="592" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:45:16" parent="592" time="593" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:45:17" parent="593" time="594" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:45:18" parent="594" time="595" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-30000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:45:24" parent="595" time="596" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 14:45:30" parent="596" time="597" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:45:37" parent="597" time="598" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:45:39" parent="598" time="599" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:45:46" parent="599" time="600" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:45:47" parent="600" time="601" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:46:04" parent="601" time="602" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="300000"/>
-    </action>
-    <action date="07 Mar 2007 14:46:10" parent="602" time="603" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:46:13" parent="603" time="604" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:46:14" parent="604" time="605" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:48:08" parent="605" time="606" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="07 Mar 2007 14:48:23" parent="606" time="607" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="40000"/>
-    </action>
-    <action date="07 Mar 2007 14:48:24" parent="607" time="608" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="40000"/>
-    </action>
-    <action date="07 Mar 2007 14:48:36" parent="608" time="609" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="68" sourceId="31" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 14:49:09" parent="609" time="610" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:49:48" parent="610" time="611" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="6"/>
-    </action>
-    <action date="07 Mar 2007 14:49:48" parent="611" time="612" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="288871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="523378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:49:49" parent="612" time="613" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="288871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="523378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:51:34" parent="613" time="614" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="32"/>
-    </action>
-    <action date="07 Mar 2007 14:51:34" parent="614" time="615" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="288871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="423378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:51:36" parent="615" time="616" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="288871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="423378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:51:40" parent="616" time="617" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="188871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="423378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:51:43" parent="617" time="618" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="188871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="07 Mar 2007 14:51:52" parent="618" time="619" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="388871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="423378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:51:54" parent="619" time="620" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="388871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="07 Mar 2007 14:51:54" parent="620" time="621" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="388871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="07 Mar 2007 14:52:05" parent="621" time="622" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="318871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="423378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:52:10" parent="622" time="623" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="318871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="07 Mar 2007 14:52:10" parent="623" time="624" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="318871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="07 Mar 2007 14:52:21" parent="624" time="625" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="318871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="323378.928288"/>
-    </action>
-    <action date="07 Mar 2007 14:53:18" parent="625" time="626" user="hvo" what="addModule">
-      <object cache="1" id="44" name="vtkGeneralTransform" x="658.203999245" y="346.159585713"/>
-    </action>
-    <action date="07 Mar 2007 14:53:18" parent="626" time="627" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="44" parameter="<no description>" parameterId="0" type="Float" value="-90"/>
-    </action>
-    <action date="07 Mar 2007 14:53:18" parent="627" time="628" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="44" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:53:24" parent="628" time="629" user="hvo" what="moveModule">
-      <move dx="-280.349513005" dy="-557.852838061" id="44"/>
-    </action>
-    <action date="07 Mar 2007 14:53:24" parent="629" time="630" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="69" sourceId="44" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:53:28" parent="630" time="631" user="hvo" what="moveModule">
-      <move dx="35.5773493661" dy="-5.69237589858" id="44"/>
-    </action>
-    <action date="07 Mar 2007 14:53:28" parent="631" time="632" user="hvo" what="addConnection">
-      <connect destinationId="44" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="70" sourceId="43" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:53:49" parent="632" time="633" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="71" sourceId="43" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:53:54" parent="633" time="634" user="hvo" what="deleteConnection">
-      <connection connectionId="69"/>
-    </action>
-    <action date="07 Mar 2007 14:54:10" parent="634" time="635" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="72" sourceId="44" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:54:12" parent="635" time="636" user="hvo" what="deleteConnection">
-      <connection connectionId="71"/>
-    </action>
-    <action date="07 Mar 2007 14:54:15" parent="636" time="637" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="73" sourceId="34" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 14:54:42" parent="637" time="638" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:54:43" parent="638" time="639" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:54:46" parent="639" time="640" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:54:47" parent="640" time="641" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:54:48" parent="641" time="642" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:55:15" parent="642" time="643" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.42309397465" id="42"/>
-    </action>
-    <action date="07 Mar 2007 14:55:15" parent="643" time="644" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:55:17" parent="644" time="645" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-300000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 14:55:43" parent="645" time="646" user="hvo" what="deleteConnection">
-      <connection connectionId="70"/>
-    </action>
-    <action date="07 Mar 2007 14:55:46" parent="646" time="647" user="hvo" what="addConnection">
-      <connect destinationId="44" destinationModule="vtkAbstractTransform" destinationPort="SetInverse(vtkAbstractTransform)" id="74" sourceId="43" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:56:02" parent="647" time="648" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="44" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:56:03" parent="648" time="649" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="44" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:56:12" parent="649" time="650" user="hvo" what="deleteConnection">
-      <connection connectionId="72"/>
-      <connection connectionId="74"/>
-    </action>
-    <action date="07 Mar 2007 14:56:12" parent="650" time="651" user="hvo" what="deleteModule">
-      <module moduleId="44"/>
-    </action>
-    <action date="07 Mar 2007 14:56:17" parent="651" time="652" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="75" sourceId="43" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:56:30" parent="652" time="653" user="hvo" what="deleteConnection">
-      <connection connectionId="75"/>
-    </action>
-    <action date="07 Mar 2007 14:56:32" parent="653" time="654" user="hvo" what="addModule">
-      <object cache="1" id="45" name="vtkGeneralTransform" x="658.203999245" y="346.159585713"/>
-    </action>
-    <action date="07 Mar 2007 14:56:32" parent="654" time="655" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="45" parameter="<no description>" parameterId="0" type="Float" value="-90"/>
-    </action>
-    <action date="07 Mar 2007 14:56:32" parent="655" time="656" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="45" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:56:38" parent="656" time="657" user="hvo" what="moveModule">
-      <move dx="-219.156472095" dy="-559.275932036" id="45"/>
-    </action>
-    <action date="07 Mar 2007 14:56:38" parent="657" time="658" user="hvo" what="addConnection">
-      <connect destinationId="45" destinationModule="vtkAbstractTransform" destinationPort="SetInverse(vtkAbstractTransform)" id="76" sourceId="43" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:56:40" parent="658" time="659" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="77" sourceId="45" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:56:42" parent="659" time="660" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="45"/>
-    </action>
-    <action date="07 Mar 2007 14:57:00" parent="660" time="661" user="hvo" what="changeParameter">
-      <set alias="" function="RotateY" functionId="0" moduleId="45" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:57:02" parent="661" time="662" user="hvo" what="changeParameter">
-      <set alias="" function="RotateY" functionId="0" moduleId="45" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:57:13" parent="662" time="663" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="45"/>
-    </action>
-    <action date="07 Mar 2007 14:57:15" parent="663" time="664" user="hvo" what="changeParameter">
-      <set alias="" function="RotateZ" functionId="0" moduleId="45" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:57:18" parent="664" time="665" user="hvo" what="changeParameter">
-      <set alias="" function="RotateZ" functionId="0" moduleId="45" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:58:21" parent="665" time="666" user="hvo" what="moveModule">
-      <move dx="-42.6928192394" dy="76.8470746309" id="32"/>
-      <move dx="-22.7695035943" dy="74.0008866816" id="45"/>
-    </action>
-    <action date="07 Mar 2007 14:58:21" parent="666" time="667" user="hvo" what="deleteConnection">
-      <connection connectionId="77"/>
-    </action>
-    <action date="07 Mar 2007 14:58:24" parent="667" time="668" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="45"/>
-    </action>
-    <action date="07 Mar 2007 14:58:24" parent="668" time="669" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="45"/>
-    </action>
-    <action date="07 Mar 2007 14:58:26" parent="669" time="670" user="hvo" what="addModule">
-      <object cache="1" id="46" name="vtkGeneralTransform" x="426.278023555" y="-130.538553616"/>
-    </action>
-    <action date="07 Mar 2007 14:58:26" parent="670" time="671" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="46" value=""/>
-    </action>
-    <action date="07 Mar 2007 14:58:33" parent="671" time="672" user="hvo" what="moveModule">
-      <move dx="-41.2697252647" dy="-2.84618794929" id="45"/>
-      <move dx="-2.84618794929" dy="-88.231826428" id="46"/>
-    </action>
-    <action date="07 Mar 2007 14:58:33" parent="672" time="673" user="hvo" what="addConnection">
-      <connect destinationId="46" destinationModule="vtkAbstractTransform" destinationPort="SetInverse(vtkAbstractTransform)" id="78" sourceId="45" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:58:36" parent="673" time="674" user="hvo" what="deleteConnection">
-      <connection connectionId="78"/>
-    </action>
-    <action date="07 Mar 2007 14:58:41" parent="674" time="675" user="hvo" what="addConnection">
-      <connect destinationId="46" destinationModule="vtkGeneralTransform" destinationPort="SetInput(vtkAbstractTransform)" id="79" sourceId="45" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:58:46" parent="675" time="676" user="hvo" what="addConnection">
-      <connect destinationId="36" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="80" sourceId="46" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 14:58:49" parent="676" time="677" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="46" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 14:59:52" parent="677" time="678" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="46" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 14:59:53" parent="678" time="679" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="46" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 15:00:18" parent="679" time="680" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.42309397465" id="33"/>
-      <move dx="0.0" dy="-1.42309397465" id="36"/>
-    </action>
-    <action date="07 Mar 2007 15:00:18" parent="680" time="681" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOff" functionId="0" moduleId="37" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 15:00:42" parent="681" time="682" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="33"/>
-    </action>
-    <action date="07 Mar 2007 15:00:42" parent="682" time="683" user="hvo" what="addModule">
-      <object cache="1" id="47" name="Integer" x="526.544770619" y="562.122119985"/>
-    </action>
-    <action date="07 Mar 2007 15:00:45" parent="683" time="684" user="hvo" what="moveModule">
-      <move dx="-79.6932625801" dy="25.6156915436" id="47"/>
-    </action>
-    <action date="07 Mar 2007 15:00:45" parent="684" time="685" user="hvo" what="changeParameter">
-      <set alias="" function="value" functionId="0" moduleId="47" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="07 Mar 2007 15:00:51" parent="685" time="686" user="hvo" what="changeParameter">
-      <set alias="" function="value" functionId="0" moduleId="47" parameter="<no description>" parameterId="0" type="Integer" value="4000"/>
-    </action>
-    <action date="07 Mar 2007 15:00:53" parent="686" time="687" user="hvo" what="changeParameter">
-      <set alias="" function="value" functionId="0" moduleId="47" parameter="<no description>" parameterId="0" type="Integer" value="4000"/>
-    </action>
-    <action date="07 Mar 2007 15:00:58" parent="687" time="688" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="28"/>
-    </action>
-    <action date="07 Mar 2007 15:01:13" parent="688" time="689" user="hvo" what="deleteConnection"/>
-    <action date="07 Mar 2007 15:01:13" parent="689" time="690" user="hvo" what="deleteModule">
-      <module moduleId="47"/>
-    </action>
-    <action date="07 Mar 2007 15:01:19" parent="690" time="691" user="hvo" what="addModule">
-      <object cache="1" id="48" name="Float" x="516.583112796" y="552.160462162"/>
-    </action>
-    <action date="07 Mar 2007 15:01:21" parent="691" time="692" user="hvo" what="addConnection">
-      <connect destinationId="28" destinationModule="vtkCylinder" destinationPort="SetRadius(Float)" id="81" sourceId="48" sourceModule="Float" sourcePort="value(Float)"/>
-    </action>
-    <action date="07 Mar 2007 15:01:24" parent="692" time="693" user="hvo" what="changeParameter">
-      <set alias="" function="value" functionId="0" moduleId="48" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 15:01:26" parent="693" time="694" user="hvo" what="changeParameter">
-      <set alias="" function="value" functionId="0" moduleId="48" parameter="<no description>" parameterId="0" type="Float" value="4000"/>
-    </action>
-    <action date="07 Mar 2007 15:01:29" parent="694" time="695" user="hvo" what="changeParameter">
-      <set alias="" function="value" functionId="0" moduleId="48" parameter="<no description>" parameterId="0" type="Float" value="4000"/>
-    </action>
-    <action date="07 Mar 2007 15:01:38" parent="695" time="696" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="33"/>
-    </action>
-    <action date="07 Mar 2007 15:02:17" parent="696" time="697" user="hvo" what="addConnection">
-      <connect destinationId="33" destinationModule="vtkDiskSource" destinationPort="SetInnerRadius(Float)" id="82" sourceId="48" sourceModule="Float" sourcePort="value(Float)"/>
-    </action>
-    <action date="07 Mar 2007 15:02:29" parent="697" time="698" user="hvo" what="addConnection">
-      <connect destinationId="33" destinationModule="vtkDiskSource" destinationPort="SetOuterRadius(Float)" id="83" sourceId="48" sourceModule="Float" sourcePort="value(Float)"/>
-    </action>
-    <action date="07 Mar 2007 15:02:37" parent="698" time="699" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="33"/>
-    </action>
-    <action date="07 Mar 2007 15:03:04" parent="699" time="700" user="hvo" what="moveModule">
-      <move dx="25.6156915436" dy="44.115913214" id="48"/>
-    </action>
-    <action date="07 Mar 2007 15:03:04" parent="700" time="701" user="hvo" what="deleteConnection">
-      <connection connectionId="81"/>
-      <connection connectionId="82"/>
-      <connection connectionId="83"/>
-    </action>
-    <action date="07 Mar 2007 15:03:04" parent="701" time="702" user="hvo" what="deleteModule">
-      <module moduleId="48"/>
-    </action>
-    <action date="07 Mar 2007 15:03:14" parent="702" time="703" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 15:03:22" parent="703" time="704" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 15:03:24" parent="704" time="705" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="4000"/>
-    </action>
-    <action date="07 Mar 2007 15:03:26" parent="705" time="706" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="4000"/>
-    </action>
-    <action date="07 Mar 2007 15:03:28" parent="706" time="707" user="hvo" what="changeParameter">
-      <set alias="" function="SetInnerRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 15:03:33" parent="707" time="708" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="33"/>
-    </action>
-    <action date="07 Mar 2007 15:03:35" parent="708" time="709" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 15:03:44" parent="709" time="710" user="hvo" what="changeParameter">
-      <set alias="" function="SetInnerRadius" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius-5000$"/>
-    </action>
-    <action date="07 Mar 2007 15:03:47" parent="710" time="711" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius+5000$"/>
-    </action>
-    <action date="07 Mar 2007 15:03:48" parent="711" time="712" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius+5000$"/>
-    </action>
-    <action date="07 Mar 2007 15:04:04" parent="712" time="713" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius+1000$"/>
-    </action>
-    <action date="07 Mar 2007 15:04:08" parent="713" time="714" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius+500$"/>
-    </action>
-    <action date="07 Mar 2007 15:04:10" parent="714" time="715" user="hvo" what="changeParameter">
-      <set alias="" function="SetInnerRadius" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius-500$"/>
-    </action>
-    <action date="07 Mar 2007 15:04:37" parent="715" time="716" user="hvo" what="moveModule">
-      <move dx="-86.8087324534" dy="56.9237589858" id="42"/>
-    </action>
-    <action date="07 Mar 2007 15:04:37" parent="716" time="717" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-280000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 15:04:48" parent="717" time="718" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-290000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 15:04:52" parent="718" time="719" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="8000"/>
-    </action>
-    <action date="07 Mar 2007 15:15:38" parent="719" time="720" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.42309397465" id="28"/>
-    </action>
-    <action date="07 Mar 2007 15:15:38" parent="720" time="721" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="07 Mar 2007 15:15:40" parent="721" time="722" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="07 Mar 2007 15:34:03" parent="722" time="723" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="20000"/>
-    </action>
-    <action date="07 Mar 2007 16:44:07" parent="723" time="724" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="32"/>
-    </action>
-    <action date="07 Mar 2007 16:44:07" parent="724" time="725" user="hvo" what="changeParameter">
-      <set alias="radius" function="SetRadius" functionId="0" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="30000"/>
-    </action>
-    <action date="07 Mar 2007 16:47:06" parent="725" time="726" user="hvo" what="moveModule">
-      <move dx="27.0387855183" dy="11.3847517972" id="34"/>
-    </action>
-    <action date="07 Mar 2007 16:47:06" parent="726" time="727" user="hvo" what="addModule">
-      <object cache="1" id="49" name="vtkProperty" x="1614.14239657" y="96.6113697478"/>
-    </action>
-    <action date="07 Mar 2007 16:47:07" parent="727" time="728" user="hvo" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="49" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="49" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="49" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 16:47:07" parent="728" time="729" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="49" value=""/>
-    </action>
-    <action date="07 Mar 2007 16:47:18" parent="729" time="730" user="hvo" what="moveModule">
-      <move dx="-710.123893348" dy="-510.890736898" id="49"/>
-    </action>
-    <action date="07 Mar 2007 16:47:18" parent="730" time="731" user="hvo" what="addConnection">
-      <connect destinationId="34" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="84" sourceId="49" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="07 Mar 2007 16:48:42" parent="731" time="732" user="hvo" what="changeParameter">
-      <set alias="" function="SetInnerRadius" functionId="2" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius-1000$"/>
-    </action>
-    <action date="07 Mar 2007 16:48:45" parent="732" time="733" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius+1000$"/>
-    </action>
-    <action date="07 Mar 2007 16:48:46" parent="733" time="734" user="hvo" what="changeParameter">
-      <set alias="" function="SetOuterRadius" functionId="3" moduleId="33" parameter="<no description>" parameterId="0" type="Float" value="$radius+1000$"/>
-    </action>
-    <action date="07 Mar 2007 17:15:39" parent="734" time="735" user="hvo" what="addModule">
-      <object cache="1" id="50" name="vtkClipPolyData" x="478.159575481" y="-555.006650112"/>
-    </action>
-    <action date="07 Mar 2007 17:15:53" parent="735" time="736" user="hvo" what="moveModule">
-      <move dx="-31.3080674422" dy="-59.7699469351" id="37"/>
-      <move dx="66.8854168083" dy="35.5773493661" id="50"/>
-    </action>
-    <action date="07 Mar 2007 17:15:53" parent="736" time="737" user="hvo" what="addConnection">
-      <connect destinationId="37" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="85" sourceId="50" sourceModule="vtkClipPolyData" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 17:15:54" parent="737" time="738" user="hvo" what="deleteConnection">
-      <connection connectionId="45"/>
-    </action>
-    <action date="07 Mar 2007 17:15:58" parent="738" time="739" user="hvo" what="addConnection">
-      <connect destinationId="50" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="86" sourceId="36" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 17:16:32" parent="739" time="740" user="hvo" what="changeParameter">
-      <set alias="" function="InsideOutOn" functionId="0" moduleId="50" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:17:02" parent="740" time="741" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:17:04" parent="741" time="742" user="hvo" what="changeParameter">
-      <set alias="" function="InsideOutOff" functionId="0" moduleId="50" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:28:42" parent="742" time="743" user="hvo" what="moveModule">
-      <move dx="-92.501108352" dy="-7.11546987323" id="28"/>
-      <move dx="-1.42309397465" dy="0.0" id="50"/>
-    </action>
-    <action date="07 Mar 2007 17:28:42" parent="743" time="744" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:28:56" parent="744" time="745" user="hvo" what="changeParameter">
-      <set alias="" function="InsideOutOn" functionId="0" moduleId="50" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:29:11" parent="745" time="746" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:29:14" parent="746" time="747" user="hvo" what="changeParameter">
-      <set alias="" function="InsideOutOff" functionId="0" moduleId="50" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:30:15" parent="747" time="748" user="hvo" what="changeParameter">
-      <set alias="" function="GenerateClippedOutputOn" functionId="1" moduleId="50" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:30:45" parent="748" time="749" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:30:47" parent="749" time="750" user="hvo" what="changeParameter">
-      <set alias="" function="InsideOutOn" functionId="1" moduleId="50" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:32:05" parent="750" time="751" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:32:06" parent="751" time="752" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:42:20" parent="752" time="753" user="hvo" what="moveModule">
-      <move dx="111.001330022" dy="9.96165782252" id="50"/>
-    </action>
-    <action date="07 Mar 2007 17:42:20" parent="753" time="754" user="hvo" what="deleteConnection">
-      <connection connectionId="85"/>
-      <connection connectionId="86"/>
-    </action>
-    <action date="07 Mar 2007 17:42:20" parent="754" time="755" user="hvo" what="deleteModule">
-      <module moduleId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:42:21" parent="755" time="756" user="hvo" what="addConnection">
-      <connect destinationId="37" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="87" sourceId="36" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 17:42:29" parent="756" time="757" user="hvo" what="addModule">
-      <object cache="1" id="51" name="vtkPointsProjectedHull" x="479.582669456" y="-462.50554176"/>
-    </action>
-    <action date="07 Mar 2007 17:42:34" parent="757" time="758" user="hvo" what="moveModule">
-      <move dx="-93.9242023266" dy="-24.192597569" id="37"/>
-      <move dx="101.0396722" dy="-39.8466312901" id="51"/>
-    </action>
-    <action date="07 Mar 2007 17:42:34" parent="758" time="759" user="hvo" what="deleteConnection">
-      <connection connectionId="87"/>
-    </action>
-    <action date="07 Mar 2007 17:42:41" parent="759" time="760" user="hvo" what="addConnection">
-      <connect destinationId="37" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="88" sourceId="36" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 17:47:03" parent="760" time="761" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="1.42309397465" id="28"/>
-      <move dx="-24.192597569" dy="56.9237589858" id="29"/>
-      <move dx="274.657137107" dy="431.197474318" id="51"/>
-    </action>
-    <action date="07 Mar 2007 17:47:03" parent="761" time="762" user="hvo" what="deleteConnection"/>
-    <action date="07 Mar 2007 17:47:03" parent="762" time="763" user="hvo" what="deleteModule">
-      <module moduleId="51"/>
-    </action>
-    <action date="07 Mar 2007 17:49:41" parent="763" time="764" user="hvo" what="moveModule">
-      <move dx="129.501551693" dy="-4.26928192394" id="28"/>
-    </action>
-    <action date="07 Mar 2007 17:49:41" parent="764" time="765" user="hvo" what="addModule">
-      <object cache="1" id="52" name="PythonSource" x="859.548760686" y="38.4235373154"/>
-    </action>
-    <action date="07 Mar 2007 17:50:14" parent="765" time="766" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.84618794929" id="52"/>
-    </action>
-    <action date="07 Mar 2007 17:50:14" parent="766" time="767" user="hvo" what="addModulePort">
-      <addPort moduleId="52" portName="points" portSpec="(vtkPoints)" portType="input"/>
-    </action>
-    <action date="07 Mar 2007 17:50:15" parent="767" time="768" user="hvo" what="addModulePort">
-      <addPort moduleId="52" portName="hull" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="07 Mar 2007 17:50:36" parent="768" time="769" user="hvo" what="moveModule">
-      <move dx="-15.6540337211" dy="-139.463209515" id="52"/>
-    </action>
-    <action date="07 Mar 2007 17:50:50" parent="769" time="770" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="52" portName="points" portType="input"/>
-    </action>
-    <action date="07 Mar 2007 17:50:50" parent="770" time="771" user="hvo" what="addModulePort">
-      <addPort moduleId="52" portName="data" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="07 Mar 2007 17:50:58" parent="771" time="772" user="hvo" what="addConnection">
-      <connect destinationId="52" destinationModule="PythonSource" destinationPort="data(vtkPolyData)" id="89" sourceId="29" sourceModule="vtkPolyDataAlgorithm" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="07 Mar 2007 17:52:18" parent="772" time="773" user="hvo" what="moveModule">
-      <move dx="22.7695035943" dy="55.5006650112" id="52"/>
-    </action>
-    <action date="07 Mar 2007 17:52:19" parent="773" time="774" user="hvo" what="deleteConnection">
-      <connection connectionId="89"/>
-    </action>
-    <action date="07 Mar 2007 17:52:19" parent="774" time="775" user="hvo" what="deleteModule">
-      <module moduleId="52"/>
-    </action>
-    <action date="07 Mar 2007 17:52:35" parent="775" time="776" user="hvo" what="addModule">
-      <object cache="1" id="53" name="vtkPolyDataMapper2D" x="842.47163299" y="-65.4623228337"/>
-    </action>
-    <action date="07 Mar 2007 17:52:45" parent="776" time="777" user="hvo" what="moveModule">
-      <move dx="1.42309397465" dy="-1.42309397465" id="29"/>
-      <move dx="39.8466312901" dy="-8.53856384787" id="53"/>
-    </action>
-    <action date="07 Mar 2007 17:52:45" parent="777" time="778" user="hvo" what="addConnection">
-      <connect destinationId="53" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="90" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 17:52:48" parent="778" time="779" user="hvo" what="addModule">
-      <object cache="1" id="54" name="vtkActor" x="816.863128427" y="-283.289064284"/>
-    </action>
-    <action date="07 Mar 2007 17:52:48" parent="779" time="780" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="54" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:53:01" parent="780" time="781" user="hvo" what="moveModule">
-      <move dx="169.348182983" dy="2.84618794929" id="54"/>
-    </action>
-    <action date="07 Mar 2007 17:53:01" parent="781" time="782" user="hvo" what="deleteConnection"/>
-    <action date="07 Mar 2007 17:53:01" parent="782" time="783" user="hvo" what="deleteModule">
-      <module moduleId="54"/>
-    </action>
-    <action date="07 Mar 2007 17:53:16" parent="783" time="784" user="hvo" what="addModule">
-      <object cache="1" id="55" name="vtkActor2D" x="1007.55053405" y="-274.657137107"/>
-    </action>
-    <action date="07 Mar 2007 17:53:19" parent="784" time="785" user="hvo" what="addConnection">
-      <connect destinationId="55" destinationModule="vtkActor2D" destinationPort="SetMapper(vtkMapper2D)" id="91" sourceId="53" sourceModule="vtkPolyDataMapper2D" sourcePort="self(vtkPolyDataMapper2D)"/>
-    </action>
-    <action date="07 Mar 2007 17:53:21" parent="785" time="786" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="92" sourceId="55" sourceModule="vtkActor2D" sourcePort="self(vtkActor2D)"/>
-    </action>
-    <action date="07 Mar 2007 17:53:24" parent="786" time="787" user="hvo" what="deleteConnection">
-      <connection connectionId="73"/>
-    </action>
-    <action date="07 Mar 2007 17:54:34" parent="787" time="788" user="hvo" what="deleteConnection">
-      <connection connectionId="46"/>
-      <connection connectionId="84"/>
-      <connection connectionId="88"/>
-    </action>
-    <action date="07 Mar 2007 17:54:34" parent="788" time="789" user="hvo" what="deleteModule">
-      <module moduleId="34"/>
-      <module moduleId="37"/>
-    </action>
-    <action date="07 Mar 2007 17:54:36" parent="789" time="790" user="hvo" what="moveModule">
-      <move dx="-291.734264802" dy="-58.3468529605" id="49"/>
-    </action>
-    <action date="07 Mar 2007 17:54:36" parent="790" time="791" user="hvo" what="deleteConnection"/>
-    <action date="07 Mar 2007 17:54:36" parent="791" time="792" user="hvo" what="deleteModule">
-      <module moduleId="49"/>
-    </action>
-    <action date="07 Mar 2007 17:54:38" parent="792" time="793" user="hvo" what="deleteConnection">
-      <connection connectionId="43"/>
-      <connection connectionId="80"/>
-    </action>
-    <action date="07 Mar 2007 17:54:38" parent="793" time="794" user="hvo" what="deleteModule">
-      <module moduleId="36"/>
-    </action>
-    <action date="07 Mar 2007 17:54:43" parent="794" time="795" user="hvo" what="deleteConnection">
-      <connection connectionId="79"/>
-      <connection connectionId="76"/>
-    </action>
-    <action date="07 Mar 2007 17:54:43" parent="795" time="796" user="hvo" what="deleteModule">
-      <module moduleId="45"/>
-      <module moduleId="46"/>
-      <module moduleId="33"/>
-    </action>
-    <action date="07 Mar 2007 17:54:56" parent="796" time="797" user="hvo" what="moveModule">
-      <move dx="32.7311614168" dy="-72.5777927069" id="42"/>
-      <move dx="2.84618794929" dy="-22.7695035943" id="43"/>
-    </action>
-    <action date="07 Mar 2007 17:54:56" parent="797" time="798" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOff" functionId="0" moduleId="53" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:57:05" parent="798" time="799" user="hvo" what="changeParameter">
-      <set alias="" function="PickableOff" functionId="0" moduleId="55" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:57:08" parent="799" time="800" user="hvo" what="changeParameter">
-      <set alias="" function="DragableOff" functionId="1" moduleId="55" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:57:11" parent="800" time="801" user="hvo" what="changeParameter">
-      <set alias="" function="VisibilityOn" functionId="2" moduleId="55" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 17:57:18" parent="801" time="802" user="hvo" what="deleteConnection">
-      <connection connectionId="50"/>
-    </action>
-    <action date="07 Mar 2007 17:58:48" parent="802" time="803" user="hvo" what="moveModule">
-      <move dx="-42.6928192394" dy="5.69237589858" id="19"/>
-      <move dx="-29.8849734676" dy="7.11546987323" id="53"/>
-    </action>
-    <action date="07 Mar 2007 18:01:24" parent="803" time="804" user="hvo" what="moveModule">
-      <move dx="-1.42309397465" dy="0.0" id="19"/>
-      <move dx="-72.5777927069" dy="54.0775710365" id="29"/>
-    </action>
-    <action date="07 Mar 2007 18:01:24" parent="804" time="805" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 18:01:25" parent="805" time="806" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 18:02:13" parent="806" time="807" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:02:15" parent="807" time="808" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="-290000"/>
-    </action>
-    <action date="07 Mar 2007 18:02:16" parent="808" time="809" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="-290000"/>
-    </action>
-    <action date="07 Mar 2007 18:02:17" parent="809" time="810" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="-290000"/>
-    </action>
-    <action date="07 Mar 2007 18:02:47" parent="810" time="811" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:02:49" parent="811" time="812" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-290000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:03:00" parent="812" time="813" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="1" type="Float" value="-290000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="43" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:03:03" parent="813" time="814" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 18:03:05" parent="814" time="815" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="42" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="07 Mar 2007 18:03:06" parent="815" time="816" user="hvo" what="deleteConnection">
-      <connection connectionId="91"/>
-      <connection connectionId="90"/>
-    </action>
-    <action date="07 Mar 2007 18:03:06" parent="816" time="817" user="hvo" what="deleteModule">
-      <module moduleId="53"/>
-    </action>
-    <action date="07 Mar 2007 18:03:07" parent="817" time="818" user="hvo" what="deleteConnection">
-      <connection connectionId="92"/>
-    </action>
-    <action date="07 Mar 2007 18:03:07" parent="818" time="819" user="hvo" what="deleteModule">
-      <module moduleId="55"/>
-    </action>
-    <action date="07 Mar 2007 18:26:12" parent="819" time="820" user="hvo" what="moveModule">
-      <move dx="-5.69237589858" dy="-93.9242023266" id="29"/>
-    </action>
-    <action date="07 Mar 2007 18:26:12" parent="820" time="821" user="hvo" what="addModule">
-      <object cache="1" id="56" name="vtkPlane" x="885.342963543" y="-13.9864607195"/>
-    </action>
-    <action date="07 Mar 2007 18:27:26" parent="821" time="822" user="hvo" what="moveModule">
-      <move dx="32.1688596548" dy="0.0" id="6"/>
-      <move dx="1.39864607195" dy="0.0" id="28"/>
-      <move dx="-4.19593821584" dy="-30.7702135828" id="56"/>
-    </action>
-    <action date="07 Mar 2007 18:27:26" parent="822" time="823" user="hvo" what="deleteConnection"/>
-    <action date="07 Mar 2007 18:27:26" parent="823" time="824" user="hvo" what="deleteModule">
-      <module moduleId="56"/>
-    </action>
-    <action date="07 Mar 2007 18:29:34" parent="824" time="825" user="hvo" what="moveModule">
-      <move dx="-46.1553203743" dy="12.5878146475" id="15"/>
-      <move dx="-25.175629295" dy="29.3715675109" id="19"/>
-      <move dx="0.0" dy="-1.39864607195" id="28"/>
-      <move dx="85.3174103888" dy="46.1553203743" id="29"/>
-    </action>
-    <action date="07 Mar 2007 18:29:34" parent="825" time="826" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="93" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 18:29:37" parent="826" time="827" user="hvo" what="addModule">
-      <object cache="1" id="57" name="vtkActor" x="770.707808053" y="-270.701249637"/>
-    </action>
-    <action date="07 Mar 2007 18:29:37" parent="827" time="828" user="hvo" what="addModule">
-      <object cache="1" id="58" name="vtkDataSetMapper" x="638.626546537" y="-131.252339361"/>
-    </action>
-    <action date="07 Mar 2007 18:29:37" parent="828" time="829" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="57" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:29:37" parent="829" time="830" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="58" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:29:37" parent="830" time="831" user="hvo" what="addConnection">
-      <connect destinationId="57" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="94" sourceId="58" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="07 Mar 2007 18:29:44" parent="831" time="832" user="hvo" what="moveModule">
-      <move dx="194.411804001" dy="-18.1823989353" id="7"/>
-      <move dx="170.634820778" dy="23.7769832231" id="57"/>
-      <move dx="170.634820778" dy="23.7769832231" id="58"/>
-    </action>
-    <action date="07 Mar 2007 18:29:44" parent="832" time="833" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="95" sourceId="57" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="07 Mar 2007 18:29:50" parent="833" time="834" user="hvo" what="addConnection">
-      <connect destinationId="58" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="96" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:31:13" parent="834" time="835" user="hvo" what="moveModule">
-      <move dx="15.3851067914" dy="-19.5810450073" id="57"/>
-      <move dx="90.9119946766" dy="-9.79052250363" id="58"/>
-    </action>
-    <action date="07 Mar 2007 18:31:13" parent="835" time="836" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOff" functionId="0" moduleId="58" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:31:28" parent="836" time="837" user="hvo" what="addModule">
-      <object cache="1" id="59" name="vtkProperty" x="1614.14239657" y="96.6113697478"/>
-    </action>
-    <action date="07 Mar 2007 18:31:28" parent="837" time="838" user="hvo" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="59" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="59" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="07 Mar 2007 18:31:28" parent="838" time="839" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="59" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:31:33" parent="839" time="840" user="hvo" what="moveModule">
-      <move dx="-688.133867398" dy="-109.094393612" id="59"/>
-    </action>
-    <action date="07 Mar 2007 18:31:33" parent="840" time="841" user="hvo" what="addConnection">
-      <connect destinationId="57" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="97" sourceId="59" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="07 Mar 2007 18:31:36" parent="841" time="842" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="59"/>
-    </action>
-    <action date="07 Mar 2007 18:31:40" parent="842" time="843" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 18:31:43" parent="843" time="844" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="07 Mar 2007 18:31:49" parent="844" time="845" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="2000"/>
-    </action>
-    <action date="07 Mar 2007 18:31:51" parent="845" time="846" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="2000"/>
-    </action>
-    <action date="07 Mar 2007 18:32:04" parent="846" time="847" user="hvo" what="moveModule">
-      <move dx="-74.1282418132" dy="15.3851067914" id="58"/>
-      <move dx="48.9526125182" dy="-8.39187643168" id="59"/>
-    </action>
-    <action date="07 Mar 2007 18:32:04" parent="847" time="848" user="hvo" what="deleteConnection">
-      <connection connectionId="93"/>
-    </action>
-    <action date="07 Mar 2007 18:32:53" parent="848" time="849" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.79729214389" id="58"/>
-    </action>
-    <action date="07 Mar 2007 18:32:53" parent="849" time="850" user="hvo" what="addModule">
-      <object cache="1" id="60" name="vtkLinearTransform" x="959.471205356" y="-107.69574754"/>
-    </action>
-    <action date="07 Mar 2007 18:32:56" parent="850" time="851" user="hvo" what="moveModule">
-      <move dx="-79.722826101" dy="5.59458428779" id="60"/>
-    </action>
-    <action date="07 Mar 2007 18:32:56" parent="851" time="852" user="hvo" what="addConnection">
-      <connect destinationId="57" destinationModule="vtkProp3D" destinationPort="SetUserTransform(vtkLinearTransform)" id="98" sourceId="60" sourceModule="vtkLinearTransform" sourcePort="self(vtkLinearTransform)"/>
-    </action>
-    <action date="07 Mar 2007 18:33:14" parent="852" time="853" user="hvo" what="moveModule">
-      <move dx="54.5471968059" dy="144.060545411" id="60"/>
-    </action>
-    <action date="07 Mar 2007 18:33:14" parent="853" time="854" user="hvo" what="deleteConnection">
-      <connection connectionId="98"/>
-    </action>
-    <action date="07 Mar 2007 18:33:14" parent="854" time="855" user="hvo" what="deleteModule">
-      <module moduleId="60"/>
-    </action>
-    <action date="07 Mar 2007 18:33:37" parent="855" time="856" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyToShiftZBuffer" functionId="1" moduleId="58" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:33:39" parent="856" time="857" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="58"/>
-    </action>
-    <action date="07 Mar 2007 18:33:46" parent="857" time="858" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyZShift" functionId="1" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 18:33:50" parent="858" time="859" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyToShiftZBuffer" functionId="2" moduleId="58" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:33:52" parent="859" time="860" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyZShift" functionId="1" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-    </action>
-    <action date="07 Mar 2007 18:33:53" parent="860" time="861" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyZShift" functionId="1" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-    </action>
-    <action date="07 Mar 2007 18:34:17" parent="861" time="862" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="58"/>
-    </action>
-    <action date="07 Mar 2007 18:34:24" parent="862" time="863" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyZShift" functionId="2" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 18:34:26" parent="863" time="864" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyZShift" functionId="2" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:34:27" parent="864" time="865" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyZShift" functionId="2" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:34:33" parent="865" time="866" user="hvo" what="moveModule">
-      <move dx="1.39864607195" dy="0.0" id="57"/>
-    </action>
-    <action date="07 Mar 2007 18:34:33" parent="866" time="867" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="07 Mar 2007 18:34:34" parent="867" time="868" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="59" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="07 Mar 2007 18:35:09" parent="868" time="869" user="hvo" what="deleteFunction">
-      <function functionId="2" moduleId="58"/>
-    </action>
-    <action date="07 Mar 2007 18:35:10" parent="869" time="870" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="58"/>
-    </action>
-    <action date="07 Mar 2007 18:35:40" parent="870" time="871" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyPolygonOffsetParameters" functionId="1" moduleId="58" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetResolveCoincidentTopologyPolygonOffsetParameters" functionId="1" moduleId="58" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 18:35:43" parent="871" time="872" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="58"/>
-    </action>
-    <action date="07 Mar 2007 18:36:45" parent="872" time="873" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyToOff" functionId="1" moduleId="58" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:36:55" parent="873" time="874" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="07 Mar 2007 18:36:57" parent="874" time="875" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:36:58" parent="875" time="876" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:36:59" parent="876" time="877" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="2" type="Float" value="10"/>
-    </action>
-    <action date="07 Mar 2007 18:37:00" parent="877" time="878" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="57" parameter="<no description>" parameterId="2" type="Float" value="10"/>
-    </action>
-    <action date="07 Mar 2007 18:38:06" parent="878" time="879" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="57"/>
-    </action>
-    <action date="07 Mar 2007 18:41:55" parent="879" time="880" user="hvo" what="addModule">
-      <object cache="1" id="61" name="vtkTransformFilter" x="902.126716406" y="-180.425343281"/>
-    </action>
-    <action date="07 Mar 2007 18:42:06" parent="880" time="881" user="hvo" what="addConnection">
-      <connect destinationId="61" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="99" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:42:11" parent="881" time="882" user="hvo" what="moveModule">
-      <move dx="39.1620900145" dy="-64.3377193096" id="58"/>
-      <move dx="-71.3309496693" dy="187.418573641" id="61"/>
-    </action>
-    <action date="07 Mar 2007 18:42:11" parent="882" time="883" user="hvo" what="deleteConnection">
-      <connection connectionId="96"/>
-    </action>
-    <action date="07 Mar 2007 18:42:14" parent="883" time="884" user="hvo" what="moveModule">
-      <move dx="103.499809324" dy="0.0" id="59"/>
-    </action>
-    <action date="07 Mar 2007 18:42:14" parent="884" time="885" user="hvo" what="addConnection">
-      <connect destinationId="58" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="100" sourceId="61" sourceModule="vtkTransformFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:42:37" parent="885" time="886" user="hvo" what="moveModule">
-      <move dx="13.9864607195" dy="-89.5133486046" id="61"/>
-    </action>
-    <action date="07 Mar 2007 18:42:37" parent="886" time="887" user="hvo" what="deleteConnection">
-      <connection connectionId="100"/>
-      <connection connectionId="99"/>
-    </action>
-    <action date="07 Mar 2007 18:42:37" parent="887" time="888" user="hvo" what="deleteModule">
-      <module moduleId="61"/>
-    </action>
-    <action date="07 Mar 2007 18:42:44" parent="888" time="889" user="hvo" what="addModule">
-      <object cache="1" id="62" name="vtkTransformPolyDataFilter" x="893.734839974" y="-78.324180029"/>
-    </action>
-    <action date="07 Mar 2007 18:42:51" parent="889" time="890" user="hvo" what="moveModule">
-      <move dx="-48.9526125182" dy="0.0" id="62"/>
-    </action>
-    <action date="07 Mar 2007 18:42:51" parent="890" time="891" user="hvo" what="addConnection">
-      <connect destinationId="62" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="101" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:42:54" parent="891" time="892" user="hvo" what="addConnection">
-      <connect destinationId="58" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="102" sourceId="62" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:42:59" parent="892" time="893" user="hvo" what="deleteConnection">
-      <connection connectionId="102"/>
-    </action>
-    <action date="07 Mar 2007 18:43:01" parent="893" time="894" user="hvo" what="addConnection">
-      <connect destinationId="58" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="103" sourceId="62" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:43:03" parent="894" time="895" user="hvo" what="deleteConnection">
-      <connection connectionId="101"/>
-    </action>
-    <action date="07 Mar 2007 18:43:07" parent="895" time="896" user="hvo" what="addConnection">
-      <connect destinationId="62" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="104" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:44:58" parent="896" time="897" user="hvo" what="moveModule">
-      <move dx="-62.6045423531" dy="-6.95606026146" id="29"/>
-      <move dx="0.0" dy="25.0418169413" id="62"/>
-    </action>
-    <action date="07 Mar 2007 18:44:58" parent="897" time="898" user="hvo" what="addModule">
-      <object cache="1" id="63" name="vtkGeneralTransform" x="673.896375143" y="250.850631589"/>
-    </action>
-    <action date="07 Mar 2007 18:44:58" parent="898" time="899" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="-330000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="-290000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:44:58" parent="899" time="900" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="63" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:45:13" parent="900" time="901" user="hvo" what="moveModule">
-      <move dx="164.16302217" dy="-191.987263216" id="63"/>
-    </action>
-    <action date="07 Mar 2007 18:45:13" parent="901" time="902" user="hvo" what="addConnection">
-      <connect destinationId="62" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="105" sourceId="63" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="07 Mar 2007 18:45:16" parent="902" time="903" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="-290000"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:45:17" parent="903" time="904" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 18:45:18" parent="904" time="905" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="100"/>
-    </action>
-    <action date="07 Mar 2007 18:45:21" parent="905" time="906" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="100"/>
-    </action>
-    <action date="07 Mar 2007 18:47:36" parent="906" time="907" user="hvo" what="changeParameter">
-      <set alias="" function="EdgeVisibilityOn" functionId="1" moduleId="59" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:48:17" parent="907" time="908" user="hvo" what="moveModule">
-      <move dx="2.78242410458" dy="-4.17363615688" id="59"/>
-    </action>
-    <action date="07 Mar 2007 18:48:17" parent="908" time="909" user="hvo" what="changeParameter">
-      <set alias="" function="SetRepresentationToWireframe" functionId="2" moduleId="59" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 18:48:19" parent="909" time="910" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="59"/>
-    </action>
-    <action date="07 Mar 2007 18:49:44" parent="910" time="911" user="hvo" what="moveModule">
-      <move dx="33.389089255" dy="6.95606026146" id="62"/>
-    </action>
-    <action date="07 Mar 2007 18:49:44" parent="911" time="912" user="hvo" what="deleteConnection">
-      <connection connectionId="104"/>
-    </action>
-    <action date="07 Mar 2007 18:49:47" parent="912" time="913" user="hvo" what="addConnection">
-      <connect destinationId="58" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="106" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 18:49:48" parent="913" time="914" user="hvo" what="deleteConnection">
-      <connection connectionId="103"/>
-    </action>
-    <action date="07 Mar 2007 19:05:33" parent="914" time="915" user="hvo" what="moveModule">
-      <move dx="-1.39121205229" dy="0.0" id="62"/>
-    </action>
-    <action date="07 Mar 2007 19:05:33" parent="915" time="916" user="hvo" what="addConnection">
-      <connect destinationId="58" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="107" sourceId="62" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 19:05:34" parent="916" time="917" user="hvo" what="deleteConnection">
-      <connection connectionId="106"/>
-    </action>
-    <action date="07 Mar 2007 19:05:37" parent="917" time="918" user="hvo" what="addConnection">
-      <connect destinationId="62" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="108" sourceId="29" sourceModule="vtkCutter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="07 Mar 2007 19:05:43" parent="918" time="919" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 19:05:43" parent="919" time="920" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="63" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 19:06:22" parent="920" time="921" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="58"/>
-    </action>
-    <action date="07 Mar 2007 19:06:32" parent="921" time="922" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolveCoincidentTopologyToPolygonOffset" functionId="1" moduleId="58" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="07 Mar 2007 19:14:35" parent="922" time="923" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.39121205229" id="16"/>
-    </action>
-    <action date="07 Mar 2007 19:14:35" parent="923" time="924" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="07 Mar 2007 19:14:36" parent="924" time="925" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 11:10:31" parent="0" time="926" user="hvo" what="addModule">
-      <object cache="1" id="0" name="PythonSource" x="-273.795107571" y="459.367347148"/>
-    </action>
-    <action date="08 Mar 2007 11:22:52" parent="926" time="927" user="hvo" what="addModulePort">
-      <addPort moduleId="0" portName="filename" portSpec="(File)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 11:22:52" parent="927" time="928" user="hvo" what="addModulePort">
-      <addPort moduleId="0" portName="polyline" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 11:22:52" parent="928" time="929" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename.name%2C%20%27r%27%29%0AvCount%20%3D%20int%28f.readline%28%29%29%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:23:13" parent="929" time="930" user="hvo" what="moveModule">
-      <move dx="-0.826507468297" dy="0.0" id="0"/>
-    </action>
-    <action date="08 Mar 2007 11:23:13" parent="930" time="931" user="hvo" what="addModule">
-      <object cache="1" id="1" name="String" x="-289.277613904" y="556.239526164"/>
-    </action>
-    <action date="08 Mar 2007 11:23:16" parent="931" time="932" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.826507468297" id="1"/>
-    </action>
-    <action date="08 Mar 2007 11:23:16" parent="932" time="933" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 11:23:16" parent="933" time="934" user="hvo" what="deleteModule">
-      <module moduleId="1"/>
-    </action>
-    <action date="08 Mar 2007 11:23:31" parent="934" time="935" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.826507468297" id="0"/>
-    </action>
-    <action date="08 Mar 2007 11:23:31" parent="935" time="936" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="0" portName="filename" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 11:23:31" parent="936" time="937" user="hvo" what="addModulePort">
-      <addPort moduleId="0" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 11:23:31" parent="937" time="938" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0AvCount%20%3D%20int%28f.readline%28%29%29%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:23:34" parent="938" time="939" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="0" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 11:23:44" parent="939" time="940" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="08 Mar 2007 11:23:44" parent="940" time="941" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="08 Mar 2007 11:24:24" parent="941" time="942" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0AvCount%20%3D%20int%28f.readline%28%29%29.rstrip%28%29%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:24:52" parent="942" time="943" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0As%20%3D%20f.readline%28%29%0Aprint%20%22%25s%22%2C%20s%0AvCount%20%3D%20int%28%29.rstrip%28%27%5Cn%27%29%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%27%5Cn%27%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:25:11" parent="943" time="944" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0As%20%3D%20f.readline%28%29%0Aprint%20%22%25s%22%2C%20s%0AvCount%20%3D%20int%28s.rstrip%28%27%5Cn%27%29%29%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%27%5Cn%27%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:34:30" parent="944" time="945" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0Aprint%20%22%25s%22%2C%20s%0AvCount%20%3D%20int%28s.rstrip%28%29%29%0Aprint%20vCount%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%27%5Cn%27%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:34:56" parent="945" time="946" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0Aprint%20%22%25s%22%2C%20s%0AvCount%20%3D%20int%28s.rstrip%28%29%29%0Aprint%20vCount%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:35:49" parent="946" time="947" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0Aprint%20%22%25s%22%2C%20s%0AvCount%20%3D%20int%28s.rstrip%28%29%29%0Aprint%20vCount%0Afor%20i%20in%20range%28vCount-1%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:36:15" parent="947" time="948" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28s.rstrip%28%29%29%0Aprint%20vCount%0Afor%20i%20in%20range%28vCount-1%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:36:50" parent="948" time="949" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0Aprint%20vCount%0Afor%20i%20in%20range%28vCount-1%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:36:56" parent="949" time="950" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="f%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0Aprint%20vCount%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstrip%28%29.split%28%29%0A%20%20%20print%20xS%2C%20yS%2C%20zS"/>
-    </action>
-    <action date="08 Mar 2007 11:40:09" parent="950" time="951" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%0A%20%20%20%28idS%2C%20xS%2C%20yS%2C%20zS%29%20%3D%20f.readline%28%29.rstri [...]
-    </action>
-    <action date="08 Mar 2007 11:54:01" parent="951" time="952" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="0" portName="polyline" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 11:54:01" parent="952" time="953" user="hvo" what="addModulePort">
-      <addPort moduleId="0" portName="ugrid" portSpec="(vtkUnstructuredGrid)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 11:54:01" parent="953" time="954" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 11:54:11" parent="954" time="955" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 11:54:20" parent="955" time="956" user="hvo" what="moveModule">
-      <move dx="-24.9978813559" dy="122.453389831" id="0"/>
-    </action>
-    <action date="08 Mar 2007 11:54:20" parent="956" time="957" user="hvo" what="addModule">
-      <object cache="1" id="2" name="vtkDataSetMapper" x="-267.730932203" y="498.146186441"/>
-    </action>
-    <action date="08 Mar 2007 11:54:32" parent="957" time="958" user="hvo" what="addModule">
-      <object cache="1" id="3" name="vtkActor" x="-254.326271186" y="384.75"/>
-    </action>
-    <action date="08 Mar 2007 11:54:34" parent="958" time="959" user="hvo" what="addConnection">
-      <connect destinationId="3" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="0" sourceId="2" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 11:54:37" parent="959" time="960" user="hvo" what="moveModule">
-      <move dx="5.07203389831" dy="-24.9978813559" id="2"/>
-    </action>
-    <action date="08 Mar 2007 11:54:37" parent="960" time="961" user="hvo" what="addConnection">
-      <connect destinationId="2" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="1" sourceId="0" sourceModule="PythonSource" sourcePort="ugrid(vtkUnstructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 11:54:44" parent="961" time="962" user="hvo" what="addModule">
-      <object cache="1" id="4" name="VTKCell" x="-247.805084746" y="295.98940678"/>
-    </action>
-    <action date="08 Mar 2007 11:54:54" parent="962" time="963" user="hvo" what="addModule">
-      <object cache="1" id="5" name="vtkRenderer" x="-350.142065935" y="297.356829864"/>
-    </action>
-    <action date="08 Mar 2007 11:55:03" parent="963" time="964" user="hvo" what="moveModule">
-      <move dx="4.10551836105" dy="-99.7054459112" id="4"/>
-      <move dx="101.46495378" dy="4.10551836105" id="5"/>
-    </action>
-    <action date="08 Mar 2007 11:55:03" parent="964" time="965" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="2" sourceId="3" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 11:55:05" parent="965" time="966" user="hvo" what="addConnection">
-      <connect destinationId="4" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="3" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="08 Mar 2007 11:55:24" parent="966" time="967" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 11:56:47" parent="925" time="968" user="hvo" what="deleteConnection">
-      <connection connectionId="107"/>
-      <connection connectionId="105"/>
-      <connection connectionId="108"/>
-      <connection connectionId="95"/>
-      <connection connectionId="94"/>
-      <connection connectionId="97"/>
-    </action>
-    <action date="08 Mar 2007 11:56:47" parent="968" time="969" user="hvo" what="deleteModule">
-      <module moduleId="62"/>
-      <module moduleId="57"/>
-      <module moduleId="58"/>
-    </action>
-    <action date="08 Mar 2007 11:56:49" parent="969" time="970" user="hvo" what="moveModule">
-      <move dx="8.34727231375" dy="-98.7760557127" id="63"/>
-    </action>
-    <action date="08 Mar 2007 11:56:49" parent="970" time="971" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 11:56:49" parent="971" time="972" user="hvo" what="deleteModule">
-      <module moduleId="63"/>
-    </action>
-    <action date="08 Mar 2007 11:56:50" parent="972" time="973" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 11:56:50" parent="973" time="974" user="hvo" what="deleteModule">
-      <module moduleId="59"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="974" time="975" user="hvo" what="addModule">
-      <object cache="1" id="64" name="vtkActor" x="-244.326271186" y="394.75"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="975" time="976" user="hvo" what="addModule">
-      <object cache="1" id="65" name="PythonSource" x="-289.619496395" y="590.994229511"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="976" time="977" user="hvo" what="addModule">
-      <object cache="1" id="66" name="vtkDataSetMapper" x="-252.658898305" y="483.148305085"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="977" time="978" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="64" value=""/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="978" time="979" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="65" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%2 [...]
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="979" time="980" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="65" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="980" time="981" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="65" value=""/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="981" time="982" user="hvo" what="addModulePort">
-      <addPort moduleId="65" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="982" time="983" user="hvo" what="addModulePort">
-      <addPort moduleId="65" portName="ugrid" portSpec="(vtkUnstructuredGrid)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="983" time="984" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="66" value=""/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="984" time="985" user="hvo" what="addConnection">
-      <connect destinationId="64" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="109" sourceId="66" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 11:57:01" parent="985" time="986" user="hvo" what="addConnection">
-      <connect destinationId="66" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="110" sourceId="65" sourceModule="PythonSource" sourcePort="ugrid(vtkUnstructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 11:57:24" parent="986" time="987" user="hvo" what="moveModule">
-      <move dx="1194.38412433" dy="-538.228795268" id="64"/>
-      <move dx="1194.38412433" dy="-538.228795268" id="65"/>
-      <move dx="1194.38412433" dy="-538.228795268" id="66"/>
-    </action>
-    <action date="08 Mar 2007 11:57:24" parent="987" time="988" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="111" sourceId="64" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 11:58:21" parent="988" time="989" user="hvo" what="moveModule">
-      <move dx="-37.8110617296" dy="-77.913702958" id="64"/>
-      <move dx="-37.8110617296" dy="-77.913702958" id="65"/>
-      <move dx="-37.8110617296" dy="-77.913702958" id="66"/>
-    </action>
-    <action date="08 Mar 2007 11:58:21" parent="989" time="990" user="hvo" what="addModule">
-      <object cache="1" id="67" name="vtkProperty" x="962.463389481" y="65.3100157148"/>
-    </action>
-    <action date="08 Mar 2007 11:58:24" parent="990" time="991" user="hvo" what="moveModule">
-      <move dx="18.3326359901" dy="-19.4784257395" id="67"/>
-    </action>
-    <action date="08 Mar 2007 11:58:24" parent="991" time="992" user="hvo" what="addConnection">
-      <connect destinationId="64" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="112" sourceId="67" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="08 Mar 2007 11:58:30" parent="992" time="993" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 11:58:33" parent="993" time="994" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 11:58:34" parent="994" time="995" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 11:58:42" parent="995" time="996" user="hvo" what="changeParameter">
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 11:58:44" parent="996" time="997" user="hvo" what="changeParameter">
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 11:58:44" parent="997" time="998" user="hvo" what="changeParameter">
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 11:58:45" parent="998" time="999" user="hvo" what="changeParameter">
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetEdgeColor" functionId="1" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 11:59:27" parent="999" time="1000" user="hvo" what="addModulePort">
-      <addPort moduleId="65" portName="zShift" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 11:59:28" parent="1000" time="1001" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="65" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%2 [...]
-    </action>
-    <action date="08 Mar 2007 11:59:31" parent="1001" time="1002" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="65" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 11:59:34" parent="1002" time="1003" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="65" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 11:59:34" parent="1003" time="1004" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="65" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 12:00:09" parent="1004" time="1005" user="hvo" what="moveModule">
-      <move dx="1.14578974938" dy="0.0" id="67"/>
-    </action>
-    <action date="08 Mar 2007 12:00:09" parent="1005" time="1006" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="67"/>
-    </action>
-    <action date="08 Mar 2007 12:00:10" parent="1006" time="1007" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="67"/>
-    </action>
-    <action date="08 Mar 2007 12:00:40" parent="1007" time="1008" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 12:00:42" parent="1008" time="1009" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:00:43" parent="1009" time="1010" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:00:44" parent="1010" time="1011" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 12:00:45" parent="1011" time="1012" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="67" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 12:01:53" parent="1012" time="1013" user="hvo" what="addModule">
-      <object cache="1" id="68" name="vtkTubeFilter" x="875.072380892" y="-82.0815110852"/>
-    </action>
-    <action date="08 Mar 2007 12:02:10" parent="1013" time="1014" user="hvo" what="moveModule">
-      <move dx="57.039694144" dy="-140.512417281" id="64"/>
-      <move dx="-19.4769687321" dy="-80.6902990329" id="66"/>
-      <move dx="84.8639351898" dy="-335.282104602" id="67"/>
-      <move dx="-18.0857566798" dy="-19.4769687321" id="68"/>
-    </action>
-    <action date="08 Mar 2007 12:02:10" parent="1014" time="1015" user="hvo" what="deleteConnection">
-      <connection connectionId="110"/>
-    </action>
-    <action date="08 Mar 2007 12:02:14" parent="1015" time="1016" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 12:02:16" parent="1016" time="1017" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 12:02:19" parent="1017" time="1018" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 12:02:21" parent="1018" time="1019" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfSides" functionId="1" moduleId="68" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="08 Mar 2007 12:02:23" parent="1019" time="1020" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfSides" functionId="1" moduleId="68" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 12:02:25" parent="1020" time="1021" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfSides" functionId="1" moduleId="68" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 12:02:27" parent="1021" time="1022" user="hvo" what="changeParameter">
-      <set alias="" function="CappingOn" functionId="2" moduleId="68" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:02:36" parent="1022" time="1023" user="hvo" what="moveModule">
-      <move dx="27.8242410458" dy="-15.3033325752" id="68"/>
-    </action>
-    <action date="08 Mar 2007 12:02:36" parent="1023" time="1024" user="hvo" what="addConnection">
-      <connect destinationId="68" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="113" sourceId="65" sourceModule="PythonSource" sourcePort="ugrid(vtkUnstructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 12:02:38" parent="1024" time="1025" user="hvo" what="addConnection">
-      <connect destinationId="66" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="114" sourceId="68" sourceModule="vtkTubeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 12:03:01" parent="1025" time="1026" user="hvo" what="changeParameter">
-      <set alias="" function="SidesShareVerticesOn" functionId="3" moduleId="68" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:07:33" parent="1026" time="1027" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.39121205229" id="65"/>
-      <move dx="0.0" dy="1.39121205229" id="68"/>
-    </action>
-    <action date="08 Mar 2007 12:07:33" parent="1027" time="1028" user="hvo" what="deleteConnection">
-      <connection connectionId="113"/>
-    </action>
-    <action date="08 Mar 2007 12:07:33" parent="1028" time="1029" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="65" portName="ugrid" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 12:07:34" parent="1029" time="1030" user="hvo" what="addModulePort">
-      <addPort moduleId="65" portName="polydata" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 12:07:34" parent="1030" time="1031" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="65" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%2 [...]
-    </action>
-    <action date="08 Mar 2007 12:07:41" parent="1031" time="1032" user="hvo" what="addConnection">
-      <connect destinationId="68" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="115" sourceId="65" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 12:08:17" parent="1032" time="1033" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="65" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%2 [...]
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="967" time="1034" user="hvo" what="addModule">
-      <object cache="1" id="6" name="PythonSource" x="876.953566205" y="-16.5394807673"/>
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1034" time="1035" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1035" time="1036" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1036" time="1037" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1037" time="1038" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="6" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1038" time="1039" user="hvo" what="addModulePort">
-      <addPort moduleId="6" portName="zShift" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1039" time="1040" user="hvo" what="addModulePort">
-      <addPort moduleId="6" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 12:09:01" parent="1040" time="1041" user="hvo" what="addModulePort">
-      <addPort moduleId="6" portName="polydata" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 12:09:12" parent="1041" time="1042" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.809964134143" id="0"/>
-      <move dx="-1406.80729087" dy="667.405997368" id="6"/>
-    </action>
-    <action date="08 Mar 2007 12:09:12" parent="1042" time="1043" user="hvo" what="deleteConnection">
-      <connection connectionId="1"/>
-    </action>
-    <action date="08 Mar 2007 12:09:12" parent="1043" time="1044" user="hvo" what="deleteModule">
-      <module moduleId="0"/>
-    </action>
-    <action date="08 Mar 2007 12:09:14" parent="1044" time="1045" user="hvo" what="addConnection">
-      <connect destinationId="2" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="4" sourceId="6" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 12:39:06" parent="1045" time="1046" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 12:41:17" parent="1046" time="1047" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 12:44:43" parent="1047" time="1048" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 12:45:06" parent="1048" time="1049" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%20 [...]
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1033" time="1050" user="hvo" what="addModule">
-      <object cache="1" id="69" name="PythonSource" x="-519.853724665" y="660.866516601"/>
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1050" time="1051" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Afor%20i%20in%20range%28vCount%29%3A%20%20%20%20%0A%2 [...]
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1051" time="1052" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1052" time="1053" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1053" time="1054" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="69" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1054" time="1055" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="zShift" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1055" time="1056" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 12:45:18" parent="1056" time="1057" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="polydata" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 12:45:24" parent="1057" time="1058" user="hvo" what="moveModule">
-      <move dx="1321.98617795" dy="-692.701244534" id="69"/>
-    </action>
-    <action date="08 Mar 2007 12:45:24" parent="1058" time="1059" user="hvo" what="deleteConnection">
-      <connection connectionId="115"/>
-    </action>
-    <action date="08 Mar 2007 12:45:24" parent="1059" time="1060" user="hvo" what="deleteModule">
-      <module moduleId="65"/>
-    </action>
-    <action date="08 Mar 2007 12:45:26" parent="1060" time="1061" user="hvo" what="addConnection">
-      <connect destinationId="68" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetOutput(vtkDataObject)" id="116" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 12:45:31" parent="1061" time="1062" user="hvo" what="moveModule">
-      <move dx="87.3542007701" dy="29.5462737899" id="69"/>
-    </action>
-    <action date="08 Mar 2007 12:45:31" parent="1062" time="1063" user="hvo" what="deleteConnection">
-      <connection connectionId="116"/>
-    </action>
-    <action date="08 Mar 2007 12:45:33" parent="1063" time="1064" user="hvo" what="addConnection">
-      <connect destinationId="68" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="117" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 12:46:20" parent="1064" time="1065" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 12:46:21" parent="1065" time="1066" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 12:46:46" parent="1066" time="1067" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="300"/>
-    </action>
-    <action date="08 Mar 2007 12:46:48" parent="1067" time="1068" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="68" parameter="<no description>" parameterId="0" type="Float" value="300"/>
-    </action>
-    <action date="08 Mar 2007 12:47:02" parent="1068" time="1069" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="318871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:47:08" parent="1069" time="1070" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="218871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:47:09" parent="1070" time="1071" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="218871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:47:43" parent="1071" time="1072" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="218871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:47:45" parent="1072" time="1073" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="218871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:48:13" parent="1073" time="1074" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="418871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:48:15" parent="1074" time="1075" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="418871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:48:16" parent="1075" time="1076" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="418871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:48:49" parent="1076" time="1077" user="hvo" what="moveModule">
-      <move dx="-1.39121205229" dy="0.0" id="20"/>
-    </action>
-    <action date="08 Mar 2007 12:48:49" parent="1077" time="1078" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:48:52" parent="1078" time="1079" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:48:54" parent="1079" time="1080" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="291735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:48:57" parent="1080" time="1081" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="311735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:49:00" parent="1081" time="1082" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="311735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:49:01" parent="1082" time="1083" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="311735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:49:30" parent="1083" time="1084" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="338871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="311735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:49:34" parent="1084" time="1085" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="338871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="301735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 12:49:40" parent="1085" time="1086" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="358871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="301735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:49:42" parent="1086" time="1087" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="338871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="301735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:49:43" parent="1087" time="1088" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="0" type="Float" value="338871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="1" type="Float" value="301735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="20" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 12:54:49" parent="1088" time="1089" user="hvo" what="deleteFunction">
-      <function functionId="2" moduleId="68"/>
-    </action>
-    <action date="08 Mar 2007 12:54:57" parent="1089" time="1090" user="hvo" what="changeParameter">
-      <set alias="" function="CappingOff" functionId="3" moduleId="68" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 12:55:55" parent="1090" time="1091" user="hvo" what="moveModule">
-      <move dx="94.6024195558" dy="-27.8242410458" id="29"/>
-      <move dx="58.4309061963" dy="139.121205229" id="69"/>
-    </action>
-    <action date="08 Mar 2007 12:55:55" parent="1091" time="1092" user="hvo" what="addModule">
-      <object cache="1" id="70" name="vtkImplicitDataSet" x="733.168751558" y="68.1693905623"/>
-    </action>
-    <action date="08 Mar 2007 12:55:58" parent="1092" time="1093" user="hvo" what="addConnection">
-      <connect destinationId="29" destinationModule="vtkCutter" destinationPort="SetCutFunction(vtkImplicitFunction)" id="118" sourceId="70" sourceModule="vtkImplicitDataSet" sourcePort="self(vtkImplicitDataSet)"/>
-    </action>
-    <action date="08 Mar 2007 12:56:09" parent="1093" time="1094" user="hvo" what="moveModule">
-      <move dx="-65.3869664577" dy="25.0418169413" id="28"/>
-      <move dx="18.0857566798" dy="-41.7363615688" id="29"/>
-    </action>
-    <action date="08 Mar 2007 12:56:09" parent="1094" time="1095" user="hvo" what="addConnection">
-      <connect destinationId="70" destinationModule="vtkImplicitDataSet" destinationPort="SetDataSet(vtkDataSet)" id="119" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 12:56:12" parent="1095" time="1096" user="hvo" what="deleteConnection">
-      <connection connectionId="29"/>
-    </action>
-    <action date="08 Mar 2007 12:56:16" parent="1096" time="1097" user="hvo" what="moveModule">
-      <move dx="40.3451495165" dy="-8.34727231375" id="19"/>
-    </action>
-    <action date="08 Mar 2007 12:56:16" parent="1097" time="1098" user="hvo" what="deleteConnection">
-      <connection connectionId="68"/>
-    </action>
-    <action date="08 Mar 2007 13:07:18" parent="1098" time="1099" user="hvo" what="addModule">
-      <object cache="1" id="71" name="vtkLinearExtrusionFilter" x="955.762679924" y="23.650604889"/>
-    </action>
-    <action date="08 Mar 2007 13:29:21" parent="1099" time="1100" user="hvo" what="moveModule">
-      <move dx="9.73848436604" dy="-6.95606026146" id="70"/>
-      <move dx="12.5209084706" dy="-29.2154530981" id="71"/>
-    </action>
-    <action date="08 Mar 2007 13:29:21" parent="1100" time="1101" user="hvo" what="deleteConnection">
-      <connection connectionId="119"/>
-    </action>
-    <action date="08 Mar 2007 13:29:25" parent="1101" time="1102" user="hvo" what="addConnection">
-      <connect destinationId="71" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="120" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 13:30:32" parent="1102" time="1103" user="hvo" what="moveModule">
-      <move dx="279.203697203" dy="-13.4827087283" id="0"/>
-      <move dx="147.468477543" dy="51.4748459348" id="1"/>
-      <move dx="-292.083996987" dy="299.711459647" id="2"/>
-      <move dx="147.468477543" dy="51.4748459348" id="3"/>
-      <move dx="48.6924218302" dy="129.382720863" id="4"/>
-      <move dx="299.110591243" dy="-4.17363615688" id="5"/>
-      <move dx="184.567294433" dy="802.348349632" id="7"/>
-      <move dx="189.204839112" dy="173.901506536" id="9"/>
-      <move dx="231.834007484" dy="-165.554234223" id="12"/>
-      <move dx="175.292718589" dy="52.8660579871" id="13"/>
-      <move dx="147.468477543" dy="51.4748459348" id="18"/>
-      <move dx="147.468477543" dy="51.4748459348" id="20"/>
-      <move dx="147.468477543" dy="51.4748459348" id="27"/>
-      <move dx="-99.5313891199" dy="9.78997270032" id="29"/>
-      <move dx="0.0" dy="744.037925225" id="32"/>
-      <move dx="-172.956184372" dy="-52.2131877351" id="64"/>
-      <move dx="-73.4247952524" dy="-58.7398362019" id="66"/>
-      <move dx="-205.589426707" dy="-57.1081740852" id="67"/>
-      <move dx="-182.746157073" dy="-16.3166211672" id="68"/>
-      <move dx="-24.4749317508" dy="-11.421634817" id="70"/>
-      <move dx="142.109582671" dy="-40.6540795221" id="71"/>
-    </action>
-    <action date="08 Mar 2007 13:30:32" parent="1103" time="1104" user="hvo" what="addModule">
-      <object cache="1" id="72" name="vtkActor" x="979.286485558" y="-351.904915507"/>
-    </action>
-    <action date="08 Mar 2007 13:30:32" parent="1104" time="1105" user="hvo" what="addModule">
-      <object cache="1" id="73" name="vtkDataSetMapper" x="894.437195563" y="-203.684492174"/>
-    </action>
-    <action date="08 Mar 2007 13:30:33" parent="1105" time="1106" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="72" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:30:33" parent="1106" time="1107" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="73" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:30:33" parent="1107" time="1108" user="hvo" what="addConnection">
-      <connect destinationId="72" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="121" sourceId="73" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 13:30:40" parent="1108" time="1109" user="hvo" what="moveModule">
-      <move dx="223.537709991" dy="1.63166211672" id="72"/>
-      <move dx="207.221088823" dy="34.2649044511" id="73"/>
-    </action>
-    <action date="08 Mar 2007 13:30:40" parent="1109" time="1110" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="122" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:30:48" parent="1110" time="1111" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="123" sourceId="72" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 13:31:01" parent="1111" time="1112" user="hvo" what="changeParameter">
-      <set alias="" function="SetVector" functionId="0" moduleId="71" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetVector" functionId="0" moduleId="71" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetVector" functionId="0" moduleId="71" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 13:31:08" parent="1112" time="1113" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="71" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 13:31:45" parent="1113" time="1114" user="hvo" what="moveModule">
-      <move dx="-83.2147679527" dy="-26.1065938675" id="15"/>
-      <move dx="-81.583105836" dy="-42.4232150347" id="19"/>
-      <move dx="39.1598908013" dy="-68.5298089023" id="64"/>
-      <move dx="96.2680648865" dy="16.3166211672" id="66"/>
-      <move dx="-93.0047406531" dy="-71.7931331357" id="67"/>
-    </action>
-    <action date="08 Mar 2007 13:31:45" parent="1114" time="1115" user="hvo" what="deleteConnection">
-      <connection connectionId="111"/>
-    </action>
-    <action date="08 Mar 2007 13:32:38" parent="1115" time="1116" user="hvo" what="changeParameter">
-      <set alias="" function="SetExtrusionTypeToVectorExtrusion" functionId="2" moduleId="71" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:33:32" parent="1116" time="1117" user="hvo" what="changeParameter">
-      <set alias="" function="SetVector" functionId="0" moduleId="71" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetVector" functionId="0" moduleId="71" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetVector" functionId="0" moduleId="71" parameter="<no description>" parameterId="2" type="Float" value="-1"/>
-    </action>
-    <action date="08 Mar 2007 13:33:35" parent="1117" time="1118" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="71" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 13:33:37" parent="1118" time="1119" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="71" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 13:33:56" parent="1119" time="1120" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="124" sourceId="64" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 13:34:25" parent="1120" time="1121" user="hvo" what="deleteConnection">
-      <connection connectionId="123"/>
-    </action>
-    <action date="08 Mar 2007 13:34:48" parent="1121" time="1122" user="hvo" what="addConnection">
-      <connect destinationId="70" destinationModule="vtkImplicitDataSet" destinationPort="SetDataSet(vtkDataSet)" id="125" sourceId="71" sourceModule="vtkPolyDataAlgorithm" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 13:34:56" parent="1122" time="1123" user="hvo" what="moveModule">
-      <move dx="43.8427548837" dy="8.76855097674" id="15"/>
-      <move dx="118.375438186" dy="2.92285032558" id="68"/>
-    </action>
-    <action date="08 Mar 2007 13:34:56" parent="1123" time="1124" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="126" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 13:42:36" parent="1124" time="1125" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.46142516279" id="70"/>
-      <move dx="11.6914013023" dy="115.45258786" id="71"/>
-    </action>
-    <action date="08 Mar 2007 13:42:36" parent="1125" time="1126" user="hvo" what="addModule">
-      <object cache="1" id="74" name="vtkProbeFilter" x="1011.30621265" y="-32.1513535814"/>
-    </action>
-    <action date="08 Mar 2007 13:42:58" parent="1126" time="1127" user="hvo" what="moveModule">
-      <move dx="-4.38427548837" dy="-17.5371019535" id="74"/>
-    </action>
-    <action date="08 Mar 2007 13:42:58" parent="1127" time="1128" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="127" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:43:05" parent="1128" time="1129" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="128" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:43:09" parent="1129" time="1130" user="hvo" what="changeParameter">
-      <set alias="" function="SpatialMatchOn" functionId="0" moduleId="74" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:43:14" parent="1130" time="1131" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="129" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:43:15" parent="1131" time="1132" user="hvo" what="deleteConnection">
-      <connection connectionId="122"/>
-    </action>
-    <action date="08 Mar 2007 13:43:57" parent="1132" time="1133" user="hvo" what="deleteConnection">
-      <connection connectionId="118"/>
-      <connection connectionId="125"/>
-    </action>
-    <action date="08 Mar 2007 13:43:57" parent="1133" time="1134" user="hvo" what="deleteModule">
-      <module moduleId="70"/>
-    </action>
-    <action date="08 Mar 2007 13:44:00" parent="1134" time="1135" user="hvo" what="deleteConnection">
-      <connection connectionId="126"/>
-    </action>
-    <action date="08 Mar 2007 13:44:18" parent="1135" time="1136" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="130" sourceId="72" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 13:45:24" parent="1136" time="1137" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="74"/>
-    </action>
-    <action date="08 Mar 2007 13:45:28" parent="1137" time="1138" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOn" functionId="0" moduleId="73" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:46:49" parent="1138" time="1139" user="hvo" what="deleteConnection">
-      <connection connectionId="127"/>
-    </action>
-    <action date="08 Mar 2007 13:46:51" parent="1139" time="1140" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="131" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:46:54" parent="1140" time="1141" user="hvo" what="deleteConnection">
-      <connection connectionId="128"/>
-    </action>
-    <action date="08 Mar 2007 13:46:56" parent="1141" time="1142" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="132" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:47:37" parent="1142" time="1143" user="hvo" what="deleteConnection">
-      <connection connectionId="132"/>
-    </action>
-    <action date="08 Mar 2007 13:47:38" parent="1143" time="1144" user="hvo" what="deleteConnection">
-      <connection connectionId="131"/>
-    </action>
-    <action date="08 Mar 2007 13:47:41" parent="1144" time="1145" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="133" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:47:44" parent="1145" time="1146" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="134" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:55:02" parent="1146" time="1147" user="hvo" what="moveModule">
-      <move dx="1.46142516279" dy="1.46142516279" id="71"/>
-      <move dx="20.4599522791" dy="-48.2270303721" id="74"/>
-    </action>
-    <action date="08 Mar 2007 13:55:02" parent="1147" time="1148" user="hvo" what="addModule">
-      <object cache="1" id="75" name="vtkLinearExtrusionFilter" x="1132.08457237" y="79.2336601288"/>
-    </action>
-    <action date="08 Mar 2007 13:55:02" parent="1148" time="1149" user="hvo" what="changeParameter">
-      <set alias="" function="SetVector" functionId="0" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetVector" functionId="0" moduleId="75" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetVector" functionId="0" moduleId="75" parameter="<no description>" parameterId="2" type="Float" value="-1"/>
-    </action>
-    <action date="08 Mar 2007 13:55:02" parent="1149" time="1150" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 13:55:02" parent="1150" time="1151" user="hvo" what="changeParameter">
-      <set alias="" function="SetExtrusionTypeToVectorExtrusion" functionId="2" moduleId="75" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:55:02" parent="1151" time="1152" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="75" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:55:09" parent="1152" time="1153" user="hvo" what="moveModule">
-      <move dx="4.38427548837" dy="-121.298288512" id="73"/>
-      <move dx="16.0756767907" dy="-62.841282" id="74"/>
-      <move dx="-24.8442277674" dy="-115.45258786" id="75"/>
-    </action>
-    <action date="08 Mar 2007 13:55:09" parent="1153" time="1154" user="hvo" what="deleteConnection">
-      <connection connectionId="133"/>
-    </action>
-    <action date="08 Mar 2007 13:55:11" parent="1154" time="1155" user="hvo" what="addConnection">
-      <connect destinationId="75" destinationModule="vtkAlgorithm" destinationPort="AddInputConnection(vtkAlgorithmOutput)" id="135" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:55:13" parent="1155" time="1156" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="136" sourceId="75" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:55:17" parent="1156" time="1157" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="75"/>
-    </action>
-    <action date="08 Mar 2007 13:55:22" parent="1157" time="1158" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="0" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 13:55:23" parent="1158" time="1159" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="75"/>
-    </action>
-    <action date="08 Mar 2007 13:55:25" parent="1159" time="1160" user="hvo" what="changeParameter">
-      <set alias="" function="SetExtrusionTypeToNormalExtrusion" functionId="1" moduleId="75" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:55:52" parent="1160" time="1161" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="75"/>
-    </action>
-    <action date="08 Mar 2007 13:56:08" parent="1161" time="1162" user="hvo" what="deleteConnection">
-      <connection connectionId="136"/>
-    </action>
-    <action date="08 Mar 2007 13:56:12" parent="1162" time="1163" user="hvo" what="moveModule">
-      <move dx="1.46142516279" dy="35.074203907" id="75"/>
-    </action>
-    <action date="08 Mar 2007 13:56:12" parent="1163" time="1164" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="137" sourceId="75" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:56:14" parent="1164" time="1165" user="hvo" what="deleteConnection">
-      <connection connectionId="129"/>
-    </action>
-    <action date="08 Mar 2007 13:56:41" parent="1165" time="1166" user="hvo" what="moveModule">
-      <move dx="8.76855097674" dy="-2.92285032558" id="75"/>
-    </action>
-    <action date="08 Mar 2007 13:56:41" parent="1166" time="1167" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 13:56:43" parent="1167" time="1168" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 13:56:44" parent="1168" time="1169" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 13:57:15" parent="1169" time="1170" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="100000"/>
-    </action>
-    <action date="08 Mar 2007 13:57:16" parent="1170" time="1171" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="1" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="100000"/>
-    </action>
-    <action date="08 Mar 2007 13:57:34" parent="1171" time="1172" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="75"/>
-    </action>
-    <action date="08 Mar 2007 13:57:39" parent="1172" time="1173" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="0" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 13:57:41" parent="1173" time="1174" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="0" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 13:57:42" parent="1174" time="1175" user="hvo" what="changeParameter">
-      <set alias="" function="SetScaleFactor" functionId="0" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 13:57:44" parent="1175" time="1176" user="hvo" what="changeParameter">
-      <set alias="" function="SetExtrusionTypeToPointExtrusion" functionId="1" moduleId="75" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 13:57:52" parent="1176" time="1177" user="hvo" what="changeParameter">
-      <set alias="" function="SetExtrusionPoint" functionId="2" moduleId="75" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetExtrusionPoint" functionId="2" moduleId="75" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetExtrusionPoint" functionId="2" moduleId="75" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 13:58:32" parent="1177" time="1178" user="hvo" what="moveModule">
-      <move dx="23.3828026046" dy="-51.1498806977" id="75"/>
-    </action>
-    <action date="08 Mar 2007 13:58:32" parent="1178" time="1179" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="75"/>
-    </action>
-    <action date="08 Mar 2007 13:58:34" parent="1179" time="1180" user="hvo" what="deleteConnection">
-      <connection connectionId="137"/>
-      <connection connectionId="135"/>
-    </action>
-    <action date="08 Mar 2007 13:58:34" parent="1180" time="1181" user="hvo" what="deleteModule">
-      <module moduleId="75"/>
-    </action>
-    <action date="08 Mar 2007 13:58:37" parent="1181" time="1182" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="138" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:58:39" parent="1182" time="1183" user="hvo" what="deleteConnection">
-      <connection connectionId="138"/>
-    </action>
-    <action date="08 Mar 2007 13:58:42" parent="1183" time="1184" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="139" sourceId="71" sourceModule="vtkLinearExtrusionFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 13:58:50" parent="1184" time="1185" user="hvo" what="moveModule">
-      <move dx="51.1498806977" dy="94.9926355814" id="74"/>
-    </action>
-    <action date="08 Mar 2007 13:58:50" parent="1185" time="1186" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="140" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:09:16" parent="1186" time="1187" user="hvo" what="moveModule">
-      <move dx="16.0756767907" dy="-27.767078093" id="71"/>
-    </action>
-    <action date="08 Mar 2007 14:09:16" parent="1187" time="1188" user="hvo" what="addModule">
-      <object cache="1" id="76" name="vtkTransformPolyDataFilter" x="1210.06003479" y="135.91254014"/>
-    </action>
-    <action date="08 Mar 2007 14:09:24" parent="1188" time="1189" user="hvo" what="moveModule">
-      <move dx="-447.196099814" dy="-61.3798568372" id="71"/>
-      <move dx="40.9199045581" dy="-102.299761395" id="74"/>
-    </action>
-    <action date="08 Mar 2007 14:09:24" parent="1189" time="1190" user="hvo" what="deleteConnection">
-      <connection connectionId="139"/>
-    </action>
-    <action date="08 Mar 2007 14:09:34" parent="1190" time="1191" user="hvo" what="moveModule">
-      <move dx="-80.3783839535" dy="-17.5371019535" id="74"/>
-      <move dx="-93.5312104186" dy="-135.91254014" id="76"/>
-    </action>
-    <action date="08 Mar 2007 14:09:34" parent="1191" time="1192" user="hvo" what="addConnection">
-      <connect destinationId="76" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="141" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 14:09:44" parent="1192" time="1193" user="hvo" what="addModule">
-      <object cache="1" id="77" name="vtkGeneralTransform" x="604.126428208" y="331.928645966"/>
-    </action>
-    <action date="08 Mar 2007 14:09:44" parent="1193" time="1194" user="hvo" what="changeParameter">
-      <set alias="" function="RotateX" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="90"/>
-    </action>
-    <action date="08 Mar 2007 14:09:44" parent="1194" time="1195" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="77" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:09:49" parent="1195" time="1196" user="hvo" what="moveModule">
-      <move dx="534.881609581" dy="-187.062420837" id="77"/>
-    </action>
-    <action date="08 Mar 2007 14:09:49" parent="1196" time="1197" user="hvo" what="addConnection">
-      <connect destinationId="76" destinationModule="vtkTransformPolyDataFilter" destinationPort="SetTransform(vtkAbstractTransform)" id="142" sourceId="77" sourceModule="vtkGeneralTransform" sourcePort="self(vtkGeneralTransform)"/>
-    </action>
-    <action date="08 Mar 2007 14:10:17" parent="1197" time="1198" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="77"/>
-    </action>
-    <action date="08 Mar 2007 14:10:20" parent="1198" time="1199" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:10:24" parent="1199" time="1200" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:10:24" parent="1200" time="1201" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:10:27" parent="1201" time="1202" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-10000"/>
-    </action>
-    <action date="08 Mar 2007 14:10:28" parent="1202" time="1203" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-10000"/>
-    </action>
-    <action date="08 Mar 2007 14:10:45" parent="1203" time="1204" user="hvo" what="moveModule">
-      <move dx="39.4584793953" dy="43.8427548837" id="76"/>
-      <move dx="-122.759713674" dy="151.98821693" id="77"/>
-    </action>
-    <action date="08 Mar 2007 14:10:45" parent="1204" time="1205" user="hvo" what="addModule">
-      <object cache="1" id="78" name="vtkRuledSurfaceFilter" x="1082.91604563" y="-62.841282"/>
-    </action>
-    <action date="08 Mar 2007 14:10:55" parent="1205" time="1206" user="hvo" what="addConnection">
-      <connect destinationId="78" destinationModule="vtkRuledSurfaceFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="143" sourceId="76" sourceModule="vtkTransformPolyDataFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:12:33" parent="1206" time="1207" user="hvo" what="addModule">
-      <object cache="1" id="79" name="vtkAppendPolyData" x="1058.07181786" y="-10.2299761395"/>
-    </action>
-    <action date="08 Mar 2007 14:12:35" parent="1207" time="1208" user="hvo" what="moveModule">
-      <move dx="2.92285032558" dy="108.145462046" id="76"/>
-    </action>
-    <action date="08 Mar 2007 14:12:35" parent="1208" time="1209" user="hvo" what="deleteConnection">
-      <connection connectionId="143"/>
-    </action>
-    <action date="08 Mar 2007 14:12:38" parent="1209" time="1210" user="hvo" what="moveModule">
-      <move dx="48.2270303721" dy="-48.2270303721" id="78"/>
-    </action>
-    <action date="08 Mar 2007 14:12:38" parent="1210" time="1211" user="hvo" what="addConnection">
-      <connect destinationId="78" destinationModule="vtkRuledSurfaceFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="144" sourceId="79" sourceModule="vtkAppendPolyData" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:12:51" parent="1211" time="1212" user="hvo" what="moveModule">
-      <move dx="-40.9199045581" dy="10.2299761395" id="69"/>
-    </action>
-    <action date="08 Mar 2007 14:12:51" parent="1212" time="1213" user="hvo" what="addConnection">
-      <connect destinationId="79" destinationModule="vtkAppendPolyData" destinationPort="AddInput(vtkPolyData)" id="145" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 14:13:04" parent="1213" time="1214" user="hvo" what="moveModule">
-      <move dx="-54.0727310232" dy="39.4584793953" id="76"/>
-    </action>
-    <action date="08 Mar 2007 14:13:07" parent="1214" time="1215" user="hvo" what="addConnection">
-      <connect destinationId="79" destinationModule="vtkAppendPolyData" destinationPort="AddInput(vtkPolyData)" id="146" sourceId="76" sourceModule="vtkPolyDataAlgorithm" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 14:13:18" parent="1215" time="1216" user="hvo" what="moveModule">
-      <move dx="11.6914013023" dy="21.9213774419" id="78"/>
-    </action>
-    <action date="08 Mar 2007 14:13:18" parent="1216" time="1217" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:13:20" parent="1217" time="1218" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:13:22" parent="1218" time="1219" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="100"/>
-    </action>
-    <action date="08 Mar 2007 14:13:23" parent="1219" time="1220" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="100"/>
-    </action>
-    <action date="08 Mar 2007 14:13:26" parent="1220" time="1221" user="hvo" what="changeParameter">
-      <set alias="" function="SetRuledModeToResample" functionId="1" moduleId="78" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:13:31" parent="1221" time="1222" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetSourceConnection(vtkAlgorithmOutput)" id="147" sourceId="78" sourceModule="vtkRuledSurfaceFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:13:34" parent="1222" time="1223" user="hvo" what="deleteConnection">
-      <connection connectionId="147"/>
-    </action>
-    <action date="08 Mar 2007 14:13:37" parent="1223" time="1224" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="148" sourceId="78" sourceModule="vtkRuledSurfaceFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:14:29" parent="1224" time="1225" user="hvo" what="deleteConnection">
-      <connection connectionId="148"/>
-    </action>
-    <action date="08 Mar 2007 14:14:32" parent="1225" time="1226" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="149" sourceId="78" sourceModule="vtkRuledSurfaceFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:14:35" parent="1226" time="1227" user="hvo" what="deleteConnection">
-      <connection connectionId="140"/>
-    </action>
-    <action date="08 Mar 2007 14:16:23" parent="1227" time="1228" user="hvo" what="deleteConnection">
-      <connection connectionId="149"/>
-    </action>
-    <action date="08 Mar 2007 14:16:29" parent="1228" time="1229" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="150" sourceId="78" sourceModule="vtkRuledSurfaceFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:16:35" parent="1229" time="1230" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="151" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:20:11" parent="1230" time="1231" user="hvo" what="moveModule">
-      <move dx="-149.065366605" dy="-43.8427548837" id="20"/>
-      <move dx="2.92285032558" dy="-27.767078093" id="72"/>
-    </action>
-    <action date="08 Mar 2007 14:20:11" parent="1231" time="1232" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="2"/>
-    </action>
-    <action date="08 Mar 2007 14:20:42" parent="1232" time="1233" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="152" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 14:21:15" parent="1233" time="1234" user="hvo" what="moveModule">
-      <move dx="70.1484078139" dy="-20.4599522791" id="29"/>
-      <move dx="176.832444698" dy="83.301234279" id="71"/>
-    </action>
-    <action date="08 Mar 2007 14:21:15" parent="1234" time="1235" user="hvo" what="deleteConnection">
-      <connection connectionId="30"/>
-      <connection connectionId="31"/>
-    </action>
-    <action date="08 Mar 2007 14:21:15" parent="1235" time="1236" user="hvo" what="deleteModule">
-      <module moduleId="29"/>
-    </action>
-    <action date="08 Mar 2007 14:21:23" parent="1236" time="1237" user="hvo" what="addConnection">
-      <connect destinationId="19" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="153" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 14:22:00" parent="1237" time="1238" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.46142516279" id="6"/>
-    </action>
-    <action date="08 Mar 2007 14:22:00" parent="1238" time="1239" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-    </action>
-    <action date="08 Mar 2007 14:22:01" parent="1239" time="1240" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-    </action>
-    <action date="08 Mar 2007 14:23:54" parent="1240" time="1241" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="45"/>
-    </action>
-    <action date="08 Mar 2007 14:23:55" parent="1241" time="1242" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="45"/>
-    </action>
-    <action date="08 Mar 2007 14:25:02" parent="1242" time="1243" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.46142516279" id="78"/>
-    </action>
-    <action date="08 Mar 2007 14:25:02" parent="1243" time="1244" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-1000"/>
-    </action>
-    <action date="08 Mar 2007 14:25:03" parent="1244" time="1245" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-1000"/>
-    </action>
-    <action date="08 Mar 2007 14:25:28" parent="1245" time="1246" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-2000"/>
-    </action>
-    <action date="08 Mar 2007 14:25:29" parent="1246" time="1247" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-2000"/>
-    </action>
-    <action date="08 Mar 2007 14:26:02" parent="1247" time="1248" user="hvo" what="deleteConnection">
-      <connection connectionId="152"/>
-    </action>
-    <action date="08 Mar 2007 14:26:07" parent="1248" time="1249" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 14:26:09" parent="1249" time="1250" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 14:31:58" parent="1250" time="1251" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.46142516279" id="2"/>
-    </action>
-    <action date="08 Mar 2007 14:31:58" parent="1251" time="1252" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:32:09" parent="1252" time="1253" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.474509803922"/>
-    </action>
-    <action date="08 Mar 2007 14:32:15" parent="1253" time="1254" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.474509803922"/>
-    </action>
-    <action date="08 Mar 2007 14:32:54" parent="1254" time="1255" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="2.5"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.81"/>
-    </action>
-    <action date="08 Mar 2007 14:32:57" parent="1255" time="1256" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="2.5"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.474509803922"/>
-    </action>
-    <action date="08 Mar 2007 14:33:00" parent="1256" time="1257" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.15"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.43"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:09" parent="1257" time="1258" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.145098039216"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.43"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:16" parent="1258" time="1259" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.145098039216"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.427450980392"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:17" parent="1259" time="1260" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.145098039216"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.427450980392"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:46" parent="1260" time="1261" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="7.5"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.15"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.72"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:47" parent="1261" time="1262" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="7.5"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.15"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.72"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:54" parent="1262" time="1263" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="7.5"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.149019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.72"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:33:56" parent="1263" time="1264" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="7.5"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.149019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.72"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:34:00" parent="1264" time="1265" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="7.5"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.149019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.717647058824"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:34:06" parent="1265" time="1266" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="10.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.16"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:34:15" parent="1266" time="1267" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="10.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.156862745098"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 14:34:31" parent="1267" time="1268" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="12.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.16"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.73"/>
-    </action>
-    <action date="08 Mar 2007 14:34:37" parent="1268" time="1269" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="12.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.164705882353"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.73"/>
-    </action>
-    <action date="08 Mar 2007 14:34:43" parent="1269" time="1270" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="12.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.164705882353"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.725490196078"/>
-    </action>
-    <action date="08 Mar 2007 14:34:45" parent="1270" time="1271" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="12.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.164705882353"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.725490196078"/>
-    </action>
-    <action date="08 Mar 2007 14:34:54" parent="1271" time="1272" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="15.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.73"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.31"/>
-    </action>
-    <action date="08 Mar 2007 14:35:23" parent="1272" time="1273" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="15.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.733333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.31"/>
-    </action>
-    <action date="08 Mar 2007 14:35:27" parent="1273" time="1274" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="15.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.733333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.309803921569"/>
-    </action>
-    <action date="08 Mar 2007 14:35:30" parent="1274" time="1275" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="17.5"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.45"/>
-    </action>
-    <action date="08 Mar 2007 14:35:41" parent="1275" time="1276" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="17.5"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.454901960784"/>
-    </action>
-    <action date="08 Mar 2007 14:35:42" parent="1276" time="1277" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="17.5"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.454901960784"/>
-    </action>
-    <action date="08 Mar 2007 14:35:53" parent="1277" time="1278" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="20.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.93"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:35:54" parent="1278" time="1279" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="20.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.93"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:07" parent="1279" time="1280" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="20.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.933333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:10" parent="1280" time="1281" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="20.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.933333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:12" parent="1281" time="1282" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="22.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.75"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:24" parent="1282" time="1283" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="22.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.749019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:25" parent="1283" time="1284" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="22.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.749019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:29" parent="1284" time="1285" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="25.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.56"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:41" parent="1285" time="1286" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="25.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.560784313725"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:42" parent="1286" time="1287" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="25.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.560784313725"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:36:57" parent="1287" time="1288" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="27.5"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.37"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:04" parent="1288" time="1289" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="27.5"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.372549019608"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:12" parent="1289" time="1290" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="30.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.88"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:21" parent="1290" time="1291" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="30.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.878431372549"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:34" parent="1291" time="1292" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.5"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.68"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:37" parent="1292" time="1293" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.5"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.674509803922"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:41" parent="1293" time="1294" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.49"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:37:58" parent="1294" time="1295" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:38:04" parent="1295" time="1296" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35.5"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.49"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:38:08" parent="1296" time="1297" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35.5"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:38:15" parent="1297" time="1298" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35.5"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:39:00" parent="1298" time="1299" user="hvo" what="moveModule">
-      <move dx="143.219665953" dy="-132.989689814" id="2"/>
-    </action>
-    <action date="08 Mar 2007 14:39:00" parent="1299" time="1300" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="154" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 14:39:44" parent="1300" time="1301" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-35"/>
-    </action>
-    <action date="08 Mar 2007 14:39:46" parent="1301" time="1302" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-35"/>
-    </action>
-    <action date="08 Mar 2007 14:40:00" parent="1302" time="1303" user="hvo" what="moveModule">
-      <move dx="64.3027071628" dy="27.767078093" id="71"/>
-      <move dx="0.0" dy="-1.46142516279" id="73"/>
-    </action>
-    <action date="08 Mar 2007 14:40:00" parent="1303" time="1304" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:40:02" parent="1304" time="1305" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:40:02" parent="1305" time="1306" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:40:06" parent="1306" time="1307" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 14:40:08" parent="1307" time="1308" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 14:40:48" parent="1308" time="1309" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 14:40:50" parent="1309" time="1310" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalScale" functionId="1" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 14:41:19" parent="1310" time="1311" user="hvo" what="deleteConnection">
-      <connection connectionId="124"/>
-    </action>
-    <action date="08 Mar 2007 14:41:25" parent="1311" time="1312" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="72"/>
-    </action>
-    <action date="08 Mar 2007 14:42:23" parent="1312" time="1313" user="hvo" what="moveModule">
-      <move dx="-86.2240846046" dy="-146.142516279" id="9"/>
-      <move dx="312.744984837" dy="2.92285032558" id="16"/>
-    </action>
-    <action date="08 Mar 2007 14:42:23" parent="1313" time="1314" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-100"/>
-    </action>
-    <action date="08 Mar 2007 14:42:26" parent="1314" time="1315" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-100"/>
-    </action>
-    <action date="08 Mar 2007 14:43:40" parent="1315" time="1316" user="hvo" what="moveModule">
-      <move dx="-39.4584793953" dy="11.6914013023" id="66"/>
-    </action>
-    <action date="08 Mar 2007 14:43:40" parent="1316" time="1317" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="155" sourceId="64" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 14:43:57" parent="1317" time="1318" user="hvo" what="deleteConnection">
-      <connection connectionId="155"/>
-    </action>
-    <action date="08 Mar 2007 14:44:01" parent="1318" time="1319" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="156" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 14:44:49" parent="1319" time="1320" user="hvo" what="moveModule">
-      <move dx="-1.46142516279" dy="0.0" id="77"/>
-    </action>
-    <action date="08 Mar 2007 14:44:49" parent="1320" time="1321" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:44:51" parent="1321" time="1322" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:45:57" parent="1322" time="1323" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="-100"/>
-    </action>
-    <action date="08 Mar 2007 14:45:59" parent="1323" time="1324" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="-100"/>
-    </action>
-    <action date="08 Mar 2007 14:46:23" parent="1324" time="1325" user="hvo" what="moveModule">
-      <move dx="-1.46142516279" dy="0.0" id="16"/>
-    </action>
-    <action date="08 Mar 2007 14:46:23" parent="1325" time="1326" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalShift" functionId="2" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:46:24" parent="1326" time="1327" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalShift" functionId="2" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:46:27" parent="1327" time="1328" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalShift" functionId="2" moduleId="16" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 14:46:29" parent="1328" time="1329" user="hvo" what="changeParameter">
-      <set alias="" function="SetVerticalShift" functionId="2" moduleId="16" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 14:46:33" parent="1329" time="1330" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:46:38" parent="1330" time="1331" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 14:46:39" parent="1331" time="1332" user="hvo" what="deleteConnection">
-      <connection connectionId="156"/>
-    </action>
-    <action date="08 Mar 2007 14:47:21" parent="1332" time="1333" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.46142516279" id="71"/>
-    </action>
-    <action date="08 Mar 2007 14:47:21" parent="1333" time="1334" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-35"/>
-    </action>
-    <action date="08 Mar 2007 14:47:22" parent="1334" time="1335" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-35"/>
-    </action>
-    <action date="08 Mar 2007 14:47:37" parent="1335" time="1336" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 14:47:39" parent="1336" time="1337" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:47:40" parent="1337" time="1338" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:47:42" parent="1338" time="1339" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 14:47:43" parent="1339" time="1340" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="100"/>
-    </action>
-    <action date="08 Mar 2007 14:48:44" parent="1340" time="1341" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="157" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 14:49:56" parent="1341" time="1342" user="hvo" what="moveModule">
-      <move dx="10.2299761395" dy="176.832444698" id="19"/>
-    </action>
-    <action date="08 Mar 2007 14:50:09" parent="1342" time="1343" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkMapper" destinationPort="SetScalarRange(Float,Float)" id="158" sourceId="19" sourceModule="vtkMapper" sourcePort="GetScalarRange(Float,Float)"/>
-    </action>
-    <action date="08 Mar 2007 14:50:15" parent="1343" time="1344" user="hvo" what="deleteConnection">
-      <connection connectionId="157"/>
-    </action>
-    <action date="08 Mar 2007 14:51:00" parent="1344" time="1345" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-25"/>
-    </action>
-    <action date="08 Mar 2007 14:51:02" parent="1345" time="1346" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-25"/>
-    </action>
-    <action date="08 Mar 2007 14:51:09" parent="1346" time="1347" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="-1"/>
-    </action>
-    <action date="08 Mar 2007 14:51:12" parent="1347" time="1348" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="69" parameter="<no description>" parameterId="0" type="Float" value="-1"/>
-    </action>
-    <action date="08 Mar 2007 14:51:17" parent="1348" time="1349" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.46142516279" id="20"/>
-      <move dx="0.0" dy="1.46142516279" id="78"/>
-    </action>
-    <action date="08 Mar 2007 14:51:17" parent="1349" time="1350" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="20"/>
-    </action>
-    <action date="08 Mar 2007 14:51:20" parent="1350" time="1351" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="20"/>
-    </action>
-    <action date="08 Mar 2007 14:52:22" parent="1351" time="1352" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="159" sourceId="15" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 14:53:44" parent="1352" time="1353" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.46142516279" id="2"/>
-    </action>
-    <action date="08 Mar 2007 14:53:44" parent="1353" time="1354" user="hvo" what="changeParameter">
-      <set alias="" function="SetColorModeToMapScalars" functionId="1" moduleId="73" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 14:56:17" parent="1354" time="1355" user="hvo" what="deleteConnection">
-      <connection connectionId="159"/>
-      <connection connectionId="20"/>
-    </action>
-    <action date="08 Mar 2007 14:56:17" parent="1355" time="1356" user="hvo" what="deleteModule">
-      <module moduleId="15"/>
-    </action>
-    <action date="08 Mar 2007 14:56:26" parent="1356" time="1357" user="hvo" what="moveModule">
-      <move dx="102.299761395" dy="-32.1513535814" id="64"/>
-      <move dx="-18.9985271163" dy="71.6098329767" id="67"/>
-    </action>
-    <action date="08 Mar 2007 14:56:26" parent="1357" time="1358" user="hvo" what="deleteConnection">
-      <connection connectionId="112"/>
-      <connection connectionId="109"/>
-      <connection connectionId="114"/>
-      <connection connectionId="117"/>
-    </action>
-    <action date="08 Mar 2007 14:56:26" parent="1358" time="1359" user="hvo" what="deleteModule">
-      <module moduleId="67"/>
-      <module moduleId="64"/>
-      <module moduleId="68"/>
-      <module moduleId="66"/>
-    </action>
-    <action date="08 Mar 2007 14:56:33" parent="1359" time="1360" user="hvo" what="moveModule">
-      <move dx="-90.608360093" dy="-36.5356290698" id="71"/>
-    </action>
-    <action date="08 Mar 2007 14:56:33" parent="1360" time="1361" user="hvo" what="deleteConnection">
-      <connection connectionId="120"/>
-    </action>
-    <action date="08 Mar 2007 14:56:33" parent="1361" time="1362" user="hvo" what="deleteModule">
-      <module moduleId="71"/>
-    </action>
-    <action date="08 Mar 2007 14:59:14" parent="1362" time="1363" user="hvo" what="moveModule">
-      <move dx="-42.3813297209" dy="792.092438232" id="31"/>
-      <move dx="154.911067256" dy="-882.700798325" id="32"/>
-    </action>
-    <action date="08 Mar 2007 14:59:14" parent="1363" time="1364" user="hvo" what="deleteConnection">
-      <connection connectionId="33"/>
-      <connection connectionId="36"/>
-      <connection connectionId="55"/>
-    </action>
-    <action date="08 Mar 2007 14:59:14" parent="1364" time="1365" user="hvo" what="deleteModule">
-      <module moduleId="32"/>
-    </action>
-    <action date="08 Mar 2007 14:59:16" parent="1365" time="1366" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 14:59:16" parent="1366" time="1367" user="hvo" what="deleteModule">
-      <module moduleId="31"/>
-    </action>
-    <action date="08 Mar 2007 14:59:20" parent="1367" time="1368" user="hvo" what="moveModule">
-      <move dx="32.1513535814" dy="-36.5356290698" id="19"/>
-      <move dx="-549.495861209" dy="-11.6914013023" id="73"/>
-    </action>
-    <action date="08 Mar 2007 14:59:20" parent="1368" time="1369" user="hvo" what="deleteConnection">
-      <connection connectionId="158"/>
-      <connection connectionId="5"/>
-      <connection connectionId="153"/>
-    </action>
-    <action date="08 Mar 2007 14:59:20" parent="1369" time="1370" user="hvo" what="deleteModule">
-      <module moduleId="19"/>
-    </action>
-    <action date="08 Mar 2007 14:59:30" parent="1370" time="1371" user="hvo" what="moveModule">
-      <move dx="1.46142516279" dy="-372.663416512" id="2"/>
-      <move dx="-135.91254014" dy="-11.6914013023" id="74"/>
-    </action>
-    <action date="08 Mar 2007 14:59:30" parent="1371" time="1372" user="hvo" what="deleteConnection">
-      <connection connectionId="16"/>
-      <connection connectionId="15"/>
-    </action>
-    <action date="08 Mar 2007 14:59:30" parent="1372" time="1373" user="hvo" what="deleteModule">
-      <module moduleId="8"/>
-      <module moduleId="11"/>
-    </action>
-    <action date="08 Mar 2007 14:59:34" parent="1373" time="1374" user="hvo" what="deleteConnection">
-      <connection connectionId="17"/>
-      <connection connectionId="24"/>
-      <connection connectionId="22"/>
-      <connection connectionId="23"/>
-    </action>
-    <action date="08 Mar 2007 14:59:34" parent="1374" time="1375" user="hvo" what="deleteModule">
-      <module moduleId="16"/>
-      <module moduleId="21"/>
-      <module moduleId="22"/>
-      <module moduleId="23"/>
-    </action>
-    <action date="08 Mar 2007 14:59:36" parent="1375" time="1376" user="hvo" what="moveModule">
-      <move dx="-27.767078093" dy="21.9213774419" id="9"/>
-    </action>
-    <action date="08 Mar 2007 14:59:36" parent="1376" time="1377" user="hvo" what="deleteConnection">
-      <connection connectionId="18"/>
-    </action>
-    <action date="08 Mar 2007 14:59:36" parent="1377" time="1378" user="hvo" what="deleteModule">
-      <module moduleId="9"/>
-    </action>
-    <action date="08 Mar 2007 14:59:37" parent="1378" time="1379" user="hvo" what="deleteConnection">
-      <connection connectionId="19"/>
-      <connection connectionId="9"/>
-    </action>
-    <action date="08 Mar 2007 14:59:37" parent="1379" time="1380" user="hvo" what="deleteModule">
-      <module moduleId="10"/>
-    </action>
-    <action date="08 Mar 2007 14:59:38" parent="1380" time="1381" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 14:59:38" parent="1381" time="1382" user="hvo" what="deleteModule">
-      <module moduleId="4"/>
-    </action>
-    <action date="08 Mar 2007 14:59:40" parent="1382" time="1383" user="hvo" what="deleteConnection">
-      <connection connectionId="2"/>
-    </action>
-    <action date="08 Mar 2007 14:59:40" parent="1383" time="1384" user="hvo" what="deleteModule">
-      <module moduleId="14"/>
-    </action>
-    <action date="08 Mar 2007 14:59:41" parent="1384" time="1385" user="hvo" what="deleteConnection">
-      <connection connectionId="3"/>
-    </action>
-    <action date="08 Mar 2007 14:59:41" parent="1385" time="1386" user="hvo" what="deleteModule">
-      <module moduleId="13"/>
-    </action>
-    <action date="08 Mar 2007 14:59:42" parent="1386" time="1387" user="hvo" what="deleteConnection">
-      <connection connectionId="4"/>
-    </action>
-    <action date="08 Mar 2007 14:59:42" parent="1387" time="1388" user="hvo" what="deleteModule">
-      <module moduleId="1"/>
-    </action>
-    <action date="08 Mar 2007 14:59:52" parent="1388" time="1389" user="hvo" what="moveModule">
-      <move dx="116.914013023" dy="-35.074203907" id="0"/>
-      <move dx="127.143989163" dy="-463.271776605" id="7"/>
-      <move dx="-1.46142516279" dy="1.46142516279" id="12"/>
-    </action>
-    <action date="08 Mar 2007 14:59:52" parent="1389" time="1390" user="hvo" what="deleteConnection">
-      <connection connectionId="66"/>
-      <connection connectionId="67"/>
-    </action>
-    <action date="08 Mar 2007 14:59:52" parent="1390" time="1391" user="hvo" what="deleteModule">
-      <module moduleId="42"/>
-      <module moduleId="28"/>
-      <module moduleId="43"/>
-    </action>
-    <action date="08 Mar 2007 15:00:57" parent="1391" time="1392" user="hvo" what="moveModule">
-      <move dx="40.9199045581" dy="-191.446696326" id="0"/>
-      <move dx="564.110112837" dy="71.6098329767" id="2"/>
-      <move dx="-73.0712581395" dy="-346.357763581" id="3"/>
-      <move dx="-182.678145349" dy="-236.750876372" id="5"/>
-      <move dx="561.187262511" dy="-160.756767907" id="6"/>
-      <move dx="-106.684036884" dy="-457.426075953" id="7"/>
-      <move dx="153.449642093" dy="-150.526791767" id="12"/>
-      <move dx="-23.3828026046" dy="-226.520900233" id="18"/>
-      <move dx="93.5312104186" dy="-412.121895907" id="20"/>
-      <move dx="711.714054279" dy="-128.605414326" id="24"/>
-      <move dx="711.714054279" dy="-128.605414326" id="25"/>
-      <move dx="711.714054279" dy="-128.605414326" id="26"/>
-      <move dx="-64.3027071628" dy="-255.749403488" id="27"/>
-      <move dx="-537.804459907" dy="151.98821693" id="69"/>
-      <move dx="-146.142516279" dy="-181.216720186" id="72"/>
-      <move dx="412.121895907" dy="-58.4570065116" id="73"/>
-      <move dx="-132.989689814" dy="-10.2299761395" id="74"/>
-      <move dx="-474.963177907" dy="-16.0756767907" id="76"/>
-      <move dx="-280.593631256" dy="113.991162698" id="77"/>
-      <move dx="-467.656052093" dy="-4.38427548837" id="78"/>
-      <move dx="-587.492915442" dy="39.4584793953" id="79"/>
-    </action>
-    <action date="08 Mar 2007 15:00:57" parent="1392" time="1393" user="hvo" what="deleteConnection">
-      <connection connectionId="144"/>
-    </action>
-    <action date="08 Mar 2007 15:00:59" parent="1393" time="1394" user="hvo" what="addConnection">
-      <connect destinationId="78" destinationModule="vtkRuledSurfaceFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="160" sourceId="79" sourceModule="vtkAppendPolyData" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 15:01:55" parent="1394" time="1395" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-10"/>
-    </action>
-    <action date="08 Mar 2007 15:02:01" parent="1395" time="1396" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-10"/>
-    </action>
-    <action date="08 Mar 2007 15:02:40" parent="1396" time="1397" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 15:02:43" parent="1397" time="1398" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 15:02:45" parent="1398" time="1399" user="hvo" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 15:02:47" parent="1399" time="1400" user="hvo" what="changeParameter">
-      <set alias="" function="SetTimeStep" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 15:03:46" parent="1400" time="1401" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.46142516279" id="26"/>
-    </action>
-    <action date="08 Mar 2007 15:04:59" parent="1401" time="1402" user="hvo" what="moveModule">
-      <move dx="-140.296815628" dy="46.7656052093" id="0"/>
-      <move dx="-1.46142516279" dy="0.0" id="2"/>
-      <move dx="-160.756767907" dy="8.76855097674" id="7"/>
-      <move dx="-73.0712581395" dy="-30.6899284186" id="73"/>
-      <move dx="-166.602468558" dy="36.5356290698" id="12"/>
-      <move dx="-29.2285032558" dy="-111.068312372" id="18"/>
-      <move dx="1.46142516279" dy="11.6914013023" id="20"/>
-      <move dx="29.2285032558" dy="17.5371019535" id="27"/>
-    </action>
-    <action date="08 Mar 2007 15:04:59" parent="1402" time="1403" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="73"/>
-    </action>
-    <action date="08 Mar 2007 15:05:09" parent="1403" time="1404" user="hvo" what="changeParameter">
-      <set alias="" function="InterpolateScalarsBeforeMappingOn" functionId="1" moduleId="73" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 15:05:22" parent="1404" time="1405" user="hvo" what="changeParameter">
-      <set alias="" function="SetScalarModeToUsePointData" functionId="2" moduleId="73" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 15:06:41" parent="1405" time="1406" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="35"/>
-    </action>
-    <action date="08 Mar 2007 15:06:43" parent="1406" time="1407" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="35"/>
-    </action>
-    <action date="08 Mar 2007 15:09:45" parent="1407" time="1408" user="hvo" what="moveModule">
-      <move dx="-1.46142516279" dy="0.0" id="76"/>
-    </action>
-    <action date="08 Mar 2007 15:09:45" parent="1408" time="1409" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-2"/>
-    </action>
-    <action date="08 Mar 2007 15:09:47" parent="1409" time="1410" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-2"/>
-    </action>
-    <action date="08 Mar 2007 15:10:48" parent="1410" time="1411" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="15"/>
-    </action>
-    <action date="08 Mar 2007 15:10:50" parent="1411" time="1412" user="hvo" what="changeParameter">
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="0" type="Integer" value="100"/>
-      <set alias="" function="SetResolution" functionId="0" moduleId="78" parameter="<no description>" parameterId="1" type="Integer" value="15"/>
-    </action>
-    <action date="08 Mar 2007 15:11:06" parent="1412" time="1413" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="73"/>
-    </action>
-    <action date="08 Mar 2007 15:11:09" parent="1413" time="1414" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="73"/>
-    </action>
-    <action date="08 Mar 2007 15:11:56" parent="1414" time="1415" user="hvo" what="addModule">
-      <object cache="1" id="80" name="vtkProperty" x="1150.14160312" y="-412.121895907"/>
-    </action>
-    <action date="08 Mar 2007 15:11:59" parent="1415" time="1416" user="hvo" what="addConnection">
-      <connect destinationId="72" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="161" sourceId="80" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="08 Mar 2007 15:13:01" parent="1416" time="1417" user="hvo" what="changeParameter">
-      <set alias="" function="SetInterpolationToFlat" functionId="0" moduleId="80" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 15:13:46" parent="1417" time="1418" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-10"/>
-    </action>
-    <action date="08 Mar 2007 15:14:51" parent="1418" time="1419" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="80"/>
-    </action>
-    <action date="08 Mar 2007 15:14:52" parent="1419" time="1420" user="hvo" what="deleteConnection">
-      <connection connectionId="161"/>
-    </action>
-    <action date="08 Mar 2007 15:14:52" parent="1420" time="1421" user="hvo" what="deleteModule">
-      <module moduleId="80"/>
-    </action>
-    <action date="08 Mar 2007 15:17:24" parent="1421" time="1422" user="hvo" what="moveModule">
-      <move dx="-58.1362943906" dy="18.433459197" id="72"/>
-      <move dx="-72.3158783884" dy="-15.5975423975" id="73"/>
-    </action>
-    <action date="08 Mar 2007 15:17:24" parent="1422" time="1423" user="hvo" what="addModule">
-      <object cache="1" id="81" name="vtkPolyDataMapper2D" x="683.45594869" y="-306.279014351"/>
-    </action>
-    <action date="08 Mar 2007 15:17:31" parent="1423" time="1424" user="hvo" what="moveModule">
-      <move dx="90.7493375854" dy="11.3436671982" id="81"/>
-    </action>
-    <action date="08 Mar 2007 15:17:31" parent="1424" time="1425" user="hvo" what="addConnection">
-      <connect destinationId="81" destinationModule="vtkPolyDataMapper2D" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="162" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 15:17:45" parent="1425" time="1426" user="hvo" what="moveModule">
-      <move dx="1.41795839977" dy="-1.41795839977" id="72"/>
-      <move dx="83.6595455865" dy="-18.433459197" id="73"/>
-      <move dx="-138.959923178" dy="-277.919846355" id="81"/>
-    </action>
-    <action date="08 Mar 2007 15:17:45" parent="1426" time="1427" user="hvo" what="addModule">
-      <object cache="1" id="82" name="vtkActor" x="1011.4682352" y="-530.823592472"/>
-    </action>
-    <action date="08 Mar 2007 15:17:45" parent="1427" time="1428" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="82" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="82" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="82" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 15:17:45" parent="1428" time="1429" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="82" value=""/>
-    </action>
-    <action date="08 Mar 2007 15:17:56" parent="1429" time="1430" user="hvo" what="moveModule">
-      <move dx="-337.474099146" dy="-180.080716771" id="82"/>
-    </action>
-    <action date="08 Mar 2007 15:17:56" parent="1430" time="1431" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 15:17:56" parent="1431" time="1432" user="hvo" what="deleteModule">
-      <module moduleId="82"/>
-    </action>
-    <action date="08 Mar 2007 15:18:07" parent="1432" time="1433" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOn" functionId="1" moduleId="73" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 15:18:13" parent="1433" time="1434" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="73"/>
-    </action>
-    <action date="08 Mar 2007 15:18:30" parent="1434" time="1435" user="hvo" what="moveModule">
-      <move dx="-1.41795839977" dy="0.0" id="73"/>
-    </action>
-    <action date="08 Mar 2007 15:18:30" parent="1435" time="1436" user="hvo" what="addModule">
-      <object cache="1" id="83" name="vtkActor2D" x="699.053491087" y="-706.143283086"/>
-    </action>
-    <action date="08 Mar 2007 15:18:32" parent="1436" time="1437" user="hvo" what="addConnection">
-      <connect destinationId="83" destinationModule="vtkActor2D" destinationPort="SetMapper(vtkMapper2D)" id="163" sourceId="81" sourceModule="vtkPolyDataMapper2D" sourcePort="self(vtkPolyDataMapper2D)"/>
-    </action>
-    <action date="08 Mar 2007 15:18:34" parent="1437" time="1438" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="164" sourceId="83" sourceModule="vtkActor2D" sourcePort="self(vtkActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 15:20:00" parent="1438" time="1439" user="hvo" what="addModule">
-      <object cache="1" id="84" name="vtkCoordinate" x="517.554815917" y="-365.833267141"/>
-    </action>
-    <action date="08 Mar 2007 15:20:03" parent="1439" time="1440" user="hvo" what="addConnection">
-      <connect destinationId="81" destinationModule="vtkPolyDataMapper2D" destinationPort="SetTransformCoordinate(vtkCoordinate)" id="165" sourceId="84" sourceModule="vtkCoordinate" sourcePort="self(vtkCoordinate)"/>
-    </action>
-    <action date="08 Mar 2007 15:20:07" parent="1440" time="1441" user="hvo" what="changeParameter">
-      <set alias="" function="SetCoordinateSystemToWorld" functionId="0" moduleId="84" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 19:48:59" parent="1441" time="1442" user="hvo" what="moveModule">
-      <move dx="-18.433459197" dy="-22.6873343963" id="0"/>
-      <move dx="2.83591679954" dy="-24.1052927961" id="7"/>
-      <move dx="-24.1052927961" dy="-56.7183359909" id="12"/>
-      <move dx="-5.67183359909" dy="-56.7183359909" id="74"/>
-    </action>
-    <action date="08 Mar 2007 19:49:08" parent="1442" time="1443" user="hvo" what="addModule">
-      <object cache="1" id="85" name="PythonSource" x="650.842905495" y="-207.021926367"/>
-    </action>
-    <action date="08 Mar 2007 19:49:17" parent="1443" time="1444" user="hvo" what="moveModule">
-      <move dx="-2.83591679954" dy="-69.4799615888" id="74"/>
-    </action>
-    <action date="08 Mar 2007 19:49:17" parent="1444" time="1445" user="hvo" what="addModulePort">
-      <addPort moduleId="85" portName="polydata" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 19:49:23" parent="1445" time="1446" user="hvo" what="addConnection">
-      <connect destinationId="85" destinationModule="PythonSource" destinationPort="polydata(vtkPolyData)" id="166" sourceId="78" sourceModule="vtkPolyDataAlgorithm" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 19:49:28" parent="1446" time="1447" user="hvo" what="moveModule">
-      <move dx="24.1052927961" dy="-12.7616255979" id="85"/>
-    </action>
-    <action date="08 Mar 2007 19:49:28" parent="1447" time="1448" user="hvo" what="deleteConnection">
-      <connection connectionId="150"/>
-      <connection connectionId="134"/>
-    </action>
-    <action date="08 Mar 2007 19:49:54" parent="1448" time="1449" user="hvo" what="moveModule">
-      <move dx="-66.6440447893" dy="0.0" id="74"/>
-      <move dx="154.557465575" dy="-79.4056703872" id="85"/>
-    </action>
-    <action date="08 Mar 2007 19:49:54" parent="1449" time="1450" user="hvo" what="deleteConnection">
-      <connection connectionId="166"/>
-    </action>
-    <action date="08 Mar 2007 19:49:54" parent="1450" time="1451" user="hvo" what="deleteModule">
-      <module moduleId="85"/>
-    </action>
-    <action date="08 Mar 2007 19:49:58" parent="1451" time="1452" user="hvo" what="moveModule">
-      <move dx="32.6130431948" dy="116.272588781" id="74"/>
-    </action>
-    <action date="08 Mar 2007 19:49:58" parent="1452" time="1453" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="167" sourceId="78" sourceModule="vtkRuledSurfaceFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 19:50:00" parent="1453" time="1454" user="hvo" what="deleteConnection">
-      <connection connectionId="167"/>
-    </action>
-    <action date="08 Mar 2007 19:50:04" parent="1454" time="1455" user="hvo" what="moveModule">
-      <move dx="2.83591679954" dy="29.7771263952" id="78"/>
-    </action>
-    <action date="08 Mar 2007 19:50:04" parent="1455" time="1456" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="168" sourceId="78" sourceModule="vtkRuledSurfaceFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 19:50:07" parent="1456" time="1457" user="hvo" what="addConnection">
-      <connect destinationId="74" destinationModule="vtkProbeFilter" destinationPort="SetInputConnection1(vtkAlgorithmOutput)" id="169" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 19:50:12" parent="1457" time="1458" user="hvo" what="deleteConnection">
-      <connection connectionId="164"/>
-      <connection connectionId="163"/>
-      <connection connectionId="165"/>
-      <connection connectionId="162"/>
-    </action>
-    <action date="08 Mar 2007 19:50:12" parent="1458" time="1459" user="hvo" what="deleteModule">
-      <module moduleId="83"/>
-      <module moduleId="84"/>
-      <module moduleId="81"/>
-    </action>
-    <action date="08 Mar 2007 19:50:24" parent="1459" time="1460" user="hvo" what="moveModule">
-      <move dx="-131.870131179" dy="-185.75255037" id="72"/>
-      <move dx="-109.182796782" dy="-172.990924772" id="73"/>
-    </action>
-    <action date="08 Mar 2007 19:50:24" parent="1460" time="1461" user="hvo" what="addModule">
-      <object cache="1" id="86" name="PythonSource" x="711.815116685" y="-344.563891145"/>
-    </action>
-    <action date="08 Mar 2007 19:50:31" parent="1461" time="1462" user="hvo" what="addModulePort">
-      <addPort moduleId="86" portName="polydata" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 19:50:52" parent="1462" time="1463" user="hvo" what="moveModule">
-      <move dx="-1.41795839977" dy="0.0" id="74"/>
-    </action>
-    <action date="08 Mar 2007 19:55:03" parent="1463" time="1464" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="78"/>
-      <move dx="-14.1795839977" dy="-21.2693759966" id="86"/>
-    </action>
-    <action date="08 Mar 2007 19:55:03" parent="1464" time="1465" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="86" portName="polydata" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 19:55:03" parent="1465" time="1466" user="hvo" what="addModulePort">
-      <addPort moduleId="86" portName="probed" portSpec="(vtkProbeFilter)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 19:55:08" parent="1466" time="1467" user="hvo" what="moveModule">
-      <move dx="55.3003775911" dy="-11.3436671982" id="86"/>
-    </action>
-    <action date="08 Mar 2007 19:55:08" parent="1467" time="1468" user="hvo" what="addConnection">
-      <connect destinationId="86" destinationModule="PythonSource" destinationPort="probed(vtkProbeFilter)" id="170" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="self(vtkProbeFilter)"/>
-    </action>
-    <action date="08 Mar 2007 19:55:26" parent="1468" time="1469" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="probeFilter%20%3D%20probed.vtkInstance%0Aprint%20type%28probeFilter%29"/>
-    </action>
-    <action date="08 Mar 2007 19:59:34" parent="1469" time="1470" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="probeFilter%20%3D%20probed.vtkInstance%0Aa%20%3D%20probeFilter.GetOutput%28%29"/>
-    </action>
-    <action date="08 Mar 2007 19:59:54" parent="1470" time="1471" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="74"/>
-    </action>
-    <action date="08 Mar 2007 20:06:47" parent="1471" time="1472" user="hvo" what="deleteConnection">
-      <connection connectionId="170"/>
-    </action>
-    <action date="08 Mar 2007 20:07:13" parent="1472" time="1473" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.41795839977" id="86"/>
-    </action>
-    <action date="08 Mar 2007 20:07:13" parent="1473" time="1474" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="86" portName="probed" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 20:07:13" parent="1474" time="1475" user="hvo" what="addModulePort">
-      <addPort moduleId="86" portName="probed" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 20:07:14" parent="1475" time="1476" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="dataset%20%3D%20probed.vtkInstance%0Aprint%20type%28dataset%29"/>
-    </action>
-    <action date="08 Mar 2007 20:07:16" parent="1476" time="1477" user="hvo" what="addConnection">
-      <connect destinationId="86" destinationModule="PythonSource" destinationPort="probed(vtkPolyData)" id="171" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 20:09:02" parent="1477" time="1478" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="polyData%20%3D%20probed.vtkInstance.GetPolyDataOutput%28%29%0Aprint%20polyData.GetNumberOfPoints%28%29"/>
-    </action>
-    <action date="08 Mar 2007 20:09:34" parent="1478" time="1479" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="polyData%20%3D%20probed.vtkInstance%0Aprint%20polyData.GetNumberOfPoints%28%29"/>
-    </action>
-    <action date="08 Mar 2007 20:10:16" parent="1479" time="1480" user="hvo" what="deleteConnection">
-      <connection connectionId="171"/>
-    </action>
-    <action date="08 Mar 2007 20:12:14" parent="1480" time="1481" user="hvo" what="moveModule">
-      <move dx="-1.41795839977" dy="0.0" id="74"/>
-    </action>
-    <action date="08 Mar 2007 20:12:16" parent="1481" time="1482" user="hvo" what="addConnection">
-      <connect destinationId="86" destinationModule="PythonSource" destinationPort="probed(vtkPolyData)" id="172" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 20:13:13" parent="1482" time="1483" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="polyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Afor%20i%20in%20range%28pCount%29%3A%0A%20%20%20%20print%20polyData.GetPoint%28i%29"/>
-    </action>
-    <action date="08 Mar 2007 20:13:21" parent="1483" time="1484" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="polyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Afor%20i%20in%20range%28pCount%29%3A%0A%20%20%20%20print%20i%2C%20polyData.GetPoint%28i%29"/>
-    </action>
-    <action date="08 Mar 2007 20:21:27" parent="1484" time="1485" user="hvo" what="moveModule">
-      <move dx="0.0" dy="4.25387519932" id="86"/>
-    </action>
-    <action date="08 Mar 2007 20:21:27" parent="1485" time="1486" user="hvo" what="addModulePort">
-      <addPort moduleId="86" portName="sgrid" portSpec="(vtkStructuredGrid)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 20:21:27" parent="1486" time="1487" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Afor%20i%20in%20range%28pCount%29%3A%0A%20%20%20%20print%20i%2C%20polyData.GetPoint%28i%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimension%2816%2C%20101%29%0Agrid.SetPoints%28polyData.GetPoints%28%29%29%0A%0Afrom%20core.modules.mo [...]
-    </action>
-    <action date="08 Mar 2007 20:21:43" parent="1487" time="1488" user="hvo" what="moveModule">
-      <move dx="-160.229299174" dy="12.7616255979" id="86"/>
-    </action>
-    <action date="08 Mar 2007 20:21:52" parent="1488" time="1489" user="hvo" what="deleteConnection">
-      <connection connectionId="151"/>
-    </action>
-    <action date="08 Mar 2007 20:21:56" parent="1489" time="1490" user="hvo" what="addConnection">
-      <connect destinationId="73" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="173" sourceId="86" sourceModule="PythonSource" sourcePort="sgrid(vtkStructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 20:22:12" parent="1490" time="1491" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Afor%20i%20in%20range%28pCount%29%3A%0A%20%20%20%20print%20i%2C%20polyData.GetPoint%28i%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%29%0Agrid.SetPoints%28polyData.GetPoints%28%29%29%0A%0Afrom%20core.modules.m [...]
-    </action>
-    <action date="08 Mar 2007 20:24:03" parent="1491" time="1492" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Afor%20i%20in%20range%28pCount%29%3A%0A%20%20%20%20print%20i%2C%20polyData.GetPoint%28i%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0Agrid.SetPoints%28polyData.GetPoints%28%29%29%0A%0Afrom%20core.mo [...]
-    </action>
-    <action date="08 Mar 2007 20:37:22" parent="1492" time="1493" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetData%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtk [...]
-    </action>
-    <action date="08 Mar 2007 20:38:04" parent="1493" time="1494" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20points.GetData%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPo [...]
-    </action>
-    <action date="08 Mar 2007 20:41:22" parent="1494" time="1495" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:42:21" parent="1495" time="1496" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:43:00" parent="1496" time="1497" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:43:17" parent="1497" time="1498" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0A%23data%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0A [...]
-    </action>
-    <action date="08 Mar 2007 20:43:39" parent="1498" time="1499" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0A%23data%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0A [...]
-    </action>
-    <action date="08 Mar 2007 20:44:07" parent="1499" time="1500" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0A%23points%20%3D%20polyData.GetPoints%28%29%0A%23data%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A [...]
-    </action>
-    <action date="08 Mar 2007 20:44:27" parent="1500" time="1501" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:44:39" parent="1501" time="1502" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:44:52" parent="1502" time="1503" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:45:03" parent="1503" time="1504" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:47:41" parent="1504" time="1505" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="86"/>
-    </action>
-    <action date="08 Mar 2007 20:47:49" parent="1505" time="1506" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="72"/>
-    </action>
-    <action date="08 Mar 2007 20:47:49" parent="1506" time="1507" user="hvo" what="addModule">
-      <object cache="0" id="87" name="Enhance" x="820.997913468" y="-392.774476737"/>
-    </action>
-    <action date="08 Mar 2007 20:47:50" parent="1507" time="1508" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 20:47:50" parent="1508" time="1509" user="hvo" what="deleteModule">
-      <module moduleId="87"/>
-    </action>
-    <action date="08 Mar 2007 20:48:31" parent="1509" time="1510" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:48:34" parent="1510" time="1511" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="72"/>
-    </action>
-    <action date="08 Mar 2007 20:48:34" parent="1511" time="1512" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="100"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 20:48:36" parent="1512" time="1513" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="100"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 20:48:38" parent="1513" time="1514" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 20:48:40" parent="1514" time="1515" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:48:41" parent="1515" time="1516" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:50:31" parent="1516" time="1517" user="hvo" what="addModule">
-      <object cache="0" id="88" name="vtkStructuredGridOutlineFilter" x="750.099993479" y="-516.136857517"/>
-    </action>
-    <action date="08 Mar 2007 20:50:34" parent="1517" time="1518" user="hvo" what="deleteConnection">
-      <connection connectionId="121"/>
-      <connection connectionId="154"/>
-      <connection connectionId="173"/>
-    </action>
-    <action date="08 Mar 2007 20:50:34" parent="1518" time="1519" user="hvo" what="deleteModule">
-      <module moduleId="73"/>
-    </action>
-    <action date="08 Mar 2007 20:50:46" parent="1519" time="1520" user="hvo" what="moveModule">
-      <move dx="-18.433459197" dy="24.1052927961" id="88"/>
-    </action>
-    <action date="08 Mar 2007 20:50:46" parent="1520" time="1521" user="hvo" what="addConnection">
-      <connect destinationId="88" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="174" sourceId="86" sourceModule="PythonSource" sourcePort="sgrid(vtkStructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 20:50:56" parent="1521" time="1522" user="hvo" what="addModule">
-      <object cache="0" id="89" name="vtkDataSetMapper" x="836.595455865" y="-615.393945501"/>
-    </action>
-    <action date="08 Mar 2007 20:51:00" parent="1522" time="1523" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="175" sourceId="88" sourceModule="vtkStructuredGridOutlineFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 20:51:02" parent="1523" time="1524" user="hvo" what="addConnection">
-      <connect destinationId="72" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="176" sourceId="89" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 20:51:31" parent="1524" time="1525" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:51:51" parent="1525" time="1526" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="177" sourceId="86" sourceModule="PythonSource" sourcePort="sgrid(vtkStructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 20:51:56" parent="1526" time="1527" user="hvo" what="moveModule">
-      <move dx="168.737049573" dy="32.6130431948" id="88"/>
-    </action>
-    <action date="08 Mar 2007 20:51:56" parent="1527" time="1528" user="hvo" what="deleteConnection">
-      <connection connectionId="175"/>
-    </action>
-    <action date="08 Mar 2007 20:52:16" parent="1528" time="1529" user="hvo" what="addModule">
-      <object cache="0" id="90" name="vtkProperty" x="1071.97655023" y="-572.855193508"/>
-    </action>
-    <action date="08 Mar 2007 20:52:19" parent="1529" time="1530" user="hvo" what="addConnection">
-      <connect destinationId="72" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="178" sourceId="90" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="08 Mar 2007 20:52:26" parent="1530" time="1531" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 20:52:28" parent="1531" time="1532" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 20:52:29" parent="1532" time="1533" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 20:52:29" parent="1533" time="1534" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="90" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 20:52:41" parent="1534" time="1535" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="86"/>
-    </action>
-    <action date="08 Mar 2007 20:52:47" parent="1535" time="1536" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:52:49" parent="1536" time="1537" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="10000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:54:53" parent="1537" time="1538" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="86" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 20:55:06" parent="1538" time="1539" user="hvo" what="moveModule">
-      <move dx="1.41795839977" dy="-1.41795839977" id="88"/>
-    </action>
-    <action date="08 Mar 2007 20:55:06" parent="1539" time="1540" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="179" sourceId="88" sourceModule="vtkStructuredGridOutlineFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 20:55:10" parent="1540" time="1541" user="hvo" what="deleteConnection">
-      <connection connectionId="177"/>
-    </action>
-    <action date="08 Mar 2007 20:55:41" parent="1541" time="1542" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="180" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 20:55:59" parent="1542" time="1543" user="hvo" what="deleteConnection">
-      <connection connectionId="179"/>
-    </action>
-    <action date="08 Mar 2007 20:56:58" parent="1543" time="1544" user="hvo" what="moveModule">
-      <move dx="-1.41795839977" dy="0.0" id="78"/>
-    </action>
-    <action date="08 Mar 2007 20:57:08" parent="1544" time="1545" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOn" functionId="0" moduleId="89" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 20:57:47" parent="1545" time="1546" user="hvo" what="moveModule">
-      <move dx="1.41795839977" dy="0.0" id="0"/>
-      <move dx="-1.41795839977" dy="-4.25387519932" id="7"/>
-      <move dx="1.41795839977" dy="0.0" id="76"/>
-    </action>
-    <action date="08 Mar 2007 20:57:51" parent="1546" time="1547" user="hvo" what="deleteConnection">
-      <connection connectionId="174"/>
-      <connection connectionId="172"/>
-    </action>
-    <action date="08 Mar 2007 20:57:51" parent="1547" time="1548" user="hvo" what="deleteModule">
-      <module moduleId="86"/>
-    </action>
-    <action date="08 Mar 2007 20:57:53" parent="1548" time="1549" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 20:57:53" parent="1549" time="1550" user="hvo" what="deleteModule">
-      <module moduleId="88"/>
-    </action>
-    <action date="08 Mar 2007 20:58:05" parent="1550" time="1551" user="hvo" what="deleteConnection">
-      <connection connectionId="178"/>
-    </action>
-    <action date="08 Mar 2007 20:58:05" parent="1551" time="1552" user="hvo" what="deleteModule">
-      <module moduleId="90"/>
-    </action>
-    <action date="08 Mar 2007 20:58:40" parent="1552" time="1553" user="hvo" what="moveModule">
-      <move dx="18.433459197" dy="161.647257574" id="72"/>
-      <move dx="-51.0465023918" dy="259.486387158" id="89"/>
-    </action>
-    <action date="08 Mar 2007 20:58:40" parent="1553" time="1554" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="10000"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:58:42" parent="1554" time="1555" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:58:45" parent="1555" time="1556" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 20:58:46" parent="1556" time="1557" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 20:59:06" parent="1557" time="1558" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 20:59:11" parent="1558" time="1559" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 20:59:13" parent="1559" time="1560" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 20:59:14" parent="1560" time="1561" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="10000"/>
-    </action>
-    <action date="08 Mar 2007 20:59:37" parent="1561" time="1562" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="181" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 20:59:47" parent="1562" time="1563" user="hvo" what="moveModule">
-      <move dx="-1.41795839977" dy="0.0" id="72"/>
-    </action>
-    <action date="08 Mar 2007 20:59:47" parent="1563" time="1564" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 20:59:49" parent="1564" time="1565" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 21:00:22" parent="1565" time="1566" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="37.5"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:00:23" parent="1566" time="1567" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="37.5"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:00:46" parent="1567" time="1568" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="36.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:00:52" parent="1568" time="1569" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="34.5"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.674509803922"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:00:54" parent="1569" time="1570" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="33.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.878431372549"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:00" parent="1570" time="1571" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31.5"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.372549019608"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:04" parent="1571" time="1572" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="30"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.560784313725"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:09" parent="1572" time="1573" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="28.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.749019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:13" parent="1573" time="1574" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="27"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.933333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:46" parent="1574" time="1575" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="37"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:50" parent="1575" time="1576" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35.5"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.674509803922"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:53" parent="1576" time="1577" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="35"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.878431372549"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:56" parent="1577" time="1578" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="34.5"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.372549019608"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:01:58" parent="1578" time="1579" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="34"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.560784313725"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:02:01" parent="1579" time="1580" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="33.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.749019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:02:03" parent="1580" time="1581" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="33"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.933333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:02:06" parent="1581" time="1582" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.5"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.454901960784"/>
-    </action>
-    <action date="08 Mar 2007 21:02:08" parent="1582" time="1583" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.733333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.309803921569"/>
-    </action>
-    <action date="08 Mar 2007 21:02:11" parent="1583" time="1584" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.164705882353"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.725490196078"/>
-    </action>
-    <action date="08 Mar 2007 21:02:13" parent="1584" time="1585" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.156862745098"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 21:02:17" parent="1585" time="1586" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.156862745098"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 21:02:46" parent="1586" time="1587" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-3"/>
-    </action>
-    <action date="08 Mar 2007 21:02:54" parent="1587" time="1588" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="36.5"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:03:03" parent="1588" time="1589" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="34.5"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.878431372549"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:03:05" parent="1589" time="1590" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="33.5"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.372549019608"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:03:08" parent="1590" time="1591" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="32.5"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.560784313725"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:03:13" parent="1591" time="1592" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="31.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.749019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:03:15" parent="1592" time="1593" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="29.5"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="0.933333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 21:03:24" parent="1593" time="1594" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="28.5"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.454901960784"/>
-    </action>
-    <action date="08 Mar 2007 21:03:29" parent="1594" time="1595" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="27.5"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.733333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.309803921569"/>
-    </action>
-    <action date="08 Mar 2007 21:03:32" parent="1595" time="1596" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="26.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.164705882353"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="0.725490196078"/>
-    </action>
-    <action date="08 Mar 2007 21:03:34" parent="1596" time="1597" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="25.5"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="1" type="Float" value="0.156862745098"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="2" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 21:04:17" parent="1597" time="1598" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="5000"/>
-    </action>
-    <action date="08 Mar 2007 21:04:18" parent="1598" time="1599" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="72" parameter="<no description>" parameterId="2" type="Float" value="5000"/>
-    </action>
-    <action date="08 Mar 2007 21:04:54" parent="1599" time="1600" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-1.5"/>
-    </action>
-    <action date="08 Mar 2007 21:04:56" parent="1600" time="1601" user="hvo" what="changeParameter">
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="Translate" functionId="0" moduleId="77" parameter="<no description>" parameterId="2" type="Float" value="-1.5"/>
-    </action>
-    <action date="08 Mar 2007 21:05:31" parent="1601" time="1602" user="hvo" what="addModule">
-      <object cache="0" id="91" name="PythonSource" x="602.706611104" y="-351.579391942"/>
-    </action>
-    <action date="08 Mar 2007 21:05:31" parent="1602" time="1603" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="91" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 21:05:31" parent="1603" time="1604" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="91" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:05:31" parent="1604" time="1605" user="hvo" what="addModulePort">
-      <addPort moduleId="91" portName="probed" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:05:31" parent="1605" time="1606" user="hvo" what="addModulePort">
-      <addPort moduleId="91" portName="sgrid" portSpec="(vtkStructuredGrid)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:06:02" parent="1606" time="1607" user="hvo" what="moveModule">
-      <move dx="75.1517951879" dy="-154.557465575" id="91"/>
-    </action>
-    <action date="08 Mar 2007 21:12:02" parent="1607" time="1608" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="91" portName="sgrid" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:12:03" parent="1608" time="1609" user="hvo" what="addModulePort">
-      <addPort moduleId="91" portName="sgrid" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:12:04" parent="1609" time="1610" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="91" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:13:56" parent="1610" time="1611" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="91" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:14:10" parent="1611" time="1612" user="hvo" what="moveModule">
-      <move dx="-49.628543992" dy="1.41795839977" id="91"/>
-    </action>
-    <action date="08 Mar 2007 21:14:15" parent="1612" time="1613" user="hvo" what="addModule">
-      <object cache="0" id="92" name="vtkDataSetMapper" x="795.548953474" y="-345.907558343"/>
-    </action>
-    <action date="08 Mar 2007 21:14:15" parent="1613" time="1614" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOn" functionId="0" moduleId="92" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:14:15" parent="1614" time="1615" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="92" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:14:19" parent="1615" time="1616" user="hvo" what="moveModule">
-      <move dx="-141.795839977" dy="-289.263513553" id="92"/>
-    </action>
-    <action date="08 Mar 2007 21:14:19" parent="1616" time="1617" user="hvo" what="addConnection">
-      <connect destinationId="92" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="182" sourceId="91" sourceModule="PythonSource" sourcePort="sgrid(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 21:14:21" parent="1617" time="1618" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="92"/>
-    </action>
-    <action date="08 Mar 2007 21:14:22" parent="1618" time="1619" user="hvo" what="addModule">
-      <object cache="0" id="93" name="vtkActor" x="898.031563223" y="-559.182760468"/>
-    </action>
-    <action date="08 Mar 2007 21:14:22" parent="1619" time="1620" user="hvo" what="changeParameter">
-      <set alias="" function="SetScale" functionId="0" moduleId="93" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="93" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetScale" functionId="0" moduleId="93" parameter="<no description>" parameterId="2" type="Float" value="5000"/>
-    </action>
-    <action date="08 Mar 2007 21:14:22" parent="1620" time="1621" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="93" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:14:26" parent="1621" time="1622" user="hvo" what="moveModule">
-      <move dx="-75.1517951879" dy="-181.498675171" id="93"/>
-    </action>
-    <action date="08 Mar 2007 21:14:26" parent="1622" time="1623" user="hvo" what="addConnection">
-      <connect destinationId="93" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="183" sourceId="92" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 21:14:29" parent="1623" time="1624" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.41795839977" id="92"/>
-    </action>
-    <action date="08 Mar 2007 21:14:29" parent="1624" time="1625" user="hvo" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOn" functionId="0" moduleId="92" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:14:36" parent="1625" time="1626" user="hvo" what="addConnection">
-      <connect destinationId="92" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="184" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 21:14:40" parent="1626" time="1627" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkViewport" destinationPort="AddActor2D(vtkProp)" id="185" sourceId="93" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 21:14:41" parent="1627" time="1628" user="hvo" what="deleteConnection">
-      <connection connectionId="185"/>
-    </action>
-    <action date="08 Mar 2007 21:14:44" parent="1628" time="1629" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="186" sourceId="93" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 21:15:19" parent="1629" time="1630" user="hvo" what="moveModule">
-      <move dx="-103.510963183" dy="39.7028351936" id="91"/>
-    </action>
-    <action date="08 Mar 2007 21:15:19" parent="1630" time="1631" user="hvo" what="addConnection">
-      <connect destinationId="91" destinationModule="PythonSource" destinationPort="probed(vtkPolyData)" id="187" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 21:16:26" parent="1631" time="1632" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="91" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:16:39" parent="1632" time="1633" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="91" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:17:28" parent="1633" time="1634" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="91" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:17:59" parent="1634" time="1635" user="hvo" what="deleteConnection">
-      <connection connectionId="182"/>
-    </action>
-    <action date="08 Mar 2007 21:18:00" parent="1635" time="1636" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="91" portName="sgrid" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:18:01" parent="1636" time="1637" user="hvo" what="addModulePort">
-      <addPort moduleId="91" portName="polyData" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:18:04" parent="1637" time="1638" user="hvo" what="addConnection">
-      <connect destinationId="92" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="188" sourceId="91" sourceModule="PythonSource" sourcePort="polyData(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 21:19:11" parent="1638" time="1639" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="7"/>
-    </action>
-    <action date="08 Mar 2007 21:19:11" parent="1639" time="1640" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="93"/>
-    </action>
-    <action date="08 Mar 2007 21:19:46" parent="1640" time="1641" user="hvo" what="deleteConnection">
-      <connection connectionId="183"/>
-      <connection connectionId="184"/>
-      <connection connectionId="188"/>
-      <connection connectionId="187"/>
-    </action>
-    <action date="08 Mar 2007 21:19:46" parent="1641" time="1642" user="hvo" what="deleteModule">
-      <module moduleId="92"/>
-      <module moduleId="91"/>
-    </action>
-    <action date="08 Mar 2007 21:19:47" parent="1642" time="1643" user="hvo" what="deleteConnection">
-      <connection connectionId="186"/>
-    </action>
-    <action date="08 Mar 2007 21:19:47" parent="1643" time="1644" user="hvo" what="deleteModule">
-      <module moduleId="93"/>
-    </action>
-    <action date="08 Mar 2007 21:23:20" parent="1644" time="1645" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="26"/>
-    </action>
-    <action date="08 Mar 2007 21:23:20" parent="1645" time="1646" user="hvo" what="addModule">
-      <object cache="0" id="94" name="Unzip" x="456.582604727" y="-330.384307147"/>
-    </action>
-    <action date="08 Mar 2007 21:23:31" parent="1646" time="1647" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="78"/>
-    </action>
-    <action date="08 Mar 2007 21:23:31" parent="1647" time="1648" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 21:23:31" parent="1648" time="1649" user="hvo" what="deleteModule">
-      <module moduleId="94"/>
-    </action>
-    <action date="08 Mar 2007 21:37:29" parent="1649" time="1650" user="hvo" what="addModule">
-      <object cache="0" id="95" name="PythonSource" x="534.718899117" y="-455.016063924"/>
-    </action>
-    <action date="08 Mar 2007 21:37:29" parent="1650" time="1651" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:37:29" parent="1651" time="1652" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="95" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:37:29" parent="1652" time="1653" user="hvo" what="addModulePort">
-      <addPort moduleId="95" portName="probed" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:37:29" parent="1653" time="1654" user="hvo" what="addModulePort">
-      <addPort moduleId="95" portName="polyData" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:37:44" parent="1654" time="1655" user="hvo" what="moveModule">
-      <move dx="1.41795839977" dy="-26.9412095957" id="95"/>
-    </action>
-    <action date="08 Mar 2007 21:37:44" parent="1655" time="1656" user="hvo" what="addConnection">
-      <connect destinationId="95" destinationModule="PythonSource" destinationPort="probed(vtkPolyData)" id="189" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="GetOutput(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 21:38:38" parent="1656" time="1657" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-79.4056703872" id="89"/>
-    </action>
-    <action date="08 Mar 2007 21:38:45" parent="1657" time="1658" user="hvo" what="moveModule">
-      <move dx="41.1207935934" dy="-155.975423975" id="72"/>
-      <move dx="36.8669183941" dy="-207.021926367" id="89"/>
-    </action>
-    <action date="08 Mar 2007 21:38:45" parent="1658" time="1659" user="hvo" what="deleteConnection">
-      <connection connectionId="180"/>
-    </action>
-    <action date="08 Mar 2007 21:38:47" parent="1659" time="1660" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="190" sourceId="95" sourceModule="PythonSource" sourcePort="polyData(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 21:39:13" parent="1660" time="1661" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:47:35" parent="1661" time="1662" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoints%20%3D%20vtk.vtkPoints%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 21:48:28" parent="1662" time="1663" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Aprint%20points.GetNumberOfPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016% [...]
-    </action>
-    <action date="08 Mar 2007 21:49:05" parent="1663" time="1664" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0Aprint%20polyData.__classname__%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 21:49:18" parent="1664" time="1665" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0ApolyData%20%3D%20probed.vtkInstance%0Aprint%20polyData.classname%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0AnewPoin [...]
-    </action>
-    <action date="08 Mar 2007 21:49:29" parent="1665" time="1666" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="74"/>
-    </action>
-    <action date="08 Mar 2007 21:49:37" parent="1666" time="1667" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="74"/>
-    </action>
-    <action date="08 Mar 2007 21:51:57" parent="1667" time="1668" user="hvo" what="moveModule">
-      <move dx="188.58846717" dy="-2.83591679954" id="95"/>
-    </action>
-    <action date="08 Mar 2007 21:51:57" parent="1668" time="1669" user="hvo" what="deleteConnection">
-      <connection connectionId="189"/>
-    </action>
-    <action date="08 Mar 2007 21:51:58" parent="1669" time="1670" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="95" portName="probed" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:51:58" parent="1670" time="1671" user="hvo" what="addModulePort">
-      <addPort moduleId="95" portName="probed" portSpec="(vtkProbeFilter)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:51:59" parent="1671" time="1672" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0Aprint%20polyData.classname%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29. [...]
-    </action>
-    <action date="08 Mar 2007 21:52:05" parent="1672" time="1673" user="hvo" what="addConnection">
-      <connect destinationId="95" destinationModule="PythonSource" destinationPort="probed(vtkProbeFilter)" id="191" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="self(vtkProbeFilter)"/>
-    </action>
-    <action date="08 Mar 2007 21:52:29" parent="1673" time="1674" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 21:53:49" parent="1674" time="1675" user="hvo" what="addModule">
-      <object cache="0" id="96" name="PythonSource" x="602.706611104" y="-351.579391942"/>
-    </action>
-    <action date="08 Mar 2007 21:53:49" parent="1675" time="1676" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="96" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0ApolyData%20%3D%20probed.vtkInstance%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%2816%2C%20101%2C%201%29%0A%0AcolCount%20%3D%20101%0ArowCount%20%3D%2016%0A%0Anew [...]
-    </action>
-    <action date="08 Mar 2007 21:53:49" parent="1676" time="1677" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="96" value=""/>
-    </action>
-    <action date="08 Mar 2007 21:53:49" parent="1677" time="1678" user="hvo" what="addModulePort">
-      <addPort moduleId="96" portName="probed" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:53:49" parent="1678" time="1679" user="hvo" what="addModulePort">
-      <addPort moduleId="96" portName="sgrid" portSpec="(vtkStructuredGrid)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 21:54:13" parent="1679" time="1680" user="hvo" what="moveModule">
-      <move dx="171.572966372" dy="87.9134207858" id="95"/>
-      <move dx="62.39016959" dy="-60.9722111902" id="96"/>
-    </action>
-    <action date="08 Mar 2007 21:54:13" parent="1680" time="1681" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="96" portName="probed" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:54:13" parent="1681" time="1682" user="hvo" what="addModulePort">
-      <addPort moduleId="96" portName="probed" portSpec="(vtkProbeFilter)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 21:54:14" parent="1682" time="1683" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="96" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%281 [...]
-    </action>
-    <action date="08 Mar 2007 21:54:19" parent="1683" time="1684" user="hvo" what="addConnection">
-      <connect destinationId="96" destinationModule="PythonSource" destinationPort="probed(vtkProbeFilter)" id="192" sourceId="74" sourceModule="vtkProbeFilter" sourcePort="self(vtkProbeFilter)"/>
-    </action>
-    <action date="08 Mar 2007 21:54:22" parent="1684" time="1685" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="193" sourceId="96" sourceModule="PythonSource" sourcePort="sgrid(vtkStructuredGrid)"/>
-    </action>
-    <action date="08 Mar 2007 21:54:24" parent="1685" time="1686" user="hvo" what="deleteConnection">
-      <connection connectionId="190"/>
-    </action>
-    <action date="08 Mar 2007 21:55:40" parent="1686" time="1687" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="96" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0Agrid%20%3D%20vtk.vtkStructuredGrid%28%29%0Agrid.SetDimensions%281 [...]
-    </action>
-    <action date="08 Mar 2007 21:55:55" parent="1687" time="1688" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.41795839977" id="96"/>
-    </action>
-    <action date="08 Mar 2007 21:56:13" parent="1688" time="1689" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 21:56:18" parent="1689" time="1690" user="hvo" what="addConnection">
-      <connect destinationId="89" destinationModule="vtkDataSetMapper" destinationPort="SetInput(vtkDataSet)" id="194" sourceId="95" sourceModule="PythonSource" sourcePort="polyData(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 21:56:20" parent="1690" time="1691" user="hvo" what="deleteConnection">
-      <connection connectionId="193"/>
-      <connection connectionId="192"/>
-    </action>
-    <action date="08 Mar 2007 21:56:20" parent="1691" time="1692" user="hvo" what="deleteModule">
-      <module moduleId="96"/>
-    </action>
-    <action date="08 Mar 2007 21:56:59" parent="1692" time="1693" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 21:57:57" parent="1693" time="1694" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 21:58:18" parent="1694" time="1695" user="hvo" what="moveModule">
-      <move dx="-358.743475142" dy="35.4489599943" id="95"/>
-    </action>
-    <action date="08 Mar 2007 22:03:27" parent="1695" time="1696" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 22:03:35" parent="1696" time="1697" user="hvo" what="addModule">
-      <object cache="0" id="97" name="vtkPolyDataMapper2D" x="636.663321498" y="-492.031564721"/>
-    </action>
-    <action date="08 Mar 2007 22:03:38" parent="1697" time="1698" user="hvo" what="moveModule">
-      <move dx="1.41795839977" dy="-24.1052927961" id="97"/>
-    </action>
-    <action date="08 Mar 2007 22:03:38" parent="1698" time="1699" user="hvo" what="deleteConnection">
-      <connection connectionId="194"/>
-    </action>
-    <action date="08 Mar 2007 22:03:40" parent="1699" time="1700" user="hvo" what="addConnection">
-      <connect destinationId="97" destinationModule="vtkPolyDataMapper2D" destinationPort="SetInput(vtkPolyData)" id="195" sourceId="95" sourceModule="PythonSource" sourcePort="polyData(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 22:03:56" parent="1700" time="1701" user="hvo" what="moveModule">
-      <move dx="1.41795839977" dy="0.0" id="97"/>
-    </action>
-    <action date="08 Mar 2007 22:03:56" parent="1701" time="1702" user="hvo" what="addModule">
-      <object cache="0" id="98" name="vtkActor2D" x="616.811903901" y="-650.842905495"/>
-    </action>
-    <action date="08 Mar 2007 22:03:58" parent="1702" time="1703" user="hvo" what="addConnection">
-      <connect destinationId="98" destinationModule="vtkActor2D" destinationPort="SetMapper(vtkMapper2D)" id="196" sourceId="97" sourceModule="vtkPolyDataMapper2D" sourcePort="self(vtkPolyDataMapper2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:04:07" parent="1703" time="1704" user="hvo" what="addConnection">
-      <connect destinationId="97" destinationModule="vtkPolyDataMapper2D" destinationPort="SetLookupTable(vtkScalarsToColors)" id="197" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 22:04:08" parent="1704" time="1705" user="hvo" what="deleteConnection">
-      <connection connectionId="181"/>
-    </action>
-    <action date="08 Mar 2007 22:04:09" parent="1705" time="1706" user="hvo" what="deleteConnection">
-      <connection connectionId="130"/>
-      <connection connectionId="176"/>
-    </action>
-    <action date="08 Mar 2007 22:04:09" parent="1706" time="1707" user="hvo" what="deleteModule">
-      <module moduleId="72"/>
-      <module moduleId="89"/>
-    </action>
-    <action date="08 Mar 2007 22:04:13" parent="1707" time="1708" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="198" sourceId="98" sourceModule="vtkActor2D" sourcePort="self(vtkActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:04:20" parent="1708" time="1709" user="hvo" what="addModule">
-      <object cache="0" id="99" name="vtkCoordinate" x="952.868044647" y="-564.347443109"/>
-    </action>
-    <action date="08 Mar 2007 22:04:39" parent="1709" time="1710" user="hvo" what="moveModule">
-      <move dx="266.576179157" dy="-63.8081279897" id="98"/>
-    </action>
-    <action date="08 Mar 2007 22:04:44" parent="1710" time="1711" user="hvo" what="moveModule">
-      <move dx="31.195084795" dy="-7.08979199886" id="97"/>
-      <move dx="-95.0032127847" dy="150.303590376" id="99"/>
-    </action>
-    <action date="08 Mar 2007 22:04:44" parent="1711" time="1712" user="hvo" what="addConnection">
-      <connect destinationId="97" destinationModule="vtkPolyDataMapper2D" destinationPort="SetTransformCoordinate(vtkCoordinate)" id="199" sourceId="99" sourceModule="vtkCoordinate" sourcePort="self(vtkCoordinate)"/>
-    </action>
-    <action date="08 Mar 2007 22:04:51" parent="1712" time="1713" user="hvo" what="moveModule">
-      <move dx="-25.5232511959" dy="11.3436671982" id="97"/>
-      <move dx="59.5542527904" dy="29.7771263952" id="99"/>
-    </action>
-    <action date="08 Mar 2007 22:05:11" parent="1713" time="1714" user="hvo" what="changeParameter">
-      <set alias="" function="SetCoordinateSystemToViewport" functionId="0" moduleId="99" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:05:30" parent="1714" time="1715" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="99"/>
-    </action>
-    <action date="08 Mar 2007 22:05:33" parent="1715" time="1716" user="hvo" what="changeParameter">
-      <set alias="" function="SetCoordinateSystemToNormalizedViewport" functionId="0" moduleId="99" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:06:11" parent="1716" time="1717" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 22:07:47" parent="1717" time="1718" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 22:09:03" parent="1718" time="1719" user="hvo" what="deleteConnection">
-      <connection connectionId="28"/>
-    </action>
-    <action date="08 Mar 2007 22:09:03" parent="1719" time="1720" user="hvo" what="deleteModule">
-      <module moduleId="27"/>
-    </action>
-    <action date="08 Mar 2007 22:32:06" parent="1720" time="1721" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.83771533976" id="95"/>
-    </action>
-    <action date="08 Mar 2007 22:32:06" parent="1721" time="1722" user="hvo" what="addModule">
-      <object cache="0" id="100" name="PythonSource" x="547.554815917" y="-351.430809539"/>
-    </action>
-    <action date="08 Mar 2007 22:32:07" parent="1722" time="1723" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCou [...]
-    </action>
-    <action date="08 Mar 2007 22:32:07" parent="1723" time="1724" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="100" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:32:07" parent="1724" time="1725" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="probed" portSpec="(vtkProbeFilter)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:32:07" parent="1725" time="1726" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="polyData" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 22:36:33" parent="1726" time="1727" user="hvo" what="moveModule">
-      <move dx="442.683593003" dy="-198.640073783" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:36:33" parent="1727" time="1728" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="probed" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:36:34" parent="1728" time="1729" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="polyData" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 22:36:34" parent="1729" time="1730" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="axisActor" portSpec="(vtkAxisActor2D)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 22:36:35" parent="1730" time="1731" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 22:36:38" parent="1731" time="1732" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="200" sourceId="100" sourceModule="PythonSource" sourcePort="axisActor(vtkAxisActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:37:34" parent="1732" time="1733" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.7%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.7%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29 [...]
-    </action>
-    <action date="08 Mar 2007 22:37:51" parent="1733" time="1734" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 22:40:36" parent="1734" time="1735" user="hvo" what="moveModule">
-      <move dx="1.32745454942" dy="0.0" id="0"/>
-      <move dx="-43.806000131" dy="51.7707274275" id="7"/>
-      <move dx="-13.2745454942" dy="27.8765455379" id="12"/>
-      <move dx="31.8589091862" dy="-45.1334546804" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:40:36" parent="1735" time="1736" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="LabelTextProperty" portSpec="(vtkTextProperty)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:40:37" parent="1736" time="1737" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="TitleTextProperty" portSpec="(vtkTextProperty)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:40:38" parent="1737" time="1738" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="Title" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:40:38" parent="1738" time="1739" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 22:41:26" parent="1739" time="1740" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 22:41:56" parent="1740" time="1741" user="hvo" what="moveModule">
-      <move dx="-33.1863637356" dy="-1.32745454942" id="99"/>
-      <move dx="35.8412728344" dy="23.8941818896" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:41:56" parent="1741" time="1742" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="LabelTextProperty(vtkTextProperty)" id="201" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 22:42:01" parent="1742" time="1743" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="TitleTextProperty(vtkTextProperty)" id="202" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 22:42:07" parent="1743" time="1744" user="hvo" what="changeParameter">
-      <set alias="" function="Title" functionId="1" moduleId="100" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:42:21" parent="1744" time="1745" user="hvo" what="changeParameter">
-      <set alias="" function="Title" functionId="1" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="First Transect"/>
-    </action>
-    <action date="08 Mar 2007 22:42:24" parent="1745" time="1746" user="hvo" what="changeParameter">
-      <set alias="" function="Title" functionId="1" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="First Transect"/>
-    </action>
-    <action date="08 Mar 2007 22:42:50" parent="1746" time="1747" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 22:44:14" parent="1747" time="1748" user="hvo" what="changeParameter">
-      <set alias="" function="SetHeight" functionId="1" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="0.5"/>
-    </action>
-    <action date="08 Mar 2007 22:44:16" parent="1748" time="1749" user="hvo" what="changeParameter">
-      <set alias="" function="SetHeight" functionId="1" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="0.5"/>
-    </action>
-    <action date="08 Mar 2007 22:44:43" parent="1749" time="1750" user="hvo" what="moveModule">
-      <move dx="-22.5667273402" dy="-37.1687273839" id="7"/>
-      <move dx="0.0" dy="-2.65490909885" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:45:25" parent="1750" time="1751" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="Propety" portSpec="(vtkProperty2D)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:45:26" parent="1751" time="1752" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20vtk.vtkAxisActor2D%28%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 22:45:56" parent="1752" time="1753" user="hvo" what="addModule">
-      <object cache="0" id="101" name="vtkProperty2D" x="951.784911937" y="-488.503274188"/>
-    </action>
-    <action date="08 Mar 2007 22:45:59" parent="1753" time="1754" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="Propety(vtkProperty2D)" id="203" sourceId="101" sourceModule="vtkProperty2D" sourcePort="self(vtkProperty2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:46:08" parent="1754" time="1755" user="hvo" what="moveModule">
-      <move dx="82.3021820643" dy="76.9923638666" id="7"/>
-      <move dx="116.816000349" dy="139.382727689" id="101"/>
-    </action>
-    <action date="08 Mar 2007 22:46:08" parent="1755" time="1756" user="hvo" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 22:46:11" parent="1756" time="1757" user="hvo" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:46:11" parent="1757" time="1758" user="hvo" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:46:12" parent="1758" time="1759" user="hvo" what="changeParameter">
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetColor" functionId="0" moduleId="101" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 22:46:44" parent="1759" time="1760" user="hvo" what="changeParameter">
-      <set alias="" function="SetLineWidth" functionId="1" moduleId="101" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 22:46:57" parent="1760" time="1761" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="101"/>
-    </action>
-    <action date="08 Mar 2007 22:47:26" parent="1761" time="1762" user="hvo" what="deleteConnection">
-      <connection connectionId="203"/>
-    </action>
-    <action date="08 Mar 2007 22:47:26" parent="1762" time="1763" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="Propety" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:47:27" parent="1763" time="1764" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="Property" portSpec="(vtkProperty2D)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:47:30" parent="1764" time="1765" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="Property(vtkProperty2D)" id="204" sourceId="101" sourceModule="vtkProperty2D" sourcePort="self(vtkProperty2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:48:59" parent="1765" time="1766" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.32745454942" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:49:10" parent="1766" time="1767" user="hvo" what="moveModule">
-      <move dx="25.221636439" dy="92.9218184596" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:49:10" parent="1767" time="1768" user="hvo" what="addModule">
-      <object cache="0" id="102" name="vtkAxisActor2D" x="992.936002969" y="-553.54854711"/>
-    </action>
-    <action date="08 Mar 2007 22:50:45" parent="1768" time="1769" user="hvo" what="moveModule">
-      <move dx="-111.506182152" dy="2.65490909885" id="102"/>
-    </action>
-    <action date="08 Mar 2007 22:50:45" parent="1769" time="1770" user="hvo" what="addConnection">
-      <connect destinationId="102" destinationModule="vtkActor2D" destinationPort="SetProperty(vtkProperty2D)" id="205" sourceId="101" sourceModule="vtkProperty2D" sourcePort="self(vtkProperty2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:50:50" parent="1770" time="1771" user="hvo" what="moveModule">
-      <move dx="110.178727602" dy="-55.7530910758" id="100"/>
-      <move dx="118.143454899" dy="21.2392727908" id="102"/>
-    </action>
-    <action date="08 Mar 2007 22:50:50" parent="1771" time="1772" user="hvo" what="deleteConnection">
-      <connection connectionId="204"/>
-    </action>
-    <action date="08 Mar 2007 22:50:55" parent="1772" time="1773" user="hvo" what="addConnection">
-      <connect destinationId="102" destinationModule="vtkAxisActor2D" destinationPort="SetTitleTextProperty(vtkTextProperty)" id="206" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 22:50:59" parent="1773" time="1774" user="hvo" what="addConnection">
-      <connect destinationId="102" destinationModule="vtkAxisActor2D" destinationPort="SetLabelTextProperty(vtkTextProperty)" id="207" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 22:51:07" parent="1774" time="1775" user="hvo" what="deleteConnection">
-      <connection connectionId="201"/>
-      <connection connectionId="202"/>
-    </action>
-    <action date="08 Mar 2007 22:52:17" parent="1775" time="1776" user="hvo" what="moveModule">
-      <move dx="-175.224000524" dy="-80.9747275148" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:52:17" parent="1776" time="1777" user="hvo" what="deleteConnection">
-      <connection connectionId="200"/>
-    </action>
-    <action date="08 Mar 2007 22:52:17" parent="1777" time="1778" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="LabelTextProperty" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:52:18" parent="1778" time="1779" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="Property" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:52:18" parent="1779" time="1780" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="Title" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:52:19" parent="1780" time="1781" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="TitleTextProperty" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:52:19" parent="1781" time="1782" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="axisActor" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 22:52:20" parent="1782" time="1783" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="AxisActor" portSpec="(vtkAxisActor2D)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 22:52:20" parent="1783" time="1784" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="OutputActor" portSpec="(vtkAxisActor2D)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 22:52:21" parent="1784" time="1785" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20AxisActor.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29% [...]
-    </action>
-    <action date="08 Mar 2007 22:52:25" parent="1785" time="1786" user="hvo" what="moveModule">
-      <move dx="1.32745454942" dy="0.0" id="100"/>
-    </action>
-    <action date="08 Mar 2007 22:52:25" parent="1786" time="1787" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="100"/>
-    </action>
-    <action date="08 Mar 2007 22:52:30" parent="1787" time="1788" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="AxisActor(vtkAxisActor2D)" id="208" sourceId="102" sourceModule="vtkAxisActor2D" sourcePort="self(vtkAxisActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:52:33" parent="1788" time="1789" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="209" sourceId="100" sourceModule="PythonSource" sourcePort="OutputActor(vtkAxisActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 22:53:07" parent="1789" time="1790" user="hvo" what="moveModule">
-      <move dx="104.868909404" dy="31.8589091862" id="100"/>
-      <move dx="226.994727951" dy="45.1334546804" id="102"/>
-    </action>
-    <action date="08 Mar 2007 22:53:07" parent="1790" time="1791" user="hvo" what="changeParameter">
-      <set alias="" function="SetTickOffset" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="08 Mar 2007 22:53:15" parent="1791" time="1792" user="hvo" what="changeParameter">
-      <set alias="" function="SetTickOffset" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="0.1"/>
-    </action>
-    <action date="08 Mar 2007 22:53:17" parent="1792" time="1793" user="hvo" what="changeParameter">
-      <set alias="" function="SetTickOffset" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="0.1"/>
-    </action>
-    <action date="08 Mar 2007 22:53:31" parent="1793" time="1794" user="hvo" what="changeParameter">
-      <set alias="" function="SetTickOffset" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 22:53:32" parent="1794" time="1795" user="hvo" what="changeParameter">
-      <set alias="" function="SetTickOffset" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 22:54:08" parent="1795" time="1796" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 22:54:50" parent="1796" time="1797" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 22:55:09" parent="1797" time="1798" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinorTickLength" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="08 Mar 2007 22:55:15" parent="1798" time="1799" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinorTickLength" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="08 Mar 2007 22:55:16" parent="1799" time="1800" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinorTickLength" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-    </action>
-    <action date="08 Mar 2007 22:55:33" parent="1800" time="1801" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 22:55:48" parent="1801" time="1802" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:56:05" parent="1802" time="1803" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="Distance"/>
-    </action>
-    <action date="08 Mar 2007 22:56:09" parent="1803" time="1804" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="Distance"/>
-    </action>
-    <action date="08 Mar 2007 22:56:11" parent="1804" time="1805" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFactor" functionId="1" moduleId="102" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 22:56:48" parent="1805" time="1806" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 22:56:53" parent="1806" time="1807" user="hvo" what="changeParameter">
-      <set alias="" function="AdjustLabelsOn" functionId="1" moduleId="102" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 22:57:16" parent="1807" time="1808" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 23:02:55" parent="1808" time="1809" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="length" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:02:56" parent="1809" time="1810" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20 [...]
-    </action>
-    <action date="08 Mar 2007 23:03:32" parent="1810" time="1811" user="hvo" what="moveModule">
-      <move dx="-13.2745454942" dy="-6.63727274712" id="100"/>
-    </action>
-    <action date="08 Mar 2007 23:03:32" parent="1811" time="1812" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="length" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:03:34" parent="1812" time="1813" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20AxisActor.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29% [...]
-    </action>
-    <action date="08 Mar 2007 23:03:39" parent="1813" time="1814" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 23:04:28" parent="1814" time="1815" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:04:32" parent="1815" time="1816" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="Distance"/>
-    </action>
-    <action date="08 Mar 2007 23:04:36" parent="1816" time="1817" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="Distance"/>
-    </action>
-    <action date="08 Mar 2007 23:04:40" parent="1817" time="1818" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="length(Float)" id="210" sourceId="69" sourceModule="PythonSource" sourcePort="length(Float)"/>
-    </action>
-    <action date="08 Mar 2007 23:05:23" parent="1818" time="1819" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20 [...]
-    </action>
-    <action date="08 Mar 2007 23:06:08" parent="1819" time="1820" user="hvo" what="changeParameter">
-      <set alias="" function="AdjustLabelsOn" functionId="1" moduleId="102" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:06:23" parent="1820" time="1821" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfLabels" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-    </action>
-    <action date="08 Mar 2007 23:06:25" parent="1821" time="1822" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfLabels" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="4"/>
-    </action>
-    <action date="08 Mar 2007 23:06:48" parent="1822" time="1823" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfLabels" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="3"/>
-    </action>
-    <action date="08 Mar 2007 23:06:51" parent="1823" time="1824" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfLabels" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Integer" value="3"/>
-    </action>
-    <action date="08 Mar 2007 23:07:00" parent="1824" time="1825" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 23:07:27" parent="1825" time="1826" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFactor" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:07:31" parent="1826" time="1827" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFactor" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 23:07:34" parent="1827" time="1828" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFactor" functionId="2" moduleId="102" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 23:10:04" parent="1828" time="1829" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="Distance (m)"/>
-    </action>
-    <action date="08 Mar 2007 23:11:20" parent="1829" time="1830" user="hvo" what="moveModule">
-      <move dx="-179.206364172" dy="10.6196363954" id="100"/>
-      <move dx="-201.773091512" dy="29.2040000873" id="102"/>
-    </action>
-    <action date="08 Mar 2007 23:11:20" parent="1830" time="1831" user="hvo" what="deleteConnection">
-      <connection connectionId="208"/>
-    </action>
-    <action date="08 Mar 2007 23:11:46" parent="1831" time="1832" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.32745454942" id="100"/>
-    </action>
-    <action date="08 Mar 2007 23:11:46" parent="1832" time="1833" user="hvo" what="deleteConnection">
-      <connection connectionId="209"/>
-    </action>
-    <action date="08 Mar 2007 23:11:47" parent="1833" time="1834" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="AxisActor" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:11:48" parent="1834" time="1835" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="OutputActor" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:11:48" parent="1835" time="1836" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="Actor2D" portSpec="(vtkActor2D)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:11:48" parent="1836" time="1837" user="hvo" what="addModulePort">
-      <addPort moduleId="100" portName="OutputActor" portSpec="(vtkActor2D)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:11:49" parent="1837" time="1838" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0A [...]
-    </action>
-    <action date="08 Mar 2007 23:11:52" parent="1838" time="1839" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="Actor2D(vtkActor2D)" id="211" sourceId="102" sourceModule="vtkAxisActor2D" sourcePort="self(vtkAxisActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:12:08" parent="1839" time="1840" user="hvo" what="moveModule">
-      <move dx="62.3903638229" dy="-18.5843636919" id="100"/>
-    </action>
-    <action date="08 Mar 2007 23:12:08" parent="1840" time="1841" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="212" sourceId="100" sourceModule="PythonSource" sourcePort="OutputActor(vtkActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:12:21" parent="1841" time="1842" user="hvo" what="moveModule">
-      <move dx="135.400364041" dy="13.2745454942" id="102"/>
-    </action>
-    <action date="08 Mar 2007 23:12:21" parent="1842" time="1843" user="hvo" what="addModule">
-      <object cache="0" id="103" name="vtkCubeAxesActor2D" x="911.961275454" y="-465.936546848"/>
-    </action>
-    <action date="08 Mar 2007 23:12:24" parent="1843" time="1844" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="Actor2D(vtkActor2D)" id="213" sourceId="103" sourceModule="vtkCubeAxesActor2D" sourcePort="self(vtkCubeAxesActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:12:28" parent="1844" time="1845" user="hvo" what="addModule">
-      <object cache="0" id="104" name="PythonSource" x="1004.22077257" y="-593.169065299"/>
-    </action>
-    <action date="08 Mar 2007 23:12:28" parent="1845" time="1846" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="104" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0A [...]
-    </action>
-    <action date="08 Mar 2007 23:12:28" parent="1846" time="1847" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="104" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:12:28" parent="1847" time="1848" user="hvo" what="addModulePort">
-      <addPort moduleId="104" portName="length" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:12:28" parent="1848" time="1849" user="hvo" what="addModulePort">
-      <addPort moduleId="104" portName="Actor2D" portSpec="(vtkActor2D)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:12:28" parent="1849" time="1850" user="hvo" what="addModulePort">
-      <addPort moduleId="104" portName="OutputActor" portSpec="(vtkActor2D)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:12:34" parent="1850" time="1851" user="hvo" what="moveModule">
-      <move dx="376.997092036" dy="136.727818591" id="104"/>
-    </action>
-    <action date="08 Mar 2007 23:12:37" parent="1851" time="1852" user="hvo" what="moveModule">
-      <move dx="-26.5490909885" dy="-55.7530910758" id="104"/>
-    </action>
-    <action date="08 Mar 2007 23:12:37" parent="1852" time="1853" user="hvo" what="deleteConnection">
-      <connection connectionId="211"/>
-    </action>
-    <action date="08 Mar 2007 23:12:42" parent="1853" time="1854" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.65490909885" id="100"/>
-      <move dx="-157.967091381" dy="-43.806000131" id="104"/>
-    </action>
-    <action date="08 Mar 2007 23:12:42" parent="1854" time="1855" user="hvo" what="addConnection">
-      <connect destinationId="104" destinationModule="PythonSource" destinationPort="Actor2D(vtkActor2D)" id="214" sourceId="102" sourceModule="vtkAxisActor2D" sourcePort="self(vtkAxisActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:12:45" parent="1855" time="1856" user="hvo" what="addConnection">
-      <connect destinationId="104" destinationModule="PythonSource" destinationPort="length(Float)" id="215" sourceId="69" sourceModule="PythonSource" sourcePort="length(Float)"/>
-    </action>
-    <action date="08 Mar 2007 23:14:48" parent="1856" time="1857" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetRanges%280%2C%20length%2C%205%2C%200%2C%200%2C%200%29%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.95%29%0Aactor.GetPosition2 [...]
-    </action>
-    <action date="08 Mar 2007 23:15:35" parent="1857" time="1858" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetRanges%280%2C%20length%2C%205%2C%200%2C%200%2C%200%29%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosi [...]
-    </action>
-    <action date="08 Mar 2007 23:16:29" parent="1858" time="1859" user="hvo" what="moveModule">
-      <move dx="25.221636439" dy="-18.5843636919" id="103"/>
-    </action>
-    <action date="08 Mar 2007 23:16:29" parent="1859" time="1860" user="hvo" what="changeParameter">
-      <set alias="" function="SetXLabel" functionId="0" moduleId="103" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:16:32" parent="1860" time="1861" user="hvo" what="changeParameter">
-      <set alias="" function="SetXLabel" functionId="0" moduleId="103" parameter="<no description>" parameterId="0" type="String" value="What"/>
-    </action>
-    <action date="08 Mar 2007 23:16:33" parent="1861" time="1862" user="hvo" what="changeParameter">
-      <set alias="" function="SetXLabel" functionId="0" moduleId="103" parameter="<no description>" parameterId="0" type="String" value="What"/>
-    </action>
-    <action date="08 Mar 2007 23:17:23" parent="1862" time="1863" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetRanges%280.25%2C%200.9%2C%200.65%2C%200.95%2C%200%2C%200%29%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.G [...]
-    </action>
-    <action date="08 Mar 2007 23:18:50" parent="1863" time="1864" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.32745454942" id="103"/>
-    </action>
-    <action date="08 Mar 2007 23:18:50" parent="1864" time="1865" user="hvo" what="deleteConnection">
-      <connection connectionId="213"/>
-    </action>
-    <action date="08 Mar 2007 23:18:50" parent="1865" time="1866" user="hvo" what="deleteModule">
-      <module moduleId="103"/>
-    </action>
-    <action date="08 Mar 2007 23:18:55" parent="1866" time="1867" user="hvo" what="addModule">
-      <object cache="0" id="105" name="vtkLegendBoxActor" x="958.422184684" y="-461.954183199"/>
-    </action>
-    <action date="08 Mar 2007 23:18:57" parent="1867" time="1868" user="hvo" what="addConnection">
-      <connect destinationId="100" destinationModule="PythonSource" destinationPort="Actor2D(vtkActor2D)" id="216" sourceId="105" sourceModule="vtkLegendBoxActor" sourcePort="self(vtkLegendBoxActor)"/>
-    </action>
-    <action date="08 Mar 2007 23:19:05" parent="1868" time="1869" user="hvo" what="changeParameter">
-      <set alias="" function="BorderOn" functionId="0" moduleId="105" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:19:39" parent="1869" time="1870" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 23:20:47" parent="1870" time="1871" user="hvo" what="moveModule">
-      <move dx="-1.32745454942" dy="-1.32745454942" id="104"/>
-      <move dx="-35.8412728344" dy="-2.65490909885" id="105"/>
-    </action>
-    <action date="08 Mar 2007 23:21:33" parent="1871" time="1872" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.3%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:21:45" parent="1872" time="1873" user="hvo" what="moveModule">
-      <move dx="63.7178183723" dy="-27.8765455379" id="105"/>
-    </action>
-    <action date="08 Mar 2007 23:21:45" parent="1873" time="1874" user="hvo" what="addConnection">
-      <connect destinationId="105" destinationModule="vtkActor2D" destinationPort="SetProperty(vtkProperty2D)" id="217" sourceId="101" sourceModule="vtkProperty2D" sourcePort="self(vtkProperty2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:22:05" parent="1874" time="1875" user="hvo" what="moveModule">
-      <move dx="-7.96472729654" dy="5.30981819769" id="12"/>
-    </action>
-    <action date="08 Mar 2007 23:22:05" parent="1875" time="1876" user="hvo" what="addConnection">
-      <connect destinationId="105" destinationModule="vtkLegendBoxActor" destinationPort="SetEntryTextProperty(vtkTextProperty)" id="218" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 23:22:58" parent="1876" time="1877" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.3%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:23:17" parent="1877" time="1878" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 23:23:34" parent="1878" time="1879" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.7%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:23:49" parent="1879" time="1880" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28% [...]
-    </action>
-    <action date="08 Mar 2007 23:24:34" parent="1880" time="1881" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 23:24:49" parent="1881" time="1882" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="219" sourceId="104" sourceModule="PythonSource" sourcePort="OutputActor(vtkActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:25:37" parent="1882" time="1883" user="hvo" what="changeParameter">
-      <set alias="" function="BoxOn" functionId="1" moduleId="105" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:25:49" parent="1883" time="1884" user="hvo" what="deleteFunction">
-      <function functionId="1" moduleId="105"/>
-    </action>
-    <action date="08 Mar 2007 23:37:42" parent="1884" time="1885" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetNumberOfEntries%281%29%0Aactor.SetEntryString%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:38:09" parent="1885" time="1886" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.7%2C%200.75%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetNumberOfEntries%281%29%0Aactor.SetEntryString%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:38:57" parent="1886" time="1887" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.65%2C%200.3%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetNumberOfEntries%281%29%0Aactor.SetEntryString%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:40:42" parent="1887" time="1888" user="hvo" what="moveModule">
-      <move dx="-92.9218184596" dy="50.4432728781" id="101"/>
-      <move dx="-18.5843636919" dy="2.65490909885" id="102"/>
-      <move dx="2.65490909885" dy="25.221636439" id="104"/>
-    </action>
-    <action date="08 Mar 2007 23:40:42" parent="1888" time="1889" user="hvo" what="addModule">
-      <object cache="0" id="106" name="vtkAxisActor2D" x="1170.1952762" y="-432.042364958"/>
-    </action>
-    <action date="08 Mar 2007 23:40:43" parent="1889" time="1890" user="hvo" what="addModule">
-      <object cache="0" id="107" name="PythonSource" x="1205.37422769" y="-547.327792464"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1890" time="1891" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="106" parameter="<no description>" parameterId="0" type="String" value="Distance (m)"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1891" time="1892" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfLabels" functionId="1" moduleId="106" parameter="<no description>" parameterId="0" type="Integer" value="3"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1892" time="1893" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFactor" functionId="2" moduleId="106" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1893" time="1894" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="106" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1894" time="1895" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="107" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0A [...]
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1895" time="1896" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="107" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1896" time="1897" user="hvo" what="addModulePort">
-      <addPort moduleId="107" portName="length" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1897" time="1898" user="hvo" what="addModulePort">
-      <addPort moduleId="107" portName="Actor2D" portSpec="(vtkActor2D)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1898" time="1899" user="hvo" what="addModulePort">
-      <addPort moduleId="107" portName="OutputActor" portSpec="(vtkActor2D)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:40:44" parent="1899" time="1900" user="hvo" what="addConnection">
-      <connect destinationId="107" destinationModule="PythonSource" destinationPort="Actor2D(vtkActor2D)" id="220" sourceId="106" sourceModule="vtkAxisActor2D" sourcePort="self(vtkAxisActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:40:58" parent="1900" time="1901" user="hvo" what="moveModule">
-      <move dx="116.816000349" dy="14.6020000437" id="0"/>
-      <move dx="211.065273358" dy="19.9118182414" id="106"/>
-      <move dx="195.135818765" dy="23.8941818896" id="107"/>
-    </action>
-    <action date="08 Mar 2007 23:40:58" parent="1901" time="1902" user="hvo" what="addConnection">
-      <connect destinationId="106" destinationModule="vtkAxisActor2D" destinationPort="SetTitleTextProperty(vtkTextProperty)" id="221" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 23:41:00" parent="1902" time="1903" user="hvo" what="addConnection">
-      <connect destinationId="106" destinationModule="vtkAxisActor2D" destinationPort="SetLabelTextProperty(vtkTextProperty)" id="222" sourceId="12" sourceModule="vtkTextProperty" sourcePort="self(vtkTextProperty)"/>
-    </action>
-    <action date="08 Mar 2007 23:41:04" parent="1903" time="1904" user="hvo" what="addConnection">
-      <connect destinationId="106" destinationModule="vtkActor2D" destinationPort="SetProperty(vtkProperty2D)" id="223" sourceId="101" sourceModule="vtkProperty2D" sourcePort="self(vtkProperty2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:41:35" parent="1904" time="1905" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="107" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.25%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0 [...]
-    </action>
-    <action date="08 Mar 2007 23:41:49" parent="1905" time="1906" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="107" portName="length" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:41:49" parent="1906" time="1907" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="107" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.25%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.25%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0 [...]
-    </action>
-    <action date="08 Mar 2007 23:42:15" parent="1907" time="1908" user="hvo" what="moveModule">
-      <move dx="-160.62200048" dy="-80.9747275148" id="107"/>
-    </action>
-    <action date="08 Mar 2007 23:42:15" parent="1908" time="1909" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="224" sourceId="107" sourceModule="PythonSource" sourcePort="OutputActor(vtkActor2D)"/>
-    </action>
-    <action date="08 Mar 2007 23:44:03" parent="1909" time="1910" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="107" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.9%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aa [...]
-    </action>
-    <action date="08 Mar 2007 23:44:41" parent="1910" time="1911" user="hvo" what="changeParameter">
-      <set alias="" function="SetTitle" functionId="0" moduleId="106" parameter="<no description>" parameterId="0" type="String" value="z(m)"/>
-    </action>
-    <action date="08 Mar 2007 23:45:00" parent="1911" time="1912" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="107" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.9%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.9%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aa [...]
-    </action>
-    <action date="08 Mar 2007 23:45:26" parent="1912" time="1913" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="08 Mar 2007 23:45:34" parent="1913" time="1914" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="100" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPosition%280.15%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPosition2%280.65%2C%200.3%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetNumberOfEntries%281%29%0Aactor.SetEntryString%2 [...]
-    </action>
-    <action date="08 Mar 2007 23:45:41" parent="1914" time="1915" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="104" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.15%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.8%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0A [...]
-    </action>
-    <action date="08 Mar 2007 23:45:50" parent="1915" time="1916" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="107" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.8%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.8%2C%200.95%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aa [...]
-    </action>
-    <action date="08 Mar 2007 23:46:38" parent="1916" time="1917" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFormat" functionId="3" moduleId="102" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:46:43" parent="1917" time="1918" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFormat" functionId="3" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="%d"/>
-    </action>
-    <action date="08 Mar 2007 23:46:58" parent="1918" time="1919" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFormat" functionId="3" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="%.0g"/>
-    </action>
-    <action date="08 Mar 2007 23:47:12" parent="1919" time="1920" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFormat" functionId="3" moduleId="102" parameter="<no description>" parameterId="0" type="String" value="%.0f"/>
-    </action>
-    <action date="08 Mar 2007 23:47:39" parent="1920" time="1921" user="hvo" what="deleteFunction">
-      <function functionId="2" moduleId="106"/>
-    </action>
-    <action date="08 Mar 2007 23:47:45" parent="1921" time="1922" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFormat" functionId="2" moduleId="106" parameter="<no description>" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:47:49" parent="1922" time="1923" user="hvo" what="deleteFunction">
-      <function functionId="2" moduleId="102"/>
-    </action>
-    <action date="08 Mar 2007 23:47:58" parent="1923" time="1924" user="hvo" what="changeParameter">
-      <set alias="" function="SetLabelFormat" functionId="2" moduleId="106" parameter="<no description>" parameterId="0" type="String" value="%.0f"/>
-    </action>
-    <action date="08 Mar 2007 23:49:05" parent="157" time="1925" user="hvo" what="deleteConnection">
-      <connection connectionId="21"/>
-    </action>
-    <action date="08 Mar 2007 23:49:05" parent="1925" time="1926" user="hvo" what="deleteModule">
-      <module moduleId="17"/>
-    </action>
-    <action date="08 Mar 2007 23:49:44" parent="1926" time="1927" user="hvo" what="addModule">
-      <object cache="0" id="27" name="vtkCamera" x="1413.70913982" y="-608.611545767"/>
-    </action>
-    <action date="08 Mar 2007 23:49:44" parent="1927" time="1928" user="hvo" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="27" parameter="<no description>" parameterId="0" type="Float" value="338871.329767"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="27" parameter="<no description>" parameterId="1" type="Float" value="301735.486037"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="27" parameter="<no description>" parameterId="2" type="Float" value="123378.928288"/>
-    </action>
-    <action date="08 Mar 2007 23:49:44" parent="1928" time="1929" user="hvo" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="27" parameter="<no description>" parameterId="0" type="Float" value="338871.329767"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="27" parameter="<no description>" parameterId="1" type="Float" value="301735.486037"/>
-      <set alias="" function="SetFocalPoint" functionId="1" moduleId="27" parameter="<no description>" parameterId="2" type="Float" value="-2550"/>
-    </action>
-    <action date="08 Mar 2007 23:49:44" parent="1929" time="1930" user="hvo" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="27" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="27" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="27" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 23:49:44" parent="1930" time="1931" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="27" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:49:50" parent="1931" time="1932" user="hvo" what="moveModule">
-      <move dx="-266.118834651" dy="333.004317157" id="27"/>
-    </action>
-    <action date="08 Mar 2007 23:49:50" parent="1932" time="1933" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="SetActiveCamera(vtkCamera)" id="28" sourceId="27" sourceModule="vtkCamera" sourcePort="self(vtkCamera)"/>
-    </action>
-    <action date="08 Mar 2007 23:49:51" parent="1933" time="1934" user="hvo" what="deleteConnection">
-      <connection connectionId="12"/>
-    </action>
-    <action date="08 Mar 2007 23:49:51" parent="1934" time="1935" user="hvo" what="deleteModule">
-      <module moduleId="20"/>
-    </action>
-    <action date="08 Mar 2007 23:50:20" parent="1935" time="1936" user="hvo" what="deleteConnection">
-      <connection connectionId="22"/>
-      <connection connectionId="16"/>
-      <connection connectionId="15"/>
-      <connection connectionId="17"/>
-      <connection connectionId="24"/>
-      <connection connectionId="23"/>
-    </action>
-    <action date="08 Mar 2007 23:50:20" parent="1936" time="1937" user="hvo" what="deleteModule">
-      <module moduleId="21"/>
-      <module moduleId="8"/>
-      <module moduleId="11"/>
-      <module moduleId="16"/>
-      <module moduleId="22"/>
-      <module moduleId="23"/>
-    </action>
-    <action date="08 Mar 2007 23:50:23" parent="1937" time="1938" user="hvo" what="deleteConnection">
-      <connection connectionId="9"/>
-      <connection connectionId="3"/>
-      <connection connectionId="19"/>
-      <connection connectionId="2"/>
-      <connection connectionId="18"/>
-    </action>
-    <action date="08 Mar 2007 23:50:23" parent="1938" time="1939" user="hvo" what="deleteModule">
-      <module moduleId="4"/>
-      <module moduleId="13"/>
-      <module moduleId="14"/>
-      <module moduleId="10"/>
-      <module moduleId="9"/>
-    </action>
-    <action date="08 Mar 2007 23:50:24" parent="1939" time="1940" user="hvo" what="deleteConnection">
-      <connection connectionId="4"/>
-    </action>
-    <action date="08 Mar 2007 23:50:24" parent="1940" time="1941" user="hvo" what="deleteModule">
-      <module moduleId="1"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1941" time="1942" user="hvo" what="addModule">
-      <object cache="0" id="28" name="vtkColorTransferFunction" x="1356.73099808" y="120.05781881"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1942" time="1943" user="hvo" what="changeParameter">
-      <set alias="" function="SetColorSpaceToRGB" functionId="0" moduleId="28" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1943" time="1944" user="hvo" what="changeParameter">
-      <set alias="" function="ClampingOn" functionId="1" moduleId="28" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1944" time="1945" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.474509803922"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1945" time="1946" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="2.5"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-      <set alias="" function="AddRGBPoint" functionId="3" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.474509803922"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1946" time="1947" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="5.0"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.145098039216"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.427450980392"/>
-      <set alias="" function="AddRGBPoint" functionId="4" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1947" time="1948" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="7.5"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.149019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.717647058824"/>
-      <set alias="" function="AddRGBPoint" functionId="5" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1948" time="1949" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="25.5"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.156862745098"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="6" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1949" time="1950" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="26.5"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.164705882353"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="7" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.725490196078"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1950" time="1951" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="27.5"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.733333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="8" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.309803921569"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1951" time="1952" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="28.5"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="9" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.454901960784"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1952" time="1953" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="29.5"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.933333333333"/>
-      <set alias="" function="AddRGBPoint" functionId="10" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1953" time="1954" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="31.5"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.749019607843"/>
-      <set alias="" function="AddRGBPoint" functionId="11" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1954" time="1955" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="32.5"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.560784313725"/>
-      <set alias="" function="AddRGBPoint" functionId="12" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1955" time="1956" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="33.5"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.372549019608"/>
-      <set alias="" function="AddRGBPoint" functionId="13" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1956" time="1957" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="34.5"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.878431372549"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="14" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1957" time="1958" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="35.5"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.674509803922"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="15" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1958" time="1959" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="36.5"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="16" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1959" time="1960" user="hvo" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="28" parameter="<no description>" parameterId="0" type="Float" value="37.5"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="28" parameter="<no description>" parameterId="1" type="Float" value="0.494117647059"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="28" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="17" moduleId="28" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:50:36" parent="1960" time="1961" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="28" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:50:40" parent="1961" time="1962" user="hvo" what="moveModule">
-      <move dx="-336.264896945" dy="40.0017721273" id="28"/>
-    </action>
-    <action date="08 Mar 2007 23:50:40" parent="1962" time="1963" user="hvo" what="addConnection">
-      <connect destinationId="19" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="29" sourceId="28" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 23:50:47" parent="1963" time="1964" user="hvo" what="addConnection">
-      <connect destinationId="7" destinationModule="vtkScalarBarActor" destinationPort="SetLookupTable(vtkScalarsToColors)" id="30" sourceId="28" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 23:50:48" parent="1964" time="1965" user="hvo" what="deleteConnection">
-      <connection connectionId="5"/>
-      <connection connectionId="6"/>
-    </action>
-    <action date="08 Mar 2007 23:50:48" parent="1965" time="1966" user="hvo" what="deleteModule">
-      <module moduleId="2"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1966" time="1967" user="hvo" what="addModule">
-      <object cache="0" id="29" name="PythonSource" x="379.193195786" y="309.050944155"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1967" time="1968" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="29" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20 [...]
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1968" time="1969" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="29" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1969" time="1970" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="29" parameter="<no description>" parameterId="0" type="Float" value="-1"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1970" time="1971" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="29" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1971" time="1972" user="hvo" what="addModulePort">
-      <addPort moduleId="29" portName="zShift" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1972" time="1973" user="hvo" what="addModulePort">
-      <addPort moduleId="29" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1973" time="1974" user="hvo" what="addModulePort">
-      <addPort moduleId="29" portName="polydata" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:51:53" parent="1974" time="1975" user="hvo" what="addModulePort">
-      <addPort moduleId="29" portName="length" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1975" time="1976" user="hvo" what="addModule">
-      <object cache="0" id="30" name="vtkProperty" x="778.21158305" y="-408.351821848"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1976" time="1977" user="hvo" what="addModule">
-      <object cache="0" id="31" name="vtkDataSetMapper" x="877.821985802" y="-234.416305906"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1977" time="1978" user="hvo" what="addModule">
-      <object cache="0" id="32" name="vtkTubeFilter" x="830.440146371" y="-118.864371182"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1978" time="1979" user="hvo" what="addModule">
-      <object cache="0" id="33" name="vtkActor" x="845.490191988" y="-472.647912144"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1979" time="1980" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="30" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="30" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="30" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1980" time="1981" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="30" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1981" time="1982" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="31" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1982" time="1983" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="32" parameter="<no description>" parameterId="0" type="Float" value="300"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1983" time="1984" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfSides" functionId="1" moduleId="32" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1984" time="1985" user="hvo" what="changeParameter">
-      <set alias="" function="SidesShareVerticesOn" functionId="2" moduleId="32" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1985" time="1986" user="hvo" what="changeParameter">
-      <set alias="" function="CappingOff" functionId="3" moduleId="32" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1986" time="1987" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="32" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1987" time="1988" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="33" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1988" time="1989" user="hvo" what="addConnection">
-      <connect destinationId="33" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="31" sourceId="30" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1989" time="1990" user="hvo" what="addConnection">
-      <connect destinationId="33" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="32" sourceId="31" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 23:52:18" parent="1990" time="1991" user="hvo" what="addConnection">
-      <connect destinationId="31" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="33" sourceId="32" sourceModule="vtkTubeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 23:52:45" parent="1991" time="1992" user="hvo" what="moveModule">
-      <move dx="67.5029904648" dy="157.506977751" id="0"/>
-      <move dx="16.2507199267" dy="-62.5027689489" id="32"/>
-      <move dx="490.021708559" dy="161.257143888" id="7"/>
-      <move dx="415.018385821" dy="-88.7539319075" id="12"/>
-      <move dx="16.2507199267" dy="-62.5027689489" id="33"/>
-      <move dx="42.5018828853" dy="5.00022151591" id="24"/>
-      <move dx="-190.008417605" dy="-110.00487335" id="28"/>
-      <move dx="507.522483865" dy="-410.018164305" id="29"/>
-      <move dx="16.2507199267" dy="-62.5027689489" id="30"/>
-      <move dx="16.2507199267" dy="-62.5027689489" id="31"/>
-    </action>
-    <action date="08 Mar 2007 23:52:45" parent="1992" time="1993" user="hvo" what="addConnection">
-      <connect destinationId="32" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="34" sourceId="29" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="08 Mar 2007 23:52:48" parent="1993" time="1994" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="35" sourceId="33" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 23:53:12" parent="1994" time="1995" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="32" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 23:53:17" parent="1995" time="1996" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="32" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="08 Mar 2007 23:53:37" parent="1996" time="1997" user="hvo" what="deleteConnection">
-      <connection connectionId="11"/>
-      <connection connectionId="14"/>
-      <connection connectionId="30"/>
-    </action>
-    <action date="08 Mar 2007 23:53:37" parent="1997" time="1998" user="hvo" what="deleteModule">
-      <module moduleId="7"/>
-    </action>
-    <action date="08 Mar 2007 23:53:43" parent="1998" time="1999" user="hvo" what="moveModule">
-      <move dx="85.0037657705" dy="-67.5029904648" id="0"/>
-    </action>
-    <action date="08 Mar 2007 23:53:43" parent="1999" time="2000" user="hvo" what="deleteConnection">
-      <connection connectionId="1"/>
-      <connection connectionId="0"/>
-    </action>
-    <action date="08 Mar 2007 23:53:43" parent="2000" time="2001" user="hvo" what="deleteModule">
-      <module moduleId="0"/>
-    </action>
-    <action date="08 Mar 2007 23:53:44" parent="2001" time="2002" user="hvo" what="deleteConnection"/>
-    <action date="08 Mar 2007 23:53:44" parent="2002" time="2003" user="hvo" what="deleteModule">
-      <module moduleId="12"/>
-    </action>
-    <action date="08 Mar 2007 23:56:26" parent="1924" time="2004" user="hvo" what="addModule">
-      <object cache="0" id="108" name="vtkDataSetMapper" x="588.36256334" y="-36.76947102"/>
-    </action>
-    <action date="08 Mar 2007 23:56:26" parent="2004" time="2005" user="hvo" what="addModule">
-      <object cache="0" id="109" name="vtkActor" x="674.542307966" y="-291.817763707"/>
-    </action>
-    <action date="08 Mar 2007 23:56:26" parent="2005" time="2006" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="108" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:56:26" parent="2006" time="2007" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="109" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:56:26" parent="2007" time="2008" user="hvo" what="addConnection">
-      <connect destinationId="109" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="225" sourceId="108" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="08 Mar 2007 23:56:38" parent="2008" time="2009" user="hvo" what="moveModule">
-      <move dx="894.691354307" dy="32.633119306" id="108"/>
-      <move dx="894.691354307" dy="32.633119306" id="109"/>
-    </action>
-    <action date="08 Mar 2007 23:56:38" parent="2009" time="2010" user="hvo" what="addConnection">
-      <connect destinationId="108" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="226" sourceId="6" sourceModule="vtkCORIEUnstructuredGridReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="08 Mar 2007 23:57:10" parent="2010" time="2011" user="hvo" what="addModule">
-      <object cache="0" id="110" name="vtkRenderer" x="1136.59136348" y="-472.339603991"/>
-    </action>
-    <action date="08 Mar 2007 23:57:10" parent="2011" time="2012" user="hvo" what="changeParameter">
-      <set alias="" function="SetBackground" functionId="0" moduleId="110" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="110" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="110" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="08 Mar 2007 23:57:10" parent="2012" time="2013" user="hvo" what="changeParameter">
-      <set alias="" function="ResetCameraClippingRange" functionId="1" moduleId="110" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:57:10" parent="2013" time="2014" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="110" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:57:20" parent="2014" time="2015" user="hvo" what="moveModule">
-      <move dx="437.827684023" dy="-103.338211136" id="110"/>
-    </action>
-    <action date="08 Mar 2007 23:57:20" parent="2015" time="2016" user="hvo" what="addConnection">
-      <connect destinationId="110" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="227" sourceId="109" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="08 Mar 2007 23:57:38" parent="2016" time="2017" user="hvo" what="moveModule">
-      <move dx="-5.43885321767" dy="-12.2374197398" id="110"/>
-    </action>
-    <action date="08 Mar 2007 23:57:38" parent="2017" time="2018" user="hvo" what="addConnection">
-      <connect destinationId="3" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="228" sourceId="110" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="08 Mar 2007 23:58:09" parent="2018" time="2019" user="hvo" what="changeParameter">
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="08 Mar 2007 23:58:20" parent="2019" time="2020" user="hvo" what="changeParameter">
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="2" type="Float" value=""/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:58:27" parent="2020" time="2021" user="hvo" what="changeParameter">
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="1" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="2" type="Float" value=""/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:58:56" parent="2021" time="2022" user="hvo" what="changeParameter">
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="1" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="2" type="Float" value="0.5"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="08 Mar 2007 23:58:59" parent="2022" time="2023" user="hvo" what="changeParameter">
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="1" type="Float" value="0.1"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="2" type="Float" value="0.5"/>
-      <set alias="" function="SetViewport" functionId="2" moduleId="110" parameter="<no description>" parameterId="3" type="Float" value="0.5"/>
-    </action>
-    <action date="08 Mar 2007 23:59:32" parent="2023" time="2024" user="hvo" what="moveModule">
-      <move dx="-1.35971330442" dy="-85.6619381783" id="108"/>
-    </action>
-    <action date="08 Mar 2007 23:59:32" parent="2024" time="2025" user="hvo" what="addConnection">
-      <connect destinationId="108" destinationModule="vtkMapper" destinationPort="SetLookupTable(vtkScalarsToColors)" id="229" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="08 Mar 2007 23:59:57" parent="2025" time="2026" user="hvo" what="moveModule">
-      <move dx="-24.4748394795" dy="96.5396446137" id="20"/>
-    </action>
-    <action date="08 Mar 2007 23:59:57" parent="2026" time="2027" user="hvo" what="deleteConnection">
-      <connection connectionId="12"/>
-    </action>
-    <action date="08 Mar 2007 23:59:59" parent="2027" time="2028" user="hvo" what="addConnection">
-      <connect destinationId="110" destinationModule="vtkRenderer" destinationPort="SetActiveCamera(vtkCamera)" id="230" sourceId="20" sourceModule="vtkCamera" sourcePort="self(vtkCamera)"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2028" time="2029" user="hvo" what="addModule">
-      <object cache="0" id="111" name="vtkDataSetMapper" x="904.072705729" y="-286.919074855"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2029" time="2030" user="hvo" what="addModule">
-      <object cache="0" id="112" name="vtkProperty" x="804.462302977" y="-460.854590797"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2030" time="2031" user="hvo" what="addModule">
-      <object cache="0" id="113" name="vtkActor" x="871.740911915" y="-525.150681093"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2031" time="2032" user="hvo" what="addModule">
-      <object cache="0" id="114" name="vtkTubeFilter" x="856.690866298" y="-171.367140131"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2032" time="2033" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="111" value=""/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2033" time="2034" user="hvo" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="112" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="112" parameter="<no description>" parameterId="1" type="Float" value="0"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="112" parameter="<no description>" parameterId="2" type="Float" value="0"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2034" time="2035" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="112" value=""/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2035" time="2036" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="113" value=""/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2036" time="2037" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="114" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2037" time="2038" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfSides" functionId="1" moduleId="114" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2038" time="2039" user="hvo" what="changeParameter">
-      <set alias="" function="SidesShareVerticesOn" functionId="2" moduleId="114" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2039" time="2040" user="hvo" what="changeParameter">
-      <set alias="" function="CappingOff" functionId="3" moduleId="114" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2040" time="2041" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="114" value=""/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2041" time="2042" user="hvo" what="addConnection">
-      <connect destinationId="113" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="231" sourceId="111" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2042" time="2043" user="hvo" what="addConnection">
-      <connect destinationId="111" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="232" sourceId="114" sourceModule="vtkTubeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="09 Mar 2007 00:00:53" parent="2043" time="2044" user="hvo" what="addConnection">
-      <connect destinationId="113" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="233" sourceId="112" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="09 Mar 2007 00:01:06" parent="2044" time="2045" user="hvo" what="moveModule">
-      <move dx="-458.223383589" dy="-4.07913991325" id="111"/>
-      <move dx="-458.223383589" dy="-4.07913991325" id="112"/>
-      <move dx="-458.223383589" dy="-4.07913991325" id="113"/>
-      <move dx="-458.223383589" dy="-4.07913991325" id="114"/>
-    </action>
-    <action date="09 Mar 2007 00:01:06" parent="2045" time="2046" user="hvo" what="addConnection">
-      <connect destinationId="114" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="234" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="09 Mar 2007 00:01:19" parent="2046" time="2047" user="hvo" what="addConnection">
-      <connect destinationId="110" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="235" sourceId="113" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="09 Mar 2007 09:52:49" parent="2047" time="2048" user="hvo" what="moveModule">
-      <move dx="-1.37056987171" dy="0.0" id="2"/>
-    </action>
-    <action date="09 Mar 2007 09:52:49" parent="2048" time="2049" user="hvo" what="changeParameter">
-      <set alias="TimeStep" function="SetTimeStep" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="09 Mar 2007 09:55:30" parent="2049" time="2050" user="hvo" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 $int(TimeStep*45/60)$:$int((TimeStep*45) % 60)$:00"/>
-    </action>
-    <action date="09 Mar 2007 09:57:31" parent="2050" time="2051" user="hvo" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 $int(TimeStep/4)$:$int((TimeStep%4)*15)$:00"/>
-    </action>
-    <action date="09 Mar 2007 10:04:05" parent="2051" time="2052" user="hvo" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 $int(TimeStep/4)$:$'%2d' % (int((TimeStep%4)*15))$:00"/>
-    </action>
-    <action date="09 Mar 2007 10:04:07" parent="2052" time="2053" user="hvo" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 $int(TimeStep/4)$:$'%2d' % (int((TimeStep%4)*15))$:00"/>
-    </action>
-    <action date="09 Mar 2007 10:12:24" parent="2053" time="2054" user="hvo" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 $int(TimeStep/4)$:$'%02d' % (int((TimeStep%4)*15))$:00"/>
-    </action>
-    <action date="09 Mar 2007 10:19:59" parent="2054" time="2055" user="hvo" what="changeParameter">
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="Integer" value="1"/>
-      <set alias="" function="SetText" functionId="0" moduleId="0" parameter="<no description>" parameterId="1" type="String" value="2006-Jul-11 $'%02d' % (int(TimeStep/4))$:$'%02d' % (int((TimeStep%4)*15))$:00"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="0" time="2056" user="hvo" what="addModule">
-      <object cache="0" id="0" name="vtkDataSetMapper" x="455.84932214" y="-280.998214768"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2056" time="2057" user="hvo" what="addModule">
-      <object cache="0" id="1" name="PythonSource" x="379.193195786" y="309.050944155"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2057" time="2058" user="hvo" what="addModule">
-      <object cache="0" id="2" name="vtkTubeFilter" x="408.467482709" y="-165.446280044"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2058" time="2059" user="hvo" what="addModule">
-      <object cache="0" id="3" name="vtkActor" x="423.517528326" y="-519.229821006"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2059" time="2060" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="0" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2060" time="2061" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2061" time="2062" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2062" time="2063" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="1" parameter="<no description>" parameterId="0" type="Float" value="-1"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2063" time="2064" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="1" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2064" time="2065" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="zShift" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2065" time="2066" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2066" time="2067" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="polydata" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2067" time="2068" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="length" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2068" time="2069" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="2" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2069" time="2070" user="hvo" what="changeParameter">
-      <set alias="" function="SetNumberOfSides" functionId="1" moduleId="2" parameter="<no description>" parameterId="0" type="Integer" value="10"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2070" time="2071" user="hvo" what="changeParameter">
-      <set alias="" function="SidesShareVerticesOn" functionId="2" moduleId="2" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2071" time="2072" user="hvo" what="changeParameter">
-      <set alias="" function="CappingOff" functionId="3" moduleId="2" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2072" time="2073" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="2" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2073" time="2074" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="3" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2074" time="2075" user="hvo" what="addConnection">
-      <connect destinationId="3" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="0" sourceId="0" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2075" time="2076" user="hvo" what="addConnection">
-      <connect destinationId="0" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="1" sourceId="2" sourceModule="vtkTubeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="09 Mar 2007 13:15:31" parent="2076" time="2077" user="hvo" what="addConnection">
-      <connect destinationId="2" destinationModule="vtkPolyDataAlgorithm" destinationPort="SetInput(vtkDataObject)" id="2" sourceId="1" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="09 Mar 2007 13:15:44" parent="2077" time="2078" user="hvo" what="moveModule">
-      <move dx="44.2160934173" dy="244.072835663" id="0"/>
-      <move dx="-3.53728747338" dy="91.0851524396" id="1"/>
-      <move dx="40.6788059439" dy="303.322400843" id="2"/>
-      <move dx="73.3987150727" dy="318.355872605" id="3"/>
-    </action>
-    <action date="09 Mar 2007 13:15:44" parent="2078" time="2079" user="hvo" what="addModule">
-      <object cache="0" id="4" name="VTKCell" x="831.310665335" y="-468.248456393"/>
-    </action>
-    <action date="09 Mar 2007 13:15:49" parent="2079" time="2080" user="hvo" what="addModule">
-      <object cache="0" id="5" name="vtkRenderer" x="652.607148161" y="-368.717383536"/>
-    </action>
-    <action date="09 Mar 2007 13:15:56" parent="2080" time="2081" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="3" sourceId="3" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="09 Mar 2007 13:15:59" parent="2081" time="2082" user="hvo" what="addConnection">
-      <connect destinationId="4" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="4" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="09 Mar 2007 13:25:39" parent="2082" time="2083" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:26:09" parent="2083" time="2084" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:26:33" parent="2084" time="2085" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:28:33" parent="2085" time="2086" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:29:08" parent="2086" time="2087" user="hvo" what="addModule">
-      <object cache="0" id="6" name="vtkSphereSource" x="685.407160807" y="232.993193277"/>
-    </action>
-    <action date="09 Mar 2007 13:29:32" parent="2087" time="2088" user="hvo" what="moveModule">
-      <move dx="15.8344888635" dy="41.8482919964" id="6"/>
-    </action>
-    <action date="09 Mar 2007 13:30:17" parent="2088" time="2089" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="centerX" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:30:18" parent="2089" time="2090" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="centerY" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:30:18" parent="2090" time="2091" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="centerZ" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:30:18" parent="2091" time="2092" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:30:23" parent="2092" time="2093" user="hvo" what="addModule">
-      <object cache="0" id="7" name="Tuple" x="357.407034348" y="278.23459003"/>
-    </action>
-    <action date="09 Mar 2007 13:30:34" parent="2093" time="2094" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.13103491882" id="7"/>
-    </action>
-    <action date="09 Mar 2007 13:30:34" parent="2094" time="2095" user="hvo" what="addModulePort">
-      <addPort moduleId="7" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 13:30:34" parent="2095" time="2096" user="hvo" what="addModulePort">
-      <addPort moduleId="7" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 13:30:34" parent="2096" time="2097" user="hvo" what="addModulePort">
-      <addPort moduleId="7" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 13:30:35" parent="2097" time="2098" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="7" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:30:35" parent="2098" time="2099" user="hvo" what="addModulePort">
-      <addPort moduleId="7" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 13:30:48" parent="2099" time="2100" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-55.4207110223" id="6"/>
-    </action>
-    <action date="09 Mar 2007 13:30:50" parent="2100" time="2101" user="hvo" what="addConnection">
-      <connect destinationId="6" destinationModule="vtkSphereSource" destinationPort="SetCenter(Float,Float,Float)" id="5" sourceId="7" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 13:30:59" parent="2101" time="2102" user="hvo" what="moveModule">
-      <move dx="-47.5034665906" dy="-11.3103491882" id="6"/>
-      <move dx="217.158704414" dy="21.4896634576" id="7"/>
-    </action>
-    <action date="09 Mar 2007 13:30:59" parent="2102" time="2103" user="hvo" what="addConnection">
-      <connect destinationId="7" destinationModule="Tuple" destinationPort="centerY(Float)" id="6" sourceId="1" sourceModule="PythonSource" sourcePort="centerY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 13:31:07" parent="2103" time="2104" user="hvo" what="addConnection">
-      <connect destinationId="7" destinationModule="Tuple" destinationPort="centerX(Float)" id="7" sourceId="1" sourceModule="PythonSource" sourcePort="centerX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 13:31:09" parent="2104" time="2105" user="hvo" what="addConnection">
-      <connect destinationId="7" destinationModule="Tuple" destinationPort="centerZ(Float)" id="8" sourceId="1" sourceModule="PythonSource" sourcePort="centerZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 13:31:18" parent="2105" time="2106" user="hvo" what="moveModule">
-      <move dx="-147.034539447" dy="-20.3586285388" id="7"/>
-    </action>
-    <action date="09 Mar 2007 13:31:18" parent="2106" time="2107" user="hvo" what="addModule">
-      <object cache="0" id="8" name="vtkDataSetMapper" x="510.065415557" y="-26.9253791045"/>
-    </action>
-    <action date="09 Mar 2007 13:31:19" parent="2107" time="2108" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="8" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:31:23" parent="2108" time="2109" user="hvo" what="moveModule">
-      <move dx="270.317345599" dy="-27.1448380517" id="8"/>
-    </action>
-    <action date="09 Mar 2007 13:31:23" parent="2109" time="2110" user="hvo" what="addModule">
-      <object cache="0" id="9" name="vtkActor" x="506.916243399" y="-190.873948401"/>
-    </action>
-    <action date="09 Mar 2007 13:31:23" parent="2110" time="2111" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="9" value=""/>
-    </action>
-    <action date="09 Mar 2007 13:31:28" parent="2111" time="2112" user="hvo" what="moveModule">
-      <move dx="249.95871706" dy="14.7034539447" id="9"/>
-    </action>
-    <action date="09 Mar 2007 13:31:28" parent="2112" time="2113" user="hvo" what="addConnection">
-      <connect destinationId="9" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="9" sourceId="8" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="09 Mar 2007 13:31:31" parent="2113" time="2114" user="hvo" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="10" sourceId="9" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="09 Mar 2007 13:31:38" parent="2114" time="2115" user="hvo" what="addConnection">
-      <connect destinationId="8" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="11" sourceId="6" sourceModule="vtkSphereSource" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="09 Mar 2007 13:32:14" parent="2115" time="2116" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:32:23" parent="2116" time="2117" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:32:34" parent="2117" time="2118" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 13:32:37" parent="2118" time="2119" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="09 Mar 2007 13:32:38" parent="2119" time="2120" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="09 Mar 2007 13:33:46" parent="2120" time="2121" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:40:27" parent="2121" time="2122" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:41:20" parent="2122" time="2123" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:41:54" parent="2123" time="2124" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:43:32" parent="2124" time="2125" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:45:22" parent="2125" time="2126" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:50:04" parent="2126" time="2127" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:51:22" parent="2127" time="2128" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:52:53" parent="2128" time="2129" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:53:26" parent="2129" time="2130" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:58:04" parent="2130" time="2131" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 13:58:41" parent="2131" time="2132" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:04:11" parent="2132" time="2133" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:06:28" parent="2133" time="2134" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:06:47" parent="2134" time="2135" user="hvo" what="moveModule">
-      <move dx="-0.924067941514" dy="0.0" id="1"/>
-    </action>
-    <action date="09 Mar 2007 14:07:47" parent="2135" time="2136" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:08:18" parent="2136" time="2137" user="hvo" what="deleteConnection">
-      <connection connectionId="5"/>
-    </action>
-    <action date="09 Mar 2007 14:30:34" parent="2137" time="2138" user="hvo" what="deleteConnection">
-      <connection connectionId="6"/>
-      <connection connectionId="7"/>
-      <connection connectionId="8"/>
-    </action>
-    <action date="09 Mar 2007 14:30:34" parent="2138" time="2139" user="hvo" what="deleteModule">
-      <module moduleId="7"/>
-    </action>
-    <action date="09 Mar 2007 14:30:38" parent="2139" time="2140" user="hvo" what="addModule">
-      <object cache="0" id="10" name="Tuple" x="426.919388979" y="268.903770981"/>
-    </action>
-    <action date="09 Mar 2007 14:30:48" parent="2140" time="2141" user="hvo" what="addModulePort">
-      <addPort moduleId="10" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:30:49" parent="2141" time="2142" user="hvo" what="addModulePort">
-      <addPort moduleId="10" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:30:49" parent="2142" time="2143" user="hvo" what="addModulePort">
-      <addPort moduleId="10" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:30:50" parent="2143" time="2144" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="10" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 14:30:50" parent="2144" time="2145" user="hvo" what="addModulePort">
-      <addPort moduleId="10" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 14:31:02" parent="2145" time="2146" user="hvo" what="moveModule">
-      <move dx="27.7220382454" dy="0.0" id="10"/>
-    </action>
-    <action date="09 Mar 2007 14:31:02" parent="2146" time="2147" user="hvo" what="addConnection">
-      <connect destinationId="10" destinationModule="Tuple" destinationPort="centerX(Float)" id="12" sourceId="1" sourceModule="PythonSource" sourcePort="centerX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:31:03" parent="2147" time="2148" user="hvo" what="addConnection">
-      <connect destinationId="10" destinationModule="Tuple" destinationPort="centerY(Float)" id="13" sourceId="1" sourceModule="PythonSource" sourcePort="centerY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:31:05" parent="2148" time="2149" user="hvo" what="addConnection">
-      <connect destinationId="10" destinationModule="Tuple" destinationPort="centerZ(Float)" id="14" sourceId="1" sourceModule="PythonSource" sourcePort="centerZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:31:15" parent="2149" time="2150" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.924067941514" id="6"/>
-    </action>
-    <action date="09 Mar 2007 14:31:17" parent="2150" time="2151" user="hvo" what="addConnection">
-      <connect destinationId="6" destinationModule="vtkSphereSource" destinationPort="SetCenter(Float,Float,Float)" id="15" sourceId="10" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:31:46" parent="2151" time="2152" user="hvo" what="deleteConnection">
-      <connection connectionId="15"/>
-      <connection connectionId="12"/>
-      <connection connectionId="13"/>
-      <connection connectionId="14"/>
-    </action>
-    <action date="09 Mar 2007 14:31:46" parent="2152" time="2153" user="hvo" what="deleteModule">
-      <module moduleId="10"/>
-    </action>
-    <action date="09 Mar 2007 14:32:37" parent="2153" time="2154" user="hvo" what="moveModule">
-      <move dx="60.0644161984" dy="-123.825104163" id="1"/>
-      <move dx="-37.8867856021" dy="172.800705063" id="6"/>
-    </action>
-    <action date="09 Mar 2007 14:32:37" parent="2154" time="2155" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="spheresource" portSpec="(vtkSphereSource)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:32:37" parent="2155" time="2156" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:42:48" parent="2156" time="2157" user="hvo" what="addModule">
-      <object cache="0" id="11" name="Tuple" x="569.582137467" y="197.093501536"/>
-    </action>
-    <action date="09 Mar 2007 14:43:02" parent="2157" time="2158" user="hvo" what="moveModule">
-      <move dx="47.9172274377" dy="-19.8901698798" id="11"/>
-    </action>
-    <action date="09 Mar 2007 14:43:02" parent="2158" time="2159" user="hvo" what="addModulePort">
-      <addPort moduleId="11" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:43:03" parent="2159" time="2160" user="hvo" what="addModulePort">
-      <addPort moduleId="11" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:43:03" parent="2160" time="2161" user="hvo" what="addModulePort">
-      <addPort moduleId="11" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:43:04" parent="2161" time="2162" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="11" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 14:43:04" parent="2162" time="2163" user="hvo" what="addModulePort">
-      <addPort moduleId="11" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 14:43:12" parent="2163" time="2164" user="hvo" what="addConnection">
-      <connect destinationId="11" destinationModule="Tuple" destinationPort="centerX(Float)" id="16" sourceId="1" sourceModule="PythonSource" sourcePort="centerX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:43:15" parent="2164" time="2165" user="hvo" what="addConnection">
-      <connect destinationId="11" destinationModule="Tuple" destinationPort="centerY(Float)" id="17" sourceId="1" sourceModule="PythonSource" sourcePort="centerY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:43:17" parent="2165" time="2166" user="hvo" what="addConnection">
-      <connect destinationId="11" destinationModule="Tuple" destinationPort="centerZ(Float)" id="18" sourceId="1" sourceModule="PythonSource" sourcePort="centerZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:43:51" parent="2166" time="2167" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:54:55" parent="2167" time="2168" user="hvo" what="moveModule">
-      <move dx="0.0" dy="1.93270236987" id="11"/>
-    </action>
-    <action date="09 Mar 2007 14:54:55" parent="2168" time="2169" user="hvo" what="deleteConnection">
-      <connection connectionId="16"/>
-      <connection connectionId="17"/>
-      <connection connectionId="18"/>
-    </action>
-    <action date="09 Mar 2007 14:54:55" parent="2169" time="2170" user="hvo" what="deleteModule">
-      <module moduleId="11"/>
-    </action>
-    <action date="09 Mar 2007 14:54:59" parent="2170" time="2171" user="hvo" what="addModule">
-      <object cache="0" id="12" name="Tuple" x="564.349092001" y="183.606725137"/>
-    </action>
-    <action date="09 Mar 2007 14:56:22" parent="2171" time="2172" user="hvo" what="addModulePort">
-      <addPort moduleId="12" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:56:22" parent="2172" time="2173" user="hvo" what="addModulePort">
-      <addPort moduleId="12" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:56:23" parent="2173" time="2174" user="hvo" what="addModulePort">
-      <addPort moduleId="12" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:56:23" parent="2174" time="2175" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="12" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 14:56:24" parent="2175" time="2176" user="hvo" what="addModulePort">
-      <addPort moduleId="12" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 14:56:29" parent="2176" time="2177" user="hvo" what="addConnection">
-      <connect destinationId="12" destinationModule="Tuple" destinationPort="centerX(Float)" id="19" sourceId="1" sourceModule="PythonSource" sourcePort="centerX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:56:31" parent="2177" time="2178" user="hvo" what="addConnection">
-      <connect destinationId="12" destinationModule="Tuple" destinationPort="centerY(Float)" id="20" sourceId="1" sourceModule="PythonSource" sourcePort="centerY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:56:33" parent="2178" time="2179" user="hvo" what="addConnection">
-      <connect destinationId="12" destinationModule="Tuple" destinationPort="centerZ(Float)" id="21" sourceId="1" sourceModule="PythonSource" sourcePort="centerZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:56:49" parent="2179" time="2180" user="hvo" what="moveModule">
-      <move dx="37.0680438669" dy="-44.3008329141" id="12"/>
-    </action>
-    <action date="09 Mar 2007 14:56:52" parent="2180" time="2181" user="hvo" what="moveModule">
-      <move dx="70.5196932101" dy="-339.941085218" id="6"/>
-    </action>
-    <action date="09 Mar 2007 14:56:54" parent="2181" time="2182" user="hvo" what="addConnection">
-      <connect destinationId="6" destinationModule="vtkSphereSource" destinationPort="SetCenter(Float,Float,Float)" id="22" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 14:59:02" parent="2182" time="2183" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="1" portName="spheresource" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 14:59:02" parent="2183" time="2184" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 14:59:20" parent="2184" time="2185" user="hvo" what="moveModule">
-      <move dx="10.4175151979" dy="-25.6431143334" id="6"/>
-    </action>
-    <action date="09 Mar 2007 14:59:20" parent="2185" time="2186" user="hvo" what="addModule">
-      <object cache="0" id="13" name="vtkSliderWidget" x="931.966936554" y="-129.01691899"/>
-    </action>
-    <action date="09 Mar 2007 14:59:47" parent="2186" time="2187" user="hvo" what="moveModule">
-      <move dx="-90.5522474898" dy="-77.7306903231" id="8"/>
-      <move dx="-71.3199117397" dy="-52.8889233126" id="9"/>
-      <move dx="-36.8619768542" dy="-44.8754500834" id="13"/>
-    </action>
-    <action date="09 Mar 2007 14:59:47" parent="2187" time="2188" user="hvo" what="addModule">
-      <object cache="0" id="14" name="vtkInteractionHandler" x="927.960199939" y="-342.175306886"/>
-    </action>
-    <action date="09 Mar 2007 14:59:49" parent="2188" time="2189" user="hvo" what="moveModule">
-      <move dx="-52.8889233126" dy="20.8350303959" id="14"/>
-    </action>
-    <action date="09 Mar 2007 14:59:49" parent="2189" time="2190" user="hvo" what="addConnection">
-      <connect destinationId="4" destinationModule="VTKCell" destinationPort="InteractionHandler(vtkInteractionHandler)" id="23" sourceId="14" sourceModule="vtkInteractionHandler" sourcePort="self(vtkInteractionHandler)"/>
-    </action>
-    <action date="09 Mar 2007 14:59:52" parent="2190" time="2191" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="Observer(vtkInteractorObserver)" id="24" sourceId="13" sourceModule="vtkSliderWidget" sourcePort="self(vtkSliderWidget)"/>
-    </action>
-    <action date="09 Mar 2007 15:00:14" parent="2191" time="2192" user="hvo" what="moveModule">
-      <move dx="28.8485036251" dy="36.8619768542" id="13"/>
-    </action>
-    <action date="09 Mar 2007 15:00:14" parent="2192" time="2193" user="hvo" what="addModule">
-      <object cache="0" id="15" name="vtkSliderRepresentation3D" x="886.290139148" y="-4.00673661459"/>
-    </action>
-    <action date="09 Mar 2007 15:00:17" parent="2193" time="2194" user="hvo" what="moveModule">
-      <move dx="-32.8552402397" dy="-33.6565875626" id="15"/>
-    </action>
-    <action date="09 Mar 2007 15:00:17" parent="2194" time="2195" user="hvo" what="addConnection">
-      <connect destinationId="13" destinationModule="vtkSliderWidget" destinationPort="SetRepresentation(vtkSliderRepresentation)" id="25" sourceId="15" sourceModule="vtkSliderRepresentation3D" sourcePort="self(vtkSliderRepresentation3D)"/>
-    </action>
-    <action date="09 Mar 2007 15:01:12" parent="2195" time="2196" user="hvo" what="moveModule">
-      <move dx="-12.0202098438" dy="-80.9360796148" id="13"/>
-      <move dx="42.4714081147" dy="-30.4511982709" id="15"/>
-    </action>
-    <action date="09 Mar 2007 15:01:18" parent="2196" time="2197" user="hvo" what="addConnection">
-      <connect destinationId="15" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint1InWorldCoordinates(Float,Float,Float)" id="26" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:01:21" parent="2197" time="2198" user="hvo" what="moveModule">
-      <move dx="-122.606140407" dy="26.4444616563" id="6"/>
-    </action>
-    <action date="09 Mar 2007 15:01:21" parent="2198" time="2199" user="hvo" what="deleteConnection">
-      <connection connectionId="11"/>
-      <connection connectionId="22"/>
-    </action>
-    <action date="09 Mar 2007 15:01:21" parent="2199" time="2200" user="hvo" what="deleteModule">
-      <module moduleId="6"/>
-    </action>
-    <action date="09 Mar 2007 15:02:28" parent="2200" time="2201" user="hvo" what="moveModule">
-      <move dx="66.5118278022" dy="-71.3199117397" id="12"/>
-    </action>
-    <action date="09 Mar 2007 15:02:28" parent="2201" time="2202" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="rayX" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 15:02:28" parent="2202" time="2203" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="rayY" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 15:02:29" parent="2203" time="2204" user="hvo" what="addModulePort">
-      <addPort moduleId="1" portName="rayZ" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 15:02:29" parent="2204" time="2205" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:03:51" parent="2205" time="2206" user="hvo" what="addModule">
-      <object cache="0" id="16" name="Tuple" x="677.92896367" y="77.9859804832"/>
-    </action>
-    <action date="09 Mar 2007 15:03:51" parent="2206" time="2207" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="16" value=""/>
-    </action>
-    <action date="09 Mar 2007 15:03:51" parent="2207" time="2208" user="hvo" what="addModulePort">
-      <addPort moduleId="16" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 15:03:51" parent="2208" time="2209" user="hvo" what="addModulePort">
-      <addPort moduleId="16" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 15:03:51" parent="2209" time="2210" user="hvo" what="addModulePort">
-      <addPort moduleId="16" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 15:03:51" parent="2210" time="2211" user="hvo" what="addModulePort">
-      <addPort moduleId="16" portName="value" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 15:03:59" parent="2211" time="2212" user="hvo" what="moveModule">
-      <move dx="100.168415365" dy="-14.4242518125" id="16"/>
-    </action>
-    <action date="09 Mar 2007 15:03:59" parent="2212" time="2213" user="hvo" what="addConnection">
-      <connect destinationId="16" destinationModule="Tuple" destinationPort="centerX(Float)" id="27" sourceId="1" sourceModule="PythonSource" sourcePort="rayX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:04:01" parent="2213" time="2214" user="hvo" what="addConnection">
-      <connect destinationId="16" destinationModule="Tuple" destinationPort="centerY(Float)" id="28" sourceId="1" sourceModule="PythonSource" sourcePort="rayY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:04:04" parent="2214" time="2215" user="hvo" what="addConnection">
-      <connect destinationId="16" destinationModule="Tuple" destinationPort="centerZ(Float)" id="29" sourceId="1" sourceModule="PythonSource" sourcePort="rayZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:04:20" parent="2215" time="2216" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.801347322918" id="15"/>
-    </action>
-    <action date="09 Mar 2007 15:04:41" parent="2216" time="2217" user="hvo" what="deleteConnection">
-      <connection connectionId="29"/>
-    </action>
-    <action date="09 Mar 2007 15:04:41" parent="2217" time="2218" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="16" portName="centerZ" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 15:04:42" parent="2218" time="2219" user="hvo" what="addModulePort">
-      <addPort moduleId="16" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 15:04:42" parent="2219" time="2220" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="16" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 15:04:42" parent="2220" time="2221" user="hvo" what="addModulePort">
-      <addPort moduleId="16" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 15:04:58" parent="2221" time="2222" user="hvo" what="addConnection">
-      <connect destinationId="15" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint2InWorldCoordinates(Float,Float,Float)" id="30" sourceId="16" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:05:06" parent="2222" time="2223" user="hvo" what="addConnection">
-      <connect destinationId="16" destinationModule="Tuple" destinationPort="centerZ(Float)" id="31" sourceId="1" sourceModule="PythonSource" sourcePort="rayZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:05:46" parent="2223" time="2224" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:06:00" parent="2224" time="2225" user="hvo" what="addModule">
-      <object cache="0" id="17" name="vtkSphereSource" x="580.175461793" y="9.61616787502"/>
-    </action>
-    <action date="09 Mar 2007 15:06:22" parent="2225" time="2226" user="hvo" what="moveModule">
-      <move dx="147.447907417" dy="125.010182375" id="12"/>
-      <move dx="-59.299701896" dy="80.1347322918" id="16"/>
-      <move dx="37.6633241772" dy="58.498354573" id="17"/>
-    </action>
-    <action date="09 Mar 2007 15:06:22" parent="2226" time="2227" user="hvo" what="addConnection">
-      <connect destinationId="8" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="32" sourceId="17" sourceModule="vtkSphereSource" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="09 Mar 2007 15:06:39" parent="2227" time="2228" user="hvo" what="moveModule">
-      <move dx="-228.383987032" dy="-68.1145224481" id="12"/>
-      <move dx="9.61616787502" dy="-0.801347322918" id="16"/>
-      <move dx="93.7576367814" dy="-42.4714081147" id="17"/>
-    </action>
-    <action date="09 Mar 2007 15:06:39" parent="2228" time="2229" user="hvo" what="addConnection">
-      <connect destinationId="17" destinationModule="vtkSphereSource" destinationPort="SetCenter(Float,Float,Float)" id="33" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:06:59" parent="2229" time="2230" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="17" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:07:01" parent="2230" time="2231" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="17" parameter="<no description>" parameterId="0" type="Float" value="10000"/>
-    </action>
-    <action date="09 Mar 2007 15:07:02" parent="2231" time="2232" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="17" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="09 Mar 2007 15:07:03" parent="2232" time="2233" user="hvo" what="changeParameter">
-      <set alias="" function="SetRadius" functionId="0" moduleId="17" parameter="<no description>" parameterId="0" type="Float" value="1000"/>
-    </action>
-    <action date="09 Mar 2007 15:07:47" parent="2233" time="2234" user="hvo" what="moveModule">
-      <move dx="0.0" dy="0.801347322918" id="15"/>
-    </action>
-    <action date="09 Mar 2007 15:07:47" parent="2234" time="2235" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:07:49" parent="2235" time="2236" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="500"/>
-    </action>
-    <action date="09 Mar 2007 15:07:53" parent="2236" time="2237" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="500"/>
-    </action>
-    <action date="09 Mar 2007 15:09:44" parent="2237" time="2238" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:10:51" parent="2238" time="2239" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="100"/>
-    </action>
-    <action date="09 Mar 2007 15:14:16" parent="2239" time="2240" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="17"/>
-    </action>
-    <action date="09 Mar 2007 15:14:37" parent="2240" time="2241" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:14:45" parent="2241" time="2242" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="15"/>
-    </action>
-    <action date="09 Mar 2007 15:15:00" parent="2242" time="2243" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:15:04" parent="2243" time="2244" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-    </action>
-    <action date="09 Mar 2007 15:15:05" parent="2244" time="2245" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="10"/>
-    </action>
-    <action date="09 Mar 2007 15:15:15" parent="2245" time="2246" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="2"/>
-    </action>
-    <action date="09 Mar 2007 15:15:16" parent="2246" time="2247" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="2"/>
-    </action>
-    <action date="09 Mar 2007 15:15:36" parent="2247" time="2248" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="09 Mar 2007 15:15:42" parent="2248" time="2249" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="1.2"/>
-    </action>
-    <action date="09 Mar 2007 15:15:43" parent="2249" time="2250" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="1.2"/>
-    </action>
-    <action date="09 Mar 2007 15:15:53" parent="2250" time="2251" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-    </action>
-    <action date="09 Mar 2007 15:15:54" parent="2251" time="2252" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-    </action>
-    <action date="09 Mar 2007 15:16:12" parent="2252" time="2253" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:16:17" parent="2253" time="2254" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.2"/>
-    </action>
-    <action date="09 Mar 2007 15:16:41" parent="2254" time="2255" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-    </action>
-    <action date="09 Mar 2007 15:16:42" parent="2255" time="2256" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="15" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-    </action>
-    <action date="09 Mar 2007 15:16:56" parent="2256" time="2257" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="15"/>
-    </action>
-    <action date="09 Mar 2007 15:17:22" parent="2257" time="2258" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:18:23" parent="2258" time="2259" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:18:41" parent="2259" time="2260" user="hvo" what="deleteConnection">
-      <connection connectionId="32"/>
-      <connection connectionId="33"/>
-    </action>
-    <action date="09 Mar 2007 15:18:41" parent="2260" time="2261" user="hvo" what="deleteModule">
-      <module moduleId="17"/>
-    </action>
-    <action date="09 Mar 2007 15:18:43" parent="2261" time="2262" user="hvo" what="deleteConnection">
-      <connection connectionId="9"/>
-    </action>
-    <action date="09 Mar 2007 15:18:43" parent="2262" time="2263" user="hvo" what="deleteModule">
-      <module moduleId="8"/>
-    </action>
-    <action date="09 Mar 2007 15:18:44" parent="2263" time="2264" user="hvo" what="deleteConnection">
-      <connection connectionId="10"/>
-    </action>
-    <action date="09 Mar 2007 15:18:44" parent="2264" time="2265" user="hvo" what="deleteModule">
-      <module moduleId="9"/>
-    </action>
-    <action date="09 Mar 2007 15:19:06" parent="2265" time="2266" user="hvo" what="changeParameter">
-      <set alias="" function="SetSliderShapeToCylinder" functionId="0" moduleId="15" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 15:20:51" parent="2266" time="2267" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:21:58" parent="2267" time="2268" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="15"/>
-    </action>
-    <action date="09 Mar 2007 15:22:10" parent="2268" time="2269" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.801347322918" id="15"/>
-    </action>
-    <action date="09 Mar 2007 15:22:10" parent="2269" time="2270" user="hvo" what="deleteConnection">
-      <connection connectionId="25"/>
-      <connection connectionId="26"/>
-      <connection connectionId="30"/>
-    </action>
-    <action date="09 Mar 2007 15:22:10" parent="2270" time="2271" user="hvo" what="deleteModule">
-      <module moduleId="15"/>
-    </action>
-    <action date="09 Mar 2007 15:22:15" parent="2271" time="2272" user="hvo" what="addModule">
-      <object cache="0" id="18" name="vtkSliderRepresentation3D" x="837.40795245" y="-93.7576367814"/>
-    </action>
-    <action date="09 Mar 2007 15:22:17" parent="2272" time="2273" user="hvo" what="moveModule">
-      <move dx="5.60943126043" dy="45.6767974063" id="18"/>
-    </action>
-    <action date="09 Mar 2007 15:22:17" parent="2273" time="2274" user="hvo" what="addConnection">
-      <connect destinationId="13" destinationModule="vtkSliderWidget" destinationPort="SetRepresentation(vtkSliderRepresentation)" id="34" sourceId="18" sourceModule="vtkSliderRepresentation3D" sourcePort="self(vtkSliderRepresentation3D)"/>
-    </action>
-    <action date="09 Mar 2007 15:22:29" parent="2274" time="2275" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint1InWorldCoordinates(Float,Float,Float)" id="35" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:22:37" parent="2275" time="2276" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint2InWorldCoordinates(Float,Float,Float)" id="36" sourceId="16" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:24:09" parent="2276" time="2277" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:24:28" parent="2277" time="2278" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:24:51" parent="2278" time="2279" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:24:52" parent="2279" time="2280" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="09 Mar 2007 15:24:55" parent="2280" time="2281" user="hvo" what="changeParameter">
-      <set alias="" function="SetTubeWidth" functionId="0" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="09 Mar 2007 15:26:58" parent="2281" time="2282" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:27:12" parent="2282" time="2283" user="hvo" what="deleteFunction">
-      <function functionId="0" moduleId="18"/>
-    </action>
-    <action date="09 Mar 2007 15:27:57" parent="2283" time="2284" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:28:22" parent="2284" time="2285" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:29:29" parent="2285" time="2286" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:30:23" parent="2286" time="2287" user="hvo" what="changeParameter">
-      <set alias="" function="SetSliderShapeToCylinder" functionId="0" moduleId="18" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 15:35:22" parent="2287" time="2288" user="hvo" what="moveModule">
-      <move dx="-56.8956599272" dy="-35.2592822084" id="2"/>
-      <move dx="24.0404196876" dy="63.3064385105" id="18"/>
-    </action>
-    <action date="09 Mar 2007 15:35:22" parent="2288" time="2289" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="37" sourceId="1" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="09 Mar 2007 15:36:59" parent="2289" time="2290" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20shareData%29%3A%0A%20%20%20%20print%20type%28obj%29%2C%20type%28sharedData%29"/>
-    </action>
-    <action date="09 Mar 2007 15:39:12" parent="2290" time="2291" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20print%20type%28obj%29%2C%20type%28sharedData%29"/>
-    </action>
-    <action date="09 Mar 2007 15:41:14" parent="2291" time="2292" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29"/>
-    </action>
-    <action date="09 Mar 2007 15:42:08" parent="2292" time="2293" user="hvo" what="changeParameter">
-      <set alias="" function="SetMaximumValue" functionId="1" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:42:11" parent="2293" time="2294" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:42:20" parent="2294" time="2295" user="hvo" what="changeParameter">
-      <set alias="" function="SetMaximumValue" functionId="1" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="1.0"/>
-    </action>
-    <action date="09 Mar 2007 15:42:21" parent="2295" time="2296" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:42:22" parent="2296" time="2297" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:42:34" parent="2297" time="2298" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20print%20rep.GetValue%28%29"/>
-    </action>
-    <action date="09 Mar 2007 15:43:04" parent="2298" time="2299" user="hvo" what="deleteConnection">
-      <connection connectionId="35"/>
-    </action>
-    <action date="09 Mar 2007 15:43:08" parent="2299" time="2300" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint2InWorldCoordinates(Float,Float,Float)" id="38" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:43:09" parent="2300" time="2301" user="hvo" what="deleteConnection">
-      <connection connectionId="38"/>
-      <connection connectionId="36"/>
-    </action>
-    <action date="09 Mar 2007 15:43:17" parent="2301" time="2302" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint2InWorldCoordinates(Float,Float,Float)" id="39" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:43:25" parent="2302" time="2303" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint1InWorldCoordinates(Float,Float,Float)" id="40" sourceId="16" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:43:55" parent="2303" time="2304" user="hvo" what="moveModule">
-      <move dx="41.6700607918" dy="-24.8417670105" id="12"/>
-      <move dx="-8.8148205521" dy="19.23233575" id="16"/>
-    </action>
-    <action date="09 Mar 2007 15:43:55" parent="2304" time="2305" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint1InWorldCoordinates(Float,Float,Float)" id="41" sourceId="12" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:43:58" parent="2305" time="2306" user="hvo" what="addConnection">
-      <connect destinationId="18" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint2InWorldCoordinates(Float,Float,Float)" id="42" sourceId="16" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 15:43:59" parent="2306" time="2307" user="hvo" what="deleteConnection">
-      <connection connectionId="40"/>
-    </action>
-    <action date="09 Mar 2007 15:44:02" parent="2307" time="2308" user="hvo" what="moveModule">
-      <move dx="14.4242518125" dy="33.6565875626" id="12"/>
-    </action>
-    <action date="09 Mar 2007 15:44:02" parent="2308" time="2309" user="hvo" what="deleteConnection">
-      <connection connectionId="39"/>
-    </action>
-    <action date="09 Mar 2007 15:44:17" parent="2309" time="2310" user="hvo" what="changeParameter">
-      <set alias="" function="SetMaximumValue" functionId="1" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:44:19" parent="2310" time="2311" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="1.0"/>
-    </action>
-    <action date="09 Mar 2007 15:44:22" parent="2311" time="2312" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="1.0"/>
-    </action>
-    <action date="09 Mar 2007 15:45:57" parent="2312" time="2313" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20print%20rep.GetPoint1Coordinate%28%29.GetValues%28%29"/>
-    </action>
-    <action date="09 Mar 2007 15:46:26" parent="2313" time="2314" user="hvo" what="changeParameter">
-      <set alias="" function="ShowSliderLabelOff" functionId="3" moduleId="18" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 15:46:55" parent="2314" time="2315" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:47:01" parent="2315" time="2316" user="hvo" what="changeParameter">
-      <set alias="" function="SetValue" functionId="4" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="09 Mar 2007 15:47:04" parent="2316" time="2317" user="hvo" what="changeParameter">
-      <set alias="" function="SetValue" functionId="4" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="-0.5"/>
-    </action>
-    <action date="09 Mar 2007 15:47:06" parent="2317" time="2318" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="09 Mar 2007 15:47:07" parent="2318" time="2319" user="hvo" what="changeParameter">
-      <set alias="" function="SetMaximumValue" functionId="1" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="09 Mar 2007 15:47:09" parent="2319" time="2320" user="hvo" what="changeParameter">
-      <set alias="" function="SetValue" functionId="4" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.5"/>
-    </action>
-    <action date="09 Mar 2007 15:47:10" parent="2320" time="2321" user="hvo" what="changeParameter">
-      <set alias="" function="SetValue" functionId="4" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.5"/>
-    </action>
-    <action date="09 Mar 2007 15:47:46" parent="2321" time="2322" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 15:47:58" parent="2322" time="2323" user="hvo" what="moveModule">
-      <move dx="-0.801347322918" dy="0.0" id="13"/>
-    </action>
-    <action date="09 Mar 2007 15:48:24" parent="2323" time="2324" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20print%20rep.GetPoint1Coordinate%28%29.GetValue%28%29"/>
-    </action>
-    <action date="09 Mar 2007 15:51:44" parent="2324" time="2325" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 15:52:15" parent="2325" time="2326" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 15:56:21" parent="2326" time="2327" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 15:57:07" parent="2327" time="2328" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 15:57:38" parent="2328" time="2329" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 15:58:29" parent="2329" time="2330" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 15:58:55" parent="2330" time="2331" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:00:00" parent="2331" time="2332" user="hvo" what="moveModule">
-      <move dx="-4.80808393751" dy="-18.4309884271" id="2"/>
-    </action>
-    <action date="09 Mar 2007 16:04:49" parent="2332" time="2333" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:05:10" parent="2333" time="2334" user="hvo" what="moveModule">
-      <move dx="-0.801347322918" dy="0.0" id="14"/>
-    </action>
-    <action date="09 Mar 2007 16:06:19" parent="2334" time="2335" user="hvo" what="moveModule">
-      <move dx="-0.801347322918" dy="0.0" id="18"/>
-    </action>
-    <action date="09 Mar 2007 16:06:40" parent="2335" time="2336" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:09:14" parent="2336" time="2337" user="hvo" what="moveModule">
-      <move dx="-87.3468581981" dy="-118.599403792" id="0"/>
-      <move dx="60.1010492189" dy="-109.78458324" id="2"/>
-      <move dx="12.8215571667" dy="-39.266018823" id="3"/>
-      <move dx="0.0" dy="-0.801347322918" id="14"/>
-    </action>
-    <action date="09 Mar 2007 16:09:39" parent="2337" time="2338" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:10:43" parent="2338" time="2339" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.801347322918" id="3"/>
-    </action>
-    <action date="09 Mar 2007 16:10:50" parent="2339" time="2340" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="43" sourceId="2" sourceModule="vtkTubeFilter" sourcePort="self(vtkTubeFilter)"/>
-    </action>
-    <action date="09 Mar 2007 16:11:15" parent="2340" time="2341" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20 [...]
-    </action>
-    <action date="09 Mar 2007 16:12:02" parent="2341" time="2342" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20print%20sharedData%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.Ge [...]
-    </action>
-    <action date="09 Mar 2007 16:14:53" parent="2342" time="2343" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20 [...]
-    </action>
-    <action date="09 Mar 2007 16:16:31" parent="2343" time="2344" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20 [...]
-    </action>
-    <action date="09 Mar 2007 16:16:42" parent="2344" time="2345" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.801347322918" id="0"/>
-      <move dx="-11.2188625209" dy="109.78458324" id="5"/>
-    </action>
-    <action date="09 Mar 2007 16:16:42" parent="2345" time="2346" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="44" sourceId="5" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="09 Mar 2007 16:17:11" parent="2346" time="2347" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20 [...]
-    </action>
-    <action date="09 Mar 2007 16:17:38" parent="2347" time="2348" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20 [...]
-    </action>
-    <action date="09 Mar 2007 16:18:23" parent="2348" time="2349" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData%5B0%5D.vtkInstance%0A%20%20%20%20tubeFilter%20%3D%20sharedData%5B1%5D.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20 [...]
-    </action>
-    <action date="09 Mar 2007 16:20:30" parent="2349" time="2350" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:20:32" parent="2350" time="2351" user="hvo" what="deleteConnection">
-      <connection connectionId="44"/>
-    </action>
-    <action date="09 Mar 2007 16:20:34" parent="2351" time="2352" user="hvo" what="deleteConnection">
-      <connection connectionId="43"/>
-    </action>
-    <action date="09 Mar 2007 16:21:05" parent="2352" time="2353" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:21:35" parent="2353" time="2354" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:28:23" parent="2354" time="2355" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:29:04" parent="2355" time="2356" user="hvo" what="moveModule">
-      <move dx="-23.2390723646" dy="-78.532037646" id="5"/>
-    </action>
-    <action date="09 Mar 2007 16:29:04" parent="2356" time="2357" user="hvo" what="deleteFunction">
-      <function functionId="2" moduleId="2"/>
-    </action>
-    <action date="09 Mar 2007 16:29:25" parent="2357" time="2358" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20%20%20value%20%3D%20rep.GetValue%28%29%0A%20%20%20%20center%20%3D%20copy. [...]
-    </action>
-    <action date="09 Mar 2007 16:29:52" parent="2358" time="2359" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="45" sourceId="2" sourceModule="vtkTubeFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="09 Mar 2007 16:29:54" parent="2359" time="2360" user="hvo" what="deleteConnection">
-      <connection connectionId="37"/>
-    </action>
-    <action date="09 Mar 2007 16:49:24" parent="2360" time="2361" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20sharedData.SetCapping%281-sharedData%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%20% [...]
-    </action>
-    <action date="09 Mar 2007 16:49:41" parent="2361" time="2362" user="hvo" what="deleteConnection">
-      <connection connectionId="45"/>
-    </action>
-    <action date="09 Mar 2007 16:49:43" parent="2362" time="2363" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="46" sourceId="2" sourceModule="vtkTubeFilter" sourcePort="self(vtkTubeFilter)"/>
-    </action>
-    <action date="09 Mar 2007 16:50:12" parent="2363" time="2364" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20sharedData.SetRadiusFactor%28100000%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%20%2 [...]
-    </action>
-    <action date="09 Mar 2007 16:50:19" parent="2364" time="2365" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20sharedData.vtkInstance.SetRadiusFactor%28100000%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%2 [...]
-    </action>
-    <action date="09 Mar 2007 16:52:35" parent="2365" time="2366" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20sharedData.vtkInstance.SetRadiusFactor%28100000%29%0A%20%20%20%20print%20obj.GetInteractor%28%29.GetRenderWindow%28%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyDa [...]
-    </action>
-    <action date="09 Mar 2007 16:53:06" parent="2366" time="2367" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20sharedData.vtkInstance.SetInput%28None%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.GetRepresentation%28%29%0A%2 [...]
-    </action>
-    <action date="09 Mar 2007 16:54:05" parent="2367" time="2368" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20tubeFilter.SetInput%28None%29%0A%20%20%20%20tubeFilter.Update%28%29%0A%20%20%20%20print%20tubeFilter.GetOutput%28%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20shar [...]
-    </action>
-    <action date="09 Mar 2007 16:54:38" parent="2368" time="2369" user="hvo" what="moveModule">
-      <move dx="-1.99788383718" dy="-23.9746060462" id="0"/>
-    </action>
-    <action date="09 Mar 2007 16:54:51" parent="2369" time="2370" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20tubeFilter.SetInput%28vtk.vtkPolyData%28%29%29%0A%20%20%20%20tubeFilter.Update%28%29%0A%20%20%20%20print%20tubeFilter.GetOutput%28%29%0A%20%20%20% [...]
-    </action>
-    <action date="09 Mar 2007 16:55:07" parent="2370" time="2371" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20tubeFilter.SetInput%28vtk.vtkPolyData%28%29%29%0A%20%20%20%20print%20tubeFilter.GetOutput%28%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D% [...]
-    </action>
-    <action date="09 Mar 2007 16:55:32" parent="2371" time="2372" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20tubeFilter.SetInput%28vtk.vtkPolyData%28%29%29%0A%20%20%20%20return%0A%20%20%20%20polyData%20%3D%20sharedData.vtkInstance%0A%20%20%20%20points%20% [...]
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2372" time="2373" user="hvo" what="moveModule">
-      <move dx="8.99047726733" dy="-58.9375731969" id="14"/>
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2373" time="2374" user="hvo" what="addModule">
-      <object cache="0" id="19" name="Tuple" x="653.087196659" y="143.696460962"/>
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2374" time="2375" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="19" value=""/>
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2375" time="2376" user="hvo" what="addModulePort">
-      <addPort moduleId="19" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2376" time="2377" user="hvo" what="addModulePort">
-      <addPort moduleId="19" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2377" time="2378" user="hvo" what="addModulePort">
-      <addPort moduleId="19" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 16:55:47" parent="2378" time="2379" user="hvo" what="addModulePort">
-      <addPort moduleId="19" portName="value" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 16:55:53" parent="2379" time="2380" user="hvo" what="moveModule">
-      <move dx="-67.9280504643" dy="-33.9640252321" id="12"/>
-      <move dx="29.9682575578" dy="-299.682575578" id="19"/>
-    </action>
-    <action date="09 Mar 2007 16:55:54" parent="2380" time="2381" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.998941918592" id="19"/>
-    </action>
-    <action date="09 Mar 2007 16:55:54" parent="2381" time="2382" user="hvo" what="deleteConnection"/>
-    <action date="09 Mar 2007 16:55:54" parent="2382" time="2383" user="hvo" what="deleteModule">
-      <module moduleId="19"/>
-    </action>
-    <action date="09 Mar 2007 16:56:00" parent="2383" time="2384" user="hvo" what="addModule">
-      <object cache="0" id="20" name="Tuple" x="712.245587956" y="-132.859275173"/>
-    </action>
-    <action date="09 Mar 2007 16:56:18" parent="2384" time="2385" user="hvo" what="moveModule">
-      <move dx="-76.9185277316" dy="-2.99682575578" id="20"/>
-    </action>
-    <action date="09 Mar 2007 16:56:18" parent="2385" time="2386" user="hvo" what="addModulePort">
-      <addPort moduleId="20" portName="tubefilter" portSpec="(vtkTubeFilter)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 16:56:18" parent="2386" time="2387" user="hvo" what="addModulePort">
-      <addPort moduleId="20" portName="originaldata" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 16:56:18" parent="2387" time="2388" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="20" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 16:56:19" parent="2388" time="2389" user="hvo" what="addModulePort">
-      <addPort moduleId="20" portName="value" portSpec="(vtkTubeFilter,vtkPolyData)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 16:56:23" parent="2389" time="2390" user="hvo" what="moveModule">
-      <move dx="35.9619090693" dy="9.98941918592" id="20"/>
-    </action>
-    <action date="09 Mar 2007 16:56:23" parent="2390" time="2391" user="hvo" what="deleteConnection">
-      <connection connectionId="46"/>
-    </action>
-    <action date="09 Mar 2007 16:56:41" parent="2391" time="2392" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.998941918592" id="20"/>
-    </action>
-    <action date="09 Mar 2007 16:56:41" parent="2392" time="2393" user="hvo" what="deleteConnection"/>
-    <action date="09 Mar 2007 16:56:41" parent="2393" time="2394" user="hvo" what="deleteModule">
-      <module moduleId="20"/>
-    </action>
-    <action date="09 Mar 2007 16:56:52" parent="2394" time="2395" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="47" sourceId="2" sourceModule="vtkTubeFilter" sourcePort="self(vtkTubeFilter)"/>
-    </action>
-    <action date="09 Mar 2007 16:57:37" parent="2395" time="2396" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20polyData%20%3D%20vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28tubeFilter.GetInput%28%29%29%0A%20%20%20%20points%20%3D%20polyData.GetPoin [...]
-    </action>
-    <action date="09 Mar 2007 16:57:57" parent="2396" time="2397" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28tubeFilter.GetInput%28%29%29%0A%20%20%20%20points%20%3D%20polyData.Get [...]
-    </action>
-    <action date="09 Mar 2007 16:58:22" parent="2397" time="2398" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.01"/>
-    </action>
-    <action date="09 Mar 2007 16:58:23" parent="2398" time="2399" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.01"/>
-    </action>
-    <action date="09 Mar 2007 16:58:37" parent="2399" time="2400" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.1"/>
-    </action>
-    <action date="09 Mar 2007 16:58:58" parent="2400" time="2401" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.3"/>
-    </action>
-    <action date="09 Mar 2007 16:58:59" parent="2401" time="2402" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0.3"/>
-    </action>
-    <action date="09 Mar 2007 16:59:16" parent="2402" time="2403" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-0.998941918592" id="14"/>
-    </action>
-    <action date="09 Mar 2007 17:00:59" parent="2403" time="2404" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="09 Mar 2007 17:01:00" parent="2404" time="2405" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="18" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="09 Mar 2007 17:01:38" parent="2405" time="2406" user="hvo" what="moveModule">
-      <move dx="-0.912864542162" dy="0.0" id="1"/>
-      <move dx="15.9830706975" dy="-64.9312247085" id="3"/>
-      <move dx="16.9820126161" dy="-50.9460378482" id="5"/>
-      <move dx="-4.99470959296" dy="77.9174696502" id="14"/>
-    </action>
-    <action date="09 Mar 2007 17:02:33" parent="2406" time="2407" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20N [...]
-    </action>
-    <action date="09 Mar 2007 17:03:27" parent="2407" time="2408" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28tubeFilter.GetInput%28%29%29%0A%20%20%20%20points%20%3D%20polyData.Get [...]
-    </action>
-    <action date="09 Mar 2007 17:04:51" parent="2408" time="2409" user="hvo" what="deleteConnection">
-      <connection connectionId="47"/>
-    </action>
-    <action date="09 Mar 2007 17:04:55" parent="2409" time="2410" user="hvo" what="addConnection">
-      <connect destinationId="14" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="48" sourceId="1" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="09 Mar 2007 17:06:04" parent="2410" time="2411" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20sharedData.vtkInstance.SetPolys%28vtk.vtkCellArray%28%29%29%0A%20%20%20%20return%0A%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData% [...]
-    </action>
-    <action date="09 Mar 2007 17:06:39" parent="2411" time="2412" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20sharedData.vtkInstance.ShallowCopy%28vtk.vtkPolyData%28%29%29%29%0A%20%20%20%20return%0A%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20polyData%20%3D%20vtk.vtkPoly [...]
-    </action>
-    <action date="09 Mar 2007 17:06:55" parent="2412" time="2413" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20sharedData.vtkInstance.ShallowCopy%28vtk.vtkPolyData%28%29%29%0A%20%20%20%20return%0A%0A%20%20%20%20tubeFilter%20%3D%20sharedData.vtkInstance%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyDat [...]
-    </action>
-    <action date="09 Mar 2007 17:07:56" parent="2413" time="2414" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="14" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28sharedData.vtkInstance%29%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj.G [...]
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2055" time="2415" user="hvo" what="addModule">
-      <object cache="0" id="115" name="PythonSource" x="443.883392027" y="286.310992432"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2415" time="2416" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="115" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%2 [...]
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2416" time="2417" user="hvo" what="changeParameter">
-      <set alias="" function="filename" functionId="1" moduleId="115" parameter="<no description>" parameterId="0" type="String" value="../examples/data/vslice_circ1.bp"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2417" time="2418" user="hvo" what="changeParameter">
-      <set alias="" function="zShift" functionId="2" moduleId="115" parameter="<no description>" parameterId="0" type="Float" value="-1"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2418" time="2419" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="115" value=""/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2419" time="2420" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="zShift" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2420" time="2421" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="filename" portSpec="(String)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2421" time="2422" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="polydata" portSpec="(vtkPolyData)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2422" time="2423" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="rayX" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2423" time="2424" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="rayY" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2424" time="2425" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="rayZ" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2425" time="2426" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="length" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2426" time="2427" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="centerZ" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2427" time="2428" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="centerX" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:31" parent="2428" time="2429" user="hvo" what="addModulePort">
-      <addPort moduleId="115" portName="centerY" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:08:41" parent="2429" time="2430" user="hvo" what="moveModule">
-      <move dx="119.239578839" dy="30.1525371776" id="115"/>
-    </action>
-    <action date="09 Mar 2007 17:09:08" parent="2430" time="2431" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="centerX" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:09:09" parent="2431" time="2432" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="centerY" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:09:09" parent="2432" time="2433" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="centerZ" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:09:10" parent="2433" time="2434" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="rayX" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:09:11" parent="2434" time="2435" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="rayY" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:09:11" parent="2435" time="2436" user="hvo" what="addModulePort">
-      <addPort moduleId="69" portName="rayZ" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:09:12" parent="2436" time="2437" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20 [...]
-    </action>
-    <action date="09 Mar 2007 17:09:13" parent="2437" time="2438" user="hvo" what="deleteConnection"/>
-    <action date="09 Mar 2007 17:09:13" parent="2438" time="2439" user="hvo" what="deleteModule">
-      <module moduleId="115"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2439" time="2440" user="hvo" what="addModule">
-      <object cache="0" id="116" name="vtkSliderWidget" x="921.131906158" y="-207.966471834"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2440" time="2441" user="hvo" what="addModule">
-      <object cache="0" id="117" name="vtkInteractionHandler" x="888.265696978" y="-294.160669278"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2441" time="2442" user="hvo" what="addModule">
-      <object cache="0" id="118" name="vtkSliderRepresentation3D" x="876.256456075" y="25.2255991354"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2442" time="2443" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="116" value=""/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2443" time="2444" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="117" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28sharedData.vtkInstance%29%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj. [...]
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2444" time="2445" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="117" value=""/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2445" time="2446" user="hvo" what="changeParameter">
-      <set alias="" function="SetSliderShapeToCylinder" functionId="0" moduleId="118" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2446" time="2447" user="hvo" what="changeParameter">
-      <set alias="" function="SetMaximumValue" functionId="1" moduleId="118" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2447" time="2448" user="hvo" what="changeParameter">
-      <set alias="" function="SetMinimumValue" functionId="2" moduleId="118" parameter="<no description>" parameterId="0" type="Float" value="0"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2448" time="2449" user="hvo" what="changeParameter">
-      <set alias="" function="ShowSliderLabelOff" functionId="3" moduleId="118" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2449" time="2450" user="hvo" what="changeParameter">
-      <set alias="" function="SetValue" functionId="4" moduleId="118" parameter="<no description>" parameterId="0" type="Float" value="0.5"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2450" time="2451" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="118" value=""/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2451" time="2452" user="hvo" what="addConnection">
-      <connect destinationId="117" destinationModule="vtkInteractionHandler" destinationPort="Observer(vtkInteractorObserver)" id="236" sourceId="116" sourceModule="vtkSliderWidget" sourcePort="self(vtkSliderWidget)"/>
-    </action>
-    <action date="09 Mar 2007 17:46:02" parent="2452" time="2453" user="hvo" what="addConnection">
-      <connect destinationId="116" destinationModule="vtkSliderWidget" destinationPort="SetRepresentation(vtkSliderRepresentation)" id="237" sourceId="118" sourceModule="vtkSliderRepresentation3D" sourcePort="self(vtkSliderRepresentation3D)"/>
-    </action>
-    <action date="09 Mar 2007 17:46:21" parent="2453" time="2454" user="hvo" what="moveModule">
-      <move dx="39.7465262796" dy="-586.603905092" id="116"/>
-      <move dx="39.7465262796" dy="-586.603905092" id="117"/>
-      <move dx="39.7465262796" dy="-586.603905092" id="118"/>
-    </action>
-    <action date="09 Mar 2007 17:46:21" parent="2454" time="2455" user="hvo" what="addConnection">
-      <connect destinationId="3" destinationModule="VTKCell" destinationPort="InteractionHandler(vtkInteractionHandler)" id="238" sourceId="117" sourceModule="vtkInteractionHandler" sourcePort="self(vtkInteractionHandler)"/>
-    </action>
-    <action date="09 Mar 2007 17:46:50" parent="2455" time="2456" user="hvo" what="moveModule">
-      <move dx="87.7164717895" dy="1.37056987171" id="116"/>
-      <move dx="278.225683957" dy="12.3351288454" id="117"/>
-      <move dx="-84.9753320461" dy="644.167839704" id="118"/>
-    </action>
-    <action date="09 Mar 2007 17:46:50" parent="2456" time="2457" user="hvo" what="addModule">
-      <object cache="0" id="119" name="Tuple" x="679.802656369" y="243.961437165"/>
-    </action>
-    <action date="09 Mar 2007 17:47:04" parent="2457" time="2458" user="hvo" what="addModulePort">
-      <addPort moduleId="119" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:47:05" parent="2458" time="2459" user="hvo" what="addModulePort">
-      <addPort moduleId="119" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:47:05" parent="2459" time="2460" user="hvo" what="addModulePort">
-      <addPort moduleId="119" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:47:06" parent="2460" time="2461" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="119" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:47:07" parent="2461" time="2462" user="hvo" what="addModulePort">
-      <addPort moduleId="119" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:47:09" parent="2462" time="2463" user="hvo" what="addModule">
-      <object cache="0" id="120" name="Tuple" x="838.788761487" y="265.890555112"/>
-    </action>
-    <action date="09 Mar 2007 17:47:19" parent="2463" time="2464" user="hvo" what="addModulePort">
-      <addPort moduleId="120" portName="centerX" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:47:20" parent="2464" time="2465" user="hvo" what="addModulePort">
-      <addPort moduleId="120" portName="centerY" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:47:21" parent="2465" time="2466" user="hvo" what="addModulePort">
-      <addPort moduleId="120" portName="centerZ" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="09 Mar 2007 17:47:21" parent="2466" time="2467" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="120" portName="value" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:47:22" parent="2467" time="2468" user="hvo" what="addModulePort">
-      <addPort moduleId="120" portName="value" portSpec="(Float,Float,Float)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 17:50:45" parent="2468" time="2469" user="hvo" what="addConnection">
-      <connect destinationId="119" destinationModule="Tuple" destinationPort="centerX(Float)" id="239" sourceId="69" sourceModule="PythonSource" sourcePort="centerX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:50:47" parent="2469" time="2470" user="hvo" what="addConnection">
-      <connect destinationId="119" destinationModule="Tuple" destinationPort="centerY(Float)" id="240" sourceId="69" sourceModule="PythonSource" sourcePort="centerY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:50:51" parent="2470" time="2471" user="hvo" what="addConnection">
-      <connect destinationId="119" destinationModule="Tuple" destinationPort="centerZ(Float)" id="241" sourceId="69" sourceModule="PythonSource" sourcePort="centerZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:50:55" parent="2471" time="2472" user="hvo" what="moveModule">
-      <move dx="115.127869224" dy="-74.0107730724" id="119"/>
-    </action>
-    <action date="09 Mar 2007 17:50:55" parent="2472" time="2473" user="hvo" what="addConnection">
-      <connect destinationId="120" destinationModule="Tuple" destinationPort="centerX(Float)" id="242" sourceId="69" sourceModule="PythonSource" sourcePort="rayX(Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:50:58" parent="2473" time="2474" user="hvo" what="addConnection">
-      <connect destinationId="120" destinationModule="Tuple" destinationPort="centerY(Float)" id="243" sourceId="69" sourceModule="PythonSource" sourcePort="rayY(Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:51:01" parent="2474" time="2475" user="hvo" what="addConnection">
-      <connect destinationId="120" destinationModule="Tuple" destinationPort="centerZ(Float)" id="244" sourceId="69" sourceModule="PythonSource" sourcePort="rayZ(Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:51:29" parent="2475" time="2476" user="hvo" what="moveModule">
-      <move dx="21.9291179474" dy="-20.5585480757" id="118"/>
-    </action>
-    <action date="09 Mar 2007 17:51:35" parent="2476" time="2477" user="hvo" what="moveModule">
-      <move dx="69.8990634573" dy="2.74113974342" id="119"/>
-    </action>
-    <action date="09 Mar 2007 17:51:35" parent="2477" time="2478" user="hvo" what="addConnection">
-      <connect destinationId="118" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint1InWorldCoordinates(Float,Float,Float)" id="245" sourceId="119" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:51:44" parent="2478" time="2479" user="hvo" what="addConnection">
-      <connect destinationId="118" destinationModule="vtkSliderRepresentation3D" destinationPort="SetPoint2InWorldCoordinates(Float,Float,Float)" id="246" sourceId="120" sourceModule="Tuple" sourcePort="value(Float,Float,Float)"/>
-    </action>
-    <action date="09 Mar 2007 17:52:28" parent="2479" time="2480" user="hvo" what="addConnection">
-      <connect destinationId="117" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="247" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="09 Mar 2007 17:53:30" parent="2480" time="2481" user="hvo" what="moveModule">
-      <move dx="74.0107730724" dy="5.48227948684" id="117"/>
-    </action>
-    <action date="09 Mar 2007 17:55:53" parent="2481" time="2482" user="hvo" what="moveModule">
-      <move dx="1.37056987171" dy="1.37056987171" id="114"/>
-    </action>
-    <action date="09 Mar 2007 17:57:11" parent="2482" time="2483" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.92988347575" id="3"/>
-    </action>
-    <action date="09 Mar 2007 17:57:15" parent="2483" time="2484" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-2.92988347575" id="117"/>
-    </action>
-    <action date="09 Mar 2007 18:00:43" parent="2484" time="2485" user="hvo" what="moveModule">
-      <move dx="-100.051600635" dy="1.37056987171" id="117"/>
-    </action>
-    <action date="09 Mar 2007 18:00:43" parent="2485" time="2486" user="hvo" what="addModule">
-      <object cache="0" id="121" name="vtkInteractionHandler" x="1290.24868029" y="-855.877049514"/>
-    </action>
-    <action date="09 Mar 2007 18:00:43" parent="2486" time="2487" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="121" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28sharedData.vtkInstance%29%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj. [...]
-    </action>
-    <action date="09 Mar 2007 18:00:43" parent="2487" time="2488" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="121" value=""/>
-    </action>
-    <action date="09 Mar 2007 18:00:48" parent="2488" time="2489" user="hvo" what="moveModule">
-      <move dx="-2.74113974342" dy="47.9699455099" id="121"/>
-    </action>
-    <action date="09 Mar 2007 18:00:48" parent="2489" time="2490" user="hvo" what="addConnection">
-      <connect destinationId="3" destinationModule="VTKCell" destinationPort="InteractionHandler(vtkInteractionHandler)" id="248" sourceId="121" sourceModule="vtkInteractionHandler" sourcePort="self(vtkInteractionHandler)"/>
-    </action>
-    <action date="09 Mar 2007 18:00:52" parent="2490" time="2491" user="hvo" what="addConnection">
-      <connect destinationId="121" destinationModule="vtkInteractionHandler" destinationPort="Observer(vtkInteractorObserver)" id="249" sourceId="116" sourceModule="vtkSliderWidget" sourcePort="self(vtkSliderWidget)"/>
-    </action>
-    <action date="09 Mar 2007 18:01:13" parent="2491" time="2492" user="hvo" what="addConnection">
-      <connect destinationId="121" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="250" sourceId="95" sourceModule="PythonSource" sourcePort="polyData(vtkPolyData)"/>
-    </action>
-    <action date="09 Mar 2007 18:01:33" parent="2492" time="2493" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="121" parameter="<no description>" parameterId="0" type="String" value="def%20endInteractionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20print%20%27hi%27"/>
-    </action>
-    <action date="09 Mar 2007 18:01:37" parent="2493" time="2494" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.37056987171" id="117"/>
-    </action>
-    <action date="09 Mar 2007 18:04:28" parent="2494" time="2495" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="121" parameter="<no description>" parameterId="0" type="String" value="def%20endInteractionHandler%28obj%2C%20ps%29%3A%0A%20%20%20%20ps.compute%28%29"/>
-    </action>
-    <action date="09 Mar 2007 18:05:16" parent="2495" time="2496" user="hvo" what="deleteConnection">
-      <connection connectionId="250"/>
-    </action>
-    <action date="09 Mar 2007 18:05:40" parent="2496" time="2497" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="121" parameter="<no description>" parameterId="0" type="String" value="def%20endInteractionHandler%28obj%2C%20ps%29%3A%0A%20%20%20%20ps.compute%28%29"/>
-    </action>
-    <action date="09 Mar 2007 18:12:40" parent="2497" time="2498" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:12:46" parent="2498" time="2499" user="hvo" what="deleteConnection">
-      <connection connectionId="248"/>
-      <connection connectionId="249"/>
-    </action>
-    <action date="09 Mar 2007 18:12:46" parent="2499" time="2500" user="hvo" what="deleteModule">
-      <module moduleId="121"/>
-    </action>
-    <action date="09 Mar 2007 18:14:38" parent="2500" time="2501" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:17:56" parent="2501" time="2502" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:19:07" parent="2502" time="2503" user="hvo" what="moveModule">
-      <move dx="104.16331025" dy="37.0053865362" id="95"/>
-    </action>
-    <action date="09 Mar 2007 18:19:07" parent="2503" time="2504" user="hvo" what="addModulePort">
-      <addPort moduleId="95" portName="self" portSpec="(PythonSource)" portType="output"/>
-    </action>
-    <action date="09 Mar 2007 18:19:13" parent="2504" time="2505" user="hvo" what="addModule">
-      <object cache="0" id="122" name="vtkInteractionHandler" x="1190.19707965" y="-855.877049514"/>
-    </action>
-    <action date="09 Mar 2007 18:19:13" parent="2505" time="2506" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="122" parameter="<no description>" parameterId="0" type="String" value="def%20interactionHandler%28obj%2C%20sharedData%29%3A%0A%20%20%20%20import%20math%0A%20%20%20%20import%20copy%0A%20%20%20%20import%20vtk%0A%20%20%20%20%0A%20%20%20%20polyData%20%3D%20vtk.vtkPolyData%28%29%0A%20%20%20%20polyData.ShallowCopy%28sharedData.vtkInstance%29%0A%20%20%20%20points%20%3D%20polyData.GetPoints%28%29%0A%20%20%20%20rep%20%3D%20obj. [...]
-    </action>
-    <action date="09 Mar 2007 18:19:13" parent="2506" time="2507" user="hvo" what="changeAnnotation">
-      <set key="" moduleId="122" value=""/>
-    </action>
-    <action date="09 Mar 2007 18:19:20" parent="2507" time="2508" user="hvo" what="moveModule">
-      <move dx="-98.6810307632" dy="-37.0053865362" id="117"/>
-      <move dx="98.6810307632" dy="54.8227948684" id="122"/>
-    </action>
-    <action date="09 Mar 2007 18:19:20" parent="2508" time="2509" user="hvo" what="addConnection">
-      <connect destinationId="122" destinationModule="vtkInteractionHandler" destinationPort="Observer(vtkInteractorObserver)" id="251" sourceId="116" sourceModule="vtkSliderWidget" sourcePort="self(vtkSliderWidget)"/>
-    </action>
-    <action date="09 Mar 2007 18:19:24" parent="2509" time="2510" user="hvo" what="moveModule">
-      <move dx="-74.0107730724" dy="30.1525371776" id="122"/>
-    </action>
-    <action date="09 Mar 2007 18:19:24" parent="2510" time="2511" user="hvo" what="addConnection">
-      <connect destinationId="3" destinationModule="VTKCell" destinationPort="InteractionHandler(vtkInteractionHandler)" id="252" sourceId="122" sourceModule="vtkInteractionHandler" sourcePort="self(vtkInteractionHandler)"/>
-    </action>
-    <action date="09 Mar 2007 18:19:44" parent="2511" time="2512" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="122" parameter="<no description>" parameterId="0" type="String" value="def%20endInteractionHandler%28obj%2C%20ps%29%3A%0A%20%20%20%20print%20type%28ps%29"/>
-    </action>
-    <action date="09 Mar 2007 18:20:09" parent="2512" time="2513" user="hvo" what="moveModule">
-      <move dx="63.0462140987" dy="-30.1525371776" id="122"/>
-    </action>
-    <action date="09 Mar 2007 18:20:09" parent="2513" time="2514" user="hvo" what="addConnection">
-      <connect destinationId="122" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="253" sourceId="95" sourceModule="PythonSource" sourcePort="self(PythonSource)"/>
-    </action>
-    <action date="09 Mar 2007 18:20:48" parent="2514" time="2515" user="hvo" what="changeParameter">
-      <set alias="" function="Handler" functionId="0" moduleId="122" parameter="<no description>" parameterId="0" type="String" value="def%20endInteractionHandler%28obj%2C%20ps%29%3A%0A%20%20%20%20ps.compute%28%29"/>
-    </action>
-    <action date="09 Mar 2007 18:22:19" parent="2515" time="2516" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:24:08" parent="2516" time="2517" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:25:06" parent="2517" time="2518" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:27:20" parent="2518" time="2519" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:29:36" parent="2519" time="2520" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:31:12" parent="2520" time="2521" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:32:20" parent="2521" time="2522" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:33:25" parent="2522" time="2523" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="09 Mar 2007 18:34:36" parent="2523" time="2524" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="12 Mar 2007 13:05:39" parent="2524" time="2525" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="69" value=""/>
-    </action>
-    <action date="12 Mar 2007 13:06:04" parent="2525" time="2526" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="69" value="Read Slice"/>
-    </action>
-    <action date="12 Mar 2007 13:06:30" parent="2526" time="2527" user="hvo" what="moveModule">
-      <move dx="56.1933647401" dy="47.9699455099" id="69"/>
-    </action>
-    <action date="12 Mar 2007 13:06:30" parent="2527" time="2528" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="69" value="where is it"/>
-    </action>
-    <action date="12 Mar 2007 13:07:04" parent="2528" time="2529" user="hvo" what="moveModule">
-      <move dx="60.3050743553" dy="-13.7056987171" id="118"/>
-    </action>
-    <action date="12 Mar 2007 13:07:27" parent="2529" time="2530" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="120" value=""/>
-    </action>
-    <action date="12 Mar 2007 13:07:38" parent="2530" time="2531" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="120" value="center"/>
-    </action>
-    <action date="12 Mar 2007 13:07:58" parent="2531" time="2532" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="119" value=""/>
-    </action>
-    <action date="12 Mar 2007 13:08:03" parent="2532" time="2533" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="119" value="ray"/>
-    </action>
-    <action date="12 Mar 2007 13:08:35" parent="2533" time="2534" user="hvo" what="moveModule">
-      <move dx="-39.7465262796" dy="-1.37056987171" id="119"/>
-    </action>
-    <action date="12 Mar 2007 13:08:45" parent="2534" time="2535" user="hvo" what="moveModule">
-      <move dx="0.0" dy="-1.37056987171" id="69"/>
-    </action>
-    <action date="12 Mar 2007 13:08:45" parent="2535" time="2536" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="69" value="read vertical slice"/>
-    </action>
-    <action date="12 Mar 2007 13:09:27" parent="2536" time="2537" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0AlastXY%20%3D%20 [...]
-    </action>
-    <action date="12 Mar 2007 13:19:22" parent="2537" time="2538" user="hvo" what="moveModule">
-      <move dx="89.0870416612" dy="-5.48227948684" id="102"/>
-    </action>
-    <action date="12 Mar 2007 13:39:30" parent="2538" time="2539" user="hvo" what="moveModule">
-      <move dx="28.7819673059" dy="-6.85284935855" id="95"/>
-    </action>
-    <action date="12 Mar 2007 13:40:40" parent="2539" time="2540" user="hvo" what="moveModule">
-      <move dx="-448.176348049" dy="-27.4113974342" id="100"/>
-    </action>
-    <action date="12 Mar 2007 13:41:26" parent="2540" time="2541" user="hvo" what="moveModule">
-      <move dx="87.7164717895" dy="-71.269633329" id="100"/>
-    </action>
-    <action date="12 Mar 2007 13:41:28" parent="2541" time="2542" user="hvo" what="moveModule">
-      <move dx="1.37056987171" dy="0.0" id="114"/>
-    </action>
-    <action date="12 Mar 2007 13:41:28" parent="2542" time="2543" user="hvo" what="deleteConnection">
-      <connection connectionId="210"/>
-    </action>
-    <action date="12 Mar 2007 13:41:32" parent="2543" time="2544" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="100" portName="length" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 13:42:47" parent="2544" time="2545" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0Afor%20i%20in%20 [...]
-    </action>
-    <action date="12 Mar 2007 13:45:26" parent="2545" time="2546" user="hvo" what="addModulePort">
-      <addPort moduleId="95" portName="length" portSpec="(Float)" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 13:45:27" parent="2546" time="2547" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28 [...]
-    </action>
-    <action date="12 Mar 2007 13:45:33" parent="2547" time="2548" user="hvo" what="deleteConnection">
-      <connection connectionId="215"/>
-    </action>
-    <action date="12 Mar 2007 13:45:34" parent="2548" time="2549" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="69" portName="length" portType="output"/>
-    </action>
-    <action date="12 Mar 2007 13:45:58" parent="2549" time="2550" user="hvo" what="moveModule">
-      <move dx="-1.37056987171" dy="0.0" id="95"/>
-    </action>
-    <action date="12 Mar 2007 13:45:58" parent="2550" time="2551" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="95" portName="length" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 13:45:58" parent="2551" time="2552" user="hvo" what="addModulePort">
-      <addPort moduleId="95" portName="length" portSpec="(Float)" portType="output"/>
-    </action>
-    <action date="12 Mar 2007 13:46:02" parent="2552" time="2553" user="hvo" what="addConnection">
-      <connect destinationId="104" destinationModule="PythonSource" destinationPort="length(Float)" id="254" sourceId="95" sourceModule="PythonSource" sourcePort="length(Float)"/>
-    </action>
-    <action date="12 Mar 2007 13:46:50" parent="2553" time="2554" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28 [...]
-    </action>
-    <action date="12 Mar 2007 13:47:48" parent="2554" time="2555" user="hvo" what="moveModule">
-      <move dx="-1.37056987171" dy="0.0" id="117"/>
-    </action>
-    <action date="12 Mar 2007 13:49:08" parent="2555" time="2556" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="95" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0AprobeFilter%20%3D%20probed.vtkInstance%0AprobeFilter.Update%28%29%0ApolyData%20%3D%20probeFilter.GetOutput%28%29%0ApCount%20%3D%20polyData.GetNumberOfPoints%28%29%0Apoints%20%3D%20polyData.GetPoints%28%29%0Adata%20%3D%20polyData.GetPointData%28%29.GetScalars%28%29%0A%0AcolCoun [...]
-    </action>
-    <action date="12 Mar 2007 13:49:26" parent="2556" time="2557" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="69" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Af%20%3D%20open%28filename%2C%20%27r%27%29%0Afn%20%3D%20f.readline%28%29.rstrip%28%29%0AvCount%20%3D%20int%28f.readline%28%29.rstrip%28%29%29%0A%0Apoints%20%3D%20vtk.vtkPoints%28%29%0Apoints.SetNumberOfPoints%28vCount%29%0A%0Alength%20%3D%200.0%0Afor%20i%20in%20range%28vCount%2 [...]
-    </action>
-    <action date="12 Mar 2007 13:55:56" parent="2557" time="2558" user="hvo" what="moveModule">
-      <move dx="-30.1525371776" dy="-8.22341923027" id="102"/>
-      <move dx="0.0" dy="-1.37056987171" id="104"/>
-    </action>
-    <action date="12 Mar 2007 13:56:14" parent="2558" time="2559" user="hvo" what="deleteConnection">
-      <connection connectionId="254"/>
-    </action>
-    <action date="12 Mar 2007 13:56:14" parent="2559" time="2560" user="hvo" what="deleteModulePort">
-      <deletePort moduleId="104" portName="length" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 13:56:16" parent="2560" time="2561" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="104" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.15%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.8%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0A [...]
-    </action>
-    <action date="12 Mar 2007 13:58:42" parent="2561" time="2562" user="hvo" what="moveModule">
-      <move dx="254.925996138" dy="-26.0408275625" id="5"/>
-      <move dx="-120.610148711" dy="-31.5231070494" id="116"/>
-      <move dx="41.1170961513" dy="-31.5231070494" id="122"/>
-    </action>
-    <action date="12 Mar 2007 13:58:42" parent="2562" time="2563" user="hvo" what="addModule">
-      <object cache="0" id="123" name="PythonSource" x="1121.12615506" y="-683.914365984"/>
-    </action>
-    <action date="12 Mar 2007 13:59:45" parent="2563" time="2564" user="hvo" what="moveModule">
-      <move dx="-111.016159609" dy="49.3405153816" id="123"/>
-    </action>
-    <action date="12 Mar 2007 13:59:45" parent="2564" time="2565" user="hvo" what="addModulePort">
-      <addPort moduleId="123" portName="bend" portSpec="(PythonSource)" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 13:59:46" parent="2565" time="2566" user="hvo" what="addModulePort">
-      <addPort moduleId="123" portName="measure" portSpec="(PythonSource)" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 13:59:47" parent="2566" time="2567" user="hvo" what="addModulePort">
-      <addPort moduleId="123" portName="self" portSpec="(PythonSource)" portType="output"/>
-    </action>
-    <action date="12 Mar 2007 13:59:47" parent="2567" time="2568" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="123" parameter="<no description>" parameterId="0" type="String" value="bend.compute%28%29%0Ameasure.compute%28%29"/>
-    </action>
-    <action date="12 Mar 2007 13:59:50" parent="2568" time="2569" user="hvo" what="addConnection">
-      <connect destinationId="122" destinationModule="vtkInteractionHandler" destinationPort="SharedData(Module)" id="255" sourceId="123" sourceModule="PythonSource" sourcePort="self(PythonSource)"/>
-    </action>
-    <action date="12 Mar 2007 13:59:52" parent="2569" time="2570" user="hvo" what="deleteConnection">
-      <connection connectionId="253"/>
-    </action>
-    <action date="12 Mar 2007 13:59:56" parent="2570" time="2571" user="hvo" what="addConnection">
-      <connect destinationId="123" destinationModule="PythonSource" destinationPort="bend(PythonSource)" id="256" sourceId="95" sourceModule="PythonSource" sourcePort="self(PythonSource)"/>
-    </action>
-    <action date="12 Mar 2007 14:00:17" parent="2571" time="2572" user="hvo" what="moveModule">
-      <move dx="-82.2341923027" dy="16.4468384605" id="123"/>
-    </action>
-    <action date="12 Mar 2007 14:00:17" parent="2572" time="2573" user="hvo" what="addModule">
-      <object cache="0" id="124" name="PythonSource" x="855.235599948" y="-487.922874329"/>
-    </action>
-    <action date="12 Mar 2007 14:01:14" parent="2573" time="2574" user="hvo" what="moveModule">
-      <move dx="142.539266658" dy="119.239578839" id="105"/>
-    </action>
-    <action date="12 Mar 2007 14:01:16" parent="2574" time="2575" user="hvo" what="moveModule">
-      <move dx="1.37056987171" dy="0.0" id="124"/>
-    </action>
-    <action date="12 Mar 2007 14:01:16" parent="2575" time="2576" user="hvo" what="deleteConnection"/>
-    <action date="12 Mar 2007 14:01:16" parent="2576" time="2577" user="hvo" what="deleteModule">
-      <module moduleId="124"/>
-    </action>
-    <action date="12 Mar 2007 14:01:25" parent="2577" time="2578" user="hvo" what="addModulePort">
-      <addPort moduleId="104" portName="self" portSpec="(PythonSource)" portType="output"/>
-    </action>
-    <action date="12 Mar 2007 14:01:28" parent="2578" time="2579" user="hvo" what="moveModule">
-      <move dx="-30.1525371776" dy="16.4468384605" id="104"/>
-    </action>
-    <action date="12 Mar 2007 14:01:28" parent="2579" time="2580" user="hvo" what="addConnection">
-      <connect destinationId="123" destinationModule="PythonSource" destinationPort="measure(PythonSource)" id="257" sourceId="104" sourceModule="PythonSource" sourcePort="self(PythonSource)"/>
-    </action>
-    <action date="12 Mar 2007 14:01:44" parent="2580" time="2581" user="hvo" what="moveModule">
-      <move dx="-28.7819673059" dy="-2.74113974342" id="102"/>
-      <move dx="-12.3351288454" dy="-20.5585480757" id="104"/>
-      <move dx="100.051600635" dy="-35.6348166645" id="123"/>
-    </action>
-    <action date="12 Mar 2007 14:01:44" parent="2581" time="2582" user="hvo" what="addModulePort">
-      <addPort moduleId="104" portName="polyline" portSpec="(vtkPolyData)" portType="input"/>
-    </action>
-    <action date="12 Mar 2007 14:01:49" parent="2582" time="2583" user="hvo" what="addConnection">
-      <connect destinationId="104" destinationModule="PythonSource" destinationPort="polyline(vtkPolyData)" id="258" sourceId="69" sourceModule="PythonSource" sourcePort="polydata(vtkPolyData)"/>
-    </action>
-    <action date="12 Mar 2007 14:05:59" parent="2583" time="2584" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="104" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.15%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.8%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedV [...]
-    </action>
-    <action date="12 Mar 2007 14:06:36" parent="2584" time="2585" user="hvo" what="changeParameter">
-      <set alias="" function="source" functionId="0" moduleId="104" parameter="<no description>" parameterId="0" type="String" value="import%20vtk%0Aimport%20math%0Afrom%20core.modules.module_registry%20import%20registry%0A%0Aactor%20%3D%20Actor2D.vtkInstance%0Aactor.SetPoint1%280.15%2C%200.65%29%0Aactor.GetPositionCoordinate%28%29.SetCoordinateSystemToNormalizedViewport%28%29%0Aactor.SetPoint2%280.8%2C%200.65%29%0Aactor.GetPosition2Coordinate%28%29.SetCoordinateSystemToNormalizedV [...]
-    </action>
-    <action date="12 Mar 2007 14:08:09" parent="2585" time="2586" user="hvo" what="moveModule">
-      <move dx="0.0" dy="5.48227948684" id="69"/>
-    </action>
-    <action date="12 Mar 2007 14:08:09" parent="2586" time="2587" user="hvo" what="changeAnnotation">
-      <set key="__desc__" moduleId="95" value=""/>
-    </action>
-    <tag name="webpage 90" time="268"/>
-    <tag name="Both" time="1354"/>
-    <tag name="Test2" time="1640"/>
-    <tag name="TimeStep 60" time="161"/>
-    <tag name="webpage 30" time="237"/>
-    <tag name="webpage 60" time="234"/>
-    <tag name="TimeStep 90" time="168"/>
-    <tag name="Test1" time="1546"/>
-    <tag name="Static" time="2439"/>
-    <tag name="TimeStep 30" time="164"/>
-    <tag name="Interactive" time="2524"/>
-    <tag name=" A transect" time="1718"/>
-    <tag name="basic workflow" time="157"/>
-  </visTrail>
diff --git a/examples-internal/mummy.xml b/examples-internal/mummy.xml
deleted file mode 100644
index 95782c8..0000000
--- a/examples-internal/mummy.xml
+++ /dev/null
@@ -1,552 +0,0 @@
-  <visTrail version="0.3.0">
-    <action date="05 Jul 2006 11:12:53" parent="0" time="2" user="emanuele" what="addModule">
-      <object cache="1" id="0" name="vtkStructuredPointsReader" x="-0.967032957532" y="1.8021978022"/>
-    </action>
-    <action date="05 Jul 2006 11:13:10" parent="2" time="3" user="emanuele" what="moveModule">
-      <move dx="-2.93040299416" dy="88.6446914673" id="0"/>
-      <move dx="-2.93040299416" dy="88.6446914673" id="0"/>
-      <move dx="-2.93040299416" dy="88.6446914673" id="0"/>
-      <move dx="2.64289617538" dy="149.323638916" id="0"/>
-    </action>
-    <action date="05 Jul 2006 11:14:15" parent="3" time="4" user="emanuele" what="moveModule">
-      <move dx="2.64289617538" dy="149.323638916" id="0"/>
-      <move dx="2.64289617538" dy="149.323638916" id="0"/>
-      <move dx="2.64289617538" dy="149.323638916" id="0"/>
-      <move dx="2.64289617538" dy="149.323638916" id="0"/>
-      <move dx="-4.12526130676" dy="-33.0020904541" id="0"/>
-      <move dx="-4.12526130676" dy="-33.0020904541" id="0"/>
-    </action>
-    <action date="05 Jul 2006 11:14:15" parent="4" time="5" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFileName" functionId="0" moduleId="0" parameter="(unnamed)" parameterId="0" type="String" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:14:41" parent="5" time="6" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFileName" functionId="0" moduleId="0" parameter="(unnamed)" parameterId="0" type="String" value="../examples/data/mummy.128.vtk"/>
-    </action>
-    <action date="05 Jul 2006 11:15:16" parent="6" time="7" user="emanuele" what="addModule">
-      <object cache="0" id="1" name="vtkPiecewiseFunction" x="-32.8559157536" y="204.296605696"/>
-    </action>
-    <action date="05 Jul 2006 11:16:04" parent="7" time="8" user="emanuele" what="moveModule">
-      <move dx="-4.12526130676" dy="-33.0020904541" id="0"/>
-      <move dx="-4.12526130676" dy="-33.0020904541" id="0"/>
-      <move dx="-4.12526130676" dy="-33.0020904541" id="0"/>
-      <move dx="-4.12526130676" dy="-33.0020904541" id="0"/>
-      <move dx="22.0703868866" dy="472.306304932" id="1"/>
-      <move dx="22.0703868866" dy="472.306304932" id="1"/>
-      <move dx="436.661560059" dy="142.583374023" id="1"/>
-      <move dx="-118.076850891" dy="-37.8737068176" id="0"/>
-      <move dx="-2.22786521912" dy="11.1393260956" id="1"/>
-    </action>
-    <action date="05 Jul 2006 11:16:04" parent="8" time="9" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="0" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="AddPoint" functionId="0" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:16:12" parent="9" time="10" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="0" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="79"/>
-      <set alias="" function="AddPoint" functionId="0" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:16:16" parent="10" time="11" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="0" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="79"/>
-      <set alias="" function="AddPoint" functionId="0" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:16:21" parent="11" time="12" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="1" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="AddPoint" functionId="1" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:16:27" parent="12" time="13" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="1" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="80"/>
-      <set alias="" function="AddPoint" functionId="1" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:16:32" parent="13" time="14" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="1" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="80"/>
-      <set alias="" function="AddPoint" functionId="1" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value="0.1"/>
-    </action>
-    <action date="05 Jul 2006 11:16:41" parent="14" time="15" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="2" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="AddPoint" functionId="2" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:16:46" parent="15" time="16" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="2" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="110"/>
-      <set alias="" function="AddPoint" functionId="2" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:16:52" parent="16" time="17" user="emanuele" what="changeParameter">
-      <set alias="" function="AddPoint" functionId="2" moduleId="1" parameter="(unnamed)" parameterId="0" type="Float" value="110"/>
-      <set alias="" function="AddPoint" functionId="2" moduleId="1" parameter="(unnamed)" parameterId="1" type="Float" value="0.8"/>
-    </action>
-    <action date="05 Jul 2006 11:17:39" parent="17" time="18" user="emanuele" what="moveModule">
-      <move dx="-61.6779518127" dy="-804.616882324" id="1"/>
-      <move dx="-204.864761353" dy="167.841003418" id="1"/>
-      <move dx="17.2777519226" dy="197.460006714" id="0"/>
-      <move dx="197.460021973" dy="88.8570022583" id="1"/>
-    </action>
-    <action date="05 Jul 2006 11:17:39" parent="18" time="19" user="emanuele" what="addModule">
-      <object cache="0" id="2" name="vtkColorTransferFunction" x="332.116694623" y="538.146279974"/>
-    </action>
-    <action date="05 Jul 2006 11:17:55" parent="19" time="20" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:18:03" parent="20" time="21" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="79.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:06" parent="21" time="22" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="79.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:09" parent="22" time="23" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="79.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:13" parent="23" time="24" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="79.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="0" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:18:15" parent="24" time="25" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:18:21" parent="25" time="26" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="80.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:24" parent="26" time="27" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="80.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.8"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:29" parent="27" time="28" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="80.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.8"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.3"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:34" parent="28" time="29" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="80.0"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.8"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.3"/>
-      <set alias="" function="AddRGBPoint" functionId="1" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:18:45" parent="29" time="30" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:18:51" parent="30" time="31" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="110.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:54" parent="31" time="32" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="110.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:56" parent="32" time="33" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="110.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:18:59" parent="33" time="34" user="emanuele" what="changeParameter">
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="0" type="Float" value="110.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="1" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="2" type="Float" value="1.0"/>
-      <set alias="" function="AddRGBPoint" functionId="2" moduleId="2" parameter="(unnamed)" parameterId="3" type="Float" value="1.0"/>
-    </action>
-    <action date="05 Jul 2006 11:19:16" parent="34" time="35" user="emanuele" what="addModule">
-      <object cache="0" id="3" name="vtkVolumeProperty" x="-172.779209448" y="604.01445454"/>
-    </action>
-    <action date="05 Jul 2006 11:19:34" parent="35" time="36" user="emanuele" what="moveModule">
-      <move dx="162.002761841" dy="-392.00668335" id="3"/>
-      <move dx="-4.00006818771" dy="10.0001707077" id="2"/>
-    </action>
-    <action date="05 Jul 2006 11:19:34" parent="36" time="37" user="emanuele" what="addConnection">
-      <connect destinationId="3" destinationModule="vtkVolumeProperty" destinationPort="SetColor_2(vtkPiecewiseFunction)" id="0" sourceId="2" sourceModule="vtkColorTransferFunction" sourcePort="self(vtkColorTransferFunction)"/>
-    </action>
-    <action date="05 Jul 2006 11:20:07" parent="37" time="38" user="emanuele" what="addConnection">
-      <connect destinationId="3" destinationModule="vtkVolumeProperty" destinationPort="SetScalarOpacity_2(vtkPiecewiseFunction)" id="1" sourceId="1" sourceModule="vtkPiecewiseFunction" sourcePort="self(vtkPiecewiseFunction)"/>
-    </action>
-    <action date="05 Jul 2006 11:21:01" parent="38" time="39" user="emanuele" what="moveModule">
-      <move dx="62.0010604858" dy="-136.002319336" id="2"/>
-      <move dx="134.002288818" dy="386.006591797" id="3"/>
-    </action>
-    <action date="05 Jul 2006 11:21:21" parent="39" time="40" user="emanuele" what="addModule">
-      <object cache="0" id="4" name="vtkVolumeRayCastCompositeFunction" x="-244.780439357" y="410.011148283"/>
-    </action>
-    <action date="05 Jul 2006 11:21:50" parent="40" time="41" user="emanuele" what="changeParameter">
-      <set alias="" function="SetInterpolationTypeToLinear" functionId="0" moduleId="3" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:22:03" parent="41" time="42" user="emanuele" what="changeParameter">
-      <set alias="" function="ShadeOn" functionId="1" moduleId="3" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:22:30" parent="42" time="43" user="emanuele" what="addModule">
-      <object cache="0" id="5" name="vtkVolumeRayCastMapper" x="-254.780610178" y="684.015817945"/>
-    </action>
-    <action date="05 Jul 2006 11:22:38" parent="43" time="44" user="emanuele" what="moveModule">
-      <move dx="-32.0005455017" dy="0.0" id="5"/>
-    </action>
-    <action date="05 Jul 2006 11:22:38" parent="44" time="45" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkVolumeRayCastMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="2" sourceId="0" sourceModule="vtkStructuredPointsReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="05 Jul 2006 11:22:54" parent="45" time="46" user="emanuele" what="moveModule">
-      <move dx="520.008911133" dy="452.00769043" id="4"/>
-      <move dx="-112.001914978" dy="86.0014648438" id="0"/>
-      <move dx="16.0002727509" dy="40.0006828308" id="4"/>
-    </action>
-    <action date="05 Jul 2006 11:22:55" parent="46" time="47" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="vtkVolumeRayCastMapper" destinationPort="SetVolumeRayCastFunction(vtkVolumeRayCastFunction)" id="3" sourceId="4" sourceModule="vtkVolumeRayCastCompositeFunction" sourcePort="self(vtkVolumeRayCastCompositeFunction)"/>
-    </action>
-    <action date="05 Jul 2006 11:23:17" parent="47" time="48" user="emanuele" what="changeParameter">
-      <set alias="" function="SetSampleDistance" functionId="0" moduleId="5" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:23:23" parent="48" time="49" user="emanuele" what="changeParameter">
-      <set alias="" function="SetSampleDistance" functionId="0" moduleId="5" parameter="(unnamed)" parameterId="0" type="Float" value="0.25"/>
-    </action>
-    <action date="05 Jul 2006 11:24:09" parent="49" time="50" user="emanuele" what="addModule">
-      <object cache="0" id="6" name="vtkVolume" x="-194.779585254" y="406.011080113"/>
-    </action>
-    <action date="05 Jul 2006 11:24:17" parent="50" time="51" user="emanuele" what="moveModule">
-      <move dx="-118.00201416" dy="-42.0007171631" id="6"/>
-    </action>
-    <action date="05 Jul 2006 11:24:17" parent="51" time="52" user="emanuele" what="addConnection">
-      <connect destinationId="6" destinationModule="vtkVolume" destinationPort="SetMapper(vtkAbstractVolumeMapper)" id="4" sourceId="5" sourceModule="vtkVolumeRayCastMapper" sourcePort="self(vtkVolumeRayCastMapper)"/>
-    </action>
-    <action date="05 Jul 2006 11:24:24" parent="52" time="53" user="emanuele" what="addConnection">
-      <connect destinationId="6" destinationModule="vtkVolume" destinationPort="SetProperty(vtkVolumeProperty)" id="5" sourceId="3" sourceModule="vtkVolumeProperty" sourcePort="self(vtkVolumeProperty)"/>
-    </action>
-    <action date="05 Jul 2006 11:25:15" parent="53" time="54" user="emanuele" what="addModule">
-      <object cache="0" id="7" name="vtkRenderer" x="151.226325141" y="134.006444536"/>
-    </action>
-    <action date="05 Jul 2006 11:25:26" parent="54" time="55" user="emanuele" what="moveModule">
-      <move dx="-306.005218506" dy="2.00003409386" id="7"/>
-    </action>
-    <action date="05 Jul 2006 11:25:26" parent="55" time="56" user="emanuele" what="addConnection">
-      <connect destinationId="7" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="6" sourceId="6" sourceModule="vtkVolume" sourcePort="self(vtkVolume)"/>
-    </action>
-    <action date="05 Jul 2006 11:25:31" parent="56" time="57" user="emanuele" what="deleteConnection">
-      <connection connectionId="6"/>
-    </action>
-    <action date="05 Jul 2006 11:25:42" parent="57" time="58" user="emanuele" what="addConnection">
-      <connect destinationId="7" destinationModule="vtkRenderer" destinationPort="AddVolume(vtkProp)" id="6" sourceId="6" sourceModule="vtkVolume" sourcePort="self(vtkVolume)"/>
-    </action>
-    <action date="05 Jul 2006 11:26:13" parent="58" time="59" user="emanuele" what="moveModule">
-      <move dx="52.0008888245" dy="42.0007171631" id="7"/>
-    </action>
-    <action date="05 Jul 2006 11:26:13" parent="59" time="60" user="emanuele" what="changeParameter">
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:26:17" parent="60" time="61" user="emanuele" what="changeParameter">
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:26:18" parent="61" time="62" user="emanuele" what="changeParameter">
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:26:21" parent="62" time="63" user="emanuele" what="changeParameter">
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:26:46" parent="63" time="64" user="emanuele" what="addModule">
-      <object cache="0" id="8" name="VTKCell" x="1.22376283138" y="-105.997645679"/>
-    </action>
-    <action date="05 Jul 2006 11:26:55" parent="64" time="65" user="emanuele" what="moveModule">
-      <move dx="110.001876831" dy="100.001701355" id="8"/>
-    </action>
-    <action date="05 Jul 2006 11:26:56" parent="65" time="66" user="emanuele" what="addConnection">
-      <connect destinationId="8" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="7" sourceId="7" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="05 Jul 2006 11:27:04" parent="66" time="67" user="emanuele" what="moveModule">
-      <move dx="52.0008888245" dy="42.0007171631" id="8"/>
-    </action>
-    <action date="05 Jul 2006 11:44:23" parent="67" time="68" user="emanuele" what="addModule">
-      <object cache="0" id="9" name="vtkCamera" x="447.024390583" y="175.802321742"/>
-    </action>
-    <action date="05 Jul 2006 11:45:01" parent="68" time="69" user="emanuele" what="moveModule">
-      <move dx="13.7722740173" dy="11.4768953323" id="9"/>
-    </action>
-    <action date="05 Jul 2006 11:45:01" parent="69" time="70" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewAngle" functionId="0" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:45:05" parent="70" time="71" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewAngle" functionId="0" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="30"/>
-    </action>
-    <action date="05 Jul 2006 11:45:13" parent="71" time="72" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:45:22" parent="72" time="73" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="658.889"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:45:32" parent="73" time="74" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="658.889"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="-346.805"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:45:41" parent="74" time="75" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="658.889"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="-346.805"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value="-195.327"/>
-    </action>
-    <action date="05 Jul 2006 11:45:50" parent="75" time="76" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:46:03" parent="76" time="77" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.166388"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:46:11" parent="77" time="78" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.166388"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="-0.394732"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:46:22" parent="78" time="79" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.166388"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="-0.394732"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value="0.903605"/>
-    </action>
-    <action date="05 Jul 2006 11:46:43" parent="79" time="80" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="05 Jul 2006 11:46:53" parent="80" time="81" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="111.157"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value=""/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:47:03" parent="81" time="82" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="111.157"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="150.498"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value=""/>
-    </action>
-    <action date="05 Jul 2006 11:47:19" parent="82" time="83" user="emanuele" what="changeParameter">
-      <notes>
-        <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:Lucida Grande; font-size:13pt; font-weight:400; font-style:normal; text-decoration:none;"><p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html>
-      </notes>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="0" type="Float" value="111.157"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="1" type="Float" value="150.498"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="9" parameter="(unnamed)" parameterId="2" type="Float" value="122.775"/>
-    </action>
-    <action date="05 Jul 2006 11:48:37" parent="83" time="84" user="emanuele" what="addConnection">
-      <connect destinationId="7" destinationModule="vtkRenderer" destinationPort="SetActiveCamera(vtkCamera)" id="8" sourceId="9" sourceModule="vtkCamera" sourcePort="self(vtkCamera)"/>
-    </action>
-    <action date="05 Jul 2006 11:48:59" parent="84" time="85" user="emanuele" what="moveModule">
-      <move dx="-427.931274414" dy="144.718582153" id="9"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="0" time="86" user="emanuele" what="addModule">
-      <object cache="0" id="0" name="vtkRenderer" x="106.147061222" y="-590.161953604"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="86" time="87" user="emanuele" what="addModule">
-      <object cache="0" id="1" name="vtkContourFilter" x="263.555115764" y="-109.797516937"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="87" time="88" user="emanuele" what="addModule">
-      <object cache="0" id="2" name="vtkDataSetMapper" x="177.838497215" y="-257.043881891"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="88" time="89" user="emanuele" what="addModule">
-      <object cache="0" id="3" name="vtkActor" x="408.945517245" y="-443.966479924"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="89" time="90" user="emanuele" what="addModule">
-      <object cache="0" id="4" name="vtkCamera" x="475.211758196" y="-724.262382954"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="90" time="91" user="emanuele" what="addModule">
-      <object cache="0" id="5" name="VTKCell" x="49.0608815312" y="-728.492757793"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="91" time="92" user="emanuele" what="addModule">
-      <object cache="0" id="6" name="vtkStructuredPointsReader" x="9.70802920407" y="13.1094890511"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="92" time="93" user="emanuele" what="addModule">
-      <object cache="0" id="7" name="vtkProperty" x="513.411929439" y="-332.785870007"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="93" time="94" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="0" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="94" time="95" user="emanuele" what="changeParameter">
-      <set alias="" function="SetValue" functionId="0" moduleId="1" parameter="" parameterId="0" type="Integer" value="0"/>
-      <set alias="" function="SetValue" functionId="0" moduleId="1" parameter="" parameterId="1" type="Float" value="67"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="95" time="96" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="1" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="96" time="97" user="emanuele" what="changeParameter">
-      <set alias="" function="ScalarVisibilityOff" functionId="0" moduleId="2" parameter="" parameterId="-1" type="" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="97" time="98" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="2" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="98" time="99" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="3" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="99" time="100" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="0" moduleId="4" parameter="" parameterId="0" type="Float" value="744.495278753"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="4" parameter="" parameterId="1" type="Float" value="-452.645563908"/>
-      <set alias="" function="SetPosition" functionId="0" moduleId="4" parameter="" parameterId="2" type="Float" value="369.493592636"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="100" time="101" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="1" moduleId="4" parameter="" parameterId="0" type="Float" value="-0.0112199962915"/>
-      <set alias="" function="SetViewUp" functionId="1" moduleId="4" parameter="" parameterId="1" type="Float" value="-0.180037940492"/>
-      <set alias="" function="SetViewUp" functionId="1" moduleId="4" parameter="" parameterId="2" type="Float" value="-0.983595674892"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="101" time="102" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="2" moduleId="4" parameter="<no description>" parameterId="0" type="Float" value="134.736557007"/>
-      <set alias="" function="SetFocalPoint" functionId="2" moduleId="4" parameter="<no description>" parameterId="1" type="Float" value="135.585741997"/>
-      <set alias="" function="SetFocalPoint" functionId="2" moduleId="4" parameter="<no description>" parameterId="2" type="Float" value="148.703317642"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="102" time="103" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="4" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="103" time="104" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="5" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="104" time="105" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFileName" functionId="0" moduleId="6" parameter="" parameterId="0" type="String" value="../examples/data/head.120.vtk"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="105" time="106" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="6" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="106" time="107" user="emanuele" what="changeParameter">
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="107" time="108" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="7" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="108" time="109" user="emanuele" what="addConnection">
-      <connect destinationId="5" destinationModule="VTKCell" destinationPort="AddRenderer(vtkRenderer)" id="0" sourceId="0" sourceModule="vtkRenderer" sourcePort="self(vtkRenderer)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="109" time="110" user="emanuele" what="addConnection">
-      <connect destinationId="0" destinationModule="vtkRenderer" destinationPort="AddActor(vtkProp)" id="1" sourceId="3" sourceModule="vtkActor" sourcePort="self(vtkActor)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="110" time="111" user="emanuele" what="addConnection">
-      <connect destinationId="0" destinationModule="vtkRenderer" destinationPort="SetActiveCamera(vtkCamera)" id="2" sourceId="4" sourceModule="vtkCamera" sourcePort="self(vtkCamera)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="111" time="112" user="emanuele" what="addConnection">
-      <connect destinationId="1" destinationModule="vtkContourFilter" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="3" sourceId="6" sourceModule="vtkStructuredPointsReader" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="112" time="113" user="emanuele" what="addConnection">
-      <connect destinationId="2" destinationModule="vtkDataSetMapper" destinationPort="SetInputConnection0(vtkAlgorithmOutput)" id="4" sourceId="1" sourceModule="vtkContourFilter" sourcePort="GetOutputPort0(vtkAlgorithmOutput)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="113" time="114" user="emanuele" what="addConnection">
-      <connect destinationId="3" destinationModule="vtkActor" destinationPort="SetMapper(vtkMapper)" id="5" sourceId="2" sourceModule="vtkDataSetMapper" sourcePort="self(vtkDataSetMapper)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:07" parent="114" time="115" user="emanuele" what="addConnection">
-      <connect destinationId="3" destinationModule="vtkActor" destinationPort="SetProperty(vtkProperty)" id="6" sourceId="7" sourceModule="vtkProperty" sourcePort="self(vtkProperty)"/>
-    </action>
-    <action date="18 Jan 2007 21:29:22" parent="115" time="116" user="emanuele" what="changeParameter">
-      <set alias="filename" function="SetFileName" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="../examples/data/head.120.vtk"/>
-    </action>
-    <action date="18 Jan 2007 21:29:33" parent="116" time="117" user="emanuele" what="changeParameter">
-      <set alias="" function="SetValue" functionId="0" moduleId="1" parameter="<no description>" parameterId="0" type="Integer" value="0"/>
-      <set alias="isovalue" function="SetValue" functionId="0" moduleId="1" parameter="<no description>" parameterId="1" type="Float" value="67"/>
-    </action>
-    <action date="18 Jan 2007 21:30:25" parent="85" time="118" user="emanuele" what="changeParameter">
-      <set alias="filename" function="SetFileName" functionId="0" moduleId="0" parameter="<no description>" parameterId="0" type="String" value="../examples/data/mummy.128.vtk"/>
-    </action>
-    <action date="18 Jan 2007 21:31:37" parent="118" time="119" user="emanuele" what="changeParameter">
-      <set alias="Background_R" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="18 Jan 2007 21:31:47" parent="119" time="120" user="emanuele" what="changeParameter">
-      <set alias="Background_R" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="Background_G" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="18 Jan 2007 21:31:57" parent="120" time="121" user="emanuele" what="changeParameter">
-      <set alias="Background_R" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="0.0"/>
-      <set alias="Background_G" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="1" type="Float" value="0.0"/>
-      <set alias="Background_B" function="SetBackground" functionId="0" moduleId="7" parameter="<no description>" parameterId="2" type="Float" value="0.0"/>
-    </action>
-    <action date="18 Jan 2007 21:46:02" parent="117" time="122" user="emanuele" what="deleteConnection">
-      <connection connectionId="2"/>
-    </action>
-    <action date="18 Jan 2007 21:46:02" parent="122" time="123" user="emanuele" what="deleteModule">
-      <module moduleId="4"/>
-    </action>
-    <action date="18 Jan 2007 21:46:04" parent="123" time="124" user="emanuele" what="addModule">
-      <object cache="0" id="4" name="vtkCamera" x="42.8653901863" y="341.997799227"/>
-    </action>
-    <action date="18 Jan 2007 21:46:04" parent="124" time="125" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewAngle" functionId="0" moduleId="4" parameter="(unnamed)" parameterId="0" type="Float" value="30"/>
-    </action>
-    <action date="18 Jan 2007 21:46:04" parent="125" time="126" user="emanuele" what="changeParameter">
-      <set alias="" function="SetPosition" functionId="1" moduleId="4" parameter="(unnamed)" parameterId="0" type="Float" value="658.889"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="4" parameter="(unnamed)" parameterId="1" type="Float" value="-346.805"/>
-      <set alias="" function="SetPosition" functionId="1" moduleId="4" parameter="(unnamed)" parameterId="2" type="Float" value="-195.327"/>
-    </action>
-    <action date="18 Jan 2007 21:46:04" parent="126" time="127" user="emanuele" what="changeParameter">
-      <set alias="" function="SetViewUp" functionId="2" moduleId="4" parameter="(unnamed)" parameterId="0" type="Float" value="0.166388"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="4" parameter="(unnamed)" parameterId="1" type="Float" value="-0.394732"/>
-      <set alias="" function="SetViewUp" functionId="2" moduleId="4" parameter="(unnamed)" parameterId="2" type="Float" value="0.903605"/>
-    </action>
-    <action date="18 Jan 2007 21:46:04" parent="127" time="128" user="emanuele" what="changeParameter">
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="4" parameter="(unnamed)" parameterId="0" type="Float" value="111.157"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="4" parameter="(unnamed)" parameterId="1" type="Float" value="150.498"/>
-      <set alias="" function="SetFocalPoint" functionId="3" moduleId="4" parameter="(unnamed)" parameterId="2" type="Float" value="122.775"/>
-    </action>
-    <action date="18 Jan 2007 21:46:04" parent="128" time="129" user="emanuele" what="changeAnnotation">
-      <set key="" moduleId="4" value=""/>
-    </action>
-    <action date="18 Jan 2007 21:46:55" parent="129" time="130" user="emanuele" what="moveModule">
-      <move dx="357.893953153" dy="-856.730355211" id="4"/>
-    </action>
-    <action date="18 Jan 2007 21:46:55" parent="130" time="131" user="emanuele" what="addConnection">
-      <connect destinationId="0" destinationModule="vtkRenderer" destinationPort="SetActiveCamera(vtkCamera)" id="2" sourceId="4" sourceModule="vtkCamera" sourcePort="self(vtkCamera)"/>
-    </action>
-    <action date="18 Jan 2007 21:47:57" parent="131" time="132" user="emanuele" what="changeParameter">
-      <set alias="filename" function="SetFileName" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="../examples/data/mummy.128.vtk"/>
-    </action>
-    <action date="18 Jan 2007 21:48:06" parent="132" time="133" user="emanuele" what="changeParameter">
-      <set alias="filename" function="SetFileName" functionId="0" moduleId="6" parameter="<no description>" parameterId="0" type="String" value="../examples/data/mummy.128.vtk"/>
-    </action>
-    <action date="18 Jan 2007 21:49:00" parent="133" time="134" user="emanuele" what="moveModule">
-      <move dx="2.62040212778" dy="2.62040212778" id="7"/>
-    </action>
-    <action date="18 Jan 2007 21:49:00" parent="134" time="135" user="emanuele" what="changeParameter">
-      <set alias="Diffuse_Color_R" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="18 Jan 2007 21:49:12" parent="135" time="136" user="emanuele" what="changeParameter">
-      <set alias="Diffuse_Color_R" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="Diffuse_Color_G" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <action date="18 Jan 2007 21:49:24" parent="136" time="137" user="emanuele" what="changeParameter">
-      <set alias="Diffuse_Color_R" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="0" type="Float" value="1"/>
-      <set alias="Diffuse_Color_G" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="1" type="Float" value="1"/>
-      <set alias="Diffuse_Color_B" function="SetDiffuseColor" functionId="0" moduleId="7" parameter="<no description>" parameterId="2" type="Float" value="1"/>
-    </action>
-    <tag name="Isosufarce" time="137"/>
-    <tag name="Volume Rendering" time="121"/>
-  </visTrail>
diff --git a/examples/EMBOSS_webservices.vt b/examples/EMBOSS_webservices.vt
deleted file mode 100644
index 076a2ce..0000000
Binary files a/examples/EMBOSS_webservices.vt and /dev/null differ
diff --git a/examples/KEGGPathway.vt b/examples/KEGGPathway.vt
deleted file mode 100644
index 3cb82e8..0000000
Binary files a/examples/KEGGPathway.vt and /dev/null differ
diff --git a/examples/KEGG_SearchEntities_webservice.vt b/examples/KEGG_SearchEntities_webservice.vt
deleted file mode 100644
index cf20cbb..0000000
Binary files a/examples/KEGG_SearchEntities_webservice.vt and /dev/null differ
diff --git a/examples/KEGG_webservices.vt b/examples/KEGG_webservices.vt
deleted file mode 100644
index 4e5ec1f..0000000
Binary files a/examples/KEGG_webservices.vt and /dev/null differ
diff --git a/examples/api/brain_output.xml b/examples/api/brain_output.xml
new file mode 100644
index 0000000..a72760e
--- /dev/null
+++ b/examples/api/brain_output.xml
@@ -0,0 +1,887 @@
+<vistrail id="" name="" version="1.0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vistrails.org/vistrail.xsd">
+  <action date="2015-03-18 16:26:24" id="1" prevId="0" session="0" user="Remi">
+    <annotation id="1" key="__description__" value="Paste" />
+    <add id="0" objectId="0" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="0" name="vtkDataSetReader" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="1" objectId="0" parentObjId="0" parentObjType="module" what="location">
+      <location id="0" x="19.9868870813" y="264.359717931" />
+    </add>
+    <add id="2" objectId="1" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="1" name="vtkProbeFilter" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="3" objectId="1" parentObjId="1" parentObjType="module" what="location">
+      <location id="1" x="97.5027154606" y="-125.404765168" />
+    </add>
+    <add id="4" objectId="2" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="2" name="vtkProperty" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="5" objectId="3" parentObjId="2" parentObjType="module" what="function">
+      <function id="3" name="SetOpacity" pos="3" />
+    </add>
+    <add id="6" objectId="5" parentObjId="3" parentObjType="function" what="parameter">
+      <parameter alias="" id="5" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="0.7" />
+    </add>
+    <add id="7" objectId="2" parentObjId="2" parentObjType="module" what="function">
+      <function id="2" name="SetSpecularPower" pos="2" />
+    </add>
+    <add id="8" objectId="4" parentObjId="2" parentObjType="function" what="parameter">
+      <parameter alias="" id="4" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="20.0" />
+    </add>
+    <add id="9" objectId="1" parentObjId="2" parentObjType="module" what="function">
+      <function id="1" name="SetSpecular" pos="1" />
+    </add>
+    <add id="10" objectId="3" parentObjId="1" parentObjType="function" what="parameter">
+      <parameter alias="" id="3" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="0.3" />
+    </add>
+    <add id="11" objectId="0" parentObjId="2" parentObjType="module" what="function">
+      <function id="0" name="SetDiffuseColor" pos="0" />
+    </add>
+    <add id="12" objectId="2" parentObjId="0" parentObjType="function" what="parameter">
+      <parameter alias="" id="2" name="<no description>" pos="2" type="edu.utah.sci.vistrails.basic:Float" val="0.25" />
+    </add>
+    <add id="13" objectId="1" parentObjId="0" parentObjType="function" what="parameter">
+      <parameter alias="" id="1" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="0.49" />
+    </add>
+    <add id="14" objectId="0" parentObjId="0" parentObjType="function" what="parameter">
+      <parameter alias="" id="0" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="1.0" />
+    </add>
+    <add id="15" objectId="2" parentObjId="2" parentObjType="module" what="location">
+      <location id="2" x="318.026813133" y="-308.312673027" />
+    </add>
+    <add id="16" objectId="3" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="3" name="vtkPolyDataMapper" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="17" objectId="4" parentObjId="3" parentObjType="module" what="function">
+      <function id="4" name="ScalarVisibilityOn" pos="0" />
+    </add>
+    <add id="18" objectId="3" parentObjId="3" parentObjType="module" what="location">
+      <location id="3" x="98.6726912122" y="-259.733017637" />
+    </add>
+    <add id="19" objectId="4" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="4" name="vtkActor" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="20" objectId="4" parentObjId="4" parentObjType="module" what="location">
+      <location id="4" x="106.360127696" y="-407.425503999" />
+    </add>
+    <add id="21" objectId="5" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="5" name="vtkContourFilter" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="22" objectId="5" parentObjId="5" parentObjType="module" what="function">
+      <function id="5" name="SetValue" pos="0" />
+    </add>
+    <add id="23" objectId="7" parentObjId="5" parentObjType="function" what="parameter">
+      <parameter alias="" id="7" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="0.6" />
+    </add>
+    <add id="24" objectId="6" parentObjId="5" parentObjType="function" what="parameter">
+      <parameter alias="" id="6" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Integer" val="0" />
+    </add>
+    <add id="25" objectId="5" parentObjId="5" parentObjType="module" what="location">
+      <location id="5" x="-297.271265348" y="191.884461486" />
+    </add>
+    <add id="26" objectId="6" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="6" name="vtkDataSetReader" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="27" objectId="6" parentObjId="6" parentObjType="module" what="location">
+      <location id="6" x="-375.540899841" y="321.858350831" />
+    </add>
+    <add id="28" objectId="7" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="7" name="vtkStripper" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="29" objectId="7" parentObjId="7" parentObjType="module" what="location">
+      <location id="7" x="-89.561012773" y="-51.0120756165" />
+    </add>
+    <add id="30" objectId="8" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="8" name="vtkLookupTable" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="31" objectId="8" parentObjId="8" parentObjType="module" what="function">
+      <function id="8" name="SetValueRange" pos="2" />
+    </add>
+    <add id="32" objectId="13" parentObjId="8" parentObjType="function" what="parameter">
+      <parameter alias="" id="13" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="1" />
+    </add>
+    <add id="33" objectId="12" parentObjId="8" parentObjType="function" what="parameter">
+      <parameter alias="" id="12" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="1" />
+    </add>
+    <add id="34" objectId="7" parentObjId="8" parentObjType="module" what="function">
+      <function id="7" name="SetSaturationRange" pos="1" />
+    </add>
+    <add id="35" objectId="11" parentObjId="7" parentObjType="function" what="parameter">
+      <parameter alias="" id="11" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="0.7" />
+    </add>
+    <add id="36" objectId="10" parentObjId="7" parentObjType="function" what="parameter">
+      <parameter alias="" id="10" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="0.3" />
+    </add>
+    <add id="37" objectId="6" parentObjId="8" parentObjType="module" what="function">
+      <function id="6" name="SetHueRange" pos="0" />
+    </add>
+    <add id="38" objectId="9" parentObjId="6" parentObjType="function" what="parameter">
+      <parameter alias="" id="9" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="0.8" />
+    </add>
+    <add id="39" objectId="8" parentObjId="6" parentObjType="function" what="parameter">
+      <parameter alias="" id="8" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="0.0" />
+    </add>
+    <add id="40" objectId="8" parentObjId="8" parentObjType="module" what="location">
+      <location id="8" x="342.555572474" y="277.738213963" />
+    </add>
+    <add id="41" objectId="9" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="9" name="vtkPolyDataNormals" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="42" objectId="9" parentObjId="9" parentObjType="module" what="function">
+      <function id="9" name="SetFeatureAngle" pos="0" />
+    </add>
+    <add id="43" objectId="14" parentObjId="9" parentObjType="function" what="parameter">
+      <parameter alias="" id="14" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="60.0" />
+    </add>
+    <add id="44" objectId="9" parentObjId="9" parentObjType="module" what="location">
+      <location id="9" x="-264.040430273" y="69.8324666965" />
+    </add>
+    <add id="45" objectId="10" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="10" name="vtkImageMapToColors" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="46" objectId="10" parentObjId="10" parentObjType="module" what="function">
+      <function id="10" name="SetOutputFormatToRGBA" pos="0" />
+    </add>
+    <add id="47" objectId="10" parentObjId="10" parentObjType="module" what="location">
+      <location id="10" x="164.143215358" y="89.9107917395" />
+    </add>
+    <add id="48" objectId="11" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="11" name="HTTPFile" namespace="" package="edu.utah.sci.vistrails.http" version="0.9.0" />
+    </add>
+    <add id="49" objectId="11" parentObjId="11" parentObjType="module" what="function">
+      <function id="11" name="url" pos="0" />
+    </add>
+    <add id="50" objectId="15" parentObjId="11" parentObjType="function" what="parameter">
+      <parameter alias="" id="15" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:String" val="http://www.vistrails.org/download/download.php?type=DATA&id=gktbhFA.vtk" />
+    </add>
+    <add id="51" objectId="11" parentObjId="11" parentObjType="module" what="location">
+      <location id="11" x="-275.87750697" y="470.705553664" />
+    </add>
+    <add id="52" objectId="12" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="12" name="HTTPFile" namespace="" package="edu.utah.sci.vistrails.http" version="0.9.0" />
+    </add>
+    <add id="53" objectId="12" parentObjId="12" parentObjType="module" what="function">
+      <function id="12" name="url" pos="0" />
+    </add>
+    <add id="54" objectId="16" parentObjId="12" parentObjType="function" what="parameter">
+      <parameter alias="" id="16" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:String" val="http://www.vistrails.org/download/download.php?type=DATA&id=gktbhL123.vtk" />
+    </add>
+    <add id="55" objectId="12" parentObjId="12" parentObjType="module" what="location">
+      <location id="12" x="6.03904236942" y="437.732857835" />
+    </add>
+    <add id="56" objectId="13" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="13" name="vtkRenderer" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="57" objectId="13" parentObjId="13" parentObjType="module" what="function">
+      <function id="13" name="SetBackgroundWidget" pos="0" />
+    </add>
+    <add id="58" objectId="17" parentObjId="13" parentObjType="function" what="parameter">
+      <parameter alias="" id="17" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Color" val="1.0,1.0,1.0" />
+    </add>
+    <add id="59" objectId="13" parentObjId="13" parentObjType="module" what="location">
+      <location id="13" x="159.362077975" y="-500.340338504" />
+    </add>
+    <add id="60" objectId="14" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="14" name="VTKCell" namespace="" package="edu.utah.sci.vistrails.vtk" version="0.9.3" />
+    </add>
+    <add id="61" objectId="14" parentObjId="14" parentObjType="module" what="location">
+      <location id="14" x="154.657025704" y="-637.584582668" />
+    </add>
+    <add id="62" objectId="15" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="15" name="vtkCamera" namespace="" package="edu.utah.sci.vistrails.vtk" version="" />
+    </add>
+    <add id="63" objectId="16" parentObjId="15" parentObjType="module" what="function">
+      <function id="16" name="SetViewUp" pos="0" />
+    </add>
+    <add id="64" objectId="26" parentObjId="16" parentObjType="function" what="parameter">
+      <parameter alias="" id="26" name="<no description>" pos="2" type="edu.utah.sci.vistrails.basic:Float" val="0.00760380579491" />
+    </add>
+    <add id="65" objectId="25" parentObjId="16" parentObjType="function" what="parameter">
+      <parameter alias="" id="25" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="0.999556218535" />
+    </add>
+    <add id="66" objectId="24" parentObjId="16" parentObjType="function" what="parameter">
+      <parameter alias="" id="24" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="0.0288018771004" />
+    </add>
+    <add id="67" objectId="15" parentObjId="15" parentObjType="module" what="function">
+      <function id="15" name="SetFocalPoint" pos="0" />
+    </add>
+    <add id="68" objectId="23" parentObjId="15" parentObjType="function" what="parameter">
+      <parameter alias="" id="23" name="<no description>" pos="2" type="edu.utah.sci.vistrails.basic:Float" val="39.9909629822" />
+    </add>
+    <add id="69" objectId="22" parentObjId="15" parentObjType="function" what="parameter">
+      <parameter alias="" id="22" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="40.4209948182" />
+    </add>
+    <add id="70" objectId="21" parentObjId="15" parentObjType="function" what="parameter">
+      <parameter alias="" id="21" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="15.6665096283" />
+    </add>
+    <add id="71" objectId="14" parentObjId="15" parentObjType="module" what="function">
+      <function id="14" name="SetPosition" pos="0" />
+    </add>
+    <add id="72" objectId="20" parentObjId="14" parentObjType="function" what="parameter">
+      <parameter alias="" id="20" name="<no description>" pos="2" type="edu.utah.sci.vistrails.basic:Float" val="129.680115965" />
+    </add>
+    <add id="73" objectId="19" parentObjId="14" parentObjType="function" what="parameter">
+      <parameter alias="" id="19" name="<no description>" pos="1" type="edu.utah.sci.vistrails.basic:Float" val="34.1978228456" />
+    </add>
+    <add id="74" objectId="18" parentObjId="14" parentObjType="function" what="parameter">
+      <parameter alias="" id="18" name="<no description>" pos="0" type="edu.utah.sci.vistrails.basic:Float" val="207.960620311" />
+    </add>
+    <add id="75" objectId="15" parentObjId="15" parentObjType="module" what="location">
+      <location id="15" x="10.9849467438" y="5.790542473" />
+    </add>
+    <add id="76" objectId="0" parentObjId="" parentObjType="" what="connection">
+      <connection id="0" />
+    </add>
+    <add id="77" objectId="1" parentObjId="0" parentObjType="connection" what="port">
+      <port id="1" moduleId="9" moduleName="vtkPolyDataNormals" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="78" objectId="0" parentObjId="0" parentObjType="connection" what="port">
+      <port id="0" moduleId="7" moduleName="vtkStripper" name="SetInputConnection0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="79" objectId="1" parentObjId="" parentObjType="" what="connection">
+      <connection id="1" />
+    </add>
+    <add id="80" objectId="3" parentObjId="1" parentObjType="connection" what="port">
+      <port id="3" moduleId="5" moduleName="vtkContourFilter" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="81" objectId="2" parentObjId="1" parentObjType="connection" what="port">
+      <port id="2" moduleId="9" moduleName="vtkPolyDataNormals" name="SetInputConnection0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="82" objectId="2" parentObjId="" parentObjType="" what="connection">
+      <connection id="2" />
+    </add>
+    <add id="83" objectId="5" parentObjId="2" parentObjType="connection" what="port">
+      <port id="5" moduleId="10" moduleName="vtkImageMapToColors" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="84" objectId="4" parentObjId="2" parentObjType="connection" what="port">
+      <port id="4" moduleId="1" moduleName="vtkProbeFilter" name="SetInputConnection1" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="85" objectId="3" parentObjId="" parentObjType="" what="connection">
+      <connection id="3" />
+    </add>
+    <add id="86" objectId="7" parentObjId="3" parentObjType="connection" what="port">
+      <port id="7" moduleId="0" moduleName="vtkDataSetReader" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="87" objectId="6" parentObjId="3" parentObjType="connection" what="port">
+      <port id="6" moduleId="10" moduleName="vtkImageMapToColors" name="SetInputConnection0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="88" objectId="4" parentObjId="" parentObjType="" what="connection">
+      <connection id="4" />
+    </add>
+    <add id="89" objectId="9" parentObjId="4" parentObjType="connection" what="port">
+      <port id="9" moduleId="8" moduleName="vtkLookupTable" name="self" signature="(edu.utah.sci.vistrails.vtk:vtkLookupTable)" type="source" />
+    </add>
+    <add id="90" objectId="8" parentObjId="4" parentObjType="connection" what="port">
+      <port id="8" moduleId="10" moduleName="vtkImageMapToColors" name="SetLookupTable" signature="(edu.utah.sci.vistrails.vtk:vtkScalarsToColors)" type="destination" />
+    </add>
+    <add id="91" objectId="5" parentObjId="" parentObjType="" what="connection">
+      <connection id="5" />
+    </add>
+    <add id="92" objectId="11" parentObjId="5" parentObjType="connection" what="port">
+      <port id="11" moduleId="1" moduleName="vtkProbeFilter" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="93" objectId="10" parentObjId="5" parentObjType="connection" what="port">
+      <port id="10" moduleId="3" moduleName="vtkPolyDataMapper" name="SetInputConnection0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="94" objectId="6" parentObjId="" parentObjType="" what="connection">
+      <connection id="6" />
+    </add>
+    <add id="95" objectId="13" parentObjId="6" parentObjType="connection" what="port">
+      <port id="13" moduleId="2" moduleName="vtkProperty" name="self" signature="(edu.utah.sci.vistrails.vtk:vtkProperty)" type="source" />
+    </add>
+    <add id="96" objectId="12" parentObjId="6" parentObjType="connection" what="port">
+      <port id="12" moduleId="4" moduleName="vtkActor" name="SetProperty" signature="(edu.utah.sci.vistrails.vtk:vtkProperty)" type="destination" />
+    </add>
+    <add id="97" objectId="7" parentObjId="" parentObjType="" what="connection">
+      <connection id="7" />
+    </add>
+    <add id="98" objectId="15" parentObjId="7" parentObjType="connection" what="port">
+      <port id="15" moduleId="3" moduleName="vtkPolyDataMapper" name="self" signature="(edu.utah.sci.vistrails.vtk:vtkPolyDataMapper)" type="source" />
+    </add>
+    <add id="99" objectId="14" parentObjId="7" parentObjType="connection" what="port">
+      <port id="14" moduleId="4" moduleName="vtkActor" name="SetMapper" signature="(edu.utah.sci.vistrails.vtk:vtkMapper)" type="destination" />
+    </add>
+    <add id="100" objectId="8" parentObjId="" parentObjType="" what="connection">
+      <connection id="8" />
+    </add>
+    <add id="101" objectId="17" parentObjId="8" parentObjType="connection" what="port">
+      <port id="17" moduleId="6" moduleName="vtkDataSetReader" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="102" objectId="16" parentObjId="8" parentObjType="connection" what="port">
+      <port id="16" moduleId="5" moduleName="vtkContourFilter" name="SetInputConnection0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="103" objectId="9" parentObjId="" parentObjType="" what="connection">
+      <connection id="9" />
+    </add>
+    <add id="104" objectId="19" parentObjId="9" parentObjType="connection" what="port">
+      <port id="19" moduleId="7" moduleName="vtkStripper" name="GetOutputPort0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="105" objectId="18" parentObjId="9" parentObjType="connection" what="port">
+      <port id="18" moduleId="1" moduleName="vtkProbeFilter" name="SetInputConnection0" signature="(edu.utah.sci.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="106" objectId="10" parentObjId="" parentObjType="" what="connection">
+      <connection id="10" />
+    </add>
+    <add id="107" objectId="21" parentObjId="10" parentObjType="connection" what="port">
+      <port id="21" moduleId="6" moduleName="vtkDataSetReader" name="SetFile" signature="(edu.utah.sci.vistrails.basic:File)" type="destination" />
+    </add>
+    <add id="108" objectId="20" parentObjId="10" parentObjType="connection" what="port">
+      <port id="20" moduleId="11" moduleName="HTTPFile" name="file" signature="(edu.utah.sci.vistrails.basic:File)" type="source" />
+    </add>
+    <add id="109" objectId="11" parentObjId="" parentObjType="" what="connection">
+      <connection id="11" />
+    </add>
+    <add id="110" objectId="23" parentObjId="11" parentObjType="connection" what="port">
+      <port id="23" moduleId="0" moduleName="vtkDataSetReader" name="SetFile" signature="(edu.utah.sci.vistrails.basic:File)" type="destination" />
+    </add>
+    <add id="111" objectId="22" parentObjId="11" parentObjType="connection" what="port">
+      <port id="22" moduleId="12" moduleName="HTTPFile" name="file" signature="(edu.utah.sci.vistrails.basic:File)" type="source" />
+    </add>
+    <add id="112" objectId="12" parentObjId="" parentObjType="" what="connection">
+      <connection id="12" />
+    </add>
+    <add id="113" objectId="25" parentObjId="12" parentObjType="connection" what="port">
+      <port id="25" moduleId="13" moduleName="vtkRenderer" name="AddActor" signature="(edu.utah.sci.vistrails.vtk:vtkProp)" type="destination" />
+    </add>
+    <add id="114" objectId="24" parentObjId="12" parentObjType="connection" what="port">
+      <port id="24" moduleId="4" moduleName="vtkActor" name="self" signature="(edu.utah.sci.vistrails.vtk:vtkActor)" type="source" />
+    </add>
+    <add id="115" objectId="13" parentObjId="" parentObjType="" what="connection">
+      <connection id="13" />
+    </add>
+    <add id="116" objectId="27" parentObjId="13" parentObjType="connection" what="port">
+      <port id="27" moduleId="14" moduleName="VTKCell" name="AddRenderer" signature="(edu.utah.sci.vistrails.vtk:vtkRenderer)" type="destination" />
+    </add>
+    <add id="117" objectId="26" parentObjId="13" parentObjType="connection" what="port">
+      <port id="26" moduleId="13" moduleName="vtkRenderer" name="self" signature="(edu.utah.sci.vistrails.vtk:vtkRenderer)" type="source" />
+    </add>
+    <add id="118" objectId="14" parentObjId="" parentObjType="" what="connection">
+      <connection id="14" />
+    </add>
+    <add id="119" objectId="29" parentObjId="14" parentObjType="connection" what="port">
+      <port id="29" moduleId="13" moduleName="vtkRenderer" name="SetActiveCamera" signature="(edu.utah.sci.vistrails.vtk:vtkCamera)" type="destination" />
+    </add>
+    <add id="120" objectId="28" parentObjId="14" parentObjType="connection" what="port">
+      <port id="28" moduleId="15" moduleName="vtkCamera" name="self" signature="(edu.utah.sci.vistrails.vtk:vtkCamera)" type="source" />
+    </add>
+  </action>
+  <action date="2015-03-18 16:26:33" id="2" prevId="1" session="0" user="Remi">
+    <annotation id="2" key="__description__" value="Upgrade" />
+    <delete id="121" objectId="25" parentObjId="12" parentObjType="connection" what="port" />
+    <delete id="122" objectId="24" parentObjId="12" parentObjType="connection" what="port" />
+    <delete id="123" objectId="12" parentObjId="" parentObjType="" what="connection" />
+    <delete id="124" objectId="13" parentObjId="6" parentObjType="connection" what="port" />
+    <delete id="125" objectId="12" parentObjId="6" parentObjType="connection" what="port" />
+    <delete id="126" objectId="6" parentObjId="" parentObjType="" what="connection" />
+    <delete id="127" objectId="15" parentObjId="7" parentObjType="connection" what="port" />
+    <delete id="128" objectId="14" parentObjId="7" parentObjType="connection" what="port" />
+    <delete id="129" objectId="7" parentObjId="" parentObjType="" what="connection" />
+    <delete id="130" objectId="4" parentObjId="4" parentObjType="module" what="location" />
+    <delete id="131" objectId="4" parentObjId="" parentObjType="" what="module" />
+    <delete id="132" objectId="17" parentObjId="8" parentObjType="connection" what="port" />
+    <delete id="133" objectId="16" parentObjId="8" parentObjType="connection" what="port" />
+    <delete id="134" objectId="8" parentObjId="" parentObjType="" what="connection" />
+    <delete id="135" objectId="3" parentObjId="1" parentObjType="connection" what="port" />
+    <delete id="136" objectId="2" parentObjId="1" parentObjType="connection" what="port" />
+    <delete id="137" objectId="1" parentObjId="" parentObjType="" what="connection" />
+    <delete id="138" objectId="5" parentObjId="5" parentObjType="module" what="location" />
+    <delete id="139" objectId="6" parentObjId="5" parentObjType="function" what="parameter" />
+    <delete id="140" objectId="7" parentObjId="5" parentObjType="function" what="parameter" />
+    <delete id="141" objectId="5" parentObjId="5" parentObjType="module" what="function" />
+    <delete id="142" objectId="5" parentObjId="" parentObjType="" what="module" />
+    <delete id="143" objectId="21" parentObjId="10" parentObjType="connection" what="port" />
+    <delete id="144" objectId="20" parentObjId="10" parentObjType="connection" what="port" />
+    <delete id="145" objectId="10" parentObjId="" parentObjType="" what="connection" />
+    <delete id="146" objectId="6" parentObjId="6" parentObjType="module" what="location" />
+    <delete id="147" objectId="6" parentObjId="" parentObjType="" what="module" />
+    <delete id="148" objectId="1" parentObjId="0" parentObjType="connection" what="port" />
+    <delete id="149" objectId="0" parentObjId="0" parentObjType="connection" what="port" />
+    <delete id="150" objectId="0" parentObjId="" parentObjType="" what="connection" />
+    <delete id="151" objectId="19" parentObjId="9" parentObjType="connection" what="port" />
+    <delete id="152" objectId="18" parentObjId="9" parentObjType="connection" what="port" />
+    <delete id="153" objectId="9" parentObjId="" parentObjType="" what="connection" />
+    <delete id="154" objectId="7" parentObjId="7" parentObjType="module" what="location" />
+    <delete id="155" objectId="7" parentObjId="" parentObjType="" what="module" />
+    <delete id="156" objectId="9" parentObjId="4" parentObjType="connection" what="port" />
+    <delete id="157" objectId="8" parentObjId="4" parentObjType="connection" what="port" />
+    <delete id="158" objectId="4" parentObjId="" parentObjType="" what="connection" />
+    <delete id="159" objectId="8" parentObjId="8" parentObjType="module" what="location" />
+    <delete id="160" objectId="8" parentObjId="6" parentObjType="function" what="parameter" />
+    <delete id="161" objectId="9" parentObjId="6" parentObjType="function" what="parameter" />
+    <delete id="162" objectId="6" parentObjId="8" parentObjType="module" what="function" />
+    <delete id="163" objectId="10" parentObjId="7" parentObjType="function" what="parameter" />
+    <delete id="164" objectId="11" parentObjId="7" parentObjType="function" what="parameter" />
+    <delete id="165" objectId="7" parentObjId="8" parentObjType="module" what="function" />
+    <delete id="166" objectId="12" parentObjId="8" parentObjType="function" what="parameter" />
+    <delete id="167" objectId="13" parentObjId="8" parentObjType="function" what="parameter" />
+    <delete id="168" objectId="8" parentObjId="8" parentObjType="module" what="function" />
+    <delete id="169" objectId="8" parentObjId="" parentObjType="" what="module" />
+    <delete id="170" objectId="29" parentObjId="14" parentObjType="connection" what="port" />
+    <delete id="171" objectId="28" parentObjId="14" parentObjType="connection" what="port" />
+    <delete id="172" objectId="14" parentObjId="" parentObjType="" what="connection" />
+    <delete id="173" objectId="15" parentObjId="15" parentObjType="module" what="location" />
+    <delete id="174" objectId="24" parentObjId="16" parentObjType="function" what="parameter" />
+    <delete id="175" objectId="25" parentObjId="16" parentObjType="function" what="parameter" />
+    <delete id="176" objectId="26" parentObjId="16" parentObjType="function" what="parameter" />
+    <delete id="177" objectId="16" parentObjId="15" parentObjType="module" what="function" />
+    <delete id="178" objectId="21" parentObjId="15" parentObjType="function" what="parameter" />
+    <delete id="179" objectId="22" parentObjId="15" parentObjType="function" what="parameter" />
+    <delete id="180" objectId="23" parentObjId="15" parentObjType="function" what="parameter" />
+    <delete id="181" objectId="15" parentObjId="15" parentObjType="module" what="function" />
+    <delete id="182" objectId="18" parentObjId="14" parentObjType="function" what="parameter" />
+    <delete id="183" objectId="19" parentObjId="14" parentObjType="function" what="parameter" />
+    <delete id="184" objectId="20" parentObjId="14" parentObjType="function" what="parameter" />
+    <delete id="185" objectId="14" parentObjId="15" parentObjType="module" what="function" />
+    <delete id="186" objectId="15" parentObjId="" parentObjType="" what="module" />
+    <delete id="187" objectId="9" parentObjId="9" parentObjType="module" what="location" />
+    <delete id="188" objectId="14" parentObjId="9" parentObjType="function" what="parameter" />
+    <delete id="189" objectId="9" parentObjId="9" parentObjType="module" what="function" />
+    <delete id="190" objectId="9" parentObjId="" parentObjType="" what="module" />
+    <delete id="191" objectId="5" parentObjId="2" parentObjType="connection" what="port" />
+    <delete id="192" objectId="4" parentObjId="2" parentObjType="connection" what="port" />
+    <delete id="193" objectId="2" parentObjId="" parentObjType="" what="connection" />
+    <delete id="194" objectId="7" parentObjId="3" parentObjType="connection" what="port" />
+    <delete id="195" objectId="6" parentObjId="3" parentObjType="connection" what="port" />
+    <delete id="196" objectId="3" parentObjId="" parentObjType="" what="connection" />
+    <delete id="197" objectId="10" parentObjId="10" parentObjType="module" what="location" />
+    <delete id="198" objectId="10" parentObjId="10" parentObjType="module" what="function" />
+    <delete id="199" objectId="10" parentObjId="" parentObjType="" what="module" />
+    <delete id="200" objectId="27" parentObjId="13" parentObjType="connection" what="port" />
+    <delete id="201" objectId="26" parentObjId="13" parentObjType="connection" what="port" />
+    <delete id="202" objectId="13" parentObjId="" parentObjType="" what="connection" />
+    <delete id="203" objectId="13" parentObjId="13" parentObjType="module" what="location" />
+    <delete id="204" objectId="17" parentObjId="13" parentObjType="function" what="parameter" />
+    <delete id="205" objectId="13" parentObjId="13" parentObjType="module" what="function" />
+    <delete id="206" objectId="13" parentObjId="" parentObjType="" what="module" />
+    <delete id="207" objectId="14" parentObjId="14" parentObjType="module" what="location" />
+    <delete id="208" objectId="14" parentObjId="" parentObjType="" what="module" />
+    <delete id="209" objectId="23" parentObjId="11" parentObjType="connection" what="port" />
+    <delete id="210" objectId="22" parentObjId="11" parentObjType="connection" what="port" />
+    <delete id="211" objectId="11" parentObjId="" parentObjType="" what="connection" />
+    <delete id="212" objectId="0" parentObjId="0" parentObjType="module" what="location" />
+    <delete id="213" objectId="0" parentObjId="" parentObjType="" what="module" />
+    <delete id="214" objectId="11" parentObjId="5" parentObjType="connection" what="port" />
+    <delete id="215" objectId="10" parentObjId="5" parentObjType="connection" what="port" />
+    <delete id="216" objectId="5" parentObjId="" parentObjType="" what="connection" />
+    <delete id="217" objectId="1" parentObjId="1" parentObjType="module" what="location" />
+    <delete id="218" objectId="1" parentObjId="" parentObjType="" what="module" />
+    <delete id="219" objectId="2" parentObjId="2" parentObjType="module" what="location" />
+    <delete id="220" objectId="0" parentObjId="0" parentObjType="function" what="parameter" />
+    <delete id="221" objectId="1" parentObjId="0" parentObjType="function" what="parameter" />
+    <delete id="222" objectId="2" parentObjId="0" parentObjType="function" what="parameter" />
+    <delete id="223" objectId="0" parentObjId="2" parentObjType="module" what="function" />
+    <delete id="224" objectId="3" parentObjId="1" parentObjType="function" what="parameter" />
+    <delete id="225" objectId="1" parentObjId="2" parentObjType="module" what="function" />
+    <delete id="226" objectId="4" parentObjId="2" parentObjType="function" what="parameter" />
+    <delete id="227" objectId="2" parentObjId="2" parentObjType="module" what="function" />
+    <delete id="228" objectId="5" parentObjId="3" parentObjType="function" what="parameter" />
+    <delete id="229" objectId="3" parentObjId="2" parentObjType="module" what="function" />
+    <delete id="230" objectId="2" parentObjId="" parentObjType="" what="module" />
+    <delete id="231" objectId="3" parentObjId="3" parentObjType="module" what="location" />
+    <delete id="232" objectId="4" parentObjId="3" parentObjType="module" what="function" />
+    <delete id="233" objectId="3" parentObjId="" parentObjType="" what="module" />
+    <delete id="234" objectId="12" parentObjId="12" parentObjType="module" what="location" />
+    <delete id="235" objectId="16" parentObjId="12" parentObjType="function" what="parameter" />
+    <delete id="236" objectId="12" parentObjId="12" parentObjType="module" what="function" />
+    <delete id="237" objectId="12" parentObjId="" parentObjType="" what="module" />
+    <delete id="238" objectId="11" parentObjId="11" parentObjType="module" what="location" />
+    <delete id="239" objectId="15" parentObjId="11" parentObjType="function" what="parameter" />
+    <delete id="240" objectId="11" parentObjId="11" parentObjType="module" what="function" />
+    <delete id="241" objectId="11" parentObjId="" parentObjType="" what="module" />
+    <add id="242" objectId="32" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="32" name="vtkActor" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="243" objectId="32" parentObjId="32" parentObjType="module" what="location">
+      <location id="32" x="106.360127696" y="-407.425503999" />
+    </add>
+    <add id="244" objectId="33" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="33" name="vtkContourFilter" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="245" objectId="34" parentObjId="33" parentObjType="module" what="function">
+      <function id="34" name="SetValue" pos="0" />
+    </add>
+    <add id="246" objectId="55" parentObjId="34" parentObjType="function" what="parameter">
+      <parameter alias="" id="55" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="0.6" />
+    </add>
+    <add id="247" objectId="54" parentObjId="34" parentObjType="function" what="parameter">
+      <parameter alias="" id="54" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Integer" val="0" />
+    </add>
+    <add id="248" objectId="33" parentObjId="33" parentObjType="module" what="location">
+      <location id="33" x="-297.271265348" y="191.884461486" />
+    </add>
+    <add id="249" objectId="34" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="34" name="vtkDataSetReader" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="250" objectId="34" parentObjId="34" parentObjType="module" what="location">
+      <location id="34" x="-375.540899841" y="321.858350831" />
+    </add>
+    <add id="251" objectId="50" parentObjId="" parentObjType="" what="connection">
+      <connection id="50" />
+    </add>
+    <add id="252" objectId="100" parentObjId="50" parentObjType="connection" what="port">
+      <port id="100" moduleId="34" moduleName="vtkDataSetReader" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="253" objectId="101" parentObjId="50" parentObjType="connection" what="port">
+      <port id="101" moduleId="33" moduleName="vtkContourFilter" name="SetInputConnection0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="254" objectId="35" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="35" name="vtkStripper" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="255" objectId="35" parentObjId="35" parentObjType="module" what="location">
+      <location id="35" x="-89.561012773" y="-51.0120756165" />
+    </add>
+    <add id="256" objectId="36" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="36" name="vtkLookupTable" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="257" objectId="37" parentObjId="36" parentObjType="module" what="function">
+      <function id="37" name="SetValueRange" pos="2" />
+    </add>
+    <add id="258" objectId="61" parentObjId="37" parentObjType="function" what="parameter">
+      <parameter alias="" id="61" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="1" />
+    </add>
+    <add id="259" objectId="60" parentObjId="37" parentObjType="function" what="parameter">
+      <parameter alias="" id="60" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="1" />
+    </add>
+    <add id="260" objectId="36" parentObjId="36" parentObjType="module" what="function">
+      <function id="36" name="SetSaturationRange" pos="1" />
+    </add>
+    <add id="261" objectId="59" parentObjId="36" parentObjType="function" what="parameter">
+      <parameter alias="" id="59" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="0.7" />
+    </add>
+    <add id="262" objectId="58" parentObjId="36" parentObjType="function" what="parameter">
+      <parameter alias="" id="58" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="0.3" />
+    </add>
+    <add id="263" objectId="35" parentObjId="36" parentObjType="module" what="function">
+      <function id="35" name="SetHueRange" pos="0" />
+    </add>
+    <add id="264" objectId="57" parentObjId="35" parentObjType="function" what="parameter">
+      <parameter alias="" id="57" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="0.8" />
+    </add>
+    <add id="265" objectId="56" parentObjId="35" parentObjType="function" what="parameter">
+      <parameter alias="" id="56" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="0.0" />
+    </add>
+    <add id="266" objectId="36" parentObjId="36" parentObjType="module" what="location">
+      <location id="36" x="342.555572474" y="277.738213963" />
+    </add>
+    <add id="267" objectId="37" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="37" name="vtkCamera" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="268" objectId="40" parentObjId="37" parentObjType="module" what="function">
+      <function id="40" name="SetPosition" pos="2" />
+    </add>
+    <add id="269" objectId="70" parentObjId="40" parentObjType="function" what="parameter">
+      <parameter alias="" id="70" name="<no description>" pos="2" type="org.vistrails.vistrails.basic:Float" val="129.680115965" />
+    </add>
+    <add id="270" objectId="69" parentObjId="40" parentObjType="function" what="parameter">
+      <parameter alias="" id="69" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="34.1978228456" />
+    </add>
+    <add id="271" objectId="68" parentObjId="40" parentObjType="function" what="parameter">
+      <parameter alias="" id="68" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="207.960620311" />
+    </add>
+    <add id="272" objectId="39" parentObjId="37" parentObjType="module" what="function">
+      <function id="39" name="SetFocalPoint" pos="1" />
+    </add>
+    <add id="273" objectId="67" parentObjId="39" parentObjType="function" what="parameter">
+      <parameter alias="" id="67" name="<no description>" pos="2" type="org.vistrails.vistrails.basic:Float" val="39.9909629822" />
+    </add>
+    <add id="274" objectId="66" parentObjId="39" parentObjType="function" what="parameter">
+      <parameter alias="" id="66" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="40.4209948182" />
+    </add>
+    <add id="275" objectId="65" parentObjId="39" parentObjType="function" what="parameter">
+      <parameter alias="" id="65" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="15.6665096283" />
+    </add>
+    <add id="276" objectId="38" parentObjId="37" parentObjType="module" what="function">
+      <function id="38" name="SetViewUp" pos="0" />
+    </add>
+    <add id="277" objectId="64" parentObjId="38" parentObjType="function" what="parameter">
+      <parameter alias="" id="64" name="<no description>" pos="2" type="org.vistrails.vistrails.basic:Float" val="0.00760380579491" />
+    </add>
+    <add id="278" objectId="63" parentObjId="38" parentObjType="function" what="parameter">
+      <parameter alias="" id="63" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="0.999556218535" />
+    </add>
+    <add id="279" objectId="62" parentObjId="38" parentObjType="function" what="parameter">
+      <parameter alias="" id="62" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="0.0288018771004" />
+    </add>
+    <add id="280" objectId="37" parentObjId="37" parentObjType="module" what="location">
+      <location id="37" x="10.9849467438" y="5.790542473" />
+    </add>
+    <add id="281" objectId="38" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="38" name="vtkPolyDataNormals" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="282" objectId="41" parentObjId="38" parentObjType="module" what="function">
+      <function id="41" name="SetFeatureAngle" pos="0" />
+    </add>
+    <add id="283" objectId="71" parentObjId="41" parentObjType="function" what="parameter">
+      <parameter alias="" id="71" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="60.0" />
+    </add>
+    <add id="284" objectId="38" parentObjId="38" parentObjType="module" what="location">
+      <location id="38" x="-264.040430273" y="69.8324666965" />
+    </add>
+    <add id="285" objectId="56" parentObjId="" parentObjType="" what="connection">
+      <connection id="56" />
+    </add>
+    <add id="286" objectId="112" parentObjId="56" parentObjType="connection" what="port">
+      <port id="112" moduleId="38" moduleName="vtkPolyDataNormals" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="287" objectId="113" parentObjId="56" parentObjType="connection" what="port">
+      <port id="113" moduleId="35" moduleName="vtkStripper" name="SetInputConnection0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="288" objectId="57" parentObjId="" parentObjType="" what="connection">
+      <connection id="57" />
+    </add>
+    <add id="289" objectId="114" parentObjId="57" parentObjType="connection" what="port">
+      <port id="114" moduleId="33" moduleName="vtkContourFilter" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="290" objectId="115" parentObjId="57" parentObjType="connection" what="port">
+      <port id="115" moduleId="38" moduleName="vtkPolyDataNormals" name="SetInputConnection0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="291" objectId="39" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="39" name="vtkImageMapToColors" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="292" objectId="42" parentObjId="39" parentObjType="module" what="function">
+      <function id="42" name="SetOutputFormatToRGBA" pos="0" />
+    </add>
+    <add id="293" objectId="39" parentObjId="39" parentObjType="module" what="location">
+      <location id="39" x="164.143215358" y="89.9107917395" />
+    </add>
+    <add id="294" objectId="60" parentObjId="" parentObjType="" what="connection">
+      <connection id="60" />
+    </add>
+    <add id="295" objectId="120" parentObjId="60" parentObjType="connection" what="port">
+      <port id="120" moduleId="36" moduleName="vtkLookupTable" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkLookupTable)" type="source" />
+    </add>
+    <add id="296" objectId="121" parentObjId="60" parentObjType="connection" what="port">
+      <port id="121" moduleId="39" moduleName="vtkImageMapToColors" name="SetLookupTable" signature="(org.vistrails.vistrails.vtk:vtkScalarsToColors)" type="destination" />
+    </add>
+    <add id="297" objectId="40" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="40" name="vtkRenderer" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="298" objectId="43" parentObjId="40" parentObjType="module" what="function">
+      <function id="43" name="SetBackgroundWidget" pos="0" />
+    </add>
+    <add id="299" objectId="72" parentObjId="43" parentObjType="function" what="parameter">
+      <parameter alias="" id="72" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Color" val="1.0,1.0,1.0" />
+    </add>
+    <add id="300" objectId="40" parentObjId="40" parentObjType="module" what="location">
+      <location id="40" x="159.362077975" y="-500.340338504" />
+    </add>
+    <add id="301" objectId="62" parentObjId="" parentObjType="" what="connection">
+      <connection id="62" />
+    </add>
+    <add id="302" objectId="124" parentObjId="62" parentObjType="connection" what="port">
+      <port id="124" moduleId="32" moduleName="vtkActor" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkActor)" type="source" />
+    </add>
+    <add id="303" objectId="125" parentObjId="62" parentObjType="connection" what="port">
+      <port id="125" moduleId="40" moduleName="vtkRenderer" name="AddActor" signature="(org.vistrails.vistrails.vtk:vtkProp)" type="destination" />
+    </add>
+    <add id="304" objectId="63" parentObjId="" parentObjType="" what="connection">
+      <connection id="63" />
+    </add>
+    <add id="305" objectId="126" parentObjId="63" parentObjType="connection" what="port">
+      <port id="126" moduleId="37" moduleName="vtkCamera" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkCamera)" type="source" />
+    </add>
+    <add id="306" objectId="127" parentObjId="63" parentObjType="connection" what="port">
+      <port id="127" moduleId="40" moduleName="vtkRenderer" name="SetActiveCamera" signature="(org.vistrails.vistrails.vtk:vtkCamera)" type="destination" />
+    </add>
+    <add id="307" objectId="41" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="41" name="VTKCell" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="308" objectId="41" parentObjId="41" parentObjType="module" what="location">
+      <location id="41" x="154.657025704" y="-637.584582668" />
+    </add>
+    <add id="309" objectId="64" parentObjId="" parentObjType="" what="connection">
+      <connection id="64" />
+    </add>
+    <add id="310" objectId="128" parentObjId="64" parentObjType="connection" what="port">
+      <port id="128" moduleId="40" moduleName="vtkRenderer" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkRenderer)" type="source" />
+    </add>
+    <add id="311" objectId="129" parentObjId="64" parentObjType="connection" what="port">
+      <port id="129" moduleId="41" moduleName="VTKCell" name="AddRenderer" signature="(org.vistrails.vistrails.vtk:vtkRenderer)" type="destination" />
+    </add>
+    <add id="312" objectId="42" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="42" name="vtkDataSetReader" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="313" objectId="42" parentObjId="42" parentObjType="module" what="location">
+      <location id="42" x="19.9868870813" y="264.359717931" />
+    </add>
+    <add id="314" objectId="65" parentObjId="" parentObjType="" what="connection">
+      <connection id="65" />
+    </add>
+    <add id="315" objectId="130" parentObjId="65" parentObjType="connection" what="port">
+      <port id="130" moduleId="42" moduleName="vtkDataSetReader" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="316" objectId="131" parentObjId="65" parentObjType="connection" what="port">
+      <port id="131" moduleId="39" moduleName="vtkImageMapToColors" name="SetInputConnection0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="317" objectId="43" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="43" name="vtkProbeFilter" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="318" objectId="43" parentObjId="43" parentObjType="module" what="location">
+      <location id="43" x="97.5027154606" y="-125.404765168" />
+    </add>
+    <add id="319" objectId="68" parentObjId="" parentObjType="" what="connection">
+      <connection id="68" />
+    </add>
+    <add id="320" objectId="136" parentObjId="68" parentObjType="connection" what="port">
+      <port id="136" moduleId="35" moduleName="vtkStripper" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="321" objectId="137" parentObjId="68" parentObjType="connection" what="port">
+      <port id="137" moduleId="43" moduleName="vtkProbeFilter" name="SetInputConnection0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="322" objectId="69" parentObjId="" parentObjType="" what="connection">
+      <connection id="69" />
+    </add>
+    <add id="323" objectId="138" parentObjId="69" parentObjType="connection" what="port">
+      <port id="138" moduleId="39" moduleName="vtkImageMapToColors" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="324" objectId="139" parentObjId="69" parentObjType="connection" what="port">
+      <port id="139" moduleId="43" moduleName="vtkProbeFilter" name="SetInputConnection1" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="325" objectId="44" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="44" name="vtkProperty" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="326" objectId="47" parentObjId="44" parentObjType="module" what="function">
+      <function id="47" name="SetOpacity" pos="3" />
+    </add>
+    <add id="327" objectId="78" parentObjId="47" parentObjType="function" what="parameter">
+      <parameter alias="" id="78" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="0.7" />
+    </add>
+    <add id="328" objectId="46" parentObjId="44" parentObjType="module" what="function">
+      <function id="46" name="SetSpecularPower" pos="2" />
+    </add>
+    <add id="329" objectId="77" parentObjId="46" parentObjType="function" what="parameter">
+      <parameter alias="" id="77" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="20.0" />
+    </add>
+    <add id="330" objectId="45" parentObjId="44" parentObjType="module" what="function">
+      <function id="45" name="SetSpecular" pos="1" />
+    </add>
+    <add id="331" objectId="76" parentObjId="45" parentObjType="function" what="parameter">
+      <parameter alias="" id="76" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="0.3" />
+    </add>
+    <add id="332" objectId="44" parentObjId="44" parentObjType="module" what="function">
+      <function id="44" name="SetDiffuseColor" pos="0" />
+    </add>
+    <add id="333" objectId="75" parentObjId="44" parentObjType="function" what="parameter">
+      <parameter alias="" id="75" name="<no description>" pos="2" type="org.vistrails.vistrails.basic:Float" val="0.25" />
+    </add>
+    <add id="334" objectId="74" parentObjId="44" parentObjType="function" what="parameter">
+      <parameter alias="" id="74" name="<no description>" pos="1" type="org.vistrails.vistrails.basic:Float" val="0.49" />
+    </add>
+    <add id="335" objectId="73" parentObjId="44" parentObjType="function" what="parameter">
+      <parameter alias="" id="73" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:Float" val="1.0" />
+    </add>
+    <add id="336" objectId="44" parentObjId="44" parentObjType="module" what="location">
+      <location id="44" x="318.026813133" y="-308.312673027" />
+    </add>
+    <add id="337" objectId="70" parentObjId="" parentObjType="" what="connection">
+      <connection id="70" />
+    </add>
+    <add id="338" objectId="140" parentObjId="70" parentObjType="connection" what="port">
+      <port id="140" moduleId="44" moduleName="vtkProperty" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkProperty)" type="source" />
+    </add>
+    <add id="339" objectId="141" parentObjId="70" parentObjType="connection" what="port">
+      <port id="141" moduleId="32" moduleName="vtkActor" name="SetProperty" signature="(org.vistrails.vistrails.vtk:vtkProperty)" type="destination" />
+    </add>
+    <add id="340" objectId="45" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="45" name="vtkPolyDataMapper" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="341" objectId="48" parentObjId="45" parentObjType="module" what="function">
+      <function id="48" name="ScalarVisibilityOn" pos="0" />
+    </add>
+    <add id="342" objectId="45" parentObjId="45" parentObjType="module" what="location">
+      <location id="45" x="98.6726912122" y="-259.733017637" />
+    </add>
+    <add id="343" objectId="71" parentObjId="" parentObjType="" what="connection">
+      <connection id="71" />
+    </add>
+    <add id="344" objectId="142" parentObjId="71" parentObjType="connection" what="port">
+      <port id="142" moduleId="45" moduleName="vtkPolyDataMapper" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkPolyDataMapper)" type="source" />
+    </add>
+    <add id="345" objectId="143" parentObjId="71" parentObjType="connection" what="port">
+      <port id="143" moduleId="32" moduleName="vtkActor" name="SetMapper" signature="(org.vistrails.vistrails.vtk:vtkMapper)" type="destination" />
+    </add>
+    <add id="346" objectId="72" parentObjId="" parentObjType="" what="connection">
+      <connection id="72" />
+    </add>
+    <add id="347" objectId="144" parentObjId="72" parentObjType="connection" what="port">
+      <port id="144" moduleId="43" moduleName="vtkProbeFilter" name="GetOutputPort0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="source" />
+    </add>
+    <add id="348" objectId="145" parentObjId="72" parentObjType="connection" what="port">
+      <port id="145" moduleId="45" moduleName="vtkPolyDataMapper" name="SetInputConnection0" signature="(org.vistrails.vistrails.vtk:vtkAlgorithmOutput)" type="destination" />
+    </add>
+    <add id="349" objectId="46" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="46" name="DownloadFile" namespace="" package="org.vistrails.vistrails.url" version="1.0.0" />
+    </add>
+    <add id="350" objectId="49" parentObjId="46" parentObjType="module" what="function">
+      <function id="49" name="url" pos="0" />
+    </add>
+    <add id="351" objectId="79" parentObjId="49" parentObjType="function" what="parameter">
+      <parameter alias="" id="79" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:String" val="http://www.vistrails.org/download/download.php?type=DATA&id=gktbhL123.vtk" />
+    </add>
+    <add id="352" objectId="46" parentObjId="46" parentObjType="module" what="location">
+      <location id="46" x="6.03904236942" y="437.732857835" />
+    </add>
+    <add id="353" objectId="73" parentObjId="" parentObjType="" what="connection">
+      <connection id="73" />
+    </add>
+    <add id="354" objectId="146" parentObjId="73" parentObjType="connection" what="port">
+      <port id="146" moduleId="46" moduleName="DownloadFile" name="file" signature="(org.vistrails.vistrails.basic:File)" type="source" />
+    </add>
+    <add id="355" objectId="147" parentObjId="73" parentObjType="connection" what="port">
+      <port id="147" moduleId="42" moduleName="vtkDataSetReader" name="SetFile" signature="(org.vistrails.vistrails.basic:File)" type="destination" />
+    </add>
+    <add id="356" objectId="47" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="47" name="DownloadFile" namespace="" package="org.vistrails.vistrails.url" version="1.0.0" />
+    </add>
+    <add id="357" objectId="50" parentObjId="47" parentObjType="module" what="function">
+      <function id="50" name="url" pos="0" />
+    </add>
+    <add id="358" objectId="80" parentObjId="50" parentObjType="function" what="parameter">
+      <parameter alias="" id="80" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:String" val="http://www.vistrails.org/download/download.php?type=DATA&id=gktbhFA.vtk" />
+    </add>
+    <add id="359" objectId="47" parentObjId="47" parentObjType="module" what="location">
+      <location id="47" x="-275.87750697" y="470.705553664" />
+    </add>
+    <add id="360" objectId="74" parentObjId="" parentObjType="" what="connection">
+      <connection id="74" />
+    </add>
+    <add id="361" objectId="148" parentObjId="74" parentObjType="connection" what="port">
+      <port id="148" moduleId="47" moduleName="DownloadFile" name="file" signature="(org.vistrails.vistrails.basic:File)" type="source" />
+    </add>
+    <add id="362" objectId="149" parentObjId="74" parentObjType="connection" what="port">
+      <port id="149" moduleId="34" moduleName="vtkDataSetReader" name="SetFile" signature="(org.vistrails.vistrails.basic:File)" type="destination" />
+    </add>
+  </action>
+  <action date="2015-03-18 16:26:33" id="3" prevId="2" session="0" user="Remi">
+    <delete id="363" objectId="128" parentObjId="64" parentObjType="connection" what="port" />
+    <delete id="364" objectId="129" parentObjId="64" parentObjType="connection" what="port" />
+    <delete id="365" objectId="64" parentObjId="" parentObjType="" what="connection" />
+    <delete id="366" objectId="41" parentObjId="41" parentObjType="module" what="location" />
+    <delete id="367" objectId="41" parentObjId="" parentObjType="" what="module" />
+  </action>
+  <action date="2015-03-18 16:26:39" id="4" prevId="3" session="0" user="Remi">
+    <add id="368" objectId="48" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="48" name="vtkRendererOutput" namespace="" package="org.vistrails.vistrails.vtk" version="0.9.5" />
+    </add>
+    <add id="369" objectId="48" parentObjId="48" parentObjType="module" what="location">
+      <location id="48" x="163.953643376" y="-644.103598976" />
+    </add>
+  </action>
+  <action date="2015-03-18 16:26:45" id="5" prevId="4" session="0" user="Remi">
+    <change id="370" newObjId="49" oldObjId="48" parentObjId="48" parentObjType="module" what="location">
+      <location id="49" x="162.001814288" y="-614.826162659" />
+    </change>
+  </action>
+  <action date="2015-03-18 16:26:45" id="6" prevId="5" session="0" user="Remi">
+    <add id="371" objectId="75" parentObjId="" parentObjType="" what="connection">
+      <connection id="75" />
+    </add>
+    <add id="372" objectId="150" parentObjId="75" parentObjType="connection" what="port">
+      <port id="150" moduleId="40" moduleName="vtkRenderer" name="Instance" signature="(org.vistrails.vistrails.vtk:vtkRenderer)" type="source" />
+    </add>
+    <add id="373" objectId="151" parentObjId="75" parentObjType="connection" what="port">
+      <port id="151" moduleId="48" moduleName="vtkRendererOutput" name="value" signature="(org.vistrails.vistrails.vtk:vtkRenderer)" type="destination" />
+    </add>
+  </action>
+  <actionAnnotation actionId="1" date="2015-03-18 16:26:33" id="3" key="__upgrade__" user="Remi" value="2" />
+</vistrail>
diff --git a/examples/api/imagemagick.vt b/examples/api/imagemagick.vt
new file mode 100644
index 0000000..2c8a660
Binary files /dev/null and b/examples/api/imagemagick.vt differ
diff --git a/examples/api/ipython-notebook.ipynb b/examples/api/ipython-notebook.ipynb
new file mode 100644
index 0000000..abedcc1
--- /dev/null
+++ b/examples/api/ipython-notebook.ipynb
@@ -0,0 +1,1350 @@
+{
+ "metadata": {
+  "name": "",
+  "signature": "sha256:60187fe17c0a32826b5856d40a5920f473bfc630c413d515bbfeb9180885a128"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# Sets up import path, if you're running from the source distrib\n",
+      "import os, sys\n",
+      "sys.path.append(os.path.join(os.getcwd(), '../..'))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import traceback"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 2
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "# VisTrails API example\n",
+      "\n",
+      "This notebook showcases the new API. Inlined are some comments and explanations."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import vistrails as vt"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The new API is exposed under the top-level `vistrails` package. The moment you use one of the API functions, like `load_vistrail()`, it will create an application and load the same configuration that the VisTrails application uses (although it will automatically enable packages the moment you need them)."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "## `Vistrail`s and `Pipeline`s\n",
+      "\n",
+      "You can get a `Vistrail` through `load_vistrail()`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vistrail = vt.load_vistrail('simplemath.vt')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "A `Vistrail` is a whole version tree, where each version is a different pipeline. From it we can get `Pipeline`s, but it is also stateful (i.e. has a current version); this is useful for editing (creating new versions from the current one). It also provides the interface that `Pipeline` has, implicitely acting on the `current_pipeline`.\n",
+      "\n",
+      "If GraphViz is available, `Vistrail` and `Pipeline` will be rendered in the IPython notebook."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vistrail"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: G Pages: 1 -->\r\n",
+        "<svg width=\"158pt\" height=\"116pt\"\r\n",
+        " viewBox=\"0.00 0.00 158.00 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\r\n",
+        "<title>G</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-112 155,-112 155,5 -4,5\"/>\r\n",
+        "<!-- 0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>0</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"75\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 28 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>28</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"75\" cy=\"-18\" rx=\"75.0904\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"75\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Added annotation</text>\r\n",
+        "</g>\r\n",
+        "<!-- 0->28 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>0->28</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M75,-71.6966C75,-63.9827 75,-54.7125 75,-46.1124\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"78.5001,-46.1043 75,-36.1043 71.5001,-46.1044 78.5001,-46.1043\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Vistrail: simplemath.vt, version -1, not changed></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 5,
+       "text": [
+        "<Vistrail: simplemath.vt, version -1, not changed>"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vistrail.select_latest_version()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vistrail"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: G Pages: 1 -->\r\n",
+        "<svg width=\"158pt\" height=\"116pt\"\r\n",
+        " viewBox=\"0.00 0.00 158.00 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\r\n",
+        "<title>G</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-112 155,-112 155,5 -4,5\"/>\r\n",
+        "<!-- 0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>0</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"75\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 28 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>28</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"red\" cx=\"75\" cy=\"-18\" rx=\"75.0904\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"75\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Added annotation</text>\r\n",
+        "</g>\r\n",
+        "<!-- 0->28 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>0->28</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M75,-71.6966C75,-63.9827 75,-54.7125 75,-46.1124\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"78.5001,-46.1043 75,-36.1043 71.5001,-46.1044 78.5001,-46.1043\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Vistrail: simplemath.vt, version 28, not changed></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 7,
+       "text": [
+        "<Vistrail: simplemath.vt, version 28, not changed>"
+       ]
+      }
+     ],
+     "prompt_number": 7
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vistrail.get_pipeline(2)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: _anonymous_0 Pages: 1 -->\r\n",
+        "<svg width=\"102pt\" height=\"44pt\"\r\n",
+        " viewBox=\"0.00 0.00 102.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\r\n",
+        "<title>_anonymous_0</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-40 99,-40 99,5 -4,5\"/>\r\n",
+        "<!-- module0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>module0</title>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"8,-7 8,-28 87,-28 87,-7 8,-7\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"8,-7 8,-28 87,-28 87,-7 8,-7\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"11.5\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">PythonCalc</text>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Pipeline: 1 modules, 0 connections></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 8,
+       "text": [
+        "<Pipeline: 1 modules, 0 connections>"
+       ]
+      }
+     ],
+     "prompt_number": 8
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "# Packages\n",
+      "\n",
+      "Only `basic_modules` (and `abstractions`?) are loaded on initialization, so that using the API stays fast. A package might be auto-enabled when it is requested, which is efficient and convenient.\n",
+      "\n",
+      "Note that `load_package()` only accepts package identifiers."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "tabledata = vt.load_package('org.vistrails.vistrails.tabledata')\n",
+      "tabledata"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 9,
+       "text": [
+        "<Package: org.vistrails.vistrails.tabledata, 23 modules>"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "You can get `Module`s from the package using the dot or bracket syntax. These modules are \"dangling\" modules, not yet instanciated in a specific pipeline/vistrail.\n",
+      "\n",
+      "These will be useful once editing pipelines is added to the API."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "tabledata.convert"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 10,
+       "text": [
+        "<Namespace convert of package org.vistrails.vistrails.tabledata>"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from vistrails.core.modules.module_registry import MissingModule\n",
+      "try:\n",
+      "    tabledata['convert']  # can't get namespaces this way, use a dot\n",
+      "except MissingModule:\n",
+      "    pass\n",
+      "else:\n",
+      "    assert False"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "tabledata.BuildTable, tabledata['BuildTable']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 12,
+       "text": [
+        "(vistrails.core.api.BuildTable, vistrails.core.api.BuildTable)"
+       ]
+      }
+     ],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "tabledata.read.CSVFile, tabledata['read|CSVFile']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 13,
+       "text": [
+        "(vistrails.core.api.CSVFile, vistrails.core.api.CSVFile)"
+       ]
+      }
+     ],
+     "prompt_number": 13
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "(note: [IPython bug 6709](https://github.com/ipython/ipython/issues/6709) causes the '`vistrails.core.api.`' prefixes above)"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "# Pipeline manipulation\n",
+      "\n",
+      "Unfortunately this is not yet available, stay tuned!"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "# Execution\n",
+      "\n",
+      "In addition to executing a `Pipeline` or `Vistrail`, you can easily pass values in on InputPort modules (to use subworkflows as Python functions) and get results out (either on OutputPort modules or any port of any module).\n",
+      "\n",
+      "Execution returns a `Results` object from which you can get all of this. In addition, output modules (such as matplotlib's MplFigureOutput) will output to the IPython notebook if possible."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "## Gets output"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "outputs = vt.load_vistrail('outputs.vt')\n",
+      "outputs.select_version(1)\n",
+      "outputs"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: G Pages: 1 -->\r\n",
+        "<svg width=\"154pt\" height=\"188pt\"\r\n",
+        " viewBox=\"0.00 0.00 154.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\r\n",
+        "<title>G</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-184 151,-184 151,5 -4,5\"/>\r\n",
+        "<!-- 0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>0</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"73\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 1 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>1</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"red\" cx=\"73\" cy=\"-90\" rx=\"64.4914\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"73\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Added module</text>\r\n",
+        "</g>\r\n",
+        "<!-- 0->1 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>0->1</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M73,-143.697C73,-135.983 73,-126.712 73,-118.112\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"76.5001,-118.104 73,-108.104 69.5001,-118.104 76.5001,-118.104\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 5 -->\r\n",
+        "<g id=\"node3\" class=\"node\"><title>5</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"73\" cy=\"-18\" rx=\"73.1654\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"73\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Added parameter</text>\r\n",
+        "</g>\r\n",
+        "<!-- 1->5 -->\r\n",
+        "<g id=\"edge4\" class=\"edge\"><title>1->5</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M73,-71.6966C73,-63.9827 73,-54.7125 73,-46.1124\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"76.5001,-46.1043 73,-36.1043 69.5001,-46.1044 76.5001,-46.1043\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Vistrail: outputs.vt, version 1, not changed></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 14,
+       "text": [
+        "<Vistrail: outputs.vt, version 1, not changed>"
+       ]
+      }
+     ],
+     "prompt_number": 14
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# Errors\n",
+      "try:\n",
+      "    result = outputs.execute()\n",
+      "except vt.ExecutionErrors:\n",
+      "    traceback.print_exc()\n",
+      "else:\n",
+      "    assert False"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stderr",
+       "text": [
+        "Traceback (most recent call last):\n",
+        "  File \"<ipython-input-15-979bf6416e43>\", line 3, in <module>\n",
+        "    result = outputs.execute()\n",
+        "  File \"C:\\programmation\\vistrails\\dat\\vistrails\\examples\\api\\../..\\vistrails\\core\\api.py\", line 243, in execute\n",
+        "    return self.current_pipeline.execute(*args, **kwargs)\n",
+        "  File \"C:\\programmation\\vistrails\\dat\\vistrails\\examples\\api\\../..\\vistrails\\core\\api.py\", line 462, in execute\n",
+        "    raise ExecutionErrors(self, result)\n",
+        "ExecutionErrors: Pipeline execution failed: 1 error:\n",
+        "0: Missing value from port value\n"
+       ]
+      }
+     ],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# Results\n",
+      "outputs.select_latest_version()\n",
+      "result = outputs.execute()\n",
+      "result"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 16,
+       "text": [
+        "<ExecutionResult: 2 modules>"
+       ]
+      }
+     ],
+     "prompt_number": 16
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "outputs"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: G Pages: 1 -->\r\n",
+        "<svg width=\"154pt\" height=\"116pt\"\r\n",
+        " viewBox=\"0.00 0.00 154.00 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\r\n",
+        "<title>G</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-112 151,-112 151,5 -4,5\"/>\r\n",
+        "<!-- 0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>0</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"73\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 5 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>5</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"red\" cx=\"73\" cy=\"-18\" rx=\"73.1654\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"73\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Added parameter</text>\r\n",
+        "</g>\r\n",
+        "<!-- 0->5 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>0->5</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M73,-71.6966C73,-63.9827 73,-54.7125 73,-46.1124\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"76.5001,-46.1043 73,-36.1043 69.5001,-46.1044 76.5001,-46.1043\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Vistrail: outputs.vt, version 5, changed></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 17,
+       "text": [
+        "<Vistrail: outputs.vt, version 5, changed>"
+       ]
+      }
+     ],
+     "prompt_number": 17
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "outputs.current_pipeline"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: _anonymous_0 Pages: 1 -->\r\n",
+        "<svg width=\"102pt\" height=\"152pt\"\r\n",
+        " viewBox=\"0.00 0.00 102.00 152.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 148)\">\r\n",
+        "<title>_anonymous_0</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-148 99,-148 99,5 -4,5\"/>\r\n",
+        "<!-- module0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>module0</title>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"24,-118 24,-139 69,-139 69,-118 24,-118\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"24,-118 24,-139 69,-139 69,-118 24,-118\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"27.5\" y=\"-125.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">String</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"26,-96 26,-116 67,-116 67,-96 26,-96\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"32\" y=\"-102.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value</text>\r\n",
+        "</g>\r\n",
+        "<!-- module1 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>module1</title>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"10,-26 10,-47 84,-47 84,-26 10,-26\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"13.5\" y=\"-33.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">InternalPipe</text>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"8,-4 8,-24 86,-24 86,-4 8,-4\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"8,-4 8,-24 86,-24 86,-4 8,-4\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"12\" y=\"-10.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">OutputPort</text>\r\n",
+        "</g>\r\n",
+        "<!-- module0->module1 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>module0:out0->module1:in0</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M47,-95C47,-78.0278 47,-71.398 47,-58.3042\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"50.5001,-58 47,-48 43.5001,-58 50.5001,-58\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Pipeline: 2 modules, 1 connections; outputs: msg></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 18,
+       "text": [
+        "<Pipeline: 2 modules, 1 connections; outputs: msg>"
+       ]
+      }
+     ],
+     "prompt_number": 18
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This gets the value on any output port of any module (no need to insert OutputPort or GenericOutput modules, if you know how to find the module):"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "result.module_output(0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 19,
+       "text": [
+        "{'self': <vistrails.core.modules.basic_modules.String at 0x5bd7bb0>,\n",
+        " 'value': 'Hello, world',\n",
+        " 'value_as_string': 'Hello, world'}"
+       ]
+      }
+     ],
+     "prompt_number": 19
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This gets the value passed to an OutputPort module, using the OutputPort's name:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "result.output_port('msg')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 20,
+       "text": [
+        "'Hello, world'"
+       ]
+      }
+     ],
+     "prompt_number": 20
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "## Sets inputs"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pipeline = vistrail.current_pipeline\n",
+      "pipeline"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: _anonymous_0 Pages: 1 -->\r\n",
+        "<svg width=\"247pt\" height=\"266pt\"\r\n",
+        " viewBox=\"0.00 0.00 247.00 266.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 262)\">\r\n",
+        "<title>_anonymous_0</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-262 244,-262 244,5 -4,5\"/>\r\n",
+        "<!-- module0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>module0</title>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"18,-140 18,-161 61,-161 61,-140 18,-140\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"21.5\" y=\"-147.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value2</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"61,-140 61,-161 103,-161 103,-140 61,-140\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"64\" y=\"-147.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value1</text>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"16,-118 16,-138 105,-138 105,-118 16,-118\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"16,-118 16,-138 105,-138 105,-118 16,-118\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"56\" y=\"-124.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">+</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"18,-96 18,-116 103,-116 103,-96 18,-96\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"46\" y=\"-102.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value</text>\r\n",
+        "</g>\r\n",
+        "<!-- module4 -->\r\n",
+        "<g id=\"node5\" class=\"node\"><title>module4</title>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"24,-26 24,-47 98,-47 98,-26 24,-26\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"27.5\" y=\"-33.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">InternalPipe</text>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"22,-4 22,-24 100,-24 100,-4 22,-4\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"22,-4 22,-24 100,-24 100,-4 22,-4\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"26\" y=\"-10.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">OutputPort</text>\r\n",
+        "</g>\r\n",
+        "<!-- module0->module4 -->\r\n",
+        "<g id=\"edge10\" class=\"edge\"><title>module0:out0->module4:in0</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M61,-95C61,-78.0278 61,-71.398 61,-58.3042\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"64.5001,-58 61,-48 57.5001,-58 64.5001,-58\"/>\r\n",
+        "</g>\r\n",
+        "<!-- module1 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>module1</title>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"153,-232 153,-253 231,-253 231,-232 153,-232\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"153,-232 153,-253 231,-253 231,-232 153,-232\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"160\" y=\"-239.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">First input</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"155,-210 155,-230 229,-230 229,-210 155,-210\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"158.5\" y=\"-216.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">InternalPipe</text>\r\n",
+        "</g>\r\n",
+        "<!-- module1->module0 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>module1:out0->module0:in1</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M154,-220C138.171,-220 127.099,-171.783 112.83,-155.962\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"114.432,-152.848 104,-151 111.003,-158.95 114.432,-152.848\"/>\r\n",
+        "</g>\r\n",
+        "<!-- module3 -->\r\n",
+        "<g id=\"node4\" class=\"node\"><title>module3</title>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"141,-140 141,-161 184,-161 184,-140 141,-140\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"144.5\" y=\"-147.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value2</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"184,-140 184,-161 226,-161 226,-140 184,-140\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"187\" y=\"-147.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value1</text>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"139,-118 139,-138 228,-138 228,-118 139,-118\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"139,-118 139,-138 228,-138 228,-118 139,-118\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"179.5\" y=\"-124.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">*</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"141,-96 141,-116 226,-116 226,-96 141,-96\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"169\" y=\"-102.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">value</text>\r\n",
+        "</g>\r\n",
+        "<!-- module1->module3 -->\r\n",
+        "<g id=\"edge6\" class=\"edge\"><title>module1:out0->module3:in1</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M192,-209C192,-191.221 200.748,-185.568 203.892,-172.147\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"207.393,-172.321 205,-162 200.435,-171.561 207.393,-172.321\"/>\r\n",
+        "</g>\r\n",
+        "<!-- module2 -->\r\n",
+        "<g id=\"node3\" class=\"node\"><title>module2</title>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"8,-232 8,-253 94,-253 94,-232 8,-232\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"8,-232 8,-253 94,-253 94,-232 8,-232\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"11.5\" y=\"-239.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Second input</text>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"10,-210 10,-230 92,-230 92,-210 10,-210\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"17.5\" y=\"-216.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">InternalPipe</text>\r\n",
+        "</g>\r\n",
+        "<!-- module2->module0 -->\r\n",
+        "<g id=\"edge4\" class=\"edge\"><title>module2:out0->module0:in0</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M51,-209C51,-191.315 42.925,-185.525 40.0231,-172.115\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"43.4887,-171.597 39,-162 36.5243,-172.301 43.4887,-171.597\"/>\r\n",
+        "</g>\r\n",
+        "<!-- module2->module3 -->\r\n",
+        "<g id=\"edge8\" class=\"edge\"><title>module2:out0->module3:in0</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M93,-220C108.364,-220 117.79,-172.68 131.113,-156.414\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"133.281,-159.192 140,-151 129.639,-153.214 133.281,-159.192\"/>\r\n",
+        "</g>\r\n",
+        "<!-- module5 -->\r\n",
+        "<g id=\"node6\" class=\"node\"><title>module5</title>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"147,-26 147,-47 221,-47 221,-26 147,-26\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"150.5\" y=\"-33.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">InternalPipe</text>\r\n",
+        "<polygon fill=\"grey\" stroke=\"grey\" points=\"145,-4 145,-24 223,-24 223,-4 145,-4\"/>\r\n",
+        "<polygon fill=\"none\" stroke=\"black\" points=\"145,-4 145,-24 223,-24 223,-4 145,-4\"/>\r\n",
+        "<text text-anchor=\"start\" x=\"149\" y=\"-10.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">OutputPort</text>\r\n",
+        "</g>\r\n",
+        "<!-- module3->module5 -->\r\n",
+        "<g id=\"edge12\" class=\"edge\"><title>module3:out0->module5:in0</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M184,-95C184,-78.0278 184,-71.398 184,-58.3042\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"187.5,-58 184,-48 180.5,-58 187.5,-58\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Pipeline: 6 modules, 6 connections; inputs: in_a, in_b; outputs: out_times, out_plus></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 21,
+       "text": [
+        "<Pipeline: 6 modules, 6 connections; inputs: in_a, in_b; outputs: out_times, out_plus>"
+       ]
+      }
+     ],
+     "prompt_number": 21
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "in_a = pipeline.get_input('in_a')\n",
+      "assert (in_a == pipeline.get_module('First input')) is True\n",
+      "in_a"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 22,
+       "text": [
+        "<Module 'InputPort' from org.vistrails.vistrails.basic, id 1, label \"First input\">"
+       ]
+      }
+     ],
+     "prompt_number": 22
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We need to provide value to this workflow, for its two InputPort modules. Input can be supplied to `execute()` in two ways:\n",
+      "* either by using `module_obj == value`, where module_obj is a module obtained from the pipeline, using `get_input()` or `get_module()`;\n",
+      "* or by using `module_name=value`, where module_name is the name set on an InputPort module\n",
+      "\n",
+      "Note that, to Python, `module_obj` is a variable and must be bound to a value (of type Module), whereas module_name is a keyword-parameter name."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "result = pipeline.execute(in_a == 2, in_b=4)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 23
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "result.output_port('out_times'), result.output_port('out_plus')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 24,
+       "text": [
+        "(8.0, 6.0)"
+       ]
+      }
+     ],
+     "prompt_number": 24
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "## Other example"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "im = vt.load_vistrail('imagemagick.vt')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 25
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "im.select_version('read')\n",
+      "im"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: G Pages: 1 -->\r\n",
+        "<svg width=\"143pt\" height=\"188pt\"\r\n",
+        " viewBox=\"0.00 0.00 143.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\r\n",
+        "<title>G</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-184 140,-184 140,5 -4,5\"/>\r\n",
+        "<!-- 0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>0</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"65\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 6 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>6</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"red\" cx=\"65\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"65\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">read</text>\r\n",
+        "</g>\r\n",
+        "<!-- 0->6 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>0->6</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M65,-143.697C65,-135.983 65,-126.712 65,-118.112\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"68.5001,-118.104 65,-108.104 61.5001,-118.104 68.5001,-118.104\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 14 -->\r\n",
+        "<g id=\"node3\" class=\"node\"><title>14</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">blur</text>\r\n",
+        "</g>\r\n",
+        "<!-- 6->14 -->\r\n",
+        "<g id=\"edge4\" class=\"edge\"><title>6->14</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M56.1865,-72.7646C51.5823,-64.2831 45.845,-53.7144 40.6786,-44.1974\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"43.6126,-42.266 35.7657,-35.1473 37.4607,-45.6057 43.6126,-42.266\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 21 -->\r\n",
+        "<g id=\"node4\" class=\"node\"><title>21</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"104\" cy=\"-18\" rx=\"31.2735\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"104\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">edges</text>\r\n",
+        "</g>\r\n",
+        "<!-- 6->21 -->\r\n",
+        "<g id=\"edge6\" class=\"edge\"><title>6->21</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M74.0454,-72.7646C78.7033,-64.4043 84.4911,-54.0159 89.7338,-44.6059\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"92.9232,-46.0726 94.7328,-35.6334 86.8083,-42.6656 92.9232,-46.0726\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Vistrail: imagemagick.vt, version 6 (tag read), not changed></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 26,
+       "text": [
+        "<Vistrail: imagemagick.vt, version 6 (tag read), not changed>"
+       ]
+      }
+     ],
+     "prompt_number": 26
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Note that if you print a File value, IPython will try to render it."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "im.execute().output_port('result')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAIcAAACHCAYAAAA850oKAAAACXBIWXMAAAsTAAALEwEAmpwYAAAK\nTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQ\nWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec\n5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28A\nAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0\nST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaO\nWJAPQGAAg [...]
+       "prompt_number": 27,
+       "text": [
+        "PathObject('vistrails_logo.png')"
+       ]
+      }
+     ],
+     "prompt_number": 27
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "im.select_version('blur')\n",
+      "im"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n",
+        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n",
+        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n",
+        "<!-- Generated by graphviz version 2.28.0 (20110507.0327)\r\n",
+        " -->\r\n",
+        "<!-- Title: G Pages: 1 -->\r\n",
+        "<svg width=\"143pt\" height=\"188pt\"\r\n",
+        " viewBox=\"0.00 0.00 143.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n",
+        "<g id=\"graph1\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\r\n",
+        "<title>G</title>\r\n",
+        "<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-184 140,-184 140,5 -4,5\"/>\r\n",
+        "<!-- 0 -->\r\n",
+        "<g id=\"node1\" class=\"node\"><title>0</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"65\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 6 -->\r\n",
+        "<g id=\"node2\" class=\"node\"><title>6</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"65\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"65\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">read</text>\r\n",
+        "</g>\r\n",
+        "<!-- 0->6 -->\r\n",
+        "<g id=\"edge2\" class=\"edge\"><title>0->6</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M65,-143.697C65,-135.983 65,-126.712 65,-118.112\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"68.5001,-118.104 65,-108.104 61.5001,-118.104 68.5001,-118.104\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 14 -->\r\n",
+        "<g id=\"node3\" class=\"node\"><title>14</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"red\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">blur</text>\r\n",
+        "</g>\r\n",
+        "<!-- 6->14 -->\r\n",
+        "<g id=\"edge4\" class=\"edge\"><title>6->14</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M56.1865,-72.7646C51.5823,-64.2831 45.845,-53.7144 40.6786,-44.1974\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"43.6126,-42.266 35.7657,-35.1473 37.4607,-45.6057 43.6126,-42.266\"/>\r\n",
+        "</g>\r\n",
+        "<!-- 21 -->\r\n",
+        "<g id=\"node4\" class=\"node\"><title>21</title>\r\n",
+        "<ellipse fill=\"none\" stroke=\"black\" cx=\"104\" cy=\"-18\" rx=\"31.2735\" ry=\"18\"/>\r\n",
+        "<text text-anchor=\"middle\" x=\"104\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">edges</text>\r\n",
+        "</g>\r\n",
+        "<!-- 6->21 -->\r\n",
+        "<g id=\"edge6\" class=\"edge\"><title>6->21</title>\r\n",
+        "<path fill=\"none\" stroke=\"black\" d=\"M74.0454,-72.7646C78.7033,-64.4043 84.4911,-54.0159 89.7338,-44.6059\"/>\r\n",
+        "<polygon fill=\"black\" stroke=\"black\" points=\"92.9232,-46.0726 94.7328,-35.6334 86.8083,-42.6656 92.9232,-46.0726\"/>\r\n",
+        "</g>\r\n",
+        "</g>\r\n",
+        "</svg>\r\n",
+        "<pre><Vistrail: imagemagick.vt, version 14 (tag blur), changed></pre>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 28,
+       "text": [
+        "<Vistrail: imagemagick.vt, version 14 (tag blur), changed>"
+       ]
+      }
+     ],
+     "prompt_number": 28
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "im.execute().output_port('result')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAIcAAACHCAYAAAA850oKAAAABGdBTUEAALGOfPtRkwAAACBjSFJN\nAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAABmJLR0QA/wD/AP+gvaeTAAAA\nCXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wMaDA8Rs4oMKAAAQwdJREFUeNrtvdmS5DiWpvlh\nIambmXlEZGRmVVZVd0uPyMzlvP97zIxMS1eG75u5m+mu3ADMBQASpFLNTd0jq3qqkiJqpsoVJH6e\n858FB/D35e/L35e/L9cuIvmeA/Pkk/97N+7vy7/pUgOn5FPrZON8efeXX/Ni9WedzX9VWXGns8WT\nZ3PfutyP7/A3Wp553efsJqZ/iGcfJ6Y3iYltIv4TF87Vrzg/XJz9c87inKWpDrTNadPUx/umOn48\nbD7cMwZHX [...]
+       "prompt_number": 29,
+       "text": [
+        "PathObject('c:\\\\users\\\\remi\\\\appdata\\\\local\\\\temp\\\\vt_tmpf92izb\\\\vt_tmplppjj8.png')"
+       ]
+      }
+     ],
+     "prompt_number": 29
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "im.select_version('edges')\n",
+      "im.execute().output_port('result')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAIcAAACHCAYAAAA850oKAAAABGdBTUEAALGOfPtRkwAAACBjSFJN\nAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAABmJLR0QA/wD/AP+gvaeTAAAA\nCXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wMaDA8Rs4oMKAAAJdhJREFUeNrtfVvIbctV5jfm\nXGv9e2ef7BNjjklAu0+ng+RBDSrES7QRDIHuKCgNiiCiD/3QIj4o3SCKrxE0IOKTKIig+KKISKMS\nvGK3Ct4iRuSQeAuN8XASzz47Z//rX2vW8KFqjBqjquZl3f59kvPXZu1/rTnrOuqrcasxaxIAxl26\nSyPpDhx3qZlW8uXz3voubK7eiH51BepWoK4HUYf11YMD4LMw48lwPK6Cw4ZxQBtE+esBeZtlWvfL\na5RLUVUJN [...]
+       "prompt_number": 30,
+       "text": [
+        "PathObject('c:\\\\users\\\\remi\\\\appdata\\\\local\\\\temp\\\\vt_tmpf92izb\\\\vt_tmpv_zekh.png')"
+       ]
+      }
+     ],
+     "prompt_number": 30
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "## Output mode"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "mpl = vt.load_vistrail('../matplotlib/pie_ex1.vt')\n",
+      "mpl.select_latest_version()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 31
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This workflow uses MplFigureOutput, which outputs to the IPython notebook if available (and since the spreadsheet is not running)."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "mpl.execute()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stderr",
+       "text": [
+        "WARNING:vistrails.logger:C:\\programmation\\vistrails\\dat\\vistrails\\examples\\api\\../..\\vistrails\\core\\modules\\vistrails_module.py, line 1724\n",
+        "UserWarning: A Module instance was used as data: module=MplFigure, port=self, object=<vistrails.packages.matplotlib.bases.MplFigure object at 0x05951770>\n",
+        "  UserWarning)\n",
+        "\n"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAH0CAYAAACtlpxpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3Xd4VuXhxvHvOSeMhEAYAgEVREEQEZTlQHGgiAJurVtU\nQDaKuFulra1otdpaS0WqOFBEVH7gAkVAUKaAyJaNkARCTGIGGeec3x9vcFTIfN8877g/18WFtpjc\ntpjcnnE/1rx583xEREREJGbYpgOIiIiISPVSARQRERGJMSqAIiIiIjFGBVBEREQkxqgAioiIiMQY\nFUARERGRGKMCKCIiIhJjVABFREREYowKoIiIiEiMUQEUERERiTEqgCIiIiIxRgVQREREJMaoAIqI\niIjEGBVAERERkRijAigiIiISY1QARURERGKMCqCIiIhIjFEBFBEREYkxKoAiIiIiMUYFUERERCTG\nqACKiIiIx [...]
+       "text": [
+        "<matplotlib.figure.Figure at 0x60e9bb0>"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 32,
+       "text": [
+        "<ExecutionResult: 3 modules>"
+       ]
+      }
+     ],
+     "prompt_number": 32
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "richtext = vt.load_vistrail('out_html.xml')\n",
+      "richtext.select_latest_version()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 33
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This one uses RichTextOutput:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "richtext.execute()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "this is a <strong>test</strong> hehe"
+       ],
+       "metadata": {},
+       "output_type": "display_data",
+       "text": [
+        "<IPython.core.display.HTML at 0x5f9e850>"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 34,
+       "text": [
+        "<ExecutionResult: 2 modules>"
+       ]
+      }
+     ],
+     "prompt_number": 34
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "tbl = vt.load_vistrail('table.xml')\n",
+      "tbl.select_latest_version()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 35
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "TableOutput:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "tbl.execute()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "html": [
+        "<!DOCTYPE html>\n",
+        "<html>\n",
+        "  <head>\n",
+        "    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n",
+        "    <title>Exported table</title>\n",
+        "    <style type=\"text/css\">\n",
+        "table { border-collapse: collapse; }\n",
+        "td, th { border: 1px solid black; }\n",
+        "    </style>\n",
+        "  </head>\n",
+        "  <body>\n",
+        "    <table>\n",
+        "<tr>\n",
+        "  <th>a</th>\n",
+        "  <th>b</th>\n",
+        "</tr>\n",
+        "<tr>\n",
+        "  <td>1</td>\n",
+        "  <td>4</td>\n",
+        "</tr>\n",
+        "<tr>\n",
+        "  <td>2</td>\n",
+        "  <td>5</td>\n",
+        "</tr>\n",
+        "<tr>\n",
+        "  <td>3</td>\n",
+        "  <td>6</td>\n",
+        "</tr>\n",
+        "    </table>\n",
+        "  </body>\n",
+        "</html>\n"
+       ],
+       "metadata": {},
+       "output_type": "display_data",
+       "text": [
+        "<IPython.core.display.HTML at 0x5faf530>"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 36,
+       "text": [
+        "<ExecutionResult: 2 modules>"
+       ]
+      }
+     ],
+     "prompt_number": 36
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "render = vt.load_vistrail('brain_output.xml')\n",
+      "render.select_latest_version()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 37
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "And vtkRendererOutput:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "render.execute()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {
+        "png": {
+         "height": 480,
+         "width": 640
+        }
+       },
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAIAAAC6s0uzAAAgAElEQVR4nOzdd3xVRdoH8GfmlNtz\nb3pCGoRQQuhFQHovKkVx7QVU7Lr21XXtZa27Ytm1YS+oFFFBQAXpSO8hEJKQ3m5ubj9lZt4/2Nd1\nITRBruX5/uEn3DNnznMm8vkx95QhQghACCGE0OlFY10AQggh9EeEAYwQQgjFAAYwQgghFAMYwAgh\nhFAMYAAjhBBCMYABjBBCCMUABjBCCCEUAxjACCGEUAxgACOEEEIxgAGMEEIIxQAGMEIIIRQDGMAI\nIYRQDGAAI4QQQjGAAYwQQgjFAAYwQgghFAMYwAghhFAMYAAjhBBCMYABjBBCCMUABjBCCCEUAxjA\nCCGEUAxgACOEEEIxgAGMEEIIxQAGMEIIIRQDGMAIIYRQDGAAI4QQQjGAAYwQQgjFAAYwQgghFAMY\nwAghhFAMY [...]
+       "text": [
+        "<IPython.core.display.Image at 0x12f7c7d0>"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 38,
+       "text": [
+        "<ExecutionResult: 16 modules>"
+       ]
+      }
+     ],
+     "prompt_number": 38
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/examples/api/out_html.xml b/examples/api/out_html.xml
new file mode 100644
index 0000000..a358597
--- /dev/null
+++ b/examples/api/out_html.xml
@@ -0,0 +1,37 @@
+<vistrail id="" name="" version="1.0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vistrails.org/vistrail.xsd">
+  <action date="2015-03-10 23:56:38" id="1" prevId="0" session="0" user="Remi">
+    <add id="0" objectId="0" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="0" name="RichTextOutput" namespace="" package="org.vistrails.vistrails.basic" version="2.1.1" />
+    </add>
+    <add id="1" objectId="0" parentObjId="0" parentObjType="module" what="location">
+      <location id="0" x="15.0" y="6.0" />
+    </add>
+  </action>
+  <action date="2015-03-10 23:56:42" id="2" prevId="1" session="0" user="Remi">
+    <add id="2" objectId="1" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="1" name="WriteFile" namespace="" package="org.vistrails.vistrails.basic" version="2.1.1" />
+    </add>
+    <add id="3" objectId="1" parentObjId="1" parentObjType="module" what="location">
+      <location id="1" x="-93.0" y="91.0" />
+    </add>
+  </action>
+  <action date="2015-03-10 23:56:42" id="3" prevId="2" session="0" user="Remi">
+    <add id="4" objectId="0" parentObjId="" parentObjType="" what="connection">
+      <connection id="0" />
+    </add>
+    <add id="5" objectId="0" parentObjId="0" parentObjType="connection" what="port">
+      <port id="0" moduleId="1" moduleName="WriteFile" name="out_value" signature="(org.vistrails.vistrails.basic:File)" type="source" />
+    </add>
+    <add id="6" objectId="1" parentObjId="0" parentObjType="connection" what="port">
+      <port id="1" moduleId="0" moduleName="RichTextOutput" name="value" signature="(org.vistrails.vistrails.basic:File)" type="destination" />
+    </add>
+  </action>
+  <action date="2015-03-10 23:56:53" id="4" prevId="3" session="0" user="Remi">
+    <add id="7" objectId="0" parentObjId="1" parentObjType="module" what="function">
+      <function id="0" name="in_value" pos="0" />
+    </add>
+    <add id="8" objectId="0" parentObjId="0" parentObjType="function" what="parameter">
+      <parameter alias="" id="0" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:String" val="this is a <strong>test</strong> hehe" />
+    </add>
+  </action>
+</vistrail>
diff --git a/examples/api/outputs.vt b/examples/api/outputs.vt
new file mode 100644
index 0000000..e157637
Binary files /dev/null and b/examples/api/outputs.vt differ
diff --git a/examples/api/simplemath.vt b/examples/api/simplemath.vt
new file mode 100644
index 0000000..5ecedaa
Binary files /dev/null and b/examples/api/simplemath.vt differ
diff --git a/examples/api/table.xml b/examples/api/table.xml
new file mode 100644
index 0000000..02e3eb5
--- /dev/null
+++ b/examples/api/table.xml
@@ -0,0 +1,58 @@
+<vistrail id="" name="" version="1.0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vistrails.org/vistrail.xsd">
+  <action date="2015-03-17 16:48:52" id="1" prevId="0" session="0" user="Remi">
+    <add id="0" objectId="0" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="0" name="BuildTable" namespace="" package="org.vistrails.vistrails.tabledata" version="0.1.5" />
+    </add>
+    <add id="1" objectId="0" parentObjId="0" parentObjType="module" what="location">
+      <location id="0" x="-147.0" y="96.0" />
+    </add>
+  </action>
+  <action date="2015-03-17 16:48:57" id="2" prevId="1" session="0" user="Remi">
+    <add id="2" objectId="0" parentObjId="0" parentObjType="module" what="portSpec">
+      <portSpec depth="0" id="0" maxConns="-1" minConns="0" name="a" optional="0" sortKey="-1" type="input">
+        <portSpecItem default="" entryType="" id="0" label="" module="List" namespace="" package="org.vistrails.vistrails.basic" pos="0" values="" />
+      </portSpec>
+    </add>
+    <add id="3" objectId="1" parentObjId="0" parentObjType="module" what="portSpec">
+      <portSpec depth="0" id="1" maxConns="-1" minConns="0" name="b" optional="0" sortKey="-1" type="input">
+        <portSpecItem default="" entryType="" id="1" label="" module="List" namespace="" package="org.vistrails.vistrails.basic" pos="0" values="" />
+      </portSpec>
+    </add>
+  </action>
+  <action date="2015-03-17 16:49:04" id="3" prevId="2" session="0" user="Remi">
+    <add id="4" objectId="0" parentObjId="0" parentObjType="module" what="function">
+      <function id="0" name="a" pos="0" />
+    </add>
+    <add id="5" objectId="0" parentObjId="0" parentObjType="function" what="parameter">
+      <parameter alias="" id="0" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:List" val="[1, 2, 3]" />
+    </add>
+  </action>
+  <action date="2015-03-17 16:49:13" id="4" prevId="3" session="0" user="Remi">
+    <add id="6" objectId="1" parentObjId="0" parentObjType="module" what="function">
+      <function id="1" name="b" pos="1" />
+    </add>
+    <add id="7" objectId="1" parentObjId="1" parentObjType="function" what="parameter">
+      <parameter alias="" id="1" name="<no description>" pos="0" type="org.vistrails.vistrails.basic:List" val="[4, 5, 6]" />
+    </add>
+  </action>
+  <action date="2015-03-17 16:49:30" id="5" prevId="4" session="0" user="Remi">
+    <add id="8" objectId="1" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="1" name="TableOutput" namespace="" package="org.vistrails.vistrails.tabledata" version="0.1.5" />
+    </add>
+    <add id="9" objectId="1" parentObjId="1" parentObjType="module" what="location">
+      <location id="1" x="-115.0" y="-14.0" />
+    </add>
+  </action>
+  <action date="2015-03-17 16:49:30" id="6" prevId="5" session="0" user="Remi">
+    <add id="10" objectId="0" parentObjId="" parentObjType="" what="connection">
+      <connection id="0" />
+    </add>
+    <add id="11" objectId="0" parentObjId="0" parentObjType="connection" what="port">
+      <port id="0" moduleId="0" moduleName="BuildTable" name="value" signature="(org.vistrails.vistrails.tabledata:Table)" type="source" />
+    </add>
+    <add id="12" objectId="1" parentObjId="0" parentObjType="connection" what="port">
+      <port id="1" moduleId="1" moduleName="TableOutput" name="value" signature="(org.vistrails.vistrails.tabledata:Table)" type="destination" />
+    </add>
+  </action>
+  <actionAnnotation actionId="6" date="2015-03-17 16:49:46" id="1" key="__thumb__" user="Remi" value="255d9840-cce7-11e4-98a0-df5eb7a2e824.png" />
+</vistrail>
diff --git a/examples/api/vistrails_logo.png b/examples/api/vistrails_logo.png
new file mode 100644
index 0000000..a726910
Binary files /dev/null and b/examples/api/vistrails_logo.png differ
diff --git a/examples/chebi_webservice.vt b/examples/chebi_webservice.vt
index 88dcaf1..1138dc7 100644
Binary files a/examples/chebi_webservice.vt and b/examples/chebi_webservice.vt differ
diff --git a/examples/hadoop-nodeinfo.vt b/examples/hadoop-nodeinfo.vt
new file mode 100644
index 0000000..db7d242
Binary files /dev/null and b/examples/hadoop-nodeinfo.vt differ
diff --git a/examples/infovis.vt b/examples/infovis.vt
index 799222b..492a3ab 100644
Binary files a/examples/infovis.vt and b/examples/infovis.vt differ
diff --git a/examples/list-handling.vt b/examples/list-handling.vt
new file mode 100644
index 0000000..54d7bd5
Binary files /dev/null and b/examples/list-handling.vt differ
diff --git a/examples/matplotlib/Acorr_ex8.vt b/examples/matplotlib/Acorr_ex8.vt
index f4e9e27..5df0ce4 100644
Binary files a/examples/matplotlib/Acorr_ex8.vt and b/examples/matplotlib/Acorr_ex8.vt differ
diff --git a/examples/matplotlib/Arrow_ex9.vt b/examples/matplotlib/Arrow_ex9.vt
index 2643084..5579d89 100644
Binary files a/examples/matplotlib/Arrow_ex9.vt and b/examples/matplotlib/Arrow_ex9.vt differ
diff --git a/examples/matplotlib/Psd.vt b/examples/matplotlib/Psd.vt
index d671910..922d944 100644
Binary files a/examples/matplotlib/Psd.vt and b/examples/matplotlib/Psd.vt differ
diff --git a/examples/matplotlib/annotate.vt b/examples/matplotlib/annotate.vt
index e3b9956..220ea36 100644
Binary files a/examples/matplotlib/annotate.vt and b/examples/matplotlib/annotate.vt differ
diff --git a/examples/matplotlib/axhspan_ex5.vt b/examples/matplotlib/axhspan_ex5.vt
index 12eabe2..35c1229 100644
Binary files a/examples/matplotlib/axhspan_ex5.vt and b/examples/matplotlib/axhspan_ex5.vt differ
diff --git a/examples/matplotlib/bar_ex1.vt b/examples/matplotlib/bar_ex1.vt
index 88c4373..c726a58 100644
Binary files a/examples/matplotlib/bar_ex1.vt and b/examples/matplotlib/bar_ex1.vt differ
diff --git a/examples/matplotlib/cohere.vt b/examples/matplotlib/cohere.vt
index c706ee2..5f1ded6 100644
Binary files a/examples/matplotlib/cohere.vt and b/examples/matplotlib/cohere.vt differ
diff --git a/examples/matplotlib/contour.vt b/examples/matplotlib/contour.vt
index 248022a..38b6364 100644
Binary files a/examples/matplotlib/contour.vt and b/examples/matplotlib/contour.vt differ
diff --git a/examples/matplotlib/contourf.vt b/examples/matplotlib/contourf.vt
index c54aec7..6a6cd0a 100644
Binary files a/examples/matplotlib/contourf.vt and b/examples/matplotlib/contourf.vt differ
diff --git a/examples/matplotlib/hist_ex1.vt b/examples/matplotlib/hist_ex1.vt
index b8533bd..ecdd94d 100644
Binary files a/examples/matplotlib/hist_ex1.vt and b/examples/matplotlib/hist_ex1.vt differ
diff --git a/examples/matplotlib/line2d_ex4.vt b/examples/matplotlib/line2d_ex4.vt
index c0d6443..15179bf 100644
Binary files a/examples/matplotlib/line2d_ex4.vt and b/examples/matplotlib/line2d_ex4.vt differ
diff --git a/examples/matplotlib/line2d_ex7.vt b/examples/matplotlib/line2d_ex7.vt
index ad5c7e1..d72a55a 100644
Binary files a/examples/matplotlib/line2d_ex7.vt and b/examples/matplotlib/line2d_ex7.vt differ
diff --git a/examples/matplotlib/lineplot_ex3.vt b/examples/matplotlib/lineplot_ex3.vt
index c90a889..4e8a794 100644
Binary files a/examples/matplotlib/lineplot_ex3.vt and b/examples/matplotlib/lineplot_ex3.vt differ
diff --git a/examples/matplotlib/pcolor.vt b/examples/matplotlib/pcolor.vt
index 0dcd34c..2dac211 100644
Binary files a/examples/matplotlib/pcolor.vt and b/examples/matplotlib/pcolor.vt differ
diff --git a/examples/matplotlib/pie_ex1.vt b/examples/matplotlib/pie_ex1.vt
index 25f3433..2fe03e3 100644
Binary files a/examples/matplotlib/pie_ex1.vt and b/examples/matplotlib/pie_ex1.vt differ
diff --git a/examples/matplotlib/polar_ex10.vt b/examples/matplotlib/polar_ex10.vt
index 846b616..2f37b41 100644
Binary files a/examples/matplotlib/polar_ex10.vt and b/examples/matplotlib/polar_ex10.vt differ
diff --git a/examples/matplotlib/scatter.vt b/examples/matplotlib/scatter.vt
index c002e72..1e96cc5 100644
Binary files a/examples/matplotlib/scatter.vt and b/examples/matplotlib/scatter.vt differ
diff --git a/examples/matplotlib/semilog.vt b/examples/matplotlib/semilog.vt
index 94db983..f144151 100644
Binary files a/examples/matplotlib/semilog.vt and b/examples/matplotlib/semilog.vt differ
diff --git a/examples/mta-yankees.vt b/examples/mta-yankees.vt
new file mode 100644
index 0000000..9aaa07a
Binary files /dev/null and b/examples/mta-yankees.vt differ
diff --git a/examples/mta.vt b/examples/mta.vt
new file mode 100644
index 0000000..fcb4c87
Binary files /dev/null and b/examples/mta.vt differ
diff --git a/examples/scripting/README b/examples/scripting/README
deleted file mode 100644
index 80dbbb0..0000000
--- a/examples/scripting/README
+++ /dev/null
@@ -1,11 +0,0 @@
-This file explains script vtk_book_3rd_p189_script.py. It is a script that generates the same pipeline found in the example vt file with (practically) the same name, and is used to compare the new layout options designed to improve incremental/online layout.
-
-Two options were added to the original layout algorithm:
-
--preserve_order: this preserves the order in the x-coordinate of existing modules in the pipeline. Modules with no previous x position (new modules) are positioned based on the original layout algorithm which tries to minimize connection crossings. 
-
--no_gaps: this prevents connected modules from being more than one layer (aka row) apart from eachother.
-
-VisTrails files were generated using each of the 4 combinations of the above boolean options. These can be regenerated by changing the parameters in function layoutAndAdd on line 40 of the script, and the output file name at the end of the script. Open these in vistrails and traverse the version tree using undo and redo to see how the pipelines are layed out incrementally.
-
-brain_script.py builds the example pipeline from brain_vistrail.vt, and combined_script.py builds a pipeline of the two combined.
\ No newline at end of file
diff --git a/examples/scripting/brain_from_script.vt b/examples/scripting/brain_from_script.vt
deleted file mode 100644
index d30ae3b..0000000
Binary files a/examples/scripting/brain_from_script.vt and /dev/null differ
diff --git a/examples/scripting/brain_script.py b/examples/scripting/brain_script.py
deleted file mode 100644
index 292535f..0000000
--- a/examples/scripting/brain_script.py
+++ /dev/null
@@ -1,110 +0,0 @@
-import os
-import sys
-
-try:
-    import vistrails
-except:
-    #try to append vistrails source dir relative to examples/scripting
-    this_dir = os.path.split(__file__)[0]
-    sys.path.append(os.path.join(this_dir, '../..'))
-    import vistrails
-
-from vistrails.core.application import init as vt_init
-from vistrails.core.api import Package, get_api
-
-#init vistrails
-vt_app = vt_init()
-vt_app.new_vistrail()
-api = get_api()
-
-httppkg = 'edu.utah.sci.vistrails.http'
-vtkpkg = 'edu.utah.sci.vistrails.vtk'
-
-http = Package(httppkg)
-vtk = Package(vtkpkg)
-
-#start with http file module
-httpFA = http.HTTPFile()
-httpFA.url = \
-    'http://www.vistrails.org/download/download.php?type=DATA&id=gktbhFA.vtk'
-
-#add and connect vtkDataSetReader
-dataFA = api.add_and_connect_module(vtkpkg, 'vtkDataSetReader', 'SetFile',
-                                    httpFA, 'file')
-
-#add contour filter
-contour = api.add_and_connect_module(vtkpkg, 'vtkContourFilter',
-                                     'SetInputConnection0',
-                                     dataFA, 'GetOutputPort0')
-contour.SetValue = (0, 0.6)
-
-#add normals, stripper, and probe filter
-normals = api.add_and_connect_module(vtkpkg, 'vtkPolyDataNormals',
-                                     'SetInputConnection0',
-                                     contour, 'GetOutputPort0')
-normals.SetFeatureAngle = 60.0
-
-stripper = api.add_and_connect_module(vtkpkg, 'vtkStripper',
-                                      'SetInputConnection0',
-                                      normals, 'GetOutputPort0')
-
-probe = api.add_and_connect_module(vtkpkg, 'vtkProbeFilter',
-                                   'SetInputConnection0',
-                                   stripper, 'GetOutputPort0')
-
-#build other branch in reverse
-colors = api.add_and_connect_module(vtkpkg, 'vtkImageMapToColors',
-                                    'GetOutputPort0',
-                                    probe, 'SetInputConnection1', True)
-colors.SetOutputFormatToRGBA = True
-
-lookup = api.add_and_connect_module(vtkpkg, 'vtkLookupTable', 'self',
-                                    colors, 'SetLookupTable', True)
-lookup.SetHueRange = (0.0, 0.8)
-lookup.SetSaturationRange = (0.3, 0.7)
-lookup.SetValueRange = (1.0, 1.0)
-
-dataL123 = api.add_and_connect_module(vtkpkg, 'vtkDataSetReader',
-                                      'GetOutputPort0',
-                                      colors, 'SetInputConnection0', True)
-
-httpL123 = api.add_and_connect_module(httppkg, 'HTTPFile', 'file',
-                                      dataL123, 'SetFile', True)
-
-httpL123.url = \
-    'http://www.vistrails.org/download/download.php?type=DATA&id=gktbhL123.vtk'
-
-#finish bottom section
-mapper = api.add_and_connect_module(vtkpkg, 'vtkPolyDataMapper',
-                                    'SetInputConnection0',
-                                    probe, 'GetOutputPort0')
-mapper.ScalarVisibilityOn = True
-
-actor = api.add_and_connect_module(vtkpkg, 'vtkActor', 'SetMapper',
-                                   mapper, 'self')
-
-prop = api.add_and_connect_module(vtkpkg, 'vtkProperty', 'self',
-                                  actor, 'SetProperty', True)
-prop.SetDiffuseColor = (1.0, 0.49, 0.25)
-prop.SetOpacity = 0.7
-prop.SetSpecular = 0.3
-prop.SetSpecularPower = 2.0
-
-renderer = api.add_and_connect_module(vtkpkg, 'vtkRenderer', 'AddActor',
-                                      actor, 'self')
-
-# Thought this used to work. Right now fails to convert to color when executed
-#renderer.SetBackgroundWidget = 'white'
-
-camera = api.add_and_connect_module(vtkpkg, 'vtkCamera', 'self',
-                                    renderer, 'SetActiveCamera', True)
-camera.SetFocalPoint = (15.666, 40.421, 39.991)
-camera.SetPosition = (207.961, 34.197, 129.680)
-camera.SetViewUp = (0.029, 1.0, 0.008)
-
-
-cell = api.add_and_connect_module(vtkpkg, 'VTKCell', 'AddRenderer',
-                                  renderer, 'self')
-
-#write to file
-api.save_vistrail('brain_from_script.vt')
diff --git a/examples/scripting/combined_script.py b/examples/scripting/combined_script.py
deleted file mode 100644
index dbc6b1f..0000000
--- a/examples/scripting/combined_script.py
+++ /dev/null
@@ -1,224 +0,0 @@
-import os
-import sys
-
-try:
-    import vistrails
-except:
-    #try to append vistrails source dir relative to examples/scripting
-    this_dir = os.path.split(__file__)[0]
-    sys.path.append(os.path.join(this_dir, '../..'))
-    import vistrails
-
-import vistrails.core.application
-import vistrails.core.db.action
-import vistrails.core.db.locator
-import vistrails.core.modules.module_registry
-
-
-#init vistrails
-vt_app = vistrails.core.application.init()
-vt_app.new_vistrail()
-controller = vt_app.get_controller()
-registry = vistrails.core.modules.module_registry.get_module_registry()
-
-#========================== convenience methods ================================
-def newModule(package_name, module_name):
-    descriptor = registry.get_descriptor_by_name(package_name, module_name)
-    return controller.create_module_from_descriptor(descriptor)
-
-def newConnection(source, source_port, target, target_port):
-    c = controller.create_connection(source, source_port, target, target_port)
-    return c
-
-def setPortValue(module, port_name, value):
-    function = controller.create_function(module, port_name, [str(value)])
-    module.add_function(function)
-    return
-
-def addToPipeline(items, ops=[]):
-    item_ops = [('add',item) for item in items]
-    action = vistrails.core.db.action.create_action(item_ops + ops)
-    controller.add_new_action(action)
-    version = controller.perform_action(action)
-    controller.change_selected_version(version)
-
-def layoutAndAdd(module, connections):
-    if not isinstance(connections, list):
-        connections = [connections]
-    ops = controller.layout_modules_ops(preserve_order=True,
-                                        new_modules=[module],
-                                        new_connections=connections)
-    addToPipeline([module] + connections, ops)
-
-#========================== package prefixes ===================================
-httppkg = 'edu.utah.sci.vistrails.http'
-vtkpkg = 'edu.utah.sci.vistrails.vtk'
-
-#============================ start script =====================================
-
-#start with http file module
-httpFA = newModule(httppkg, 'HTTPFile')
-url = 'http://www.vistrails.org/download/download.php?type=DATA&id=gktbhFA.vtk'
-setPortValue(httpFA, 'url', url)
-
-#add to pipeline
-addToPipeline([httpFA])
-
-#create data set reader module for the gktbhFA.vtk file
-dataFA = newModule(vtkpkg, 'vtkDataSetReader')
-
-#connect modules
-http_dataFA = newConnection(httpFA, 'file', dataFA, 'SetFile')
-
-#layout new modules before adding
-layoutAndAdd(dataFA, http_dataFA)
-
-#add contour filter
-contour = newModule(vtkpkg, 'vtkContourFilter')
-setPortValue(contour, 'SetValue', (0,0.6))
-dataFA_contour = newConnection(dataFA, 'GetOutputPort0',
-                               contour, 'SetInputConnection0')
-layoutAndAdd(contour, dataFA_contour)
-
-#add normals, stripper, and probe filter
-normals = newModule(vtkpkg, 'vtkPolyDataNormals') #GetOutputPort0
-setPortValue(normals, 'SetFeatureAngle', 60.0)
-contour_normals = newConnection(contour, 'GetOutputPort0', 
-                                normals, 'SetInputConnection0')
-layoutAndAdd(normals, contour_normals)
-
-stripper = newModule(vtkpkg, 'vtkStripper') #GetOutputPort0
-normals_stripper = newConnection(normals, 'GetOutputPort0',
-                                 stripper, 'SetInputConnection0')
-layoutAndAdd(stripper, normals_stripper)
-
-probe = newModule(vtkpkg, 'vtkProbeFilter') #same
-stripper_probe = newConnection(stripper, 'GetOutputPort0',
-                               probe, 'SetInputConnection0')
-layoutAndAdd(probe, stripper_probe)
-
-#build other branch in reverse
-colors = newModule(vtkpkg, 'vtkImageMapToColors')
-setPortValue(colors, 'SetOutputFormatToRGBA', True)
-colors_probe = newConnection(colors, 'GetOutputPort0',
-                             probe, 'SetInputConnection1')
-layoutAndAdd(colors, colors_probe)
-
-lookup = newModule(vtkpkg, 'vtkLookupTable')
-setPortValue(lookup, 'SetHueRange', (0.0,0.8))
-setPortValue(lookup, 'SetSaturationRange', (0.3,0.7))
-setPortValue(lookup, 'SetValueRange', (1.0,1.0))
-lookup_colors = newConnection(lookup, 'self',
-                              colors, 'SetLookupTable')
-layoutAndAdd(lookup, lookup_colors)
-
-dataL123 = newModule(vtkpkg, 'vtkDataSetReader')
-dataL123_colors = newConnection(dataL123, 'GetOutputPort0',
-                                colors, 'SetInputConnection0')
-layoutAndAdd(dataL123, dataL123_colors)
-
-httpL123 = newModule(httppkg, 'HTTPFile')
-url = 'http://www.vistrails.org/download/download.php?type=DATA&id=gktbhL123.vtk'
-setPortValue(httpL123, 'url', url)
-httpL123_dataL123 = newConnection(httpL123, 'file',
-                                  dataL123, 'SetFile')
-layoutAndAdd(httpL123, httpL123_dataL123)
-
-#finish bottom section
-mapper = newModule(vtkpkg, 'vtkPolyDataMapper')
-setPortValue(mapper, 'ScalarVisibilityOn', True)
-probe_mapper = newConnection(probe, 'GetOutputPort0',
-                             mapper, 'SetInputConnection0')
-layoutAndAdd(mapper, probe_mapper)
-
-actor = newModule(vtkpkg, 'vtkActor')
-mapper_actor = newConnection(mapper, 'self',
-                             actor, 'SetMapper')
-layoutAndAdd(actor, mapper_actor)
-
-prop = newModule(vtkpkg, 'vtkProperty')
-setPortValue(prop, 'SetDiffuseColor', (1.0,0.49,0.25))
-setPortValue(prop, 'SetOpacity', 0.7)
-setPortValue(prop, 'SetSpecular', 0.3)
-setPortValue(prop, 'SetSpecularPower', 2.0)
-prop_actor = newConnection(prop, 'self',
-                           actor, 'SetProperty')
-layoutAndAdd(prop, prop_actor)
-
-renderer = newModule(vtkpkg, 'vtkRenderer')
-setPortValue(renderer, 'SetBackgroundWidget', 'white')
-actor_renderer = newConnection(actor, 'self',
-                               renderer, 'AddActor')
-layoutAndAdd(renderer, actor_renderer)
-
-camera = newModule(vtkpkg, 'vtkCamera')
-setPortValue(camera, 'SetFocalPoint', (15.666,40.421,39.991))
-setPortValue(camera, 'SetPosition', (207.961,34.197,129.680))
-setPortValue(camera, 'SetViewUp', (0.029, 1.0, 0.008))
-camera_renderer = newConnection(camera, 'self',
-                                renderer, 'SetActiveCamera')
-layoutAndAdd(camera, camera_renderer)
-
-#this is missing when running from script??
-# cell = newModule(vtkpkg, 'VTKCell')
-# cell = newModule(vtkpkg, 'vtkCell')
-# renderer_cell = newConnection(renderer, 'self',
-#                               cell, 'AddRenderer')
-# layoutAndAdd(cell, renderer_cell)
-
-#add book 3rd p189 example
-
-qcActor = newModule(vtkpkg, 'vtkActor')
-qcActor_renderer = newConnection(qcActor, 'self',
-                                 renderer, 'AddActor')
-layoutAndAdd(qcActor, qcActor_renderer)
-
-qcMapper = newModule(vtkpkg, 'vtkPolyDataMapper')
-qcMapper_actor = newConnection(qcMapper, 'self',
-                               qcActor, 'SetMapper')
-layoutAndAdd(qcMapper, qcMapper_actor)
-
-qContour = newModule(vtkpkg, 'vtkContourFilter')
-setPortValue(qContour, 'GenerateValues', (5,0,1.2))
-qContour_mapper = newConnection(qContour, 'GetOutputPort0',
-                                qcMapper, 'SetInputConnection0')
-layoutAndAdd(qContour, qContour_mapper)
-
-sample = newModule(vtkpkg, 'vtkSampleFunction')
-setPortValue(sample, 'SetSampleDimensions', (50,50,50))
-sample_qContour = newConnection(sample, 'GetOutputPort0',
-                                qContour, 'SetInputConnection0')
-layoutAndAdd(sample, sample_qContour)
-
-quad = newModule(vtkpkg, 'vtkQuadric')
-setPortValue(quad, 'SetCoefficients', (0.5,1,0.2,0,0.1,0,0,0.2,0,0))
-quad_sample = newConnection(quad, 'self',
-                            sample, 'SetImplicitFunction')
-layoutAndAdd(quad, quad_sample)
-
-oActor = newModule(vtkpkg, 'vtkActor')
-oActor_renderer = newConnection(oActor, 'self',
-                                renderer, 'AddActor')
-layoutAndAdd(oActor, oActor_renderer)
-
-oProp = newModule(vtkpkg, 'vtkProperty')
-setPortValue(oProp, 'SetColor', (0,0,0))
-oProp_actor = newConnection(oProp, 'self',
-                            oActor, 'SetProperty')
-layoutAndAdd(oProp, oProp_actor)
-
-oMapper = newModule(vtkpkg, 'vtkPolyDataMapper')
-oMapper_actor = newConnection(oMapper, 'self',
-                              oActor, 'SetMapper')
-layoutAndAdd(oMapper, oMapper_actor)
-
-outline = newModule(vtkpkg, 'vtkOutlineFilter')
-outline_mapper = newConnection(outline, 'GetOutputPort0',
-                               oMapper, 'SetInputConnection0')
-sample_outline = newConnection(sample, 'GetOutputPort0',
-                               outline, 'SetInputConnection0')
-layoutAndAdd(outline, [outline_mapper, sample_outline])
-
-#write to file
-locator = vistrails.core.db.locator.FileLocator('incremental_layout_combined.vt')
-controller.write_vistrail(locator)
diff --git a/examples/scripting/vtk_book_3rd_p189_script.py b/examples/scripting/vtk_book_3rd_p189_script.py
deleted file mode 100644
index bc835f0..0000000
--- a/examples/scripting/vtk_book_3rd_p189_script.py
+++ /dev/null
@@ -1,123 +0,0 @@
-import os
-import sys
-
-try:
-    import vistrails
-except:
-    #try to append vistrails source dir relative to examples/scripting
-    this_dir = os.path.split(__file__)[0]
-    sys.path.append(os.path.join(this_dir, '../..'))
-    import vistrails
-
-import vistrails.core.application
-import vistrails.core.db.action
-import vistrails.core.db.locator
-import vistrails.core.modules.module_registry
-
-
-#init vistrails
-vt_app = vistrails.core.application.init()
-vt_app.new_vistrail()
-controller = vt_app.get_controller()
-registry = vistrails.core.modules.module_registry.get_module_registry()
-
-#========================== convenience methods ================================
-def newModule(package_name, module_name):
-    descriptor = registry.get_descriptor_by_name(package_name, module_name)
-    return controller.create_module_from_descriptor(descriptor)
-
-def newConnection(source, source_port, target, target_port):
-    c = controller.create_connection(source, source_port, target, target_port)
-    return c
-
-def setPortValue(module, port_name, value):
-    function = controller.create_function(module, port_name, [str(value)])
-    module.add_function(function)
-    return
-
-def addToPipeline(items, ops=[]):
-    item_ops = [('add',item) for item in items]
-    action = vistrails.core.db.action.create_action(item_ops + ops)
-    controller.add_new_action(action)
-    version = controller.perform_action(action)
-    controller.change_selected_version(version)
-
-def layoutAndAdd(module, connections):
-    print 'adding %s' % module.name
-    if not isinstance(connections, list):
-        connections = [connections]
-    ops = controller.layout_modules_ops(preserve_order=True, no_gaps=False,
-                                        new_modules=[module],
-                                        new_connections=connections)
-    addToPipeline([module] + connections, ops)
-
-#========================== package prefixes ===================================
-httppkg = 'edu.utah.sci.vistrails.http'
-vtkpkg = 'edu.utah.sci.vistrails.vtk'
-
-#============================ start script =====================================
-
-renderer = newModule(vtkpkg, 'vtkRenderer')
-addToPipeline([renderer])
-
-#this is missing when running from script??
-# cell = newModule(vtkpkg, 'VTKCell')
-# cell = newModule(vtkpkg, 'vtkCell')
-# renderer_cell = newConnection(renderer, 'self',
-#                               cell, 'AddRenderer')
-# layoutAndAdd(cell, renderer_cell)
-
-qcActor = newModule(vtkpkg, 'vtkActor')
-qcActor_renderer = newConnection(qcActor, 'self',
-                                 renderer, 'AddActor')
-layoutAndAdd(qcActor, qcActor_renderer)
-
-oActor = newModule(vtkpkg, 'vtkActor')
-oActor_renderer = newConnection(oActor, 'self',
-                                renderer, 'AddActor')
-layoutAndAdd(oActor, oActor_renderer)
-
-qcMapper = newModule(vtkpkg, 'vtkPolyDataMapper')
-qcMapper_actor = newConnection(qcMapper, 'self',
-                               qcActor, 'SetMapper')
-layoutAndAdd(qcMapper, qcMapper_actor)
-
-oProp = newModule(vtkpkg, 'vtkProperty')
-setPortValue(oProp, 'SetColor', (0,0,0))
-oProp_actor = newConnection(oProp, 'self',
-                            oActor, 'SetProperty')
-layoutAndAdd(oProp, oProp_actor)
-
-oMapper = newModule(vtkpkg, 'vtkPolyDataMapper')
-oMapper_actor = newConnection(oMapper, 'self',
-                              oActor, 'SetMapper')
-layoutAndAdd(oMapper, oMapper_actor)
-
-qContour = newModule(vtkpkg, 'vtkContourFilter')
-setPortValue(qContour, 'GenerateValues', (5,0,1.2))
-qContour_mapper = newConnection(qContour, 'GetOutputPort0',
-                                qcMapper, 'SetInputConnection0')
-layoutAndAdd(qContour, qContour_mapper)
-
-sample = newModule(vtkpkg, 'vtkSampleFunction')
-setPortValue(sample, 'SetSampleDimensions', (50,50,50))
-sample_qContour = newConnection(sample, 'GetOutputPort0',
-                                qContour, 'SetInputConnection0')
-layoutAndAdd(sample, sample_qContour)
-
-outline = newModule(vtkpkg, 'vtkOutlineFilter')
-outline_mapper = newConnection(outline, 'GetOutputPort0',
-                               oMapper, 'SetInputConnection0')
-sample_outline = newConnection(sample, 'GetOutputPort0',
-                               outline, 'SetInputConnection0')
-layoutAndAdd(outline, [outline_mapper, sample_outline])
-
-quad = newModule(vtkpkg, 'vtkQuadric')
-setPortValue(quad, 'SetCoefficients', (0.5,1,0.2,0,0.1,0,0,0.2,0,0))
-quad_sample = newConnection(quad, 'self',
-                            sample, 'SetImplicitFunction')
-layoutAndAdd(quad, quad_sample)
-
-#write to file
-locator = vistrails.core.db.locator.FileLocator('p189_gaps_preserve_order.vt')
-controller.write_vistrail(locator)
diff --git a/examples/sklearn/cross_val_score.vt b/examples/sklearn/cross_val_score.vt
new file mode 100644
index 0000000..a546c73
Binary files /dev/null and b/examples/sklearn/cross_val_score.vt differ
diff --git a/examples/sklearn/dimensionality_reduction.vt b/examples/sklearn/dimensionality_reduction.vt
new file mode 100644
index 0000000..d7d3287
Binary files /dev/null and b/examples/sklearn/dimensionality_reduction.vt differ
diff --git a/examples/sklearn/grid_search.vt b/examples/sklearn/grid_search.vt
new file mode 100644
index 0000000..5ed1c45
Binary files /dev/null and b/examples/sklearn/grid_search.vt differ
diff --git a/examples/sklearn/pipeline.vt b/examples/sklearn/pipeline.vt
new file mode 100644
index 0000000..d24db83
Binary files /dev/null and b/examples/sklearn/pipeline.vt differ
diff --git a/examples/sklearn/roc_curve.vt b/examples/sklearn/roc_curve.vt
new file mode 100644
index 0000000..b9df33b
Binary files /dev/null and b/examples/sklearn/roc_curve.vt differ
diff --git a/examples/sklearn/scoring.vt b/examples/sklearn/scoring.vt
new file mode 100644
index 0000000..97307bb
Binary files /dev/null and b/examples/sklearn/scoring.vt differ
diff --git a/examples/sklearn/support_vector_machine.vt b/examples/sklearn/support_vector_machine.vt
new file mode 100644
index 0000000..11b63d5
Binary files /dev/null and b/examples/sklearn/support_vector_machine.vt differ
diff --git a/examples/sklearn/svm_decision_function.vt b/examples/sklearn/svm_decision_function.vt
new file mode 100644
index 0000000..8e46ee9
Binary files /dev/null and b/examples/sklearn/svm_decision_function.vt differ
diff --git a/examples/streaming.vt b/examples/streaming.vt
new file mode 100644
index 0000000..8e7c2f2
Binary files /dev/null and b/examples/streaming.vt differ
diff --git a/examples/terminator.vt b/examples/terminator.vt
index f0ba758..4b6e8e7 100644
Binary files a/examples/terminator.vt and b/examples/terminator.vt differ
diff --git a/examples/usersguide/mashups.vt b/examples/usersguide/mashups.vt
index 3d0ad44..706857b 100644
Binary files a/examples/usersguide/mashups.vt and b/examples/usersguide/mashups.vt differ
diff --git a/examples/weather.vt b/examples/weather.vt
new file mode 100644
index 0000000..aeea39c
Binary files /dev/null and b/examples/weather.vt differ
diff --git a/extensions/http/config.php.sample b/extensions/http/config.php.sample
index ca03a09..64aa8bb 100644
--- a/extensions/http/config.php.sample
+++ b/extensions/http/config.php.sample
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/http/get_db_vistrail_list.php b/extensions/http/get_db_vistrail_list.php
index d5830d2..29fbce5 100644
--- a/extensions/http/get_db_vistrail_list.php
+++ b/extensions/http/get_db_vistrail_list.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/http/get_vt_xml.php b/extensions/http/get_vt_xml.php
index e2534b7..12bb5bd 100644
--- a/extensions/http/get_vt_xml.php
+++ b/extensions/http/get_vt_xml.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/http/get_wf_pdf.php b/extensions/http/get_wf_pdf.php
index 9937b57..7767263 100644
--- a/extensions/http/get_wf_pdf.php
+++ b/extensions/http/get_wf_pdf.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/http/get_wf_xml.php b/extensions/http/get_wf_xml.php
index 6e1a59d..31cf79c 100644
--- a/extensions/http/get_wf_xml.php
+++ b/extensions/http/get_wf_xml.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/http/run_vistrails.php b/extensions/http/run_vistrails.php
index b6fc09c..c886a09 100644
--- a/extensions/http/run_vistrails.php
+++ b/extensions/http/run_vistrails.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/latex/crowdlabs.sty b/extensions/latex/crowdlabs.sty
index a9ef2f7..24aa6eb 100644
--- a/extensions/latex/crowdlabs.sty
+++ b/extensions/latex/crowdlabs.sty
@@ -1,34 +1,35 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%
+%% Copyright (C) 2014-2015, New York University.
 %% Copyright (C) 2011-2014, NYU-Poly.
-%% Copyright (C) 2006-2011, University of Utah. 
+%% Copyright (C) 2006-2011, University of Utah.
 %% All rights reserved.
 %% Contact: contact at vistrails.org
 %%
 %% This file is part of VisTrails.
 %%
-%% "Redistribution and use in source and binary forms, with or without 
+%% "Redistribution and use in source and binary forms, with or without
 %% modification, are permitted provided that the following conditions are met:
 %%
-%%  - Redistributions of source code must retain the above copyright notice, 
+%%  - Redistributions of source code must retain the above copyright notice,
 %%    this list of conditions and the following disclaimer.
-%%  - Redistributions in binary form must reproduce the above copyright 
-%%    notice, this list of conditions and the following disclaimer in the 
+%%  - Redistributions in binary form must reproduce the above copyright
+%%    notice, this list of conditions and the following disclaimer in the
 %%    documentation and/or other materials provided with the distribution.
-%%  - Neither the name of the University of Utah nor the names of its 
-%%    contributors may be used to endorse or promote products derived from 
+%%  - Neither the name of the New York University nor the names of its
+%%    contributors may be used to endorse or promote products derived from
 %%    this software without specific prior written permission.
 %%
-%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 %% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 %%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/extensions/latex/example.tex b/extensions/latex/example.tex
index 49fd391..6c08467 100644
--- a/extensions/latex/example.tex
+++ b/extensions/latex/example.tex
@@ -1,34 +1,35 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%
+%% Copyright (C) 2014-2015, New York University.
 %% Copyright (C) 2011-2014, NYU-Poly.
-%% Copyright (C) 2006-2011, University of Utah. 
+%% Copyright (C) 2006-2011, University of Utah.
 %% All rights reserved.
 %% Contact: contact at vistrails.org
 %%
 %% This file is part of VisTrails.
 %%
-%% "Redistribution and use in source and binary forms, with or without 
+%% "Redistribution and use in source and binary forms, with or without
 %% modification, are permitted provided that the following conditions are met:
 %%
-%%  - Redistributions of source code must retain the above copyright notice, 
+%%  - Redistributions of source code must retain the above copyright notice,
 %%    this list of conditions and the following disclaimer.
-%%  - Redistributions in binary form must reproduce the above copyright 
-%%    notice, this list of conditions and the following disclaimer in the 
+%%  - Redistributions in binary form must reproduce the above copyright
+%%    notice, this list of conditions and the following disclaimer in the
 %%    documentation and/or other materials provided with the distribution.
-%%  - Neither the name of the University of Utah nor the names of its 
-%%    contributors may be used to endorse or promote products derived from 
+%%  - Neither the name of the New York University nor the names of its
+%%    contributors may be used to endorse or promote products derived from
 %%    this software without specific prior written permission.
 %%
-%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 %% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 %%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/extensions/latex/head.tex b/extensions/latex/head.tex
index 90e7093..bc4bd98 100644
--- a/extensions/latex/head.tex
+++ b/extensions/latex/head.tex
@@ -1,34 +1,35 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%
+%% Copyright (C) 2014-2015, New York University.
 %% Copyright (C) 2011-2014, NYU-Poly.
-%% Copyright (C) 2006-2011, University of Utah. 
+%% Copyright (C) 2006-2011, University of Utah.
 %% All rights reserved.
 %% Contact: contact at vistrails.org
 %%
 %% This file is part of VisTrails.
 %%
-%% "Redistribution and use in source and binary forms, with or without 
+%% "Redistribution and use in source and binary forms, with or without
 %% modification, are permitted provided that the following conditions are met:
 %%
-%%  - Redistributions of source code must retain the above copyright notice, 
+%%  - Redistributions of source code must retain the above copyright notice,
 %%    this list of conditions and the following disclaimer.
-%%  - Redistributions in binary form must reproduce the above copyright 
-%%    notice, this list of conditions and the following disclaimer in the 
+%%  - Redistributions in binary form must reproduce the above copyright
+%%    notice, this list of conditions and the following disclaimer in the
 %%    documentation and/or other materials provided with the distribution.
-%%  - Neither the name of the University of Utah nor the names of its 
-%%    contributors may be used to endorse or promote products derived from 
+%%  - Neither the name of the New York University nor the names of its
+%%    contributors may be used to endorse or promote products derived from
 %%    this software without specific prior written permission.
 %%
-%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 %% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 %%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/extensions/latex/includecrowdlabs.py b/extensions/latex/includecrowdlabs.py
index b83f62b..9e406e4 100755
--- a/extensions/latex/includecrowdlabs.py
+++ b/extensions/latex/includecrowdlabs.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/extensions/latex/includevistrail.py b/extensions/latex/includevistrail.py
index ada8adf..4bb136f 100755
--- a/extensions/latex/includevistrail.py
+++ b/extensions/latex/includevistrail.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/extensions/latex/vistrails.sty b/extensions/latex/vistrails.sty
index 174fe97..64333b3 100644
--- a/extensions/latex/vistrails.sty
+++ b/extensions/latex/vistrails.sty
@@ -1,34 +1,35 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%
+%% Copyright (C) 2014-2015, New York University.
 %% Copyright (C) 2011-2014, NYU-Poly.
-%% Copyright (C) 2006-2011, University of Utah. 
+%% Copyright (C) 2006-2011, University of Utah.
 %% All rights reserved.
 %% Contact: contact at vistrails.org
 %%
 %% This file is part of VisTrails.
 %%
-%% "Redistribution and use in source and binary forms, with or without 
+%% "Redistribution and use in source and binary forms, with or without
 %% modification, are permitted provided that the following conditions are met:
 %%
-%%  - Redistributions of source code must retain the above copyright notice, 
+%%  - Redistributions of source code must retain the above copyright notice,
 %%    this list of conditions and the following disclaimer.
-%%  - Redistributions in binary form must reproduce the above copyright 
-%%    notice, this list of conditions and the following disclaimer in the 
+%%  - Redistributions in binary form must reproduce the above copyright
+%%    notice, this list of conditions and the following disclaimer in the
 %%    documentation and/or other materials provided with the distribution.
-%%  - Neither the name of the University of Utah nor the names of its 
-%%    contributors may be used to endorse or promote products derived from 
+%%  - Neither the name of the New York University nor the names of its
+%%    contributors may be used to endorse or promote products derived from
 %%    this software without specific prior written permission.
 %%
-%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+%% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+%% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+%% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+%% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+%% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 %% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 %%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/extensions/mediawiki/download.php b/extensions/mediawiki/download.php
index 210d339..ee385ce 100644
--- a/extensions/mediawiki/download.php
+++ b/extensions/mediawiki/download.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/mediawiki/functions.php b/extensions/mediawiki/functions.php
index 1200ff1..848384c 100644
--- a/extensions/mediawiki/functions.php
+++ b/extensions/mediawiki/functions.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/extensions/mediawiki/vistrailsExtension.php b/extensions/mediawiki/vistrailsExtension.php
index 495e768..df7cd57 100644
--- a/extensions/mediawiki/vistrailsExtension.php
+++ b/extensions/mediawiki/vistrailsExtension.php
@@ -1,35 +1,36 @@
 <?php
 ////////////////////////////////////////////////////////////////////////////
 //
+// Copyright (C) 2014-2015, New York University.
 // Copyright (C) 2011-2014, NYU-Poly.
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the New York University nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////
diff --git a/scripts/add_future_import.py b/scripts/add_future_import.py
new file mode 100755
index 0000000..2d40e8a
--- /dev/null
+++ b/scripts/add_future_import.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python
+from __future__ import absolute_import, unicode_literals
+
+import argparse
+import logging
+import re
+from rpaths import Path
+import sys
+
+
+def to_bytes(s):
+    if isinstance(s, bytes):
+        return s
+    else:
+        return s.encode('ascii')
+
+
+FUTURES = set([b'absolute_import', b'division', b'print_function',
+               b'unicode_literals'])
+
+
+def make_import_statement(imports):
+    statement = b'from __future__ import '
+    for i, feature in enumerate(imports):
+        notfirst = 2 if i != 0 else 0
+        notlast = 4 if i != len(imports) - 1 else 0
+
+        if len(statement) + notfirst + len(feature) + notlast <= 79:
+            statement += (b', ' if notfirst else b'') + feature
+        else:
+            statement += (b', ' if notfirst else b'') + b'\\\n' + feature
+    return statement + b'\n'
+
+
+re_whitespace = re.compile(br'^\s*$')
+re_comment = re.compile(br'^\s*#')
+re_import = re.compile(br'^\s*from\s+__future__\s+import(\s.+)$')
+
+
+def process_file(filename, enable):
+    logging.debug("Processing %s..." % filename)
+    with filename.open('rb') as fp:
+        lines = fp.readlines()
+
+    # Look for an import statement to check or fix
+    i = 0
+    nb = 0
+    done = False
+    while i < len(lines):
+        nb += 1
+        line = lines[i]
+
+        # Merges lines on ending backslash
+        if line.rstrip(b'\r\n').endswith(b'\\'):
+            line += lines.pop(i+1)
+            lines[i] = line
+
+        f_import = re_import.match(line)
+        if f_import is not None:
+            imports = f_import.group(1).strip(b' \t\r\n()').split(b',')
+            imports = [feature.strip() for feature in imports]
+            missing = enable - set(imports)
+            if not missing:
+                logging.debug("Found needed imports (line %d)" % nb)
+                done = True
+            else:
+                logging.debug("Enabling imports: %s (line %d)" % (
+                              ', '.join(missing),
+                              nb))
+                imports = sorted(set(imports) | enable)
+                line = make_import_statement(imports)
+                lines[i] = line
+                done = True
+                break
+
+        i += 1
+
+    # Didn't find a statement, must add one
+    # Where? Before first non-comment and non-docstring line
+    if not done:
+        i = 0
+        docstring_seen = False
+        while i < len(lines):
+            line = lines[i]
+            if re_whitespace.match(line):
+                pass
+            elif re_comment.match(line):
+                pass
+            elif not docstring_seen and '"""' in line:
+                if line.count('"""') == 1:
+                    i += 1
+                    while '"""' not in lines[i]:
+                        i += 1
+                docstring_seen = True
+            elif not docstring_seen and "'''" in line:
+                if line.count("'''") == 1:
+                    i += 1
+                    while "'''" not in lines[i]:
+                        i += 1
+                docstring_seen = True
+            else:
+                # Code here! Insert before
+                logging.debug("Inserting imports (line %d)" % (i + 1))
+                lines.insert(i, make_import_statement(enable) + b'\n')
+                break
+            i += 1
+
+    with filename.open('wb') as fp:
+        fp.writelines(lines)
+
+
+def main():
+    parser = argparse.ArgumentParser(
+            description="Adds __future__ imports to Python files")
+    parser.add_argument('-v', '--verbose', action='count', dest='verbosity',
+                        default=1)
+    parser.add_argument('-e', '--enable', action='append',
+                        help="Future import to enable")
+    parser.add_argument('file',
+                        nargs=argparse.ONE_OR_MORE,
+                        help="File or directory in which to replace")
+    args = parser.parse_args()
+    levels = [logging.CRITICAL, logging.WARNING, logging.INFO, logging.DEBUG]
+    logging.basicConfig(level=levels[args.verbosity])
+
+    if not args.enable:
+        logging.critical("Nothing to do")
+        sys.exit(1)
+
+    enable = set(to_bytes(feature) for feature in args.enable)
+    unrecognized = enable - FUTURES
+    if unrecognized:
+        logging.critical("Error: unknown futures %s" % ', '.join(unrecognized))
+        sys.exit(1)
+
+    for target in args.file:
+        target = Path(target)
+        if target.is_file():
+            if not target.name.endswith('.py'):
+                logging.warning("File %s doesn't end with .py, processing "
+                                "anyway..." % target)
+            process_file(target, enable)
+        elif target.is_dir():
+            logging.info("Processing %s recursively..." % target)
+            for filename in target.recursedir('*.py'):
+                process_file(filename, enable)
+        else:
+            logging.warning("Skipping %s..." % target)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/scripts/build_usersguide.py b/scripts/build_usersguide.py
index 9099572..b8d95ee 100755
--- a/scripts/build_usersguide.py
+++ b/scripts/build_usersguide.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -46,18 +47,25 @@ import subprocess
 import sys
 import time
 ### Begin configuration ###
+
+# Should we build the pdf version
+BUILD_PDF = True
+
+# Should we build the html version
+BUILD_HTML = False
+
 # Folder where vistrails is
-PATH_TO_VISTRAILS_GIT = "/Users/emanuele/code/vistrails"
+PATH_TO_VISTRAILS_GIT = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
 
 # Folder where the html files will be placed. This script will build
 # the docs in the standard location and move files later
 HTML_FOLDER = None
 
 # Complete file path to where copy final pdf file
-PDF_FILE = "/Users/vistrails/code/vistrails/dist/mac/dist/VisTrails/doc/VisTrails.pdf"
+PDF_FILE = os.path.join(PATH_TO_VISTRAILS_GIT, "scripts", "VisTrails.pdf")
 
 # Should we run a `git pull` before building docs? 
-PERFORM_GIT_PULL = True
+PERFORM_GIT_PULL = False
 
 ### End configuration ### 
 ### The following variables usually don't need to be changed
@@ -66,8 +74,12 @@ GIT_PULL_CMD = ["git", "pull"]
 BUILD_HTML_SUBPATH = ["_build", "html"]
 BUILD_LATEX_SUBPATH = ["_build", "latex"]
 PDF_BUILD_NAME = "VisTrails.pdf"
+if len(sys.argv)>1:
+    PDF_FILE = os.path.abspath(sys.argv[1])
+    if PDF_FILE[-4:] != '.pdf':
+        PDF_FILE = os.path.join(PDF_FILE, PDF_BUILD_NAME)
 if __name__ == '__main__':
-    if (PATH_TO_VISTRAILS_GIT is not None and 
+    if (PATH_TO_VISTRAILS_GIT is not None and
         os.path.exists(PATH_TO_VISTRAILS_GIT)):
         current_folder = os.getcwd()
         if PERFORM_GIT_PULL:
@@ -83,86 +95,82 @@ if __name__ == '__main__':
                 if proc.stdout:
                     print proc.stdout.readlines()
         
+        # The api needs path to source set
+        env = os.environ.copy()
+        env['PYTHONPATH'] = PATH_TO_VISTRAILS_GIT
+
         os.chdir(os.path.join(PATH_TO_VISTRAILS_GIT,
                               *USERSGUIDE_SUBPATH))
         
         print "Going into directory %s"%os.getcwd()
-        # now build html documentation    
-        print "now building html documentation..."
-        proc = subprocess.Popen(["make", "html"],
-                                stdin=subprocess.PIPE,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
-        proc.wait()
-        if proc.returncode != 0:
-            print "ERROR: make html failed."
-            if proc.stdout:
-                print proc.stdout.readlines()
-        else:
-            # now move files to their final place
-            if HTML_FOLDER is not None:
-                if os.path.exists(HTML_FOLDER):
-                    shutil.rmtree(HTML_FOLDER)
-                html_build = os.path.join(os.getcwd(),
-                                          *BUILD_HTML_SUBPATH)
-            
-                shutil.move(html_build, HTML_FOLDER)
-        
-        #build latex files
-        print "now preparing latex files..."
-        latex_path = os.path.join(".",
-                                  *BUILD_LATEX_SUBPATH)
-        if os.path.exists(latex_path):
-            print "removing old %s directory..."%latex_path
-            proc = subprocess.Popen(["rm", "-rf", latex_path],
+        if BUILD_HTML:
+            # now build html documentation    
+            print "now building html documentation..."
+            proc = subprocess.Popen(["make", "html"],
                                     stdin=subprocess.PIPE,
                                     stdout=subprocess.PIPE,
-                                    stderr=subprocess.STDOUT)
+                                    stderr=subprocess.STDOUT,
+                                    env=env)
             proc.wait()
-        print "building latex files..."
-        proc = subprocess.Popen(["make", "latex"],
-                                stdin=subprocess.PIPE,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
-        proc.wait()
-        if proc.returncode != 0:
-            print "ERROR: make latex failed."
-            if proc.stdout:
-                print proc.stdout.readlines()
-        else:
-            #now build pdf
-            print "now building pdf file..."
-            os.chdir(os.path.join(os.getcwd(),
-                     *BUILD_LATEX_SUBPATH))
-            proc = subprocess.Popen(["make", "all-pdf"],
-                                stdin=subprocess.PIPE,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
-            # when the pdflatex command fails, it waits indefinitely for user
-            #input. We will wait for up to 90 seconds and terminate the process
-            result = None 
-            i = 0
-            while (result == None and i < 15):
-                result = proc.poll()
-                time.sleep(20)
-                i += 1
-                print proc.stdout.readlines()
-                sys.stdout.flush()
-            if result == None:
-                proc.terminate()
-                print "ERROR: make all-pdf failed."
+            if proc.returncode != 0:
+                print "ERROR: make html failed."
                 if proc.stdout:
                     print proc.stdout.readlines()
-            elif proc.returncode != 0:
-                print "ERROR: make all-pdf failed."
+            else:
+                # now move files to their final place
+                if HTML_FOLDER is not None:
+                    if os.path.exists(HTML_FOLDER):
+                        shutil.rmtree(HTML_FOLDER)
+                    html_build = os.path.join(os.getcwd(),
+                                              *BUILD_HTML_SUBPATH)
+                    shutil.move(html_build, HTML_FOLDER)
+
+        if BUILD_PDF:
+            print "Building usersguide to ", PDF_FILE
+            #build latex files
+            print "now preparing latex files..."
+            latex_path = os.path.join(".",
+                                  *BUILD_LATEX_SUBPATH)
+            if os.path.exists(latex_path):
+                print "removing old %s directory..."%latex_path
+                proc = subprocess.Popen(["rm", "-rf", latex_path],
+                                        stdin=subprocess.PIPE,
+                                        stdout=subprocess.PIPE,
+                                        stderr=subprocess.STDOUT)
+                proc.wait()
+            print "building latex files..."
+            proc = subprocess.Popen(["make", "latex"],
+                                    stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT,
+                                    env=env)
+            proc.wait()
+            if proc.returncode != 0:
+                print "ERROR: make latex failed."
                 if proc.stdout:
                     print proc.stdout.readlines()
             else:
-                #now move file to its final place
-                if PDF_FILE is not None:
-                    pdf_build = os.path.join(os.getcwd(),
-                                             PDF_BUILD_NAME)
-                    shutil.move(pdf_build, PDF_FILE)
+                #now build pdf
+                print "now building pdf file..."
+                os.chdir(os.path.join(os.getcwd(),
+                         *BUILD_LATEX_SUBPATH))
+                proc = subprocess.Popen(["make", "LATEXOPTS=-interaction=nonstopmode -halt-on-error", "all-pdf"],
+                                    stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT,
+                                    env=env)
+                output, error = proc.communicate()
+                if proc.returncode != 0:
+                    print "ERROR: make all-pdf failed."
+                    print output, error
+                else:
+                    #now move file to its final place
+                    if PDF_FILE is not None:
+                        if os.path.exists(PDF_FILE):
+                            os.unlink(PDF_FILE)
+                        pdf_build = os.path.join(os.getcwd(),
+                                                 PDF_BUILD_NAME)
+                        shutil.move(pdf_build, PDF_FILE)
         os.chdir(current_folder)
         print "Done."
     else:
diff --git a/scripts/convert_files/convert_files.sh b/scripts/convert_files/convert_files.sh
index 410bd5d..7209246 100755
--- a/scripts/convert_files/convert_files.sh
+++ b/scripts/convert_files/convert_files.sh
@@ -1,35 +1,36 @@
 #!/bin/sh
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/convert_files/fix_file.py b/scripts/convert_files/fix_file.py
index 25d61c3..5fbd2d8 100644
--- a/scripts/convert_files/fix_file.py
+++ b/scripts/convert_files/fix_file.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/create_release_wiki_table.py b/scripts/create_release_wiki_table.py
index 1ec8d3d..1452174 100644
--- a/scripts/create_release_wiki_table.py
+++ b/scripts/create_release_wiki_table.py
@@ -6,12 +6,11 @@ wiki page
 """
 from datetime import date
 #Release version
-VT_VERSION = "2.1.4"
-VT_REVISION = "8262f078ed3b"
-
+VT_VERSION = "2.2"
+VT_REVISION = "422e1a9bbc1c"
 #Sourceforge information
 SF_ROOT_URL = "http://downloads.sourceforge.net/project/vistrails/vistrails/"
-SF_FOLDER_NAME = "v2.1.1"
+SF_FOLDER_NAME = "v2.2"
 SF_DOWNLOAD_URL = "%s%s"%(SF_ROOT_URL,SF_FOLDER_NAME)
 #binaries names
 MAC_64_BIN = "vistrails-mac-10.6-intel-%s-%s.dmg"%(VT_VERSION, VT_REVISION)
@@ -22,11 +21,11 @@ ALL_PLAT_SRC = "vistrails-src-%s-%s.tar.gz"%(VT_VERSION, VT_REVISION)
 USERSGUIDE = "VisTrails.pdf"
 
 #sizes
-MAC_64_SIZE = "182.3 MB"
-WIN_32_SIZE = "125.3 MB"
-WIN_64_SIZE = "150 MB"
-ALL_PLAT_SIZE = "19.2 MB"
-USERSGUIDE_SIZE = "8.7 MB"
+MAC_64_SIZE = "270.2 MB"
+WIN_32_SIZE = "173.9 MB"
+WIN_64_SIZE = "234.6 MB"
+ALL_PLAT_SIZE = "22.3 MB"
+USERSGUIDE_SIZE = "8.9 MB"
 
 def create_text():
     today = date.today().strftime("%Y-%m-%d")
diff --git a/scripts/create_server_media_dir_structure.py b/scripts/create_server_media_dir_structure.py
index 69d0e6c..d69bb1b 100644
--- a/scripts/create_server_media_dir_structure.py
+++ b/scripts/create_server_media_dir_structure.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/db_utils.py b/scripts/db_utils.py
index eaec86e..421dae8 100644
--- a/scripts/db_utils.py
+++ b/scripts/db_utils.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/delete_from_db.py b/scripts/delete_from_db.py
old mode 100644
new mode 100755
index 5212fb3..4433b0e
--- a/scripts/delete_from_db.py
+++ b/scripts/delete_from_db.py
@@ -1,34 +1,36 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/diff_package.py b/scripts/diff_package.py
old mode 100644
new mode 100755
index 3260e0c..222e3aa
--- a/scripts/diff_package.py
+++ b/scripts/diff_package.py
@@ -1,34 +1,36 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/extract.py b/scripts/extract.py
old mode 100644
new mode 100755
index 5475bfb..d2a696c
--- a/scripts/extract.py
+++ b/scripts/extract.py
@@ -1,34 +1,36 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,23 +38,25 @@ from PyQt4 import QtCore
 import imp
 import sys
 
-def copyDir(src, dst):
+
+def copy_dir(src, dst):
     for info in src.entryInfoList():
         if info.isDir():
             dst.mkdir(info.fileName())
             src.cd(info.fileName())
             dst.cd(info.fileName())
-            copyDir(src, dst)
+            copy_dir(src, dst)
             src.cd('..')
             dst.cd('..')
         elif info.isFile():
             QtCore.QFile.copy(info.filePath(), dst.filePath(info.fileName()))
-        
-if __name__=="__main__":
-    if len(sys.argv)!=2:
+
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
         print "Usage: python extract.py resource_rc"
         sys.exit(0)
 
-    moduleName = sys.argv[1]
-    imp.load_source('resModule', moduleName)
-    copyDir(QtCore.QDir(":"), QtCore.QDir("."))
+    module_name = sys.argv[1]
+    imp.load_source('resModule', module_name)
+    copy_dir(QtCore.QDir(":"), QtCore.QDir("."))
diff --git a/scripts/force_start_vistrails.py b/scripts/force_start_vistrails.py
index feb60db..f157787 100755
--- a/scripts/force_start_vistrails.py
+++ b/scripts/force_start_vistrails.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/force_start_vistrails_nonohup.py b/scripts/force_start_vistrails_nonohup.py
index d5b1a55..9b726bb 100755
--- a/scripts/force_start_vistrails_nonohup.py
+++ b/scripts/force_start_vistrails_nonohup.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/check_diffs.py b/scripts/gen_vtk_examples/check_diffs.py
index 186c071..4254ce2 100644
--- a/scripts/gen_vtk_examples/check_diffs.py
+++ b/scripts/gen_vtk_examples/check_diffs.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/colors.py b/scripts/gen_vtk_examples/colors.py
index af703d0..71a5cfa 100644
--- a/scripts/gen_vtk_examples/colors.py
+++ b/scripts/gen_vtk_examples/colors.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/convert_to_vt.py b/scripts/gen_vtk_examples/convert_to_vt.py
index ad600ed..767786c 100644
--- a/scripts/gen_vtk_examples/convert_to_vt.py
+++ b/scripts/gen_vtk_examples/convert_to_vt.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/copy_vtk_examples.py b/scripts/gen_vtk_examples/copy_vtk_examples.py
index bc0e20f..3eb9701 100644
--- a/scripts/gen_vtk_examples/copy_vtk_examples.py
+++ b/scripts/gen_vtk_examples/copy_vtk_examples.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/gen_vtk_examples.py b/scripts/gen_vtk_examples/gen_vtk_examples.py
index ee7ba28..6358993 100644
--- a/scripts/gen_vtk_examples/gen_vtk_examples.py
+++ b/scripts/gen_vtk_examples/gen_vtk_examples.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/get_vtk_examples.py b/scripts/gen_vtk_examples/get_vtk_examples.py
index 95f254f..4d5bd9a 100644
--- a/scripts/gen_vtk_examples/get_vtk_examples.py
+++ b/scripts/gen_vtk_examples/get_vtk_examples.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/vtk_imposter.py b/scripts/gen_vtk_examples/vtk_imposter.py
index 5c02174..3097989 100644
--- a/scripts/gen_vtk_examples/vtk_imposter.py
+++ b/scripts/gen_vtk_examples/vtk_imposter.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/gen_vtk_examples/vtk_to_vt.py b/scripts/gen_vtk_examples/vtk_to_vt.py
index 4d2a705..d13ef59 100644
--- a/scripts/gen_vtk_examples/vtk_to_vt.py
+++ b/scripts/gen_vtk_examples/vtk_to_vt.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -215,7 +216,7 @@ class VTK2VT(object):
             package_name = self.basic_name
         elif module_name == 'PythonCalc':
             package_name = self.pythoncalc_name
-        elif module_name == 'HTTPFile':
+        elif module_name == 'DownloadFile':
             package_name = self.http_name
         db_module = DBModule(id=self.max_module_id,
                              name=module_name,
@@ -687,9 +688,9 @@ class VTK2VT(object):
                     type(function.parent) == vtk_module and \
                     len(function._args) == 1 and \
                     type(function._args[0]) == str:
-                # replace SetFileName with a HTTPFile -> Unzip -> SetFile
+                # replace SetFileName with a DownloadFile -> Unzip -> SetFile
                 if not self.http_module:
-                    self.http_module = vtk_module('HTTPFile')
+                    self.http_module = vtk_module('DownloadFile')
                     self.http_module.url(self.vtk_data_url)
                     self.create_module(self.http_module)
                     self.create_functions(self.http_module)
diff --git a/scripts/generate_pkg_doc.py b/scripts/generate_pkg_doc.py
new file mode 100755
index 0000000..47cf955
--- /dev/null
+++ b/scripts/generate_pkg_doc.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+import itertools
+import sys
+
+import vistrails.core.application
+from vistrails.core.api import Package
+from vistrails.core.modules.module_registry import get_module_registry
+
+heading_order = ['*', '=', '^', '-', '"', '+', '#']
+
+def trim_docstring(docstring):
+    """Copied from PEP 257: http://www.python.org/dev/peps/pep-0257/"""
+    if not docstring:
+        return ''
+    # Convert tabs to spaces (following the normal Python rules)
+    # and split into a list of lines:
+    lines = docstring.expandtabs().splitlines()
+    # Determine minimum indentation (first line doesn't count):
+    indent = sys.maxint
+    for line in lines[1:]:
+        stripped = line.lstrip()
+        if stripped:
+            indent = min(indent, len(line) - len(stripped))
+    # Remove indentation (first line is special):
+    trimmed = [lines[0].strip()]
+    if indent < sys.maxint:
+        for line in lines[1:]:
+            trimmed.append(line[indent:].rstrip())
+    # Strip off trailing and leading blank lines:
+    while trimmed and not trimmed[-1]:
+        trimmed.pop()
+    while trimmed and not trimmed[0]:
+        trimmed.pop(0)
+    # Return a single string:
+    return '\n'.join(trimmed)
+
+def indent_docstring(docstring, indent=0):
+    new_docstring = ""
+    for line in docstring.splitlines():
+        new_docstring += (" " * indent) + line + "\n"
+    return new_docstring
+
+def format_docstring(docstring, indent=0):
+    return indent_docstring(trim_docstring(docstring), indent)
+
+def get_examples(desc):
+    return []
+
+def generate_module_doc(desc, f=None, depth=1, inherited=True):
+    reg = get_module_registry()
+    print >>f, desc.name
+    print >>f, heading_order[depth] * len(desc.name)
+    print >>f, ""
+    print >>f, ".. py:class:: %s" % desc.name
+    print >>f, ""
+    if desc.module.__doc__:
+        print >>f, format_docstring(desc.module.__doc__, 2)
+        print >>f, ""
+
+    if inherited:
+        input_ports = reg.module_destination_ports_from_descriptor(True, desc)
+        output_ports = reg.module_source_ports_from_descriptor(True, desc)
+    else:
+        input_ports = reg.module_ports('input', desc).values()
+        input_ports.sort(key=lambda x: (x.sort_key, x.id))
+        output_ports = reg.module_ports('output', desc).values()
+        output_ports.sort(key=lambda x: (x.sort_key, x.id))
+        
+    if len(input_ports) > 0:
+        print >>f, "  *Input Ports*"
+        for port in input_ports:
+            sigstring = port.sigstring.replace(':', '.')[1:-1]
+            print >>f, "    .. py:attribute:: %s" % port.name
+            print >>f, ""            
+            print >>f, "      | *Signature*: :py:class:`%s`" % sigstring
+            if port.docstring():
+                print >>f, "      | *Description*: %s" % format_docstring(port.docstring(), 9)
+            print >>f, ""
+    if len(output_ports) > 0:
+        print >>f, "  *Output Ports*"
+        for port in output_ports:
+            sigstring = port.sigstring.replace(':', '.')[1:-1]
+            print >>f, "    .. py:attribute:: %s" % port.name
+            print >>f, ""            
+            print >>f, "      | *Signature*: :py:class:`%s`" % sigstring
+            if port.docstring():
+                print >>f, "      | *Description*: %s" % format_docstring(port.docstring(), 9)
+            print >>f, ""
+
+    examples = get_examples(desc)
+    if len(examples) > 0:
+        print >>f, "  *Examples*"
+        for example in examples:
+            print >>f, "   * %s" % example
+        print >>f, ""
+
+def generate_docs(pkg, namespace=None, f=None):
+    print >>f, pkg._package.name
+    print >>f, heading_order[0] * len(pkg._package.name)
+    print >>f, ""
+    print >>f, ".. py:module:: %s\n" % pkg._package.identifier
+    print >>f, '| *Identifier*: %s' % pkg._package.identifier
+    print >>f, '| *Version*: %s\n' % pkg._package.version
+    print >>f, format_docstring(pkg._package.description, 0)
+    print >>f, ""
+    
+    if namespace == '':
+        for desc in pkg._namespaces[1]:
+            generate_module_doc(desc, f, 1)
+    else:
+        if namespace is None:
+            namespace = ''
+            for desc in pkg._namespaces[1]:
+                generate_module_doc(desc, f)
+            namespaces = sorted(item + (1,) for item in 
+                                pkg._namespaces[0].iteritems())
+        else:
+            namespace_dict = pkg._namespaces[0]
+            descs = pkg._namespaces[1]
+            split_ns = namespace.split('|')
+            for i, ns in enumerate(split_ns):
+                print >>f, ns
+                print >>f, heading_order[i+1] * len(ns)
+                print >>f, ""
+                (namespace_dict, descs) = namespace_dict[ns]
+            namespaces = [(namespace, (namespace_dict, descs), len(split_ns))]
+        
+        for (ns, (child_namespaces, descs), depth) in namespaces:
+            print >>f, ns
+            print >>f, heading_order[depth] * len(ns)
+            print >>f, ""
+            for desc in descs:
+                generate_module_doc(desc, f, depth+1)
+            namespaces = \
+                itertools.chain([(ns + '|' + c[0], c[1]) 
+                                 for c in child_namespaces.iteritems()],
+                                namespaces, depth+1)
+
+def run():
+    vistrails.core.application.init()
+    pkg = Package("org.vistrails.vistrails.basic")
+    # pkg = Package("org.vistrails.vistrails.matplotlib")
+    generate_docs(pkg)
+
+if __name__ == '__main__':
+    run()
diff --git a/scripts/get_usersguide.py b/scripts/get_usersguide.py
new file mode 100755
index 0000000..071bd48
--- /dev/null
+++ b/scripts/get_usersguide.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+import os.path
+import subprocess
+import sys
+import urllib2
+
+this_dir = os.path.dirname(os.path.abspath(__file__))
+
+DOWNLOAD_URL = "http://www.vistrails.org/usersguide/dev/html/VisTrails.pdf"
+SAVE_TO = os.path.abspath(sys.argv[1]) if len(sys.argv) > 1 else this_dir
+
+# http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
+def which(program):
+    import os
+    def is_exe(fpath):
+        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+    fpath, fname = os.path.split(program)
+    if fpath:
+        if is_exe(program):
+            return program
+    else:
+        for path in os.environ["PATH"].split(os.pathsep):
+            path = path.strip('"')
+            exe_file = os.path.join(path, program)
+            if is_exe(exe_file):
+                return exe_file
+
+    return None
+
+def download_usersguide():
+    print "Downloading usersguide from", DOWNLOAD_URL
+    response = urllib2.urlopen(DOWNLOAD_URL)
+    filename = os.path.join(SAVE_TO,
+                            DOWNLOAD_URL.split('/')[-1])
+    f = open(filename, 'wb')
+    f.write(response.read())
+    f.close()
+    
+if __name__ == "__main__":
+    if which('sphinx-build') is None:
+        print "Sphinx is not installed!"
+        download_usersguide()
+    elif which('pdflatex') is None:
+        print "pdflatex is not installed!"
+        download_usersguide()
+    else:
+        cwd = os.getcwd()
+        os.chdir(this_dir)
+        # Build usersguide
+        proc = subprocess.Popen(['./build_usersguide.py', SAVE_TO],
+                                stdin=subprocess.PIPE,
+                                stdout=subprocess.PIPE,
+                                stderr=subprocess.STDOUT)
+        proc.wait()
+        if proc.returncode != 0:
+            print "ERROR: building usersguide failed."
+            if proc.stdout:
+                print proc.stdout.readlines()        
+            sys.exit(1)
+        os.chdir(this_dir)
+
diff --git a/scripts/mac_update_bin.sh b/scripts/mac_update_bin.sh
index 0c504a0..9c3e7a3 100755
--- a/scripts/mac_update_bin.sh
+++ b/scripts/mac_update_bin.sh
@@ -1,35 +1,36 @@
 #!/bin/bash
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -62,27 +63,27 @@ for dir in $OLD_DIRS
 do
     if [ -e "$2/$BIN_PATH/$dir" ]
     then
-        rm -r $2/$BIN_PATH/$dir
+        rm -r "$2/$BIN_PATH/$dir"
     fi
 done
 
 if [ -e "$2/$BIN_PATH/$ROOT_DIR_NAME" ]
 then
-    rm -r $2/$BIN_PATH/$ROOT_DIR_NAME
+    rm -r "$2/$BIN_PATH/$ROOT_DIR_NAME"
 fi
-ln -s -f -F $1/$ROOT_DIR_NAME $2/$BIN_PATH/$ROOT_DIR_NAME
+ln -s -f -F "$1/$ROOT_DIR_NAME" "$2/$BIN_PATH/$ROOT_DIR_NAME"
 
 if [ -e "$2/$BIN_PATH/../../run.py" ]
 then
-    rm $2/$BIN_PATH/../../run.py
+    rm "$2/$BIN_PATH/../../run.py"
 fi
-ln -s -f -F $1/$ROOT_DIR_NAME/run.py $2/$BIN_PATH/../../run.py
+ln -s -f -F "$1/$ROOT_DIR_NAME/run.py" "$2/$BIN_PATH/../../run.py"
 
 if [ -e "$2/../$EXAMPLES_DIR_NAME" ]
 then
-    rm -r $2/../$EXAMPLES_DIR_NAME
+    rm -r "$2/../$EXAMPLES_DIR_NAME"
 fi
-ln -s -f -F $1/$EXAMPLES_DIR_NAME $2/../$EXAMPLES_DIR_NAME
+ln -s -f -F "$1/$EXAMPLES_DIR_NAME" "$2/../$EXAMPLES_DIR_NAME"
 
 
 exit 0
diff --git a/scripts/merge_vistrails.py b/scripts/merge_vistrails.py
old mode 100644
new mode 100755
index 79769e7..e0c86bc
--- a/scripts/merge_vistrails.py
+++ b/scripts/merge_vistrails.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/module_appearance/main.py b/scripts/module_appearance/main.py
index 714b18a..2304aaa 100755
--- a/scripts/module_appearance/main.py
+++ b/scripts/module_appearance/main.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/module_appearance/module_appearance.py b/scripts/module_appearance/module_appearance.py
index 78fd520..2e9831b 100644
--- a/scripts/module_appearance/module_appearance.py
+++ b/scripts/module_appearance/module_appearance.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/opm/opm2dot.py b/scripts/opm/opm2dot.py
index a9de8ae..f7c65b2 100644
--- a/scripts/opm/opm2dot.py
+++ b/scripts/opm/opm2dot.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/release_notes.py b/scripts/release_notes.py
index 61c4ec4..2c7c157 100755
--- a/scripts/release_notes.py
+++ b/scripts/release_notes.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -49,7 +50,7 @@ import subprocess
 import shutil
 
 #### configuration ####
-commit_start = "8262f078ed3b" # hash of version used on last release notes
+commit_start = "269e4808eca3" # hash of version used on last release notes
 commit_end = "HEAD" # current hash
 branch = "v2.1" # git branch to be used
 release_name = "2.1.4"
@@ -57,7 +58,7 @@ clonepath = None    # set this to the complete path of a vistrails clone to be
                     # used
                     # if None, the remote repository will be cloned to a
                     # temporary folder and removed at the end of the script
-clonepath = '/Users/tommy/git/vistrails'
+#clonepath = '/Users/tommy/git/vistrails'
 cloneremote = 'git://www.vistrails.org/vistrails.git'
 #### end configuration #####
 
@@ -68,6 +69,7 @@ password = None
 need_cleanup = False
 
 ################################################################################
+
 def userpass(realm, u, may_save):
     global username
     global password
@@ -80,6 +82,11 @@ def userpass(realm, u, may_save):
 
 ################################################################################
 
+def rstrip(s):
+    return '\n'.join(l.rstrip() for l in s.splitlines())
+
+################################################################################
+
 def clone_vistrails_git_repository(path_to):
     global cloneremote
     cmdlist = ['git', 'clone', cloneremote,
@@ -131,7 +138,7 @@ def cleanup_repo():
     global clonepath, need_cleanup
     if need_cleanup:
         shutil.rmtree(clonepath)
-        
+
 ################################################################################
 
 def init_branch(path_to, branch):
@@ -149,7 +156,7 @@ def init_branch(path_to, branch):
         print "   ", line
     if process.returncode == 0:
         print "Branch %s was checked out."%branch
-    os.chdir(current_dir)    
+    os.chdir(current_dir)
     return process.returncode
 
 ################################################################################
@@ -169,7 +176,7 @@ def pull_changes(path_to):
         print "   ", line
     if process.returncode == 0:
         print "Changes were pulled."
-    os.chdir(current_dir)    
+    os.chdir(current_dir)
     return process.returncode
 
 ################################################################################
@@ -184,7 +191,7 @@ def build_release_notes(repo, branch):
     global username
     global password
     global commit_start, commit_end
-    
+
     def check_inside_skip(skip_list, message):
         found = False
         for s in skip_list:
@@ -192,7 +199,7 @@ def build_release_notes(repo, branch):
                 found = True
                 break
         return found
-    
+
     re_ticket_old = re.compile(r'<ticket>(.*?)</ticket>', re.M | re.S)
     re_ticket = re.compile(r'^Ticket: (.*?)$', re.M | re.S)
     re_ticket2 = re.compile(r'^Fixes: (.*?)$', re.M | re.S)
@@ -209,14 +216,14 @@ def build_release_notes(repo, branch):
     for c in repo.iter_commits("%s..%s"%(commit_start,commit_end)):
         logs.append(c)
         log_map_time[c.hexsha] = c.committed_date
-        
+
     #populate dictionaries
     bugfixes = {}
     tickets = {}
     features = {}
     changes = {}
     ticket_info = {}
-    
+
     for log in logs:
         ls = re_skip.findall(log.message)
         lf = re_feature.findall(log.message)
@@ -243,7 +250,7 @@ def build_release_notes(repo, branch):
             bugfixes[b.strip()] = log.hexsha
         if len(ls) == 0 and len(lf) == 0 and len(lt) == 0 and len(lb) == 0:
             changes[log.message] = log.hexsha
-                
+
 
     #get ticket summaries from xmlrpc plugin installed on vistrails trac
     print "Will connect to VisTrails Trac with authentication..."
@@ -285,8 +292,8 @@ def build_release_notes(repo, branch):
     print "Release Name: v%s build %s from %s branch" % (release_name,
                                                          commit_end[0:12],
                                                          branch)
-    print 
-    print "Enhancements: "
+    print
+    print "Enhancements:"
     times = []
     for t, r in features.iteritems():
         times.append((log_map_time[r], t))
@@ -294,10 +301,10 @@ def build_release_notes(repo, branch):
     revisions.reverse()
     for (t,text) in revisions:
         r = features[text]
-        print " - %s (%s)" %(text,r[0:12])
-    
+        print " - %s (%s)" %(rstrip(text),r[0:12])
+
     print
-    print "Bug fixes: "
+    print "Bug fixes:"
     times = []
     for t, r in bugfixes.iteritems():
         times.append((log_map_time[r], t))
@@ -305,10 +312,10 @@ def build_release_notes(repo, branch):
     revisions.reverse()
     for (t,text) in revisions:
         r = bugfixes[text]
-        print " - %s (%s)" %(text,r[0:12])
+        print " - %s (%s)" %(rstrip(text),r[0:12])
 
     print
-    print "Other changes: "
+    print "Other changes:"
     times = []
     for t, r in changes.iteritems():
         times.append((log_map_time[r], t))
@@ -316,11 +323,9 @@ def build_release_notes(repo, branch):
     revisions.reverse()
     for (t,text) in revisions:
         r = changes[text]
-        print " - %s (%s)" %(text.split('\n')[0][0:100],r[0:12])
+        print " - %s (%s)" %(text.split('\n')[0][0:100].rstrip(),r[0:12])
 
 if __name__ == "__main__":
     repo = init_repo()
     build_release_notes(repo, branch)
     cleanup_repo()
-
-
diff --git a/scripts/restart-vistrails-server.sh b/scripts/restart-vistrails-server.sh
index a9b1a41..1ca0876 100755
--- a/scripts/restart-vistrails-server.sh
+++ b/scripts/restart-vistrails-server.sh
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/retarget_mpl_libs.sh b/scripts/retarget_mpl_libs.sh
new file mode 100755
index 0000000..e9a7d28
--- /dev/null
+++ b/scripts/retarget_mpl_libs.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+# The script fixes up the links to make the matplotlib installation
+# self-contained in the VisTrails.app bundle
+
+# Note that you'll need to get the libpng12.0.dylib and
+# libfreetype.6.dylib libaries (perhaps from an XQuartz installation)
+# and then copy them to <bin_dir>/Contents/Frameworks before running
+# the script
+
+BIN_PATH_25="Contents/Resources/lib/python2.5"
+BIN_PATH_26="Contents/Resources/lib/python2.6"
+BIN_PATH_27="Contents/Resources/lib/python2.7"
+FRAMEWORK_PATH="@executable_path/../Frameworks"
+X11_PATH="/usr/X11/lib"
+
+MPL_LIB_DIR="matplotlib"
+PNG_LIB="libpng12.0.dylib"
+PNG_REFS="_png.so"
+FT_LIB="libfreetype.6.dylib"
+FT_REFS="backends/_backend_agg.so backends/_tkagg.so ft2font.so"
+
+if [ -z "$1" ]
+then
+    echo "usage: $0 <bin_dir>"
+    exit 65
+fi
+
+if [ -e "$1/$BIN_PATH_27" ]
+then
+    BIN_PATH=$BIN_PATH_27
+elif [ -e "$1/$BIN_PATH_26" ]
+then
+    BIN_PATH=$BIN_PATH_26
+elif [ -e "$1/$BIN_PATH_25" ]
+then
+    BIN_PATH=$BIN_PATH_25
+fi
+
+for lib in $PNG_REFS
+do
+    install_name_tool -change $X11_PATH/$PNG_LIB $FRAMEWORK_PATH/$PNG_LIB $1/$BIN_PATH/$MPL_LIB_DIR/$lib
+done
+
+for lib in $FT_REFS
+do
+    install_name_tool -change $X11_PATH/$FT_LIB $FRAMEWORK_PATH/$FT_LIB $1/$BIN_PATH/$MPL_LIB_DIR/$lib
+done
+
diff --git a/scripts/run_vistrails_batch_xvfb.sh b/scripts/run_vistrails_batch_xvfb.sh
index 2c6b79f..de1a6a1 100755
--- a/scripts/run_vistrails_batch_xvfb.sh
+++ b/scripts/run_vistrails_batch_xvfb.sh
@@ -1,35 +1,36 @@
 #!/bin/bash
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/sql_delete.py b/scripts/sql_delete.py
old mode 100644
new mode 100755
index 15090b0..d1e1cad
--- a/scripts/sql_delete.py
+++ b/scripts/sql_delete.py
@@ -1,34 +1,36 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/sql_to_xml.py b/scripts/sql_to_xml.py
old mode 100644
new mode 100755
index 14ecdf0..0d510d5
--- a/scripts/sql_to_xml.py
+++ b/scripts/sql_to_xml.py
@@ -1,34 +1,36 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/start_vistrails.sh b/scripts/start_vistrails.sh
index 86123f3..ae1abfb 100755
--- a/scripts/start_vistrails.sh
+++ b/scripts/start_vistrails.sh
@@ -1,47 +1,48 @@
 #!/bin/bash
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 #settings
 LOG_DIR=/server/vistrails/logs
 
-VISTRAILS_DIR=/server/vistrails/trunk/vistrails
-ADDRESS="crowdlabs.sci.utah.edu"
+VISTRAILS_DIR=../vistrails
+ADDRESS="localhost"
 PORT="8081"
 CONF_FILE="server.cfg"
 NUMBER_OF_OTHER_VISTRAILS_INSTANCES="2"
-MULTI_OPTION="-M"
+MULTI_OPTION="--multithread"
 if (("$#" > "0")); then
     VIRTUAL_DISPLAY="$1"
 fi
@@ -58,7 +59,7 @@ if (("$#" == "5")); then
    if(("$5" == "0")); then
        MULTI_OPTION=""
    else
-       MULTI_OPTION="-M"
+       MULTI_OPTION="--multithread"
    fi
 fi
 
@@ -77,6 +78,6 @@ kill -9 `cat $PID`
 
 export PYTHONPATH=/home/emanuele/src/titan/build/lib:$PYTHONPATH
 export LD_LIBRARY_PATH=/home/emanuele/src/titan/build/lib:$LD_LIBRARY_PATH
-python vistrails_server.py -T $ADDRESS -R $PORT -C $CONF_FILE -O$NUMBER_OF_OTHER_VISTRAILS_INSTANCES $MULTI_OPTION&
+python vistrails_server.py --rpc-server $ADDRESS --rpc-port $PORT --rpc-config $CONF_FILE --rpc-instances $NUMBER_OF_OTHER_VISTRAILS_INSTANCES $MULTI_OPTION&
 echo $! > $PID
 
diff --git a/scripts/start_vistrails_xvfb.sh b/scripts/start_vistrails_xvfb.sh
index e57d256..40fa9e5 100755
--- a/scripts/start_vistrails_xvfb.sh
+++ b/scripts/start_vistrails_xvfb.sh
@@ -1,35 +1,36 @@
 #!/bin/bash
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -42,7 +43,7 @@ ADDRESS="vis-7.sci.utah.edu"
 PORT="8081"
 CONF_FILE="server.cfg"
 NUMBER_OF_OTHER_VISTRAILS_INSTANCES="1"
-MULTI_OPTION="-M"
+MULTI_OPTION="--multithread"
 if (("$#" > "0")); then
     VIRTUAL_DISPLAY="$1"
 fi
@@ -59,7 +60,7 @@ if (("$#" == "5")); then
    if(("$5" == "0")); then
        MULTI_OPTION=""
    else
-       MULTI_OPTION="-M"
+       MULTI_OPTION="--multithread"
    fi
 fi
 
@@ -104,6 +105,6 @@ sleep 5
 #finally kill it if it still did not respond because it was hanging
 kill -9 `cat $PID`
 
-python vistrails_server.py -T $ADDRESS -R $PORT -C $CONF_FILE -O$NUMBER_OF_OTHER_VISTRAILS_INSTANCES $MULTI_OPTION&
+python vistrails_server.py --rpc-server=$ADDRESS --rpc-port $PORT --rpc-config $CONF_FILE --rpc-instances $NUMBER_OF_OTHER_VISTRAILS_INSTANCES $MULTI_OPTION&
 echo $! > $PID
 
diff --git a/scripts/system_info.py b/scripts/system_info.py
index 74c554b..302d61b 100755
--- a/scripts/system_info.py
+++ b/scripts/system_info.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/unzip_vistrail.sh b/scripts/unzip_vistrail.sh
index 8df1878..af04c70 100755
--- a/scripts/unzip_vistrail.sh
+++ b/scripts/unzip_vistrail.sh
@@ -1,35 +1,36 @@
 #!/bin/bash
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/update_copyright_year.py b/scripts/update_copyright_year.py
index e770b6b..9218cad 100644
--- a/scripts/update_copyright_year.py
+++ b/scripts/update_copyright_year.py
@@ -1,73 +1,86 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-# Finds all .py files recursively in current directory (.)
-# and updates 2007 year with 2008 in the file header. 
-import re
+
+"""Finds all .py files recursively in current directory (.) and updates 2007
+year with 2008 in the file header.
+"""
+
+from itertools import izip
 import os
-new_copyright = ["## Copyright (C) 2011-2014, NYU-Poly.\n"]
+import re
+
 
-re_copyright = re.compile(r"\s+## Copyright \(C\) 2011-2014, NYU-Poly\.\s+")
-line_copyright = re.compile(r"## Copyright \(C\) 2011-2014, NYU-Poly\.")
+# The new copyright: the found copyright line will be replaced by this
+NEW_COPYRIGHT = ["## Copyright (C) 2014-2015, New York University.\n"]
+
+# The old copyright line: the first matching line in a file will be replaced
+# by NEW_COPYRIGHT
+RE_COPYRIGHT = re.compile(r"\s*## Copyright \(C\) 20\d\d-20\d\d, "
+                          r"New York University\.\s*")
+
+# Number of lines in which to search for the old copyright
+NB_SEARCHED_LINES = 5
+
+# List of file names to ignore
 IGNORE_LIST = ["update_copyright_year.py"]
+
 files = []
 for (path, dnames, fnames) in os.walk('.'):
     for fn in fnames:
         if fn not in IGNORE_LIST and fn.endswith(".py"):
             files.append(os.path.join(path, fn))
 
-print len(files), " files found"
+# Go through files and update them
+print "%d files found" % len(files)
 count = 0
 for fname in files:
-    fin = open(fname)
-    lines = fin.readlines()
-    fin.seek(0)
-    all_lines = fin.read()
-    fin.close()
-    if re_copyright.search(all_lines) > 0:
-        #Search through the first lines because sometimes it's not exactly in the second line:
-        for i in [2,3,4,5]:
-            if line_copyright.search(lines[i]) > 0:
-                print "Updating: %s"%fname
-                newlines = lines[:i]
-                newlines.extend(new_copyright)
-                cropped = lines[i+1:] #Replace by i+1 when it is to update just the year.
-                newlines.extend(cropped)
-                fout = file(fname, 'w')
-                fout.writelines(newlines)
-                fout.close()
+    fp = open(fname, 'rb')
+    try:
+        # Search only in the first few lines
+        for line_num, line in izip(xrange(NB_SEARCHED_LINES), fp):
+            if RE_COPYRIGHT.search(line):
+                print "Updating %s" % fname
+                fp.seek(0)
+                lines = fp.readlines()
+                fp.close()
+                lines[line_num:line_num + 1] = NEW_COPYRIGHT
+                fp = file(fname, 'wb')
+                fp.writelines(lines)
                 count += 1
                 break
-
-print count, " files updated"
+    finally:
+        fp.close()
+print "%d files updated" % count
diff --git a/scripts/update_db.py b/scripts/update_db.py
old mode 100644
new mode 100755
index cd8daa1..f05e858
--- a/scripts/update_db.py
+++ b/scripts/update_db.py
@@ -1,34 +1,36 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/update_hash.py b/scripts/update_hash.py
deleted file mode 100755
index 370ae49..0000000
--- a/scripts/update_hash.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-
-import glob
-import sys
-
-if len(sys.argv)<3:
-    print "Usage: ./update_hash.py old_hash new_hash"
-    sys.exit(-1)
-
-files = ["release_notes.py",
-         "create_release_wiki_table.py",
-         "../vistrails/core/system/__init__.py",
-         "../dist/source/make-vistrails-src-release.py",
-         "../doc/usersguide/conf.py"]
-
-for path in files:
-    for f in glob.glob(path):
-        print "Updating", f
-        file = open(f)
-        text = file.read()
-        file.close()
-        
-        text = text.replace(sys.argv[1], sys.argv[2])
-        
-        file = open(f, "w")
-        file.write(text)
-        file.close()
-
-print "These files need to be updated manually:"
-print "  ../dist/mac/Input/README"
-print "  ../dist/windows/Input/releaseNotes.txt"
diff --git a/scripts/update_to_mod_bsd_license.py b/scripts/update_to_mod_bsd_license.py
index 8c53cd3..b292745 100644
--- a/scripts/update_to_mod_bsd_license.py
+++ b/scripts/update_to_mod_bsd_license.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,34 +40,34 @@ import re
 import os
 py_bsd_3_license = """###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the University of Utah nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -74,67 +75,67 @@ py_bsd_3_license = """##########################################################
 xml_bsd_3_license = "<!--"+ py_bsd_3_license + "-->"
 php_bsd_3_license = """////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (C) 2006-2011, University of Utah. 
+// Copyright (C) 2006-2011, University of Utah.
 // All rights reserved.
 // Contact: contact at vistrails.org
 //
 // This file is part of VisTrails.
 //
-// "Redistribution and use in source and binary forms, with or without 
+// "Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
-//  - Redistributions of source code must retain the above copyright notice, 
+//  - Redistributions of source code must retain the above copyright notice,
 //    this list of conditions and the following disclaimer.
-//  - Redistributions in binary form must reproduce the above copyright 
-//    notice, this list of conditions and the following disclaimer in the 
+//  - Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
 //    documentation and/or other materials provided with the distribution.
-//  - Neither the name of the University of Utah nor the names of its 
-//    contributors may be used to endorse or promote products derived from 
+//  - Neither the name of the University of Utah nor the names of its
+//    contributors may be used to endorse or promote products derived from
 //    this software without specific prior written permission.
 //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 //
 ////////////////////////////////////////////////////////////////////////////"""
 sql_bsd_3_license = """--#############################################################################
 --
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the University of Utah nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################"""
diff --git a/scripts/update_vistrails_command.py b/scripts/update_vistrails_command.py
index d59768c..52e194f 100755
--- a/scripts/update_vistrails_command.py
+++ b/scripts/update_vistrails_command.py
@@ -1,63 +1,67 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-""" This script assumes that VisTrails.command file is located at ../ 
-Run this script after you copied the VisTrails folder and run from where it 
-is located. 
+""" This script assumes that VisTrails.command file is located at ../
+Run this script after you copied the VisTrails folder and run from where it
+is located.
 
 """
 import os, os.path
+import sys
 
 if __name__ == "__main__":
+    sys.stderr.write("Running the update_vistrails_command.py script is not required anymore.\n"
+                     "It will be removed in future releases.\n")
+    # TODO : Remove this file after 2.2
+
     # get VisTrails folder
     vt_folder = os.path.abspath(os.path.join(os.path.dirname(__file__),'..'))
-    app_command = os.path.join(vt_folder,'VisTrails.app/Contents/MacOS/vistrails')
     command_file = os.path.join(vt_folder, 'VisTrails.command')
-    
-    file_header = """#This will execute VisTrails in a separate terminal window
+
+    file_contents = """#This will execute VisTrails in a separate terminal window
 #If you get an error saying:
 #Found another instance of VisTrails running
 #Sending parameters to main instance  []
-#Failed:  QLocalSocket::connectToServer: Connection refused 
+#Failed:  QLocalSocket::connectToServer: Connection refused
 #make sure VisTrails is not already running and simply try to run the script again
-#This might indicate that VisTrails did not quit properly 
+#This might indicate that VisTrails did not quit properly
 
+cd "$(dirname "$0")"
+DYLD_LIBRARY_PATH= VisTrails.app/Contents/MacOS/vistrails
 """
-    file_contents = "DYLD_LIBRARY_PATH= " + app_command
     f = open(command_file, 'w')
-    f.write(file_header)
     f.write(file_contents)
     f.close()
-    
diff --git a/scripts/watch_vistrail_servers.py b/scripts/watch_vistrail_servers.py
old mode 100644
new mode 100755
index 1396fca..f54bb26
--- a/scripts/watch_vistrail_servers.py
+++ b/scripts/watch_vistrail_servers.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/scripts/win_update_bin.sh b/scripts/win_update_bin.sh
index 8fc9d4e..ff46879 100755
--- a/scripts/win_update_bin.sh
+++ b/scripts/win_update_bin.sh
@@ -1,35 +1,36 @@
 #!/bin/bash
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/__init__.py b/vistrails/__init__.py
index 68d6941..4bc1955 100644
--- a/vistrails/__init__.py
+++ b/vistrails/__init__.py
@@ -1,37 +1,58 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """Main file for the VisTrails distribution."""
 
-# FIXME: In the future, bootstrap everything from here.
+# This makes sure we use unittest2 everywhere
+# If we are running 2.6, since our tests are in the same files as our code,
+# VisTrails might choke up because of missing unittest features
+
+import sys
+try:
+    import unittest2
+except ImportError:
+    pass
+else:
+    sys.modules['unittest'] = unittest2
+import unittest
+
+if not hasattr(unittest, 'skipIf'):
+    # We don't have unittest2, and unittest is pre-2.7
+    sys.stderr.write("WARNING: Your unittest is missing 2.7 features. Please "
+                     "upgrade Python or\ninstall unittest2, else VisTrails "
+                     "might fail because of missing symbols.\n")
+
+
+from vistrails.core.api import *
diff --git a/vistrails/api/__init__.py b/vistrails/api/__init__.py
index 8e873b0..81c8140 100644
--- a/vistrails/api/__init__.py
+++ b/vistrails/api/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -175,8 +176,9 @@ def add_connection(output_id, output_port_spec, input_id, input_port_spec,
 def create_group(module_ids, connection_ids, controller=None):
     if controller is None:
         controller = get_current_controller()
-    controller.create_group(module_ids, connection_ids)
+    group = controller.create_group(module_ids, connection_ids)
     controller.updatePipelineScene()
+    return group
 
 def get_modules_by_name(name, package=None, namespace=None, controller=None):
     if controller is None:
diff --git a/vistrails/core/__init__.py b/vistrails/core/__init__.py
index cb7e847..9110caa 100644
--- a/vistrails/core/__init__.py
+++ b/vistrails/core/__init__.py
@@ -1,41 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
+_get_vistrails_application = None
+
 def get_vistrails_application():
-    import vistrails.core.application
-    return vistrails.core.application.get_vistrails_application()
+    global _get_vistrails_application
+    if _get_vistrails_application is None:
+        import vistrails.core.application
+        _get_vistrails_application = \
+                        vistrails.core.application.get_vistrails_application
+    return _get_vistrails_application()
 
 def is_running_gui():
     return get_vistrails_application() and get_vistrails_application().is_running_gui()
diff --git a/vistrails/core/analogy/__init__.py b/vistrails/core/analogy/__init__.py
index d1687d7..68b089c 100644
--- a/vistrails/core/analogy/__init__.py
+++ b/vistrails/core/analogy/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.data_structures.bijectivedict import Bidict
 from itertools import imap, chain
 from vistrails.core.modules.module_registry import get_module_registry, \
@@ -125,7 +128,7 @@ def perform_analogy_on_vistrail(vistrail, version_a, version_b, version_c,
                     a_connect.destination.spec == c_connect.destination.spec):
                     break
         if match is not None:
-            connection_remap[a_connect.id] = c_connect.id
+            connection_remap[a_connect.id] = match.id
         elif _debug:
             print "failed to find connection match", a_connect.id, a_source, \
                 a_dest
diff --git a/vistrails/core/analogy/eigen.py b/vistrails/core/analogy/eigen.py
index 2a81e7e..5bf3724 100644
--- a/vistrails/core/analogy/eigen.py
+++ b/vistrails/core/analogy/eigen.py
@@ -1,50 +1,51 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.core.bundles import py_import
-from vistrails.core.data_structures.bijectivedict import Bidict
-from itertools import imap, chain
-import copy
+from __future__ import division
 
+import copy
+from itertools import imap, chain
 import math
 import operator
-from pipeline_utils import *
+import scipy
+import tempfile
 
+from vistrails.core.data_structures.bijectivedict import Bidict
 from vistrails.core.utils import append_to_dict_of_lists
-from vistrails.core.system import temporary_directory
 
-import scipy
+from .pipeline_utils import pipeline_bbox, pipeline_centroid
 
 
 ##############################################################################
@@ -54,15 +55,11 @@ import scipy
 # EigenBase
 
 def mzeros(*args, **kwargs):
-    nkwargs = copy.copy(kwargs)
-    nkwargs['dtype'] = float
-    az = scipy.zeros(*args, **nkwargs)
+    az = scipy.zeros(*args, dtype=float, **kwargs)
     return scipy.matrix(az)
 
 def mones(*args, **kwargs):
-    nkwargs = copy.copy(kwargs)
-    nkwargs['dtype'] = float
-    az = scipy.ones(*args, **nkwargs)
+    az = scipy.ones(*args, dtype=float, **kwargs)
     return scipy.matrix(az)
 
 #mzeros = lambda *args, **kwargs: scipy.matrix(scipy.zeros(*args, **kwargs))
@@ -266,7 +263,7 @@ class EigenBase(object):
         (c,) = v.shape
         print "[ ",
         for j in xrange(c):
-            if left_digits != None:
+            if left_digits is not None:
                 d = left_digits[0,j]
             else:
                 d = 0
@@ -316,99 +313,14 @@ class EigenBase(object):
         return (inputs, outputs)
 
 ##############################################################################
-# EigenPipelineSimilarity
-
-class EigenPipelineSimilarity(EigenBase):
-
-    ##########################################################################
-    # Constructor and initialization
-
-    def __init__(self,
-                 pipeline1,
-                 pipeline2):
-        EigenBase.__init__(self, pipeline1, pipeline2)
-        self.init_operator()
-
-    def init_operator(self):
-        num_verts_p1 = len(self._p1.graph.vertices)
-        num_verts_p2 = len(self._p2.graph.vertices)
-        def ix(a,b): return num_verts_p2 * a + b
-        self._operator = mzeros((num_verts_p1 * num_verts_p2,
-                                 num_verts_p1 * num_verts_p2))
-
-        u = 0.85
-        
-        for i in xrange(num_verts_p1):
-            v1_id = self._g1_vertex_map.inverse[i]
-            for j in xrange(num_verts_p2):
-                ix_ij = ix(i,j)
-                self._operator[ix_ij, ix_ij] = u
-                v2_id = self._g2_vertex_map.inverse[j]
-                def edges(pip, v_id):
-                    return chain(imap(lambda (f, t, i): (t, i),
-                                      self._p1.graph.iter_edges_from(v1_id)),
-                                 imap(lambda (f, t, i): (f, i),
-                                      self._p1.graph.iter_edges_to(v1_id)))
-                p1_edges = edges(self._p1, v1_id)
-                p2_edges = edges(self._p2, v2_id)
-                running_sum = 0.0
-                for (_, p1_edge) in p1_edges:
-                    for (_, p2_edge) in p2_edges:
-                        e1_id = self._g1_edge_map[p1_edge]
-                        e2_id = self._g2_edge_map[p2_edge]
-                        running_sum += self._edge_s8y[e1_id, e2_id]
-                p1_edges = edges(self._p1, v1_id)
-                p2_edges = edges(self._p2, v2_id)
-                if not running_sum:
-                    continue
-                for (p1_v, p1_edge_id) in p1_edges:
-                    for (p2_v, p2_edge_id) in p2_edges:
-                        e1_id = self._g1_edge_map[p1_edge_id]
-                        e2_id = self._g2_edge_map[p2_edge_id]
-                        p1_v_id = self._g1_vertex_map[p1_v]
-                        p2_v_id = self._g2_vertex_map[p2_v]
-                        value = self._edge_s8y[e1_id, e2_id]
-                        value *= (1.0 - u) / running_sum
-                        self._operator[ix_ij, ix(p1_v_id, p2_v_id)] = value
-
-    ##############################################################################
-    # Solve
-
-    def step(self, m):
-        v = m.reshape(len(self._p1.modules) *
-                      len(self._p2.modules))
-        v = scipy.dot(self._operator, v)
-        v = v.reshape(len(self._p1.modules),
-                      len(self._p2.modules)).transpose()
-        v = (v / v.sum(0)).transpose()
-        return v
-
-    def solve(self):
-        i = 0
-        while i < 50:
-            i += 1
-            v = self.step(self._vertex_s8y)
-            residue = self._vertex_s8y - v
-            residue *= residue
-            if residue.sum() < 0.0001:
-                break
-            self._vertex_s8y = v
-        mp = [(self._g1_vertex_map.inverse[ix],
-               self._g2_vertex_map.inverse[v])
-              for (ix, v) in
-              enumerate(self._vertex_s8y.argmax(1))]
-        return dict(mp)
-        
-##############################################################################
 # EigenPipelineSimilarity2
 
 class EigenPipelineSimilarity2(EigenBase):
 
     def __init__(self, *args, **kwargs):
-        basekwargs = copy.copy(kwargs)
-        del basekwargs['alpha']
-        EigenBase.__init__(self, *args, **basekwargs)
-        self.init_operator(alpha=kwargs['alpha'])
+        alpha = kwargs.pop('alpha')
+        EigenBase.__init__(self, *args, **kwargs)
+        self.init_operator(alpha=alpha)
 
     def init_operator(self, alpha):
         def edges(pip, v_id):
@@ -466,7 +378,7 @@ class EigenPipelineSimilarity2(EigenBase):
         v = copy.copy(self._e)
         step = 0
         def write_current_matrix():
-            f = open('%s/%s_%03d.v' % (temporary_directory(),
+            f = open('%s/%s_%03d.v' % (tempfile.gettempdir(),
                                        self._debug_matrix_file, step), 'w')
             x = v.reshape(len(self._p1.modules),
                           len(self._p2.modules))
@@ -501,13 +413,14 @@ class EigenPipelineSimilarity2(EigenBase):
                 f.write('%d %s %f %f\n' % (i, m.name, nc.x, nc.y))
             for i, c in pipeline.connections.iteritems():
                 f.write('%d %d %d\n' % (i, c.sourceId, c.destinationId))
-            
+
         if self._debug:
-            out = open('%s/pipelines.txt' % temporary_directory(), 'w')
+            out = open('%s/pipelines.txt' % tempfile.gettempdir(), 'w')
             write_debug_pipeline_positions(self._p1, self._g1_vertex_map, out)
             write_debug_pipeline_positions(self._p2, self._g2_vertex_map, out)
             self.print_s8ys()
-            
+            out.close()
+
         self._debug_matrix_file = 'input_matrix'
         r_in  = self.solve_v(self._input_vertex_s8y)
         self._debug_matrix_file = 'output_matrix'
diff --git a/vistrails/core/analogy/pipeline_utils.py b/vistrails/core/analogy/pipeline_utils.py
index c9e3f3a..d21d97e 100644
--- a/vistrails/core/analogy/pipeline_utils.py
+++ b/vistrails/core/analogy/pipeline_utils.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,13 +37,15 @@
 
 ############################################################################
 # Utility functions for debugging on eigen.py
+from __future__ import division
+
 from vistrails.core.data_structures.point import Point
 
 def smart_sum(v):
     try:
         fst = v.next()
         return sum(v, fst)
-    except:
+    except Exception:
         pass
     fst = v[0]
     return sum(v[1:], fst)
diff --git a/vistrails/core/api.py b/vistrails/core/api.py
index 951046c..6e487f0 100644
--- a/vistrails/core/api.py
+++ b/vistrails/core/api.py
@@ -1,572 +1,941 @@
-import itertools
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import contextlib
+from itertools import izip
+import subprocess
 
 import vistrails.core.application
-from vistrails.core.db.locator import FileLocator, untitled_locator
+import vistrails.core.db.action
 import vistrails.core.db.io
-from vistrails.core.modules.basic_modules import identifier as basic_pkg
+from vistrails.core.db.locator import UntitledLocator, FileLocator
+from vistrails.core.interpreter.default import get_default_interpreter
 from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.modules.utils import create_port_spec_string
+from vistrails.core.modules.package import Package as _Package
+from vistrails.core.modules.sub_module import get_port_spec_info
+from vistrails.core.modules.utils import parse_port_spec_string
 from vistrails.core.packagemanager import get_package_manager
-from vistrails.core.vistrail.pipeline import Pipeline
-from vistrails.core.vistrail.port_spec import PortSpec
-from vistrails.core.vistrail.vistrail import Vistrail
+from vistrails.core.system import get_vistrails_basic_pkg_id
+from vistrails.core.utils import DummyView
+from vistrails.core.vistrail.controller import VistrailController
+from vistrails.core.vistrail.pipeline import Pipeline as _Pipeline
+from vistrails.core.vistrail.vistrail import Vistrail as _Vistrail
+from vistrails.db.domain import IdScope
 
-# from core.modules.package import Package as _Package
-# from core.vistrail.module import Module as _Module
 
-_api = None
+__all__ = ['Vistrail', 'Pipeline', 'Module', 'Package',
+           'ExecutionResults', 'ExecutionErrors', 'Function',
+           'load_vistrail', 'load_pipeline', 'load_package',
+           'output_mode', 'run_vistrail',
+           'NoSuchVersion', 'NoSuchPackage']
 
-def get_api():
-    if _api is None:
-        set_api(VisTrailsAPI())
-    return _api
 
-def set_api(api):
-    global _api
-    _api = api
+class NoSuchVersion(KeyError):
+    """The version number or tag you specified doesn't exist in the vistrail.
+    """
 
-class Port(object):
-    def __init__(self, module, port_spec):
-        # print 'calling vistrails_port.__init__'
-        self._vistrails_module = module
-        self._port_spec = port_spec
 
-    def __call__(self, *args, **kwargs):
-        if len(args) + len(kwargs) > 0:
-            self._vistrails_module._update_func(self._port_spec,
-                                                *args, **kwargs)
-            return None
-        return self
+class NoSuchPackage(ValueError):
+    """Couldn't find a package with the given identifier.
+    """
 
-class Module(object):
-    def __init__(self, module, *args, **kwargs):
-        self._module = module
-        self._module_desc = self._module.module_descriptor
-        self._package = None # don't think we need this now
-        self.__call__(*args, **kwargs)
 
-    def __call__(self, *args, **kwargs):
-        reg = get_module_registry()
-        if len(args) > 0:
-            constant_desc = reg.get_descriptor_by_name(basic_pkg, "Constant")
-            if reg.is_descriptor_subclass(self._module_desc, constant_desc):
-                kwargs['value'] = args[0]
-            
-        for attr_name, value in kwargs.iteritems():
-            self._process_attr_value(attr_name, value)
-        return self
-
-    @staticmethod
-    def create_module(module, *args, **kwargs):
-        m = Module(module)
-        return m
-
-    def _process_attr_value(self, attr_name, value):
-        if self._module.has_port_spec(attr_name, 'input'):
-            port_spec = self._module.get_port_spec(attr_name, 'input')
-
-            args = None
-            # FIXME want this to be any iterable
-            if isinstance(value, tuple):
-                args = value
+is_initialized = False
+_application = None
+
+
+def initialize():
+    """Initializes VisTrails.
+
+    You don't have to call this directly. Initialization will happen when you
+    start using the API.
+    """
+    global is_initialized
+    global _application
+
+    if is_initialized:
+        return False
+
+    # Creates a core application
+    _application = vistrails.core.application.init(
+            options_dict={
+                'installBundles': False,
+                'loadPackages': False,
+                'enablePackagesSilently': True},
+            args=[])
+
+    is_initialized = True
+
+    return True
+
+
+class Vistrail(object):
+    """This class wraps both Vistrail and VistrailController.
+
+    From it, you can get any pipeline from a tag name or version number.
+
+    It has a concept of "current version", from which you can create new
+    versions by performing actions.
+    """
+    _current_pipeline = None
+    _html = None
+
+    def __init__(self, arg=None):
+        initialize()
+        if arg is None:
+            # Copied from VistrailsApplicationInterface#open_vistrail()
+            locator = UntitledLocator()
+            loaded_objs = vistrails.core.db.io.load_vistrail(locator)
+            self.controller = VistrailController(*loaded_objs)
+        elif isinstance(arg, (_Pipeline, Pipeline)):
+            if isinstance(arg, Pipeline):
+                pipeline = arg.pipeline
             else:
-                args = (value,)
-            self._update_func(port_spec, *args)
+                pipeline = arg
+            # Copied from VistrailsApplicationInterface#open_workflow()
+            vistrail = _Vistrail()
+            ops = []
+            for module in pipeline.module_list:
+                ops.append(('add', module))
+            for connection in pipeline.connection_list:
+                ops.append(('add', connection))
+            action = vistrails.core.db.action.create_action(ops)
+            vistrail.add_action(action, 0L)
+            vistrail.update_id_scope()
+            vistrail.change_description("Imported pipeline", 0L)
+            self.controller = VistrailController(vistrail, UntitledLocator())
+        elif isinstance(arg, VistrailController):
+            self.controller = arg
+        elif isinstance(arg, basestring):
+            raise TypeError("Vistrail was constructed from %r.\n"
+                            "Use load_vistrail() to get a Vistrail from a "
+                            "file." % type(arg).__name__)
         else:
-            raise AttributeError("type object '%s' has no "
-                                 "attribute '%s'" % \
-                                     (self.__class__.__name__,
-                                      attr_name))                
-
-    def __getattr__(self, attr_name):
-        def create_port(port_spec):
-            return Port(self, port_spec)
-
-        if self._module.has_port_spec(attr_name, 'output'):
-            port_spec = \
-                self._module.get_port_spec(attr_name, 'output')
-            return create_port(port_spec)
-        elif self._module.has_port_spec(attr_name, 'input'):
-            port_spec = \
-                self._module.get_port_spec(attr_name, 'input')
-            return create_port(port_spec)
+            raise TypeError("Vistrail was constructed from unexpected "
+                            "argument type %r" % type(arg).__name__)
+
+    def get_pipeline(self, version):
+        """Returns a pipeline from a version number of tag.
+
+        This does not change the currently selected version in this Vistrail.
+        """
+        vistrail = self.controller.vistrail
+        if isinstance(version, (int, long)):
+            if not vistrail.db_has_action_with_id(version):
+                raise NoSuchVersion("Vistrail doesn't have a version %r" %
+                                    version)
+            return Pipeline(vistrail.getPipelineVersionNumber(version))
+        elif isinstance(version, basestring):
+            if not vistrail.has_tag_str(version):
+                raise NoSuchVersion("Vistrail doesn't have a tag %r" % version)
+            return Pipeline(vistrail.getPipelineVersionName(version))
         else:
-            raise AttributeError("type object '%s' has no "
-                                 "attribute '%s'" % \
-                                     (self.__class__.__name__, 
-                                      attr_name))
-
-    def __setattr__(self, attr_name, value):
-        if attr_name.startswith('_'):
-            self.__dict__[attr_name] = value
+            raise TypeError("get_pipeline() argument must be a string or "
+                            "integer, not %r" % type(version).__name__)
+
+    def select_version(self, version):
+        """Sets a different version as current.
+
+        The current workflow is accessible via current_workflow; it is the one
+        that gets executed when calling execute(), and the version from which
+        new versions are created if you perform actions.
+        """
+        vistrail = self.controller.vistrail
+        if isinstance(version, (int, long)):
+            if not vistrail.db_has_action_with_id(version):
+                raise NoSuchVersion("Vistrail doesn't have a version %r" %
+                                    version)
+        elif (isinstance(version, basestring)):
+            if not vistrail.has_tag_str(version):
+                raise NoSuchVersion("Vistrail doesn't have a tag %r" % version)
+            version = vistrail.get_tag_str(version).action_id
         else:
-            self._process_attr_value(attr_name, value)
+            raise TypeError("select_version() argument must be a string "
+                            "or integer, not %r" % type(version).__name__)
+        self.controller.change_selected_version(version)
+        self._current_pipeline = None
+        self._html = None
 
-    def _update_func(self, port_spec, *args, **kwargs):
-        # print 'running _update_func', port_spec.name
-        # print args
-        vt_api = get_api()
+    def select_latest_version(self):
+        """Sets the most recent version in the vistrail as current.
+        """
+        self.controller.select_latest_version()
+        self._current_pipeline = None
+        self._html = None
+
+    @property
+    def current_pipeline(self):
+        if self._current_pipeline is None:
+            self._current_pipeline = Pipeline(
+                    self.controller.current_pipeline,
+                    vistrail=(self, self.current_version))
+        return self._current_pipeline
+
+    @property
+    def current_version(self):
+        return self.controller.current_version
+
+    def set_tag(self, *args):
+        """Sets a tag for the current or specified version.
+        """
+        if len(args) == 1:
+            version, (tag,) = self.controller.current_version, args
+        elif len(args) == 2:
+            version, tag = args
+        else:
+            raise TypeError("set_tag() takes 1 or 2 arguments (%r given)" %
+                            len(args))
+        if isinstance(version, (int, long)):
+            if not self.controller.vistrail.db_has_action_with_id(version):
+                raise NoSuchVersion("Vistrail doesn't have a version %r" %
+                                    version)
+        elif isinstance(version, basestring):
+            if not self.controller.vistrail.has_tag_str(version):
+                raise NoSuchVersion("Vistrail doesn't have a tag %r" % version)
+        else:
+            raise TypeError("set_tag() expects the version to be a string or "
+                            "integer, not %r" % type(version).__name__)
+        self.controller.vistrail.set_tag(version, tag)
 
-        if port_spec.type != 'input':
-            if self._module.has_port_spec(port_spec.name, 'input'):
-                port_spec = \
-                    self._module.get_port_spec(port_spec.name, 'input')
-            else:
-                raise TypeError("cannot update an output port spec")
-
-        # FIXME deal with kwargs
-        num_ports = 0
-        num_params = 0
-        for value in args:
-            # print 'processing', type(value), value
-            if isinstance(value, Port):
-                # make connection to specified output port
-                # print 'updating port'
-                num_ports += 1
-            elif isinstance(value, Module):
-                # make connection to 'self' output port of value
-                # print 'updating module'
-                num_ports += 1
-            else:
-                # print 'update literal', type(value), value
-                num_params += 1
-        if num_ports > 1 or (num_ports == 1 and num_params > 0):
-            reg = vistrails.core.modules.module_registry.get_module_registry()
-            tuple_desc = reg.get_descriptor_by_name(basic_pkg, 'Tuple')
-            tuple_module = vt_api.add_module_from_descriptor(tuple_desc)
-            output_port_spec = PortSpec(id=-1,
-                                        name='value',
-                                        type='output',
-                                        sigstring=port_spec.sigstring)
-            vt_api.add_port_spec(tuple_module, output_port_spec)
-            self._update_func(port_spec, *[tuple_module.value()])
-            assert len(port_spec.descriptors()) == len(args)
-            for i, descriptor in enumerate(port_spec.descriptors()):
-                arg_name = 'arg%d' % i
-                sigstring = create_port_spec_string([descriptor.spec_tuple])
-                tuple_port_spec = PortSpec(id=-1,
-                                           name=arg_name,
-                                           type='input',
-                                           sigstring=sigstring)
-                vt_api.add_port_spec(tuple_module, tuple_port_spec)
-                tuple_module._process_attr_value(arg_name, args[i])
-                
-        elif num_ports == 1:
-            other = args[0]
-            if isinstance(other, Port):
-                if other._port_spec.type != 'output':
-                    other_module = other._vistrails_module._module
-                    if other_module.has_port_spec(port_spec.name, 
-                                                   'output'):
-                        other_port_spec = \
-                            other_module.get_port_spec(port_spec.name, 
-                                                        'output')
-                    else:
-                        raise TypeError("cannot update an input "
-                                        "port spec")
-                else:
-                    other_port_spec = other._port_spec
-
-                vt_api.add_connection(other._vistrails_module,
-                                      other_port_spec,
-                                      self, 
-                                      port_spec)
-            elif isinstance(other, Module):
-                other_port_spec = \
-                    other._module.get_port_spec('self', 'output')
-                vt_api.add_connection(other, 
-                                      other_port_spec,
-                                      self,
-                                      port_spec)
+    def tag(self, tag):
+        """Sets a tag for the current version.
+        """
+        self.set_tag(tag)
+
+    def execute(self, *args, **kwargs):
+        """Executes the current workflow.
+        """
+        return self.current_pipeline.execute(*args, **kwargs)
+
+    @property
+    def changed(self):
+        return self.controller.changed
+
+    # TODO : vistrail modification methods
+
+    def __repr__(self):
+        version_nb = self.controller.current_version
+        if self.controller.vistrail.has_tag(version_nb):
+            version = "%s (tag %s)" % (
+                    version_nb,
+                    self.controller.vistrail.get_tag(version_nb))
         else:
-            vt_api.change_parameter(self,
-                                    port_spec.name,
-                                    [str(x) for x in args])
-
-class Package(object):
-    def __init__(self, identifier, version=''):
-        self._package = None
-        # namespace_dict : {namespace : (namespace_dict, modules)}
-        self._namespaces = ({}, [])
-        reg = get_module_registry()
-        self._package = reg.get_package_by_name(identifier, version)
-        for desc in self._package.descriptor_list:
-            if desc.namespace:
-                namespaces = desc.namespace.split('|')
+            version = version_nb
+        return "<%s: %s, version %s, %s>" % (
+                self.__class__.__name__,
+                self.controller.name,
+                version,
+                ('not changed', 'changed')[self.controller.changed])
+
+    def _repr_html_(self):
+        if self._html is None:
+            import cgi
+            try:
+                from cStringIO import StringIO
+            except ImportError:
+                from StringIO import StringIO
+
+            self._html = ''
+            stream = StringIO()
+            self.controller.recompute_terse_graph()
+            self.controller.save_version_graph(
+                    stream,
+                    highlight=self.controller.current_version)
+            stream.seek(0)
+            dot = stream.read()
+
+            try:
+                proc = subprocess.Popen(['dot', '-Tsvg'],
+                                        stdin=subprocess.PIPE,
+                                        stdout=subprocess.PIPE)
+                svg, _ = proc.communicate(dot)
+                if proc.wait() == 0:
+                    self._html += svg
+            except OSError:
+                pass
+            self._html += '<pre>' + cgi.escape(repr(self)) + '</pre>'
+        return self._html
+
+
+def get_inputoutput_name(module):
+    for function in module.functions:
+        if function.name == 'name':
+            if len(function.params) == 1:
+                return function.params[0].strValue
+    return None
+
+
+class Pipeline(object):
+    """This class represents a single Pipeline.
+
+    It doesn't have a controller.
+    """
+    vistrail = None
+    version = None
+    _inputs = None
+    _outputs = None
+    _html = None
+
+    def __init__(self, pipeline=None, vistrail=None):
+        initialize()
+        if pipeline is None:
+            self.pipeline = _Pipeline()
+        elif isinstance(pipeline, _Pipeline):
+            self.pipeline = pipeline
+        elif isinstance(pipeline, basestring):
+            raise TypeError("Pipeline was constructed from %r.\n"
+                            "Use load_pipeline() to get a Pipeline from a "
+                            "file." % type(pipeline).__name__)
+        else:
+            raise TypeError("Pipeline was constructed from unexpected "
+                            "argument type %r" % type(pipeline).__name__)
+        if vistrail is not None:
+            if (isinstance(vistrail, tuple) and len(vistrail) == 2 and
+                    isinstance(vistrail[0], Vistrail)):
+                self.vistrail, self.version = vistrail
             else:
-                namespaces = []
-            cur_namespace = self._namespaces[0]
-            cur_modules = self._namespaces[1]
-            for namespace in namespaces:
-                if namespace not in cur_namespace:
-                    cur_namespace[namespace] = ({}, [])
-                cur_modules = cur_namespace[namespace][1]
-                cur_namespace = cur_namespace[namespace][0]
-            cur_modules.append(desc)
-
-        iteritems = [self._namespaces]
-        for (namespaces, modules) in iteritems:
-            modules.sort(key=lambda d: d.name)
-            iteritems = itertools.chain(iteritems, namespaces.itervalues())
-
-    def __getattr__(self, attr_name):
+                raise TypeError("Pipeline got unknown type %r as 'vistrail' "
+                                "argument" % type(vistrail).__name__)
+
+    @property
+    def modules(self):
+        for module in self.pipeline.module_list:
+            yield Module(descriptor=module.module_descriptor,
+                         module_id=module.id,
+                         pipeline=self)
+
+    def execute(self, *args, **kwargs):
+        """Execute the pipeline.
+
+        Positional arguments are either input values (created from
+        ``module == value``, where `module` is a Module from the pipeline and
+        `value` is some value or Function instance) for the pipeline's
+        InputPorts, or Module instances (to select sink modules).
+
+        Keyword arguments are also used to set InputPort by looking up inputs
+        by name.
+
+        Example::
+
+           input_bound = pipeline.get_input('higher_bound')
+           input_url = pipeline.get_input('url')
+           sinkmodule = pipeline.get_module(32)
+           pipeline.execute(sinkmodule,
+                            input_bound == vt.Function(Integer, 10),
+                            input_url == 'http://www.vistrails.org/',
+                            resolution=15)  # kwarg: only one equal sign
+        """
+        sinks = set()
+        inputs = {}
+
         reg = get_module_registry()
-        d = reg.get_descriptor_by_name(self._package.identifier,
-                                       attr_name, '', 
-                                       self._package.version)
-        vt_api = get_api()
-        module = vt_api.add_module_from_descriptor(d)
-        return module
- 
-    def get_modules(self, namespace=None):
-        modules = []
-        if namespace == '':
-            modules = [d.name for d in self._namespaces[1]]
+        InputPort_desc = reg.get_descriptor_by_name(
+                get_vistrails_basic_pkg_id(),
+                'InputPort')
+
+        # Read args
+        for arg in args:
+            if isinstance(arg, ModuleValuePair):
+                if arg.module.id in inputs:
+                    raise ValueError(
+                            "Multiple values set for InputPort %r" %
+                            get_inputoutput_name(arg.module))
+                if not reg.is_descriptor_subclass(arg.module.module_descriptor,
+                                                  InputPort_desc):
+                    raise ValueError("Module %d is not an InputPort" %
+                                     arg.module.id)
+                inputs[arg.module.id] = arg.value
+            elif isinstance(arg, Module):
+                sinks.add(arg.module_id)
+
+        # Read kwargs
+        for key, value in kwargs.iteritems():
+            key = self.get_input(key)  # Might raise KeyError
+            if key.module_id in inputs:
+                raise ValueError("Multiple values set for InputPort %r" %
+                                 get_inputoutput_name(key.module))
+            inputs[key.module_id] = value
+
+        reason = "API pipeline execution"
+        sinks = sinks or None
+
+        # Use controller only if no inputs were passed in
+        if (not inputs and self.vistrail is not None and
+                self.vistrail.current_version == self.version):
+            controller = self.vistrail.controller
+            results, changed = controller.execute_workflow_list([[
+                    controller.locator,  # locator
+                    self.version,  # version
+                    self.pipeline,  # pipeline
+                    DummyView(),  # view
+                    None,  # custom_aliases
+                    None,  # custom_params
+                    reason,  # reason
+                    sinks,  # sinks
+                    None,  # extra_info
+                    ]])
+            result, = results
+        else:
+            pipeline = self.pipeline
+            if inputs:
+                id_scope = IdScope()
+                id_remap = {}
+                pipeline = pipeline.do_copy(True, id_scope, id_remap)
+                create_module = \
+                        VistrailController.create_module_from_descriptor_static
+                create_function = VistrailController.create_function_static
+                create_connection = VistrailController.create_connection_static
+                # Fills in the ExternalPipe ports
+                for module_id, values in inputs.iteritems():
+                    module = pipeline.modules[module_id]
+                    if not isinstance(values, (list, tuple)):
+                        values = [values]
+
+                    # Guess the type of the InputPort
+                    _, sigstrings, _, _, _ = get_port_spec_info(pipeline, module)
+                    sigstrings = parse_port_spec_string(sigstrings)
+
+                    # Convert whatever we got to a list of strings, for the
+                    # pipeline
+                    values = [reg.convert_port_val(val, sigstring, None)
+                              for val, sigstring in izip(values, sigstrings)]
+
+                    if len(values) == 1:
+                        # Create the constant module
+                        constant_desc = reg.get_descriptor_by_name(
+                                *sigstrings[0])
+                        constant_mod = create_module(id_scope, constant_desc)
+                        func = create_function(id_scope, constant_mod,
+                                               'value', values)
+                        constant_mod.add_function(func)
+                        pipeline.add_module(constant_mod)
+
+                        # Connect it to the ExternalPipe port
+                        conn = create_connection(id_scope,
+                                                 constant_mod, 'value',
+                                                 module, 'ExternalPipe')
+                        pipeline.db_add_connection(conn)
+                    else:
+                        raise RuntimeError("TODO : create tuple")
+
+            interpreter = get_default_interpreter()
+            result = interpreter.execute(pipeline,
+                                         reason=reason,
+                                         sinks=sinks)
+
+        if result.errors:
+            raise ExecutionErrors(self, result)
         else:
-            if namespace is None:
-                namespace = ''
-                modules = [d.name for d in self._namespaces[1]]
-                namespaces = sorted(self._namespaces[0].iteritems())
+            return ExecutionResults(self, result)
+
+    def get_module(self, module_id):
+        if isinstance(module_id, (int, long)):  # module id
+            module = self.pipeline.modules[module_id]
+        elif isinstance(module_id, basestring):  # module name
+            def desc(mod):
+                if '__desc__' in mod.db_annotations_key_index:
+                    return mod.get_annotation_by_key('__desc__').value
+                else:
+                    return None
+            modules = [mod
+                       for mod in self.pipeline.modules.itervalues()
+                       if desc(mod) == module_id]
+            if not modules:
+                raise KeyError("No module with description %r" % module_id)
+            elif len(modules) > 1:
+                raise ValueError("Multiple modules with description %r" %
+                                 module_id)
             else:
-                namespace_dict = self._namespaces[0]
-                descs = self._namespaces[1]
-                for ns in namespace.split('|'):
-                    (namespace_dict, descs) = namespace_dict[ns]
-                namespaces = [(namespace, (namespace_dict, descs))]
-            
-            for (ns, (child_namespaces, descs)) in namespaces:
-                modules.extend(ns + '|' + d.name for d in descs)
-                namespaces = \
-                    itertools.chain([(ns + '|' + c[0], c[1]) 
-                                     for c in child_namespaces.iteritems()],
-                                    namespaces)
-        return modules
+                module, = modules
 
-    def list_modules(self, namespace=None):
-        for module in self.get_modules(namespace):
-            print module
-
-class VisTrailsAPI(object):
-
-    # !!! Do not pass controller or app unless you know what you are doing !!!
-    def __init__(self, controller=None, app=None):
-        self._controller = controller
-        self._app = app
-        self._packages = None
-        self._old_log = None
-
-    def _get_app(self):
-        if self._app is not None:
-            return self._app
-        return vistrails.core.application.get_vistrails_application()
-    app = property(_get_app)
-
-    # !!! Do not call set_app unless you know what you are doing !!!
-    def set_app(self, app):
-        self._app = app
-
-    def _get_controller(self):
-        if self._controller is not None:
-            return self._controller
-        controller = self.app.get_controller()
-        if controller is None:
-            raise ValueError("You must have a vistrail open before calling "
-                             "this API method.")
-        return controller
-    controller = property(_get_controller)
-
-    # !!! Do not call set_controller unless you know what you are doing !!!
-    def set_controller(self, controller=None):
-        self._controller = controller
-
-    def add_module(self, identifier, name, namespace='', internal_version=-1):
-        m = self.controller.add_module(identifier, name, namespace, 
-                                       internal_version=internal_version)
-        # have to go back since there is a copy when the action is performed
-        module = self.controller.current_pipeline.modules[m.id]
-        return Module.create_module(module)
-
-    def add_module_from_descriptor(self, desc):
-        m = self.controller.add_module_from_descriptor(desc)
-        # have to go back since there is a copy when the action is performed
-        module = self.controller.current_pipeline.modules[m.id]
-        return Module.create_module(module)
-
-    def add_connection(self, module_a, port_a, module_b, port_b):
-        conn = self.controller.add_connection(module_a._module.id, port_a,
-                                               module_b._module.id, port_b)
-
-    def add_port_spec(self, module, port_spec):
-        self.controller.add_module_port(module._module.id,
-                                         (port_spec.type, port_spec.name,
-                                          port_spec.sigstring))
-
-    def add_and_connect_module(self,
-                               identifier,
-                               name,
-                               port,
-                               module_b,
-                               port_b,
-                               is_source=False,
-                               auto_layout=True,
-                               **kwargs):
-        """Adds a module and connects in single action. Returns new module.
-
-        identifier - package identifier for new module
-        name - name of new module
-        module_b - existing module to connect new module to
-        port - port on new module to connect
-        port_b - port on existing module to connect
-        is_source - whether or not new module is source of connection
-        auto_layout - layout pipeline
-        **kwargs - additional arguments to create module
-        """
+        else:
+            raise TypeError("get_module() expects a string or integer, not "
+                            "%r" % type(module_id).__name__)
+        return Module(descriptor=module.module_descriptor,
+                      module_id=module.id,
+                      pipeline=self)
 
-        module = self.controller.create_module(identifier, name, **kwargs)
+    def _get_inputs_or_outputs(self, module_name):
+        reg = get_module_registry()
+        desc = reg.get_descriptor_by_name(
+                'org.vistrails.vistrails.basic',
+                module_name)
+        modules = {}
+        for module in self.pipeline.modules.itervalues():
+            if module.module_descriptor is desc:
+                name = get_inputoutput_name(module)
+                if name is not None:
+                    modules[name] = module
+        return modules
 
-        if is_source:
-            source, source_port = module, port
-            target, target_port = module_b._module, port_b
+    def get_input(self, name):
+        try:
+            module = self._get_inputs_or_outputs('InputPort')[name]
+        except KeyError:
+            raise KeyError("No InputPort module with name %r" % name)
         else:
-            target, target_port = module, port
-            source, source_port = module_b._module, port_b
+            return Module(descriptor=module.module_descriptor,
+                          module_id=module.id,
+                          pipeline=self)
+
+    def get_output(self, name):
+        try:
+            module = self._get_inputs_or_outputs('OutputPort')[name]
+        except KeyError:
+            raise KeyError("No OutputPort module with name %r" % name)
+        else:
+            return Module(descriptor=module.module_descriptor,
+                          module_id=module.id,
+                          pipeline=self)
+
+    @property
+    def inputs(self):
+        if self._inputs is None:
+            self._inputs = self._get_inputs_or_outputs('InputPort').keys()
+        return self._inputs
+
+    @property
+    def outputs(self):
+        if self._outputs is None:
+            self._outputs = self._get_inputs_or_outputs('OutputPort').keys()
+        return self._outputs
+
+    def __repr__(self):
+        desc = "<%s: %d modules, %d connections" % (
+                self.__class__.__name__,
+                len(self.pipeline.modules),
+                len(self.pipeline.connections))
+        inputs = self.inputs
+        if inputs:
+            desc += "; inputs: %s" % ", ".join(inputs)
+        outputs = self.outputs
+        if outputs:
+            desc += "; outputs: %s" % ", ".join(outputs)
+        return desc + ">"
+
+    def _repr_html_(self):
+        if self._html is None:
+            import cgi
+            try:
+                from cStringIO import StringIO
+            except ImportError:
+                from StringIO import StringIO
+
+            self._html = ''
+
+            # http://www.graphviz.org/doc/info/shapes.html
+            dot = ['digraph {\n    node [shape=plaintext];']
+
+            # {moduleId: (input_ports, output_ports)}
+            modules = dict((mod.id, (set(), set()))
+                           for mod in self.pipeline.module_list)
+            for conn in self.pipeline.connection_list:
+                src, dst = conn.source, conn.destination
+                modules[src.moduleId][1].add(src.name)
+                modules[dst.moduleId][0].add(dst.name)
+
+            # {moduleId: ({input_port_name: input_num},
+            #             {output_port_name: output_num})
+            # where input_num and output_num are just some sequences of numbers
+            modules = dict((mod_id,
+                            (dict((n, i) for i, n in enumerate(mod_ports[0])),
+                             dict((n, i) for i, n in enumerate(mod_ports[1]))))
+                           for mod_id, mod_ports in modules.iteritems())
+
+            # Write out the modules
+            for mod, port_lists in modules.iteritems():
+                labels = []
+                for port_type, ports in izip(('in', 'out'), port_lists):
+                    label = ('<td port="%s%s">%s</td>' % (port_type, port_num, cgi.escape(port_name))
+                             for port_name, port_num in ports.iteritems())
+                    labels.append(''.join(label))
+
+                label = ['<table border="0" cellborder="0" cellspacing="0">']
+                if labels[0]:
+                    label += ['<tr><td><table border="0" cellborder="1" cellspacing="0"><tr>', labels[0], '</tr></table></td></tr>']
+                mod_obj = self.pipeline.modules[mod]
+                if '__desc__' in mod_obj.db_annotations_key_index:
+                    name = (mod_obj.get_annotation_by_key('__desc__')
+                                 .value.strip())
+                else:
+                    name = mod_obj.label
+                label += ['<tr><td border="1" bgcolor="grey"><b>', cgi.escape(name), '</b></td></tr>']
+                if labels[1]:
+                    label += ['<tr><td><table border="0" cellborder="1" cellspacing="0"><tr>', labels[1], '</tr></table></td></tr>']
+                label += ['</table>']
+                dot.append('    module%d [label=<%s>];' % (mod, '\n'.join(label)))
+            dot.append('')
+
+            # Write out the connections
+            for conn in self.pipeline.connection_list:
+                src, dst = conn.source, conn.destination
+                dot.append('    module%d:out%d -> module%d:in%d;' % (
+                           src.moduleId,
+                           modules[src.moduleId][1][src.name],
+                           dst.moduleId,
+                           modules[dst.moduleId][0][dst.name]))
+
+            dot.append('}')
+            try:
+                proc = subprocess.Popen(['dot', '-Tsvg'],
+                                        stdin=subprocess.PIPE,
+                                        stdout=subprocess.PIPE)
+                svg, _ = proc.communicate('\n'.join(dot))
+                if proc.wait() == 0:
+                    self._html += svg
+            except OSError:
+                pass
+            self._html += '<pre>' + cgi.escape(repr(self)) + '</pre>'
+        return self._html
+
+
+class ModuleClass(type):
+    def __new__(cls, descriptor):
+        return type.__new__(cls, descriptor.name, (object,), {})
+
+    def __init__(self, descriptor):
+        self.descriptor = descriptor
+
+    def __call__(self, *args, **kwargs):
+        return Module(self.descriptor, *args, **kwargs)
+
+    # Ignored by IPython because of bug 6709
+    # https://github.com/ipython/ipython/issues/6709
+    def __repr__(self):
+        return "<Module class %r from %s>" % (self.descriptor.name,
+                                              self.descriptor.identifier)
+    __str__ = __repr__
+    __unicode__ = __repr__
+
+    def __instancecheck__(self, instance):
+        return (isinstance(instance, Module) and
+                instance.descriptor == self.descriptor)
+
+    def __subclasscheck__(self, other):
+        if not issubclass(other, type):
+            raise TypeError
+        if not isinstance(other, ModuleClass):
+            return False
+        reg = get_module_registry()
+        return reg.is_descriptor_subclass(self.descriptor, other.descriptor)
+
 
-        create_conn = self.controller.create_connection
-        conn = create_conn(source, source_port, target, target_port)
+class ModuleValuePair(object):
+    """Internal object returned by Module == value expressions.
+    """
+    def __init__(self, module, value):
+        self.module = module
+        self.value = value
 
-        if auto_layout:
-            layout = self.controller.layout_modules_ops
-            layout_ops = layout([], True, [module], [conn], None, True)
+    def __nonzero__(self):
+        raise TypeError("Took truth value of ModuleValuePair!")
+
+
+class Module(object):
+    """Wrapper for a module, which can be in a Pipeline or not yet.
+    """
+    module_id = None
+    pipeline = None
+
+    def __init__(self, descriptor, **kwargs):
+        self.descriptor = descriptor
+        if 'module_id' and 'pipeline' in kwargs:
+            self.module_id = kwargs.pop('module_id')
+            self.pipeline = kwargs.pop('pipeline')
+            if not (isinstance(self.module_id, (int, long)) and
+                    isinstance(self.pipeline, Pipeline)):
+                raise TypeError
+        elif 'module_id' in kwargs or 'pipeline' in kwargs:
+            raise TypeError("Module was given an id but no pipeline")
+
+        if kwargs:
+            raise TypeError("Module was given unexpected argument: %r" %
+                            next(iter(kwargs)))
+
+    @property
+    def module(self):
+        if self.module_id is None:
+            raise ValueError("This module is not part of a pipeline")
+        return self.pipeline.pipeline.modules[self.module_id]
+
+    @property
+    def module_class(self):
+        return ModuleClass(self.descriptor)
+
+    def __repr__(self):
+        desc = "<Module %r from %s" % (self.descriptor.name,
+                                       self.descriptor.identifier)
+        if self.module_id is not None:
+            desc += ", id %d" % self.module_id
+            if self.pipeline is not None:
+                mod = self.pipeline.pipeline.modules[self.module_id]
+                if '__desc__' in mod.db_annotations_key_index:
+                    desc += (", label \"%s\"" %
+                             mod.get_annotation_by_key('__desc__').value)
+        return desc + ">"
+
+    def __eq__(self, other):
+        if isinstance(other, Module):
+            if self.module_id is None:
+                return other.module_id is None
+            else:
+                if other.module_id is None:
+                    return False
+                return (self.module_id == other.module_id and
+                        self.pipeline == other.pipeline)
         else:
-            layout_ops = []
+            return ModuleValuePair(self.module, other)
 
-        ops = [('add', module), ('add', conn)] + layout_ops
-        action = vistrails.core.db.action.create_action(ops)
-        self.controller.add_new_action(action)
-        version = self.controller.perform_action(action)
-        self.controller.change_selected_version(version)
 
-        # have to go back since there is a copy when the action is performed
-        m = self.controller.current_pipeline.modules[module.id]
-        return Module.create_module(m)
-
-    def change_parameter(self, module, function_name, param_list):
-        self.controller.update_function(module._module, function_name,
-                                         param_list)
-
-    def execute(self, custom_aliases=None, custom_params=None,
-                 extra_info=None, reason='API Pipeline Execution'):
-        return self.controller.execute_current_workflow(custom_aliases, custom_params,
-                                                  extra_info, reason)
-
-    def get_packages(self):
-        if self._packages is None:
-            self._packages = {}
-            self._old_package_ids = {}
-            reg = get_module_registry()
-            for package in reg.package_list:
-                pkg = Package(package.identifier, package.version)
-                self._packages[package.identifier] = pkg
-                for old_name in package.old_identifiers:
-                    self._old_package_ids[old_name] = pkg
-        return self._packages
-
-    def list_packages(self):
-        for package in self.get_packages():
-            print package
-
-    def get_package(self, identifier):
-        packages = self.get_packages()
-        if identifier not in packages and identifier in self._old_package_ids:
-            return self._old_package_ids[identifier]
+class ModuleNamespace(object):
+    def __init__(self, identifier, namespace=''):
+        self.identifier = identifier
+        self._namespace = namespace
+        self._namespaces = {}
+
+    def __getattr__(self, name):
+        if name in self._namespaces:
+            return self._namespaces[name]
         else:
-            return packages[identifier]
-
-    def load_package(self, identifier, codepath):
-        packages = self.get_packages()
-        if identifier not in packages:
-            pm = get_package_manager()
-            pm.late_enable_package(codepath)
-            self._packages = None
-        return self.get_package(identifier)
-            
-    def list_modules(self):
-        for identifier, package in sorted(self.get_packages().iteritems()):
-            print identifier
-            for module in package.get_modules():
-                print ' --', module
-
-    def _convert_version(self, version):
-        if isinstance(version, basestring):
-            try:
-                version = \
-                    self.controller.vistrail.get_version_number(version)
-            except:
-                raise ValueError('Cannot locate version "%s"' % version)
-        return version
-
-    def tag_version(self, tag, version=None):
-        if version is None:
-            version = self.controller.current_version
+            return self[name]
+
+    def __getitem__(self, name):
+        name = name.rsplit('|', 1)
+        if len(name) == 2:
+            if self._namespace:
+                namespace = self._namespace + '|' + name[0]
+            else:
+                namespace = name[0]
+            name = name[1]
         else:
-            version = self._convert_version(version)
-        self.controller.vistrail.set_tag(version, tag)
+            name, = name
+            namespace = self._namespace
+        reg = get_module_registry()
+        descr = reg.get_descriptor_by_name(self.identifier,
+                                           name,
+                                           namespace)
+        return ModuleClass(descr)
+
+    def __repr__(self):
+        return "<Namespace %s of package %s>" % (self._namespace,
+                                                 self.identifier)
+
+
+class Package(ModuleNamespace):
+    """Wrapper for an enabled package.
+
+    You can get modules from a Package using either the
+    ``pkg['namespace|module']`` or ``pkg.namespace.module`` syntax.
+    """
+    def __init__(self, package):
+        if not isinstance(package, _Package):
+            raise TypeError("Can't construct a package from "
+                            "%r" % type(package).__name__)
+        ModuleNamespace.__init__(self, package.identifier)
+        self._package = package
+
+        # Builds namespaces
+        for mod, namespaces in self._package.descriptors.iterkeys():
+            if not namespaces:
+                continue
+            ns = self
+            fullname = None
+            for name in namespaces.split('|'):
+                if fullname is not None:
+                    fullname += '|' + name
+                else:
+                    fullname = name
+                if name not in ns._namespaces:
+                    ns_ = ns._namespaces[name] = ModuleNamespace(
+                            self.identifier,
+                            fullname)
+                    ns = ns_
+                else:
+                    ns = ns._namespaces[name]
 
-    def save_vistrail(self, locator_str):
-        return self.app.save_vistrail(locator_str)
+    def __repr__(self):
+        return "<Package: %s, %d modules>" % (self.identifier,
+                                              len(self._package.descriptors))
 
-    def new_vistrail(self):
-        return bool(self.app.new_vistrail())
+    def __eq__(self, other):
+        return isinstance(other, Package) and self._package is other._package
 
-    def load_vistrail(self, locator_str):
-        return bool(self.app.open_vistrail(locator_str))
-    open_vistrail = load_vistrail
+    def __ne__(self, other):
+        return not self == other
 
-    def load_workflow(self, locator_str):
-        self.app.open_workflow(locator_str)
-    open_workflow = load_workflow
 
-    def select_version(self, version):
-        self.app.select_version(version)
-
-    def close_vistrail(self):
-        self.app.close_vistrail()
-
-    def get_current_workflow(self):
-        return self.controller.current_pipeline
-
-    def get_all_executions(self):
-        wf_execs = []
-        if (self._old_log is None and
-            hasattr(self.controller.vistrail, 'db_log_filename') and
-            self.controller.vistrail.db_log_filename is not None):
-            self._old_log = \
-                vistrails.core.db.io.open_log(self.controller.vistrail.db_log_filename, True)
-        if self._old_log is not None:
-            wf_execs.extend(self._old_log.workflow_execs)
-        wf_execs.extend(self.controller.log.workflow_execs)
-        return wf_execs
-
-import os
-import unittest
-from vistrails.core.system import temporary_directory
-
-class TestAPI(unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, obj, cls, msg=None):
-            assert(isinstance(obj, cls))
-    
-    @classmethod
-    def setUpClass(cls):
-        get_api().new_vistrail()
-
-    @classmethod
-    def tearDownClass(cls):
-        get_api().close_vistrail()
-
-    def setUp(self):
-        get_api().controller.change_selected_version(0)
-
-    def get_basic_package(self):
-        basic = get_api().get_package(basic_pkg)
-        self.assertIsInstance(basic, Package)
-        return basic
-
-    def create_modules(self,basic):
-        s1 = basic.String("abc")
-        self.assertIsInstance(s1, Module)
-        s2 = basic.String("def")
-        self.assertIsInstance(s2, Module)
-        return s1, s2
-        
-    def test_api(self):
-        self.get_basic_package()
-
-    def test_add_modules(self):
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-
-        # assert there exist two String modules
-        self.assertEqual(len(get_api().controller.current_pipeline.modules), 2)
-        for m in get_api().controller.current_pipeline.modules.itervalues():
-            self.assertEqual(m.package, basic_pkg)
-            self.assertEqual(m.name, "String")
-
-    def check_connections(self):
-        conns = []
-        modules = get_api().controller.current_pipeline.modules
-        for c in get_api().controller.current_pipeline.connections.itervalues():
-            conns.append((modules[c.sourceId].name, c.source.name,
-                          modules[c.destinationId].name, c.destination.name))
-        conns.sort()
-        self.assertEqual(conns,
-                         [('String', 'value', 'ConcatenateString', 'str1'),
-                          ('String', 'value', 'ConcatenateString', 'str2')])
-
-    def test_add_connections_by_assignment(self):
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-        c = basic.ConcatenateString()
-        c.str1 = s1.value
-        c.str2 = s2.value
-        self.check_connections()
-
-    def test_add_connections_by_call(self):
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-        c = basic.ConcatenateString()
-        c.str1(s1.value)
-        c.str2(s2.value)
-        self.check_connections()
-
-    def test_add_connections_by_constructor(self):
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-        c = basic.ConcatenateString(str1=s1.value, str2=s2.value)
-        self.check_connections()
-
-    def check_parameters(self):
-        params = []
-        for m in get_api().controller.current_pipeline.modules.itervalues():
-            for f in m.functions:
-                params.append((m.name, f.name, f.params[0].strValue))
-        params.sort()
-        self.assertEqual(params,
-                         [('String', 'value', 'abc'),
-                          ('String', 'value', 'def')])
-            
-    def test_add_parameters_by_assignment(self):
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-        s1.value = "abc"
-        s2.value = "def"
-        self.check_parameters()
-
-    def test_add_parameters_by_call(self):
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-        s1.value("abc")
-        s2.value("def")
-        self.check_parameters()
-
-    def test_add_parameters_by_constructor(self):
-        basic = self.get_basic_package()
-        s1 = basic.String("abc")
-        s2 = basic.String("def")
-        self.check_parameters()
-
-    def test_write_and_read_vistrail(self):
-        self.assertTrue(get_api().new_vistrail())
-        basic = self.get_basic_package()
-        s1, s2 = self.create_modules(basic)
-        fname = os.path.join(temporary_directory(), "test_write_read.vt")
-        self.assertTrue(get_api().save_vistrail(fname))
-        self.assertTrue(os.path.exists(fname))
-        get_api().close_vistrail()
-        self.assertTrue(get_api().open_vistrail(fname))
-        self.assertEqual(get_api().controller.current_version, 4)
-        get_api().close_vistrail()
-
-if __name__ == '__main__':
-    vistrails.core.application.init()
-    unittest.main()
+class ExecutionErrors(Exception):
+    """Errors raised during a pipeline execution.
+    """
+    def __init__(self, pipeline, resultobj):
+        self.pipeline = pipeline
+        self._errors = resultobj.errors
+
+    def __str__(self):
+        return "Pipeline execution failed: %d error%s:\n%s" % (
+                len(self._errors),
+                's' if len(self._errors) >= 2 else '',
+                '\n'.join('%d: %s' % p for p in self._errors.iteritems()))
+
+
+class ExecutionResults(object):
+    """Contains the results of a pipeline execution.
+    """
+    def __init__(self, pipeline, resultobj):
+        self.pipeline = pipeline
+        self._objects = resultobj.objects
+
+    def output_port(self, output):
+        """Gets the value passed to an OutputPort module with that name.
+        """
+        if isinstance(output, basestring):
+            outputs = self.pipeline._get_inputs_or_outputs('OutputPort')
+            module_id = outputs[output].id
+        else:
+            raise TypeError("output_port() expects a string, not %r" %
+                            type(output).__name__)
+        return self._objects[module_id].get_output('ExternalPipe')
+
+    def module_output(self, module):
+        """Gets all the output ports of a specified module.
+        """
+        if not isinstance(module, Module):
+            module = self.pipeline.get_module(module)
+        return self._objects[module.module_id].outputPorts
+
+    def __repr__(self):
+        return "<ExecutionResult: %d modules>" % len(self._objects)
+
+
+class Function(object):
+    """A function, essentially a value with an explicit module type.
+    """
+    # TODO : Function
+
+
+def load_vistrail(filename, version=None):
+    """Loads a Vistrail from a filename.
+    """
+    initialize()
+    if not isinstance(filename, basestring):
+        raise TypeError("load_vistrails() expects a filename, got %r" %
+                        type(filename).__name__)
+
+    locator = FileLocator(filename)
+    # Copied from VistrailsApplicationInterface#open_vistrail()
+    loaded_objs = vistrails.core.db.io.load_vistrail(locator)
+    controller = VistrailController(loaded_objs[0], locator,
+                                    *loaded_objs[1:])
+
+    return Vistrail(controller)
+
+
+def load_pipeline(filename):
+    """Loads a single pipeline from a filename.
+    """
+    initialize()
+    if not isinstance(filename, basestring):
+        raise TypeError("load_vistrails() expects a filename, got %r" %
+                        type(filename).__name__)
+
+    # Copied from VistrailsApplicationInterface#open_workflow()
+    locator = FileLocator(filename)
+    pipeline = locator.load(_Pipeline)
+
+    return Pipeline(pipeline)
+
+
+# TODO : provide a shortcut for basic_modules
+def load_package(identifier, autoload=True):
+    """Gets a package by identifier, enabling it if necessary.
+    """
+    initialize()
+    pm = get_package_manager()
+    pkg = pm.identifier_is_available(identifier)
+    if pm.has_package(identifier):
+        return Package(pkg)
+    elif pkg is None:
+        raise NoSuchPackage("Package %r not found" % identifier)
+
+    # Copied from VistrailController#try_to_enable_package()
+    dep_graph = pm.build_dependency_graph([identifier])
+    deps = pm.get_ordered_dependencies(dep_graph)
+    for pkg_id in deps:
+        if not do_enable_package(pm, pkg_id):
+            raise NoSuchPackage("Package %r not found" % pkg_id)
+
+    return Package(pkg)
+
+
+# Copied from VistrailController#try_to_enable_package()
+def do_enable_package(pm, identifier):
+    pkg = pm.identifier_is_available(identifier)
+    if pm.has_package(pkg.identifier):
+        return True
+    if pkg and not pm.has_package(pkg.identifier):
+        pm.late_enable_package(pkg.codepath)
+        pkg = pm.get_package_by_codepath(pkg.codepath)
+        if pkg.identifier != identifier:
+            # pkg is probably a parent of the "identifier" package
+            # try to load it
+            if (hasattr(pkg.module, 'can_handle_identifier') and
+                    pkg.module.can_handle_identifier(identifier)):
+                pkg.init_module.load_from_identifier(identifier)
+        return True
+    # identifier may refer to a subpackage
+    if (pkg and pkg.identifier != identifier and
+            hasattr(pkg.module, 'can_handle_identifier') and
+            pkg.module.can_handle_identifier(identifier) and
+            hasattr(pkg.init_module, 'load_from_identifier')):
+        pkg.init_module.load_from_identifier(identifier)
+        return True
+    return False
+
+
+ at contextlib.contextmanager
+def output_mode(output, mode, **kwargs):
+    """Context manager that makes an output use a specific mode.
+    """
+    # TODO : Output mode selection
+    yield
+
+
+def run_vistrail(filename, version=None, *args, **kwargs):
+    """Shortcut for load_vistrail(filename).execute(...)
+    """
+    return load_vistrail(filename, version).execute(*args, **kwargs)
diff --git a/vistrails/core/application.py b/vistrails/core/application.py
index 5fd6b44..3797600 100644
--- a/vistrails/core/application.py
+++ b/vistrails/core/application.py
@@ -1,61 +1,61 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-import atexit
-import copy
+from __future__ import division
+
 import os
-import shutil
 import sys
-import tempfile
 import weakref
 import warnings
 
-from vistrails.core import command_line
 from vistrails.core import debug
 from vistrails.core import keychain
 from vistrails.core import system
 from vistrails.core.collection import Collection
 import vistrails.core.configuration
+from vistrails.core.configuration import ConfigurationObject
 from vistrails.core.db.locator import BaseLocator, FileLocator, DBLocator, \
     UntitledLocator
 import vistrails.core.db.io
 import vistrails.core.interpreter.cached
 import vistrails.core.interpreter.default
-import vistrails.core.startup
+from vistrails.core.modules.module_registry import ModuleRegistry
+from vistrails.core.packagemanager import PackageManager
+from vistrails.core.startup import VistrailsStartup
 from vistrails.core.thumbnails import ThumbnailCache
 from vistrails.core.utils import InstanceObject, VistrailsWarning
-from vistrails.core.utils.uxml import enter_named_element
 from vistrails.core.vistrail.pipeline import Pipeline
 from vistrails.core.vistrail.vistrail import Vistrail
 from vistrails.core.vistrail.controller import VistrailController
@@ -70,7 +70,6 @@ def finalize_vistrails(app):
     vistrails.core.interpreter.cached.CachedInterpreter.cleanup()
 
 def get_vistrails_application():
-    global VistrailsApplication
     if VistrailsApplication is not None:
         return VistrailsApplication()
     return None
@@ -83,10 +82,10 @@ def is_running_gui():
     app = get_vistrails_application()
     return app.is_running_gui()
 
-def init(options_dict={}, args=None):
+def init(options_dict={}, args=[]):
     app = VistrailsCoreApplication()
     set_vistrails_application(app)
-    app.init(optionsDict=options_dict, args=args)
+    app.init(options_dict=options_dict, args=args)
     return app
 
 class VistrailsApplicationInterface(object):
@@ -94,314 +93,82 @@ class VistrailsApplicationInterface(object):
         self._initialized = False
         self.notifications = {}
 
-    def setupOptions(self, args=None):
-        """ setupOptions() -> None
-        Check and store all command-line arguments
-        
-        """
-        add = command_line.CommandLineParser.add_option
-        add("-S", "--startup", action="store", type="str", default=None,
-            dest="dotVistrails",
-            help="Set startup file (default is ~/.vistrails)")
-        add("-?", action="help",
-            help="show this help message and exit")
-        add("-v", "--version", action="callback",
-            callback=lambda option, opt, value, parser: self.printVersion(),
-            help="print version information and quit")
-        add("-V", "--verbose", action="store", type="int", default=None,
-            dest="verbose", help="set verboseness level (0--2, "
-            "default=0, higher means more verbose)")
-        add("-n", "--nosplash", action="store_false",
-            default = None,
-            help="don't display splash on startup")
-        add("-c", "--cache", action="store", type="int", default=None,
-            dest="cache", help="enable/disable caching")
-        add("-m", "--movies", action="store", type="int", default=None,
-            dest="movies", help="set automatic movie creation on spreadsheet "
-            "(0 or 1, default=1. Set this to zero to work around vtk bug with "
-            "offscreen renderer and opengl texture3d mappers)")
-        add("-s", "--multiheads", action="store_true",
-            default = None,
-            help="display the builder and spreadsheet on different screens "
-            "(if available)")
-        add("-x", "--maximized", action="store_true",
-            default = None,
-            help="Maximize VisTrails windows at startup")
-        add("-b", "--noninteractive", action="store_true",
-            default = None,
-            help="run in non-interactive mode")
-        add("-e", "--dumpcells", action="store", dest="dumpcells",
-            default = None,
-            help="when running in non-interactive mode, directory to dump "
-            "spreadsheet cells before exiting")
-        add("-p", "--pdf", action="store_true",
-            default = None,
-            help="dump files in pdf format (non-interactive mode only)")
-        add("-l", "--nologger", action="store_true",
-            default = None,
-            help="disable the logging")
-        add('--no-logfile', action='store_true',
-            dest='nologfile',
-            default=None,
-            help="Disable the log file (output still happens in terminal)")
-        add("-d", "--debugsignals", action="store_true",
-            default = None,
-            help="debug Qt Signals")
-        add("-a", "--parameters", action="store", dest="parameters",
-            help="workflow parameter settings (non-interactive mode only)")
-        add("-t", "--host", action="store", dest="host",
-            help="hostname or ip address of database server")
-        add("-r", "--port", action="store", type="int", default=3306,
-            dest="port", help="database port")
-        add("-f", "--db", action="store", dest="db",
-            help="database name")
-        add("-u", "--user", action="store", dest="user",
-            help="database username")
-        add("-i", "--showspreadsheetonly", action="store_true",
-            default = None,
-            help="only the spreadsheet will be shown. This implies -w was given.\
-The builder window can be accessed by a spreadsheet menu option.")
-        add("-w", "--executeworkflows", action="store_true",
-            default = None,
-            help="The workflows will be executed")
-        add("-F", "--fixedcells", action="store_true",
-            default = None,
-            help="Use a fixed spreadsheet cell size of 200*180")
-        add("-I", "--workflowinfo", action="store",
-            default = None,
-            help=("Save workflow graph and spec in specified directory "
-                  "(only valid in console mode)."))
-        add("-E", "--reviewmode", action="store_true",
-            default = None,
-            help="Show the spreadsheet in the reviewing mode")
-        add("-q", "--quickstart", action="store",
-            help="Start VisTrails using the specified static registry")
-        add("-D", "--detachHistoryView", action="store_true",
-            help="Detach the history view from the builder windows")
-        add("-P", "--parameterExploration", action="store_true",
-            help="Execute Parameter Exploration")
-        add("-G", "--workflowgraph", action="store",
-            default = None,
-            help=("Save workflow graph in specified directory without running "
-                  "the workflow (only valid in console mode)."))
-        add("-U", "--evolutiongraph", action="store",
-            default = None,
-            help=("Save evolution graph in specified directory without running "
-                  "any workflow (only valid in console mode)."))
-        add("-g", "--noSingleInstance", action="store_true",
-            help=("Run VisTrails without the single instance restriction."))
-        add("--no-bundleinstall", action='store_false',
-            dest='installBundles',
-            help=("Do not try to install missing Python packages "
-                  "automatically"))
-        add('--spawned-mode', '--spawned', action='store_true',
-            dest='spawned',
-            help=("Do not use the .vistrails directory, and load packages "
-                  "automatically when needed"))
-
-        if args != None:
-            command_line.CommandLineParser.parse_options(args=args)
-        else:
-            command_line.CommandLineParser.parse_options()
-
-    def printVersion(self):
-        """ printVersion() -> None
-        Print version of Vistrail and exit
+    def read_options(self, args=None):
+        """ read_options() -> None
+        Read arguments from the command line
         
         """
-        print system.about_string()
-        sys.exit(0)
+        if args is None:
+            args = sys.argv[1:]
 
-    def read_dotvistrails_option(self, optionsDict=None):
-        """ read_dotvistrails_option() -> None
-        Check if the user sets a new dotvistrails folder and updates
-        self.temp_configuration with the new value.
+        parser = vistrails.core.configuration.build_default_parser()
+        command_line_config = vistrails.core.configuration.ConfigurationObject()
+        try:
+            parser.parse_args(args, namespace=command_line_config)
+        except SystemError:
+            print "GOT SYSTEM ERROR!"
+            debug.print_exc()
+
+        self.input = command_line_config.vistrails
+        if len(self.input) == 0:
+            self.input = None
+
+        return command_line_config
+
+    # startup is going to manage configurations
+    def _get_configuration(self):
+        return self.startup.configuration
+    configuration = property(_get_configuration)
+
+    def _get_temp_configuration(self):
+        return self.startup.temp_configuration
+    temp_configuration = property(_get_temp_configuration)
+
+    def create_registry(self, registry_filename=None):
+        if registry_filename is not None:
+            registry = vistrails.core.db.io.open_registry(registry_filename)
+            registry.set_global()
+        else:
+            registry = ModuleRegistry()
+            registry.set_global()
+        return registry
 
-        Also handles the 'spawned-mode' option, by using a temporary directory
-        as .vistrails directory, and a specific default configuration.
-        """
-        if optionsDict is None:
-            optionsDict = {}
-        def get(opt):
-            return (optionsDict.get(opt) or
-                    command_line.CommandLineParser().get_option(opt))
-
-        if get('spawned'):
-            # Here we are in 'spawned' mode, i.e. we are running
-            # non-interactively as a slave
-            # We are going to create a .vistrails directory as a temporary
-            # directory and copy a specific configuration file
-            # We don't want to load packages that the user might enabled in
-            # this machine's configuration file as it would slow down the
-            # startup time, but we'll load any needed package without
-            # confirmation
-            tmpdir = tempfile.mkdtemp(prefix='vt_spawned_')
-            @atexit.register
-            def clean_dotvistrails():
-                shutil.rmtree(tmpdir, ignore_errors=True)
-            self.temp_configuration.dotVistrails = tmpdir
-            if get('dotVistrails') is not None:
-                debug.warning("--startup option ignored since --spawned-mode "
-                              "is used")
-            shutil.copyfile(os.path.join(system.vistrails_root_directory(),
-                                         'core', 'resources',
-                                         'spawned_startup_xml'),
-                            os.path.join(tmpdir, 'startup.xml'))
-            self.temp_configuration.enablePackagesSilently = True
-            self.temp_configuration.nologfile = True
-            self.temp_configuration.singleInstance = False
-        elif get('dotVistrails') is not None:
-            self.temp_configuration.dotVistrails = get('dotVistrails')
-
-    def readOptions(self):
-        """ readOptions() -> None
-        Read arguments from the command line
-        
-        """
-        get = command_line.CommandLineParser().get_option
-        if get('nosplash')!=None:
-            self.temp_configuration.showSplash = bool(get('nosplash'))
-        if get('debugsignals')!=None:
-            self.temp_configuration.debugSignals = bool(get('debugsignals'))
-        if get('dotVistrails')!=None:
-            self.temp_configuration.dotVistrails = get('dotVistrails')
-        if get('multiheads')!=None:
-            self.temp_configuration.multiHeads = bool(get('multiheads'))
-        if get('maximized')!=None:
-            self.temp_configuration.maximizeWindows = bool(get('maximized'))
-        if get('movies')!=None:
-            self.temp_configuration.showMovies = bool(get('movies'))
-        if get('cache')!=None:
-            self.temp_configuration.useCache = bool(get('cache'))
-        if get('verbose')!=None:
-            self.temp_configuration.verbosenessLevel = get('verbose')
-            dbg = debug.DebugPrint.getInstance()
-            levels = [dbg.WARNING, dbg.INFO, dbg.DEBUG]
-            dbg.set_message_level(levels[get('verbose')])
-        if get('fixedcells') != None:
-            self.temp_configuration.fixedSpreadsheetCells = str(get('fixedcells'))
-        if get('noninteractive')!=None:
-            self.temp_configuration.interactiveMode = \
-                                                  not bool(get('noninteractive'))
-            if get('workflowinfo') != None:
-                self.temp_configuration.workflowInfo = str(get('workflowinfo'))
-            if get('dumpcells') != None:
-                self.temp_configuration.spreadsheetDumpCells = get('dumpcells')
-            if get('pdf') != None:
-                self.temp_configuration.spreadsheetDumpPDF = get('pdf')
-            if get('workflowgraph') != None:
-                self.temp_configuration.workflowGraph = str(get('workflowgraph'))
-            if get('evolutiongraph') != None:
-                self.temp_configuration.evolutionGraph = str(get('evolutiongraph'))
-        if get('executeworkflows') != None:
-            self.temp_configuration.executeWorkflows = \
-                                            bool(get('executeworkflows'))
-        if get('showspreadsheetonly') != None:
-            self.temp_configuration.showSpreadsheetOnly = \
-                                            bool(get('showspreadsheetonly'))
-            # asking to show only the spreadsheet will force the workflows to
-            # be executed
-            if get('reviewmode') != None:
-                self.temp_configuration.reviewMode = bool(get('reviewmode'))
-
-            if self.temp_configuration.showSpreadsheetOnly and not self.temp_configuration.reviewMode:
-                self.temp_configuration.executeWorkflows = True
-            
-        self.temp_db_options = InstanceObject(host=get('host'),
-                                                 port=get('port'),
-                                                 db=get('db'),
-                                                 user=get('user'),
-                                                 parameters=get('parameters')
-                                                 )
-        if get('nologger')!=None:
-            self.temp_configuration.nologger = bool(get('nologger'))
-        if get('quickstart') != None:
-            self.temp_configuration.staticRegistry = str(get('quickstart'))
-        if get('parameterExploration')!= None:
-            self.temp_configuration.parameterExploration = \
-                str(get('parameterExploration'))
-        if get('detachHistoryView')!= None:
-            self.temp_configuration.detachHistoryView = bool(get('detachHistoryView'))
-        if get('noSingleInstance')!=None:
-            self.temp_configuration.singleInstance = not bool(get('noSingleInstance'))
-        if get('installBundles')!=None:
-            self.temp_configuration.installBundles = bool(get('installBundles'))
-        self.input = command_line.CommandLineParser().positional_arguments()
-
-    def init(self, optionsDict=None, args=None):
-        """ VistrailsApplicationSingleton(optionDict: dict)
+    def init(self, options_dict=None, args=[]):
+        """ VistrailsApplicationSingleton(options_dict: dict, args: list)
                                           -> VistrailsApplicationSingleton
         Create the application with a dict of settings
         
         """
         warnings.simplefilter('once', VistrailsWarning, append=True)
-        # gui.theme.initializeCurrentTheme()
-        # self.connect(self, QtCore.SIGNAL("aboutToQuit()"), self.finishSession)
-        
-        # This is the persistent configuration
-        # Setup configuration to default
-        self.configuration = vistrails.core.configuration.default()
-        
+
+        # options_dict overrides startup configuration
+        if options_dict is not None:
+            options_config = ConfigurationObject(**options_dict)
+        else:
+            options_config = None
+
+        # command line options override both
+        command_line_config = self.read_options(args)
+
+        # startup takes care of all configurations
+        self.startup = VistrailsStartup(options_config, command_line_config)
+
         self.keyChain = keychain.KeyChain()
-        self.setupOptions(args)
-        
-        # self.temp_configuration is the configuration that will be updated 
-        # with the command line and custom options dictionary. 
-        # We have to do this because we don't want to make these settings 
-        # persistent. This is the actual VisTrails current configuration
-        self.temp_configuration = copy.copy(self.configuration)
-        
-        vistrails.core.interpreter.default.connect_to_configuration(self.temp_configuration)
-        
-        # now we want to open vistrails and point to a specific version
-        # we will store the version in temp options as it doesn't
-        # need to be persistent. We will do the same to database
-        # information passed in the command line
-        self.temp_db_options = InstanceObject(host=None,
-                                           port=None,
-                                           db=None,
-                                           user=None,
-                                           vt_id=None,
-                                           parameters=None
-                                           ) 
-        
-        # Read only new .vistrails folder option if passed in the command line
-        # or in the optionsDict because this may affect the configuration file 
-        # VistrailsStartup will load. This updates self.temp_configuration
-        self.read_dotvistrails_option(optionsDict)
-
-        # the problem here is that if the user pointed to a new .vistrails
-        # folder, the persistent configuration will always point to the 
-        # default ~/.vistrails. So we will copy whatever it's on 
-        # temp_configuration to the persistent one. In case the configuration
-        # that is on disk is different, it will overwrite this one
-        self.configuration.dotVistrails = self.temp_configuration.dotVistrails
-        
-        # During this initialization, VistrailsStartup will load the
-        # configuration from disk and update both configurations
-        self.vistrailsStartup = \
-            vistrails.core.startup.VistrailsStartup(self.configuration,
-                                          self.temp_configuration)
-
-        # Starting in version 1.2.1 logging is enabled by default.
-        # Users have to explicitly disable it through the command-line
-        self.configuration.nologger = False
-        self.temp_configuration.nologger = False
-        
-        if optionsDict:
-            for (k, v) in optionsDict.iteritems():
-                setattr(self.temp_configuration, k, v)
+        vistrails.core.interpreter.default.connect_to_configuration(
+            self.temp_configuration)
 
-        # Command line options override temp_configuration
-        self.readOptions()
+        # now we want to open vistrails and point to a specific version
 
         self.check_all_requirements()
 
         if self.temp_configuration.check('staticRegistry'):
-            reg = self.temp_configuration.staticRegistry
+            self.registry = \
+                self.create_registry(self.temp_configuration.staticRegistry)
         else:
-            reg = None
-        self.vistrailsStartup.set_registry(reg)
+            self.registry = self.create_registry(None)
+
+        self.package_manager = PackageManager(self.registry,
+                                              self.startup)
 
     def check_all_requirements(self):
         # check scipy
@@ -411,24 +178,15 @@ The builder window can be accessed by a spreadsheet menu option.")
                 'linux-fedora': 'scipy',
                 'pip': 'scipy'})
 
-        # ZIP manipulations use the command-line executables
-        vistrails.core.requirements.require_executable('zip')
-        vistrails.core.requirements.require_executable('unzip')
-
-    def get_python_environment(self):
-        """get_python_environment(): returns an environment that
-includes local definitions from startup.py. Should only be called
-after self.init()"""
-        return self._python_environment
-
     def destroy(self):
         """ destroy() -> None
         Finalize all packages to, such as, get rid of temp files
         
         """
-        if hasattr(self, 'vistrailsStartup'):
-            self.vistrailsStartup.destroy()
+        if hasattr(self, 'package_manager'):
+            self.package_manager.finalize_packages()
         Collection.clearInstance()
+        ThumbnailCache.clearInstance()
 
     def __del__(self):
         """ __del__() -> None
@@ -461,13 +219,13 @@ after self.init()"""
                     name = str(data[0])
                 # will try to convert version to int
                 # if it fails, it's a tag name
+                #maybe a tag name contains ':' in its name
+                #so we need to bring it back together
+                rest = ":".join(data[1:])
                 try:
-                    #maybe a tag name contains ':' in its name
-                    #so we need to bring it back together
-                    rest = ":".join(data[1:])
                     version = int(rest)
                 except ValueError:
-                    version = str(rest)
+                    version = rest
             elif len(data) == 1:
                 if use_filename and os.path.isfile(str(data[0])):
                     name = str(data[0])
@@ -478,7 +236,7 @@ after self.init()"""
     def process_interactive_input(self):
         pe = None
         usedb = False
-        if self.temp_db_options.host:
+        if self.temp_configuration.check('host'):
             usedb = True
         if self.input:
             #check if versions are embedded in the filename
@@ -494,14 +252,15 @@ after self.init()"""
                     # it can be either a FileLocator or a DBLocator
                     
                 elif usedb:
-                    locator = DBLocator(host=self.temp_db_options.host,
-                                        port=self.temp_db_options.port,
-                                        database=self.temp_db_options.db,
-                                        user='',
-                                        passwd='',
-                                        obj_id=f_name,
-                                        obj_type=None,
-                                        connection_id=None)
+                    locator = DBLocator(
+                           host=self.temp_configuration.check('host'),
+                           port=self.temp_configuration.check('port') or 3306,
+                           database=self.temp_configuration.check('db'),
+                           user='',
+                           passwd='',
+                           obj_id=f_name,
+                           obj_type=None,
+                           connection_id=None)
                 if locator:
                     if self.temp_configuration.check('parameterExploration'):
                         pe = version
@@ -515,7 +274,7 @@ after self.init()"""
                             # version number
                             if locator._vtag != '':
                                 version = locator._vtag
-                    execute = self.temp_configuration.executeWorkflows
+                    execute = self.temp_configuration.check('execute')
                     mashuptrail = None
                     mashupversion = None
                     if hasattr(locator, '_mshptrail'):
@@ -524,7 +283,7 @@ after self.init()"""
                         mashupversion = locator._mshpversion
                         if mashupversion:
                             execute = True
-                    if not self.temp_configuration.showSpreadsheetOnly:
+                    if self.temp_configuration.showWindow:
                         self.showBuilderWindow()
                     self.builderWindow.open_vistrail_without_prompt(locator,
                                                                     version, execute,
@@ -534,9 +293,6 @@ after self.init()"""
                     if self.temp_configuration.check('parameterExploration'):
                         self.builderWindow.executeParameterExploration(pe)
                 
-                if self.temp_configuration.reviewMode:
-                    self.builderWindow.interactiveExportCurrentPipeline()
-
         return True
 
     def finishSession(self):
@@ -550,13 +306,7 @@ after self.init()"""
         window sizes.
 
         """
-        dom = self.vistrailsStartup.startup_dom()
-        doc = dom.documentElement
-        configuration_element = enter_named_element(doc, 'configuration')
-        doc.removeChild(configuration_element)
-        self.configuration.write_to_dom(dom, doc)
-        self.vistrailsStartup.write_startup_dom(dom)
-        dom.unlink()
+        self.startup.save_persisted_startup()
 
     def create_notification(self, notification_id, *args, **kwargs):
         notifications = self.notifications
@@ -589,9 +339,9 @@ after self.init()"""
                     #print "  m: ", m
                     m(*args)
                 except Exception, e:
-                    import traceback
-                    traceback.print_exc()
-       
+                    debug.unexpected_exception(e)
+                    debug.print_exc()
+
     def showBuilderWindow(self):
         pass
  
@@ -609,7 +359,7 @@ after self.init()"""
         """
         raise NotImplementedError("Subclass must implement ensure_vistrail")
 
-    def select_version(self, version=None):
+    def select_version(self, version):
         """select_version changes the version of the currently open vistrail
         to the specified version.
 
@@ -637,7 +387,8 @@ after self.init()"""
             try:
                 version = \
                     self.get_controller().vistrail.get_version_number(version)
-            except:
+            except Exception, e:
+                debug.unexpected_exception(e)
                 version = None
         return version
 
@@ -658,7 +409,7 @@ after self.init()"""
                 controller = self.add_vistrail(loaded_objs[0], locator, 
                                                *loaded_objs[1:])
                 if locator.is_untitled():
-                    return True
+                    return controller
                 controller.is_abstraction = is_abstraction
                 thumb_cache = ThumbnailCache.getInstance()
                 controller.vistrail.thumbnails = controller.find_thumbnails(
@@ -673,57 +424,48 @@ after self.init()"""
                 if not controller.is_abstraction:
                     collection.add_to_workspace(entity)
                 collection.commit()
-            except VistrailsDBException, e:
-                import traceback
-                debug.critical(str(e), traceback.format_exc())
+            except VistrailsDBException as e:
+                debug.unexpected_exception(e)
+                debug.critical("Exception from the database: %s" % e,
+                               debug.format_exc())
                 return None
-            except Exception, e:
-                # debug.critical('An error has occurred', str(e))
-                #print "An error has occurred", str(e)
-                raise
 
         version = self.convert_version(version)
         if version is None:
             controller.select_latest_version()
             version = controller.current_version
         self.select_version(version)
-        # flush in case version was upgraded
-        controller.flush_delayed_actions()
-        return True
-        
+        return controller
+
     def open_workflow(self, locator):
         if isinstance(locator, basestring):
             locator = BaseLocator.from_url(locator)
 
-        vistrail = Vistrail()
+        new_locator = UntitledLocator()
+        controller = self.open_vistrail(new_locator)
         try:
             if locator is None:
                 return False
-            if locator is not None:
-                workflow = locator.load(Pipeline)
-                action_list = []
-                for module in workflow.module_list:
-                    action_list.append(('add', module))
-                for connection in workflow.connection_list:
-                    action_list.append(('add', connection))
-                action = vistrails.core.db.action.create_action(action_list)
-                vistrail.add_action(action, 0L)
-                vistrail.update_id_scope()
-                vistrail.addTag("Imported workflow", action.id)
-
-                # FIXME might need different locator?                
-                controller = self.add_vistrail(vistrail, locator)
-        except VistrailsDBException, e:
-            import traceback
-            debug.critical(str(e), traceback.format_exc())
+            workflow = locator.load(Pipeline)
+            action_list = []
+            for module in workflow.module_list:
+                action_list.append(('add', module))
+            for connection in workflow.connection_list:
+                action_list.append(('add', connection))
+            action = vistrails.core.db.action.create_action(action_list)
+            controller.add_new_action(action)
+            controller.perform_action(action)
+            controller.vistrail.set_tag(action.id, "Imported workflow")
+            controller.change_selected_version(action.id)
+        except VistrailsDBException as e:
+            debug.unexpected_exception(e)
+            debug.critical("Exception from the database: %s" % e,
+                           debug.format_exc())
             return None
-        except Exception, e:
-            # debug.critical('An error has occurred', str(e))
-            raise
 
         controller.select_latest_version()
         controller.set_changed(True)
-        return True
+        return controller
 
     def save_vistrail(self, locator=None, controller=None, export=False):
         if controller is None:
@@ -743,9 +485,8 @@ after self.init()"""
         try:
             controller.write_vistrail(locator, export=export)
         except Exception, e:
-            import traceback
-            debug.critical('Failed to save vistrail: %s' % str(e),
-                           traceback.format_exc())
+            debug.unexpected_exception(e)
+            debug.critical("Failed to save vistrail", debug.format_exc())
             raise
         if export:
             return controller.locator
@@ -767,8 +508,7 @@ after self.init()"""
             collection.add_to_workspace(entity)
             collection.commit()
         except Exception, e:
-            import traceback
-            debug.critical('Failed to index vistrail', traceback.format_exc())
+            debug.critical('Failed to index vistrail', debug.format_exc())
         return controller.locator
 
     def close_vistrail(self, locator=None, controller=None):
@@ -791,9 +531,11 @@ class VistrailsCoreApplication(VistrailsApplicationInterface):
         self._controllers = {}
         self._cur_controller = None
 
-    def init(self, optionsDict=None, args=None):
-        VistrailsApplicationInterface.init(self, optionsDict=optionsDict, args=args)
-        self.vistrailsStartup.init()
+    def init(self, options_dict=None, args=[]):
+        VistrailsApplicationInterface.init(self, options_dict=options_dict, 
+                                           args=args)
+        self.package_manager.initialize_packages(
+                report_missing_dependencies=not self.startup.first_run)
 
     def is_running_gui(self):
         return False
@@ -802,13 +544,14 @@ class VistrailsCoreApplication(VistrailsApplicationInterface):
         return self._cur_controller
     get_controller = get_current_controller
 
-    def add_vistrail(self, *objs):
-        (vistrail, locator, abstraction_files, thumbnail_files, mashups) = objs
+    def add_vistrail(self, vistrail, locator,
+            abstraction_files=None,  thumbnail_files=None, mashups=None):
+        objs = vistrail, locator, abstraction_files, thumbnail_files, mashups
         controller = VistrailController(*objs)
         self._controllers[locator] = controller
         self._cur_controller = controller
         return self._cur_controller
-        
+
     def remove_vistrail(self, locator=None):
         if locator is None and self._cur_controller is not None:
             locator = self._cur_controller.locator
@@ -831,4 +574,3 @@ class VistrailsCoreApplication(VistrailsApplicationInterface):
             self._cur_controller.change_selected_version(version)
             return True
         return False
-        
diff --git a/vistrails/core/bundles/__init__.py b/vistrails/core/bundles/__init__.py
index 14a819b..92885b6 100644
--- a/vistrails/core/bundles/__init__.py
+++ b/vistrails/core/bundles/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,5 +37,7 @@
 """Package for bundle management. "Bundle" refers to system-level
 packages managed by specialized systems such as RedHat's RPM, Debian
 and Ubuntu's APT, OSX's fink, etc."""
+from __future__ import division
+
 from vistrails.core.bundles.pyimport import py_import
 from vistrails.core.bundles.installbundle import install
diff --git a/vistrails/core/bundles/installbundle.py b/vistrails/core/bundles/installbundle.py
index c4f05af..38828f3 100644
--- a/vistrails/core/bundles/installbundle.py
+++ b/vistrails/core/bundles/installbundle.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core import is_running_gui
 
 def install(dependency_dictionary):
diff --git a/vistrails/core/bundles/pyimport.py b/vistrails/core/bundles/pyimport.py
index f48cb97..1cccaea 100644
--- a/vistrails/core/bundles/pyimport.py
+++ b/vistrails/core/bundles/pyimport.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,8 +37,11 @@
 """module responsible for smartly importing python modules, checking
 for necessary installs."""
 
+from __future__ import division
+
 import vistrails.core.bundles.installbundle
-from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core.configuration import get_vistrails_configuration, \
+    get_vistrails_persistent_configuration
 from vistrails.core import debug
 
 ##############################################################################
@@ -53,7 +57,7 @@ class PyImportBug(PyImportException):
 def _vanilla_import(module_name):
     return __import__(module_name, globals(), locals(), [])
 
-def py_import(module_name, dependency_dictionary):
+def py_import(module_name, dependency_dictionary, store_in_config=False):
     """Tries to import a python module, installing if necessary.
 
     If the import doesn't succeed, we guess which system we are running on and
@@ -72,10 +76,32 @@ def py_import(module_name, dependency_dictionary):
     if module_name in _previously_failed_pkgs:
         raise PyImportException("Import of Python module '%s' failed again, "
                                 "not triggering installation" % module_name)
+    if store_in_config:
+        ignored_packages_list = getattr(get_vistrails_configuration(),
+                                        'bundleDeclinedList',
+                                        None)
+        if ignored_packages_list:
+            ignored_packages = set(ignored_packages_list.split(';'))
+        else:
+            ignored_packages = set()
+        if module_name in ignored_packages:
+            raise PyImportException("Import of Python module '%s' failed "
+                                    "again, installation disabled by "
+                                    "configuration" % module_name)
     debug.warning("Import of python module '%s' failed. "
                   "Will try to install bundle." % module_name)
 
-    success = vistrails.core.bundles.installbundle.install(dependency_dictionary)
+    success = vistrails.core.bundles.installbundle.install(
+            dependency_dictionary)
+
+    if store_in_config:
+        if bool(success):
+            ignored_packages.discard(module_name)
+        else:
+            ignored_packages.add(module_name)
+        setattr(get_vistrails_persistent_configuration(),
+                'bundleDeclinedList',
+                ';'.join(sorted(ignored_packages)))
 
     if not success:
         _previously_failed_pkgs.add(module_name)
@@ -88,5 +114,3 @@ def py_import(module_name, dependency_dictionary):
         _previously_failed_pkgs.add(module_name)
         raise PyImportBug("Installation of package '%s' succeeded, but import "
                           "still fails." % module_name)
-
-##############################################################################
diff --git a/vistrails/core/cache/__init__.py b/vistrails/core/cache/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/cache/__init__.py
+++ b/vistrails/core/cache/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/cache/hasher.py b/vistrails/core/cache/hasher.py
index bdbe8b8..542249c 100644
--- a/vistrails/core/cache/hasher.py
+++ b/vistrails/core/cache/hasher.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """Hasher class for vistrail items."""
+from __future__ import division
+
 from vistrails.core.cache.utils import hash_list
 
 try:
@@ -75,6 +78,14 @@ class Hasher(object):
         return hasher.digest()
 
     @staticmethod
+    def control_param_signature(control_param, constant_hasher_map={}):
+        hasher = sha_hash()
+        u = hasher.update
+        u(control_param.name)
+        u(control_param.value)
+        return hasher.digest()
+
+    @staticmethod
     def connection_signature(c):
         hasher = sha_hash()
         u = hasher.update
@@ -84,8 +95,10 @@ class Hasher(object):
 
     @staticmethod
     def connection_subpipeline_signature(c, source_sig, dest_sig):
-        """Returns the signature for the connection, including source
-and dest subpipelines"""
+        """Returns the signature for the connection, including source and dest
+        subpipelines
+
+        """
         hasher = sha_hash()
         u = hasher.update
         u(Hasher.connection_signature(c))
@@ -102,15 +115,19 @@ and dest subpipelines"""
         u(obj.module_descriptor.namespace or '')
         u(obj.module_descriptor.package_version or '')
         u(obj.module_descriptor.version or '')
-        u(hash_list(obj.functions, Hasher.function_signature, constant_hasher_map))
+        u(hash_list(obj.functions, Hasher.function_signature,
+                    constant_hasher_map))
+        u(hash_list(obj.control_parameters, Hasher.control_param_signature,
+                    constant_hasher_map))
         return hasher.digest()
 
     @staticmethod
     def subpipeline_signature(module_sig, upstream_sigs):
-        """Returns the signature for a subpipeline, given the
-signatures for the upstream pipelines and connections.
+        """Returns the signature for a subpipeline, given the signatures for
+        the upstream pipelines and connections.
 
         WARNING: For efficiency, upstream_sigs is mutated!
+
         """
         hasher = sha_hash()
         hasher.update(module_sig)
@@ -121,9 +138,11 @@ signatures for the upstream pipelines and connections.
 
     @staticmethod
     def compound_signature(sig_list):
-        """compound_signature(list of signatures) -> sha digest
-        returns the signature of the compound object formed by the list
-        of signatures, assuming the list order is irrelevant"""
+        """compound_signature(list of signatures) -> sha digest returns the
+        signature of the compound object formed by the list of
+        signatures, assuming the list order is irrelevant
+
+        """
         hasher = sha_hash()
         for h in sorted(sig_list):
             hasher.update(h)
diff --git a/vistrails/core/cache/utils.py b/vistrails/core/cache/utils.py
index 137eefd..0f98dd6 100644
--- a/vistrails/core/cache/utils.py
+++ b/vistrails/core/cache/utils.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """Helper functions for cache package."""
 
+from __future__ import division
+
 try:
     import hashlib
     sha_hash = hashlib.sha1
diff --git a/vistrails/core/collection/__init__.py b/vistrails/core/collection/__init__.py
index f270187..1c83362 100644
--- a/vistrails/core/collection/__init__.py
+++ b/vistrails/core/collection/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import glob
 import os
 import sqlite3
@@ -45,11 +48,10 @@ from thumbnail import ThumbnailEntity
 from mashup import MashupEntity
 from parameter_exploration import ParameterExplorationEntity
 
-from vistrails.core.db.locator import ZIPFileLocator, DBLocator, FileLocator, BaseLocator
+from vistrails.core.db.locator import FileLocator, BaseLocator
 from vistrails.core.db.io import load_vistrail
 import vistrails.core.system
 import vistrails.db.services.io
-from vistrails.core.configuration import get_vistrails_configuration
 from vistrails.core import debug
 
 schema = ["create table entity(id integer primary key, type integer, "
@@ -84,11 +86,11 @@ class Collection(object):
             self.conn = sqlite3.connect(self.database)
             try:
                 cur = self.conn.cursor()
-                [cur.execute(s) for s in schema]
+                for s in schema:
+                    cur.execute(s)
                 self.conn.commit()
             except Exception, e:
-                debug.critical("Could not create vistrail index schema",
-                               str(e))
+                debug.critical("Could not create vistrail index schema", e)
         else:
             self.conn = sqlite3.connect(self.database)
         self.load_entities()
@@ -289,25 +291,6 @@ class Collection(object):
         self.add_entity(entity)
         return entity
 
-    def update_from_database(self, db_locator):
-        # db_conn = db_locator.get_connection()
-        config = (('host', db_locator._host),
-                  ('port', int(db_locator._port)),
-                  ('db', db_locator._db),
-                  ('user', db_locator._user),
-                  ('passwd', db_locator._passwd))
-        rows = vistrails.db.services.io.get_db_object_list(dict(config), 'vistrail')
-        for row in rows:
-            if row[0] in [1,]:
-                continue
-            kwargs = {'obj_type': 'vistrail', 'obj_id': row[0]}
-            locator = DBLocator(*[x[1] for x in config], **kwargs)
-            (vistrail, abstractions, thumbnails, mashups) = load_vistrail(locator)
-            vistrail.abstractions = abstractions
-            vistrail.thumbnails = thumbnails
-            vistrail.mashups = mashups
-            self.create_vistrail_entity(vistrail)
-
     def update_from_directory(self, directory):
         filenames = glob.glob(os.path.join(directory, '*.vt'))
         for filename in filenames:
@@ -326,7 +309,7 @@ class Collection(object):
         """ Check if entity with this url exist """
         locator = BaseLocator.from_url(url)
         if locator.is_valid():
-                return True
+            return True
         return False
 
     def updateVistrail(self, url, vistrail=None):
@@ -360,32 +343,3 @@ class Collection(object):
             # probably an unsaved vistrail
             pass
 #            debug.critical("Locator is not valid!")
-
-def main():
-    import sys
-    sys.path.append('/home/tommy/git/vistrails/vistrails')
-
-    # vistrail = load_vistrail(ZIPFileLocator('/vistrails/examples/spx.vt'))[0]
-#    db_locator = DBLocator('vistrails.sci.utah.edu', 3306,
-#                           'vistrails', 'vistrails', '8edLj4',
-#                           obj_id=9, obj_type='vistrail')
-    # vistrail = load_vistrail(db_locator)[0]
-    c = Collection('/home/tommy/git/vistrails/vistrails/core/collection/test.db')
-    c.clear()
-    c.update_from_directory('/home/tommy/git/vistrails/examples')
-#    c.update_from_database(db_locator)
-
-    # entity = c.create_vistrail_entity(vistrail)
-    c.entities = {}
-    c.load_entities()
-#    print c.entities[2].url
-#    locator = BaseLocator.from_url(c.entities[2].url)
-#    c.entities[1].description = 'blah blah blah'
-#    c.save_entity(c.entities[1])
-#    print locator.to_url()
-    # c.load_entities()
-
-#    print BaseLocator.from_url('/vistrails/examples/spx.xml').to_url()
-
-if __name__ == '__main__':
-    main()
diff --git a/vistrails/core/collection/entity.py b/vistrails/core/collection/entity.py
index 1e52bbb..83209b7 100644
--- a/vistrails/core/collection/entity.py
+++ b/vistrails/core/collection/entity.py
@@ -1,38 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.db.locator import BaseLocator
+from vistrails.core.system import strftime
 from datetime import datetime
 
 class Entity(object):
@@ -64,8 +68,8 @@ class Entity(object):
                 self.type_id,
                 self.name,
                 self.user,
-                self.mod_time.strftime(self.DATE_FORMAT),
-                self.create_time.strftime(self.DATE_FORMAT),
+                strftime(self.mod_time, self.DATE_FORMAT),
+                strftime(self.create_time, self.DATE_FORMAT),
                 self.size,
                 self.description,
                 self.url)
diff --git a/vistrails/core/collection/mashup.py b/vistrails/core/collection/mashup.py
index 55d58b2..f2f6547 100644
--- a/vistrails/core/collection/mashup.py
+++ b/vistrails/core/collection/mashup.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from entity import Entity
 
 class MashupEntity(Entity):
diff --git a/vistrails/core/collection/parameter_exploration.py b/vistrails/core/collection/parameter_exploration.py
index 124c93b..9844053 100644
--- a/vistrails/core/collection/parameter_exploration.py
+++ b/vistrails/core/collection/parameter_exploration.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from entity import Entity
 
 class ParameterExplorationEntity(Entity):
diff --git a/vistrails/core/collection/schema.sql b/vistrails/core/collection/schema.sql
index c916c4b..81919db 100644
--- a/vistrails/core/collection/schema.sql
+++ b/vistrails/core/collection/schema.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/core/collection/search.py b/vistrails/core/collection/search.py
index 119c96e..595eb0d 100644
--- a/vistrails/core/collection/search.py
+++ b/vistrails/core/collection/search.py
@@ -1,47 +1,49 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # search functions for entity-type objects
 # notes in plain text, not html, should be fix later
+from __future__ import division
+
+import datetime
 import re
 import time
+import unittest
 
 from vistrails.core.query import extract_text
 
-import unittest
-import datetime
-
 ################################################################################
 
 class SearchParseError(Exception):
diff --git a/vistrails/core/collection/thumbnail.py b/vistrails/core/collection/thumbnail.py
index a54ae7c..0f63fdd 100644
--- a/vistrails/core/collection/thumbnail.py
+++ b/vistrails/core/collection/thumbnail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import os
 import stat
 from time import localtime
diff --git a/vistrails/core/collection/vistrail.py b/vistrails/core/collection/vistrail.py
index 1525398..efadd74 100644
--- a/vistrails/core/collection/vistrail.py
+++ b/vistrails/core/collection/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 import locale
 import sys
@@ -178,11 +181,11 @@ class VistrailEntity(Entity):
             tag = self.vistrail.get_tag(version_id)
         try:
             workflow = self.vistrail.getPipeline(version_id)
-        except:
-            import traceback
+        except Exception, e:
+            debug.unexpected_exception(e)
             debug.critical("Failed to construct pipeline '%s'" % 
                                (tag if tag else version_id),
-                           traceback.format_exc())
+                           debug.format_exc())
             workflow = self.vistrail.getPipeline(0)
         if tag:
             workflow.name = tag
@@ -259,14 +262,14 @@ class VistrailEntity(Entity):
             action = self.vistrail.actionMap[version_id]
             try:
                 workflow = self.vistrail.getPipeline(version_id)
-            except:
-                import traceback
+            except Exception, e:
+                debug.unexpected_exception(e)
                 if self.vistrail.has_tag(version_id):
                     tag_str = self.vistrail.get_tag(version_id)
                 else:
                     tag_str = str(version_id)
                 debug.critical("Failed to construct pipeline '%s'" % tag_str,
-                               traceback.format_exc())
+                               debug.format_exc())
                 workflow = self.vistrail.getPipeline(0)
             wf_entity = self.create_workflow_entity(workflow, action)
             self.wf_entity_map[version_id] = wf_entity
@@ -344,11 +347,12 @@ class VistrailEntity(Entity):
                 #             self.add_parameter_exploration_entity(pe)
                 
             # read persisted log entries
+            log = None
             try:
                 log = vistrail.get_persisted_log()
-            except:
-                import traceback
-                debug.critical("Failed to read log", traceback.format_exc())
+            except Exception, e:
+                debug.unexpected_exception(e)
+                debug.critical("Failed to read log", debug.format_exc())
                 
             if log is not None:
                 for wf_exec in log.workflow_execs:
diff --git a/vistrails/core/collection/workflow.py b/vistrails/core/collection/workflow.py
index 44346ff..0461b82 100644
--- a/vistrails/core/collection/workflow.py
+++ b/vistrails/core/collection/workflow.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from entity import Entity
 
 class WorkflowEntity(Entity):
diff --git a/vistrails/core/collection/workflow_exec.py b/vistrails/core/collection/workflow_exec.py
index 1f21778..f03b8f3 100644
--- a/vistrails/core/collection/workflow_exec.py
+++ b/vistrails/core/collection/workflow_exec.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from entity import Entity
 
 class WorkflowExecEntity(Entity):
diff --git a/vistrails/core/command_line.py b/vistrails/core/command_line.py
deleted file mode 100644
index 386791f..0000000
--- a/vistrails/core/command_line.py
+++ /dev/null
@@ -1,101 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-"""Very thin convenience wrapper around optparse.OptionParser."""
-
-import optparse
-import sys
-
-class CommandLineParserSingleton(object):
-    """CommandLineParser is a very thin wrapper around
-    optparse.OptionParser to make easier the parsing of command line
-    parameters."""
-    def __call__(self):
-        return self
-    
-    def __init__(self):
-        self.parser = optparse.OptionParser()
-        self.options_were_read = False
-        self.args = []
-
-    def init_options(self,args=None):
-        """self.init_options(args: [string]) -> None. Initialize option dictionary,
-        by parsing command line arguments according to the options set
-        by previous add_option calls.
-
-        Few programs should call this. Call self.parse_options() unless
-        you know what you're doing."""
-        if args is None:
-            if hasattr(sys, "argv"):
-                args = sys.argv[1:]
-            else:
-                args = []
-        (self.options, self.args) = self.parser.parse_args(args)
-        self.options_were_read = True
-
-    def add_option(self, *args, **kwargs):
-        """self.add_option(*args, **kwargs) -> None. Adds a new option
-        to the command line parser. Behaves identically to the
-        optparse.OptionParser.add_option."""
-        self.parser.add_option(*args, **kwargs)
-
-    def get_option(self, key):
-        """self.get_option(key) -> value. Returns a value corresponding
-        to the given key that was parsed from the command line. Throws
-        AttributeError if key is not present."""
-        self.parse_options()
-        return getattr(self.options, key)
-
-    def parse_options(self,args=None):
-        """self.parse_options() -> None. Parse command line arguments,
-        according to the options set by previous add_option calls."""
-        if not self.options_were_read:
-            self.init_options(args)
-
-    def get_arg(self,number):
-        """self.get_arg(number) -> value. Returns the value corresponding
-        to the argument at position number from the command line. Returns 
-        None if number is greater or equal the number of arguments. """
-        if len(self.args) > number:
-            return self.args[number]
-        else:
-            return None 
-
-    def positional_arguments(self):
-        """positional_arguments() -> [string]. Returns a list of strings
-        representing the positional arguments in the command line."""
-        return self.args
-
-# singleton trick
-CommandLineParser = CommandLineParserSingleton()
diff --git a/vistrails/core/common.py b/vistrails/core/common.py
index 8ff715b..177e3eb 100644
--- a/vistrails/core/common.py
+++ b/vistrails/core/common.py
@@ -1,40 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.utils import \
      InstanceObject, \
-     lock_method, \
      enum, \
      trace_method_args, trace_method_args, bump_trace, report_stack, \
      memo_method, \
diff --git a/vistrails/core/configuration.py b/vistrails/core/configuration.py
index 1c928a1..ae68683 100644
--- a/vistrails/core/configuration.py
+++ b/vistrails/core/configuration.py
@@ -1,57 +1,1235 @@
-###############################################################################
+##############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Configuration variables for controlling specific things in VisTrails."""
+from __future__ import division
+
+import argparse
+import ast
 import copy
-import os.path
-import shutil
+import itertools
+import re
+import shlex
 import sys
-import tempfile
 import weakref
 
-from vistrails.core import debug
+import os
+
 from vistrails.core import system
-from vistrails.core.utils import (InstanceObject, Ref, append_to_dict_of_lists,
-                        VistrailsInternalError)
-from vistrails.core.utils.uxml import (named_elements,
-                             elements_filter, eval_xml_value,
-                             quote_xml_value)
+from vistrails.core.utils import Ref, append_to_dict_of_lists
+from vistrails.db.domain import DBConfiguration, DBConfigKey, DBConfigStr, \
+    DBConfigInt, DBConfigFloat, DBConfigBool
 
 ##############################################################################
 
-class ConfigurationObject(InstanceObject):
+_docs = {}
+_simple_docs = {}
+_usage_args = set()
+
+_simple_documentation = """
+autoConnect: Automatically connect dragged in modules
+autoSave: Automatically save backup vistrails every two minutes
+batch: Run in batch mode instead of interactive mode
+cache: Cache previous results so they may be used in future computations
+dataDir: Default data directory
+db: The name for the database to load the vistrail from
+dbDefault: Save vistrails in a database by default
+debugLevel: How much information should VisTrails log
+defaultFileType: Default file type/extension for vistrails (.vt or .xml)
+detachHistoryView: Show the version tree in a separate window
+dotVistrails: User configuration directory
+enablePackagesSilently: Automatically enable packages when needed
+errorLog: Write errors to a log file
+execute: Execute any specified workflows
+executionLog: Track execution provenance when running workflows
+fileDir: Default vistrail directory
+fixedSpreadsheetCells: Draw spreadsheet cells at a fixed size
+handlerDontAsk: Do not ask about extension handling at startup
+hideUpgrades: Don't show upgrade nodes in the version tree
+host: The hostname for the database to load the vistrail from
+installBundles: Install missing Python dependencies
+installBundlesWithPip: Use pip to install missing Python dependencies
+isInServerMode: Indicates whether VisTrails is being run as a server
+jobAutorun: Run jobs automatically when they finish
+jobCheckInterval: How often to check for jobs (in seconds)
+jobList: List running workflows
+jobInfo: List jobs in running workflow
+loadPackages: Whether to load the packages enabled in the configuration file
+logDir: Log files directory
+maxRecentVistrails: Number of recent vistrails
+maximizeWindows: VisTrails windows should be maximized
+migrateTags: Move tags to upgraded versions
+multiHeads: Use multiple screens for VisTrails windows
+multithread: Server will start a thread for each request
+packageDir: System packages directory
+parameterExploration: Run parameter exploration instead of workflow
+parameters: List of parameters to use when running workflow
+port: The port for the database to load the vistrail from
+repositoryHTTPURL: Remote package repository URL
+repositoryLocalPath: Local package repository directory
+rootDirectory: Directory that contains the VisTrails source code
+rpcConfig: Config file for server connection options
+rpcInstances: Number of other instances that vistrails should start
+rpcLogFile: Log file for XML RPC server
+rpcPort: Port where this xml rpc server will work
+rpcServer: Hostname or ip address where this xml rpc server will work
+shell.fontFace: Console Font
+shell.fontSize: Console Font Size
+showConnectionErrors: Show error when input value doesn't match type during execution
+showDebugPopups: Always bring debug messages to the front
+showInlineParameterWidgets: Show editable parameters inside modules
+showScrollbars: Show scrollbars on the version tree and workflow canvases
+showSplash: Show VisTrails splash screen during startup
+showSpreadsheetOnly: Hides the VisTrails main window
+showVariantErrors: Show error when variant input value doesn't match type during execution
+showWindow: Show the main window
+singleInstance: Do not allow more than one instance of VisTrails to run at once
+spreadsheetDumpCells: Defines the location for generated cells
+spreadsheetDumpPDF: Whether the spreadsheet should dump images in PDF format
+staticRegistry: XML registry file
+stopOnError: Stop all workflow execution immediately after first error
+subworkflowsDir: Local subworkflows directory
+temporaryDir: Temporary files directory
+thumbs.autoSave: Save thumbnails of visual results
+thumbs.cacheDir: Thumbnail cache directory
+thumbs.cacheSize: Thumbnail cache size (MB)
+thumbs.mouseHover: Show thumbnails when mouse is hovering above a version
+thumbs.tagsOnly: Store thumbnails only for tagged versions
+upgradeDelay: Persist upgrade only after other changes
+upgradeModuleFailPrompt: Alert when a subworkflow upgrade fails
+upgrades: Attempt to automatically upgrade old workflows
+useMacBrushedMetalStyle: Use a brushed metal interface (MacOS X only)
+user: The username for the database to the load vistrail from
+userPackageDir: Local packages directory
+viewOnLoad: Whether to show pipeline or history view when opening vistrail
+webRepositoryURL: Web repository URL
+webRepositoryUser: Web repository username
+withVersionTree: Output the version tree as an image
+withWorkflow: Output the workflow graph as an image
+"""
+
+_documentation = """
+autoConnect: Boolean
+
+    Try to automatically connect a newly dragged in module to the rest
+    of the workflow.
+
+autoSave: Boolean
+
+    Automatically save vistrails to allow recovery from crashes, etc.
+
+batch: Boolean
+
+    Run vistrails in batch mode instead of interactive mode.
+
+cache: Boolean
+
+    Cache previous results so they may be used in future computations.
+
+dataDir: Path
+
+    The location that VisTrails uses as a default directory for data.
+
+db: String
+
+    The name for the database to load the vistrail from.
+
+dbDefault: Boolean
+
+    Use a database as the default storage location for vistrails entities.
+
+debugLevel: Integer
+
+    How much information VisTrails should alert the user about (0:
+    Critical errors only, 1: Critical errors and warnings, 2: Critical
+    errors, warnings, and log messages).
+
+defaultFileType: String
+
+    Defaults to .vt but could be .xml.
+
+detachHistoryView: Boolean
+
+    Show the version tree in a separate window.
+
+dotVistrails: Path
+
+    The location to look for VisTrails user configurations and
+    storage. Defaults to ~/.vistrails.
+
+enablePackagesSilently: Boolean
+
+    Do not prompt the user to enable packages, just do so
+    automatically.
+
+errorLog: Boolean
+
+    Write errors to a log file.
+
+execute: Boolean
+
+    Execute any specified workflows.
+
+executionLog: Boolean
+
+    Track execution provenance when running workflows.
+
+fileDir: Path
+
+    The location that VisTrails uses as a default directory for
+    specifying files.
+
+fixedSpreadsheetCells: Boolean
+
+    Draw spreadsheet cells at a fixed size (for testing).
+
+handlerDontAsk: Boolean
+
+    Do not ask about extension handling at startup (Linux only).
+
+hideUpgrades: Boolean
+
+    Don't show the "upgrade" nodes in the version tree.
+
+host: URL
+
+    The hostname for the database to load the vistrail from.
+
+installBundles: Boolean
+
+    Automatically try to install missing Python dependencies.
+
+installBundlesWithPip: Boolean
+
+    Whether to try to use pip to install Python dependencies or use
+    distribution support.
+
+isInServerMode: Boolean
+
+    Indicates whether VisTrails is being run as a server.
+
+jobAutorun: Boolean
+
+    Run jobs automatically when they finish.
+
+jobCheckInterval: Integer:
+
+    How often to check for jobs (in seconds, default=600).
+
+jobList: Boolean
+
+    List running workflows.
+
+jobInfo: Boolean
+
+    List jobs in running workflow
+
+loadPackages: Boolean
+
+    Whether to load the packages enabled in the configuration file
+
+logDir: Path
+
+    The path that indicates where log files should be stored.
+
+logger: ConfigurationObject
+
+    *Deprecated*
+
+maximizeWindows: Boolean
+
+    Whether the VisTrails windows should take up the entire screen space.
+
+maxMemory: Integer
+
+    *Deprecated*
+
+maxRecentVistrails: Integer
+
+    How many recently opened vistrails should be stored for "Open
+    Recent" access.
+
+migrateTags: Boolean
+
+    Whether or not the tag on a workflow that was upgraded should be
+    moved to point to the upgraded version.
+
+minMemory: Integer
+
+    *Deprecated*
+
+multiHeads: Boolean
+
+    Whether or not to use multiple screens for VisTrails windows.
+
+multithread: Boolean
+
+    Server will start a thread for each request.
+
+OLDupgradeDelay: Boolean
+    If True, will only persist the upgrade when a user makes a
+    modification to or executes the workflow. Otherwise, the upgrade
+    will be automatically added to the version tree when a user views
+    an upgraded workflow.
+
+outputDefaultSettings: ConfigurationObject
+
+    One or more comma-separated key=value parameters.
+
+outputSettings: ConfigurationObject
+
+    One or more comma-separated key=value parameters.
+
+packageDir: Path
+
+    The directory to look for VisTrails core packages (use
+    userPackageDir for user-defined packages).
+
+parameterExploration: Boolean
+
+    Open and execute parameter exploration specified by the
+    version argument after the .vt file.
+
+parameters: String
+
+    List of parameters to use when running workflow.
+
+port: Integer
+
+    The port for the database to load the vistrail from.
+
+pythonPrompt: Boolean
+
+    *Deprecated*
+
+recentVistrailList: String
+
+    Storage for recent vistrails. Users should not edit.
+
+repositoryHTTPURL: URL
+
+    URL used to locate packages available to be installed.
+
+repositoryLocalPath: Path
+
+    Path used to locate packages available to be installed.
+
+reviewMode: Boolean
+
+    *Deprecated* Used to interactively export a pipeline.
+
+rootDirectory: Path
+
+    Directory that contains the VisTrails source code.
+
+rpcConfig: String
+
+    Config file for server connection options.
+
+rpcInstances: Integer
+
+    Number of other instances that vistrails should start.
+
+rpcLogFile: String
+
+    Log file for XML RPC server.
+
+rpcPort: Integer
+
+    Port where this xml rpc server will work.
+
+rpcServer: URL
+
+    Hostname or ip address where this xml rpc server will work.
+
+runningJobsList: String
+
+    Storage for recent vistrails; users should not edit.
+
+shell: ConfigurationObject
+
+    Settings for the appearance of the VisTrails console.
+
+shell.fontFace: String
+
+    The font to be used for the VisTrails console.
+
+shell.fontSize: Integer
+
+    The font size used for the VisTrails console.
+
+showConnectionErrors: Boolean
+
+    Alert the user if the value along a connection doesn't match
+    connection types.
+
+showDebugPopups: Boolean
+
+    Always show the debug popups or only if there is a modal widget.
+
+showMovies: Boolean
+
+    *Deprecated* Set automatic movie creation on the spreadsheet.
+
+showScrollbars: Boolean
+
+    Whether VisTrails should show scrollbars on the version tree and workflow
+    canvases.
+
+showSplash: Boolean
+
+    Whether the VisTrails splash screen should be shown on startup.
+
+showSpreadsheetOnly: Boolean
+
+    Whether the VisTrails main window should be hidden.
+
+showVariantErrors: Boolean
+
+    Alert the user if the value along a connection coming from a
+    Variant output doesn't match the input port.
+
+showWindow: Boolean
+
+    Show the main VisTrails window.
+
+singleInstance: Boolean
+
+    Whether or not VisTrails should only allow one instance to be
+    running.
+
+spreadsheetDumpCells: Path
+
+    If specified, defines the location for parameter exploration to
+    store the cells it generates.
+
+spreadsheetDumpPDF: Boolean
+
+    Whether the spreadsheet should dump images in PDF format.
+
+staticRegistry: Path
+
+    If specified, VisTrails uses an XML file defining the VisTrails
+    module registry to load modules instead of from the packages directly.
+
+stopOnError: Boolean
+
+    Whether or not VisTrails stops executing the rest of the workflow
+    if it encounters an error in one module.
+
+subworkflowsDir: Path
+
+    The location where a user's local subworkflows are stored.
+
+temporaryDir: Path
+
+    The directory to use for temporary files generated by VisTrails.
+
+thumbs: ConfiguationObject
+
+    Settings for generating and saving thumbnail images.
+
+thumbs.autoSave: Boolean
+
+    Whether to save thumbnails of results when executing VisTrails.
+
+thumbs.cacheDir: Path
+
+    The directory to be used to cache thumbnails.
+
+thumbs.cacheSize: Integer
+
+    The size (in MB) of the thumbnail cache.
+
+thumbs.mouseHover: Boolean
+
+    Whether to show thumbnails when hovering over a version in the
+    version tree.
+
+thumbs.tagsOnly: Boolean
+
+    If True, only stores thumbnails for tagged versions. Otherwise,
+    stores thumbnails for all versions.
+
+upgradeDelay: Boolean
+
+    Persist upgrade only after other changes.
+
+upgrades: Boolean
+
+    Whether to upgrade old workflows so they work with newer packages.
+
+upgradeModuleFailPrompt: Boolean
+
+    Whether to alert the user when an upgrade may fail when upgrading
+    a subworkflow.
+
+useMacBrushedMetalStyle: Boolean
+
+    Whether should use a brushed metal interface (MacOS X only).
+
+user: String
+
+    The username for the database to load the vistrail from.
+
+userPackageDir: Boolean
+
+    The location for user-installed packages (defaults to
+    ~/.vistrails/userpackages).
+
+viewOnLoad: String
+
+    Whether to show pipeline or history view when opening vistrail
+    Can be either appropriate/pipeline/history
+
+webRepositoryURL: URL
+
+    The URL of the web repository that should be attached to VisTrails
+    (e.g. www.crowdlabs.org).
+
+webRepositoryUser: String
+
+    The default username for logging into a VisTrails web repository
+    like crowdLabs.
+
+withVersionTree: Boolean
+
+    Output the version tree as an image.
+
+withWorkflow: Boolean
+
+    Output the workflow graph as an image.
+
+showInlineParameterWidgets: Boolean
+
+    Show editable parameters inside modules
+
+"""
+
+class ConfigType(object):
+    NORMAL = 0
+    SHOW_HIDE = 1
+    ON_OFF = 2
+    COMMAND_LINE = 3
+    COMMAND_LINE_FLAG = 4
+    INTERNAL = 5
+    STORAGE = 6
+    PACKAGE = 7
+    SUBOBJECT = 8
+    INTERNAL_SUBOBJECT = 9
+
+class ConfigString(object):
+    @classmethod
+    def from_string(cls, val):
+        if not val:
+            return None
+        return val
+
+    @classmethod
+    def to_string(cls, val):
+        if val is None:
+            return ""
+        return val
+
+class ConfigPath(ConfigString):
+    pass
+
+class ConfigURL(ConfigString):
+    pass
+
+class ConfigField(object):
+    def __init__(self, name, default_val, val_type,
+                 field_type=ConfigType.NORMAL, category=None, flag=None,
+                 nargs=None, widget_type=None,
+                 widget_options=None, depends_on=None):
+        self.name = name
+        self.default_val = default_val
+        self.val_type = val_type
+        self.field_type = field_type
+        self.category = category
+        self.flag = flag
+        self.nargs = nargs
+        self.widget_type = widget_type
+        if widget_options is not None:
+            self.widget_options = widget_options
+        else:
+            self.widget_options = {}
+        self.depends_on = depends_on
+
+    def from_string(self, str_val):
+        if hasattr(self.val_type, "from_string"):
+            return self.val_type.from_string(str_val)
+        if not str_val:
+            return None
+        if issubclass(self.val_type, basestring):
+            return str_val
+        val = ast.literal_eval(str_val)
+        if not isinstance(val, self.val_type):
+            raise ValueError('Output setting "%s" cannot be parsed to %s' %
+                             (self.name, self.val_type.__name__))
+        return val
+
+    def to_string(self, val):
+        if hasattr(self.val_type, "to_string"):
+            return self.val_type.to_string(val)
+        elif val is None:
+            return ""
+        return unicode(val)
+
+class ConfigFieldParent(object):
+    def __init__(self, name, sub_fields):
+        self.name = name
+        self.sub_fields = sub_fields
+
+base_config = {
+    "Command-Line":
+    [ConfigField("execute", False, bool, ConfigType.COMMAND_LINE_FLAG,
+                 flag='-e'),
+     ConfigField("batch", False, bool, ConfigType.COMMAND_LINE_FLAG,
+                 flag='-b'),
+     ConfigField("outputDirectory", None, ConfigPath, flag='-o'),
+     ConfigField('outputDefaultSettings', [], str,
+                 ConfigType.INTERNAL_SUBOBJECT),
+     ConfigField('outputSettings', [], str, ConfigType.SUBOBJECT,
+                 flag='-p'),
+     # ConfigField("package", [], str, flag='-p', nargs='*'),
+     ConfigField("parameters", None, str, ConfigType.COMMAND_LINE),
+     ConfigField("parameterExploration", False, bool,
+                 ConfigType.COMMAND_LINE_FLAG),
+     ConfigField('showWindow', True, bool, ConfigType.COMMAND_LINE_FLAG),
+     ConfigField("withVersionTree", False, bool, ConfigType.COMMAND_LINE_FLAG),
+     ConfigField("withWorkflow", False, bool, ConfigType.COMMAND_LINE_FLAG),
+     ConfigField("graphsAsPdf", True, bool, ConfigType.COMMAND_LINE_FLAG)],
+    "Database":
+    [ConfigField("host", None, ConfigURL, ConfigType.COMMAND_LINE),
+     ConfigField("port", None, int, ConfigType.COMMAND_LINE),
+     ConfigField("db", None, str, ConfigType.COMMAND_LINE),
+     ConfigField("user", None, str, ConfigType.COMMAND_LINE)],
+    "Server":
+    [ConfigField('rpcServer', None, str, ConfigType.COMMAND_LINE),
+     ConfigField('rpcPort', 8080, int, ConfigType.COMMAND_LINE),
+     ConfigField('rpcLogFile', os.path.join(system.vistrails_root_directory(),
+                       'rpcserver.log'), ConfigPath, ConfigType.COMMAND_LINE),
+     ConfigField('rpcInstances', 0, int, ConfigType.COMMAND_LINE),
+     ConfigField('multithread', None, bool, ConfigType.COMMAND_LINE_FLAG),
+     ConfigField('rpcConfig', os.path.join(system.vistrails_root_directory(),
+                      'server.cfg'), ConfigPath, ConfigType.COMMAND_LINE)],
+    "General":
+    [ConfigField('autoSave', True, bool, ConfigType.ON_OFF),
+     ConfigField('dbDefault', False, bool, ConfigType.ON_OFF),
+     ConfigField('cache', True, bool, ConfigType.ON_OFF),
+     ConfigField('stopOnError', True, bool, ConfigType.ON_OFF),
+     ConfigField('executionLog', True, bool, ConfigType.ON_OFF),
+     ConfigField('errorLog', True, bool, ConfigType.ON_OFF),
+     ConfigField('defaultFileType', system.vistrails_default_file_type(), str,
+                 widget_type="combo",
+                 widget_options={"allowed_values": [".vt", ".xml"],
+                                 "label": "Default File Type/Extension"}),
+     ConfigField('debugLevel', 0, int,
+                 flag='-v',
+                 widget_type="combo",
+                 widget_options={"allowed_values": [0,1,2],
+                                 "label": "Show alerts for",
+                                 "remap": {0: "Critical Errors Only",
+                                           1: "Critical Errors and Warnings",
+                                           2: "Errors, Warnings, and " \
+                                           "Debug Messages"}})],
+    "Startup":
+    [ConfigField('maximizeWindows', False, bool, ConfigType.ON_OFF),
+     ConfigField('multiHeads', False, bool, ConfigType.ON_OFF),
+     ConfigField('showSplash', True, bool, ConfigType.SHOW_HIDE)],
+    "Upgrades":
+    [ConfigField('upgrades', True, bool, ConfigType.ON_OFF),
+     ConfigField('migrateTags', False, bool, ConfigType.ON_OFF,
+                 depends_on="upgrades"),
+     ConfigField('hideUpgrades', True, bool, ConfigType.ON_OFF,
+                 depends_on='upgrades'),
+     ConfigField('upgradeDelay', True, bool, ConfigType.ON_OFF,
+                 depends_on="upgrades"),
+     ConfigField('upgradeModuleFailPrompt', True, bool, ConfigType.ON_OFF,
+                 depends_on="upgrades")],
+    "Interface":
+    [ConfigField('autoConnect', True, bool, ConfigType.ON_OFF),
+     ConfigField('detachHistoryView', False, bool, ConfigType.ON_OFF),
+     ConfigField('showConnectionErrors', False, bool, ConfigType.SHOW_HIDE),
+     ConfigField('showVariantErrors', True, bool, ConfigType.SHOW_HIDE),
+     ConfigField('showDebugPopups', False, bool, ConfigType.SHOW_HIDE),
+     ConfigField('showScrollbars', True, bool, ConfigType.SHOW_HIDE),
+     ConfigField('showInlineParameterWidgets', False, bool, ConfigType.SHOW_HIDE),
+     ConfigFieldParent('shell',
+        [ConfigField('fontFace', system.shell_font_face(), str),
+         ConfigField('fontSize', system.shell_font_size(), int)]),
+     ConfigField('maxRecentVistrails', 5, int),
+     ConfigField('viewOnLoad', "appropriate", str, widget_type='combo',
+                 widget_options={"allowed_values": ["appropriate",
+                                                    "history",
+                                                    "pipeline"],
+                                 "label": "Default view after loading vistrail:",
+                                 "remap": {"appropriate": "Most Appropriate",
+                                           "history": "Always History",
+                                           "pipeline": "Always Pipeline"}}),
+     ConfigField('enableCustomVersionColors', False, bool, ConfigType.ON_OFF),
+     ConfigField('fixedCustomVersionColorSaturation', False,
+                 bool, ConfigType.ON_OFF)],
+    "Thumbnails":
+    [ConfigFieldParent('thumbs',
+        [ConfigField('autoSave', True, bool, ConfigType.ON_OFF),
+         ConfigField('mouseHover', False, bool, ConfigType.ON_OFF),
+         ConfigField('tagsOnly', False, bool, ConfigType.ON_OFF),
+         ConfigField('cacheDir', "thumbs", ConfigPath,
+                     ConfigType.NORMAL),
+         ConfigField('cacheSize', 20, int, widget_type='thumbnailcache')])],
+    "Packages":
+    [ConfigField('enablePackagesSilently', False, bool, ConfigType.ON_OFF),
+     ConfigField('loadPackages', True, bool, ConfigType.ON_OFF),
+     ConfigField('installBundles', True, bool, ConfigType.ON_OFF),
+     ConfigField('installBundlesWithPip', False, bool, ConfigType.ON_OFF,
+                 depends_on="installBundles"),
+     ConfigField('repositoryLocalPath', None, ConfigPath),
+     ConfigField('repositoryHTTPURL', "http://www.vistrails.org/packages",
+                 ConfigURL)],
+    "Paths":
+    [ConfigField('dotVistrails', system.default_dot_vistrails(),
+                 ConfigPath, flag="-S"),
+     ConfigField('subworkflowsDir', "subworkflows", ConfigPath),
+     ConfigField('dataDir', None, ConfigPath),
+     ConfigField('packageDir', None, ConfigPath),
+     ConfigField('userPackageDir', "userpackages", ConfigPath),
+     ConfigField('fileDir', None, ConfigPath),
+     ConfigField('logDir', "logs", ConfigPath),
+     ConfigField('temporaryDir', None,  ConfigPath)],
+    "Advanced":
+    [ConfigField('singleInstance', True, bool, ConfigType.ON_OFF),
+     ConfigField('staticRegistry', None, ConfigPath)],
+    "Web Sharing":
+    [ConfigField('webRepositoryURL', "http://www.crowdlabs.org", ConfigURL),
+     ConfigField('webRepositoryUser', None, str)],
+    "Internal":
+    [ConfigField('recentVistrailList', None, str, ConfigType.STORAGE),
+     ConfigField('isInServerMode', False, bool, ConfigType.INTERNAL),
+     ConfigField('isRunningGUI', True, bool, ConfigType.INTERNAL),
+     ConfigField('spawned', False, bool, ConfigType.INTERNAL),
+     ConfigField('rootDirectory', None, ConfigPath, ConfigType.INTERNAL),
+     ConfigField('developerDebugger', False, bool, ConfigType.INTERNAL),
+     ConfigField('dontUnloadModules', False, bool, ConfigType.INTERNAL),
+     ConfigField('bundleDeclinedList', '', str, ConfigType.INTERNAL)],
+    "Jobs":
+    [ConfigField('jobCheckInterval', 600, int),
+     ConfigField('jobAutorun', False, bool),
+     ConfigField('jobList', False, bool, ConfigType.COMMAND_LINE_FLAG),
+     ConfigField('jobInfo', False, bool, ConfigType.COMMAND_LINE_FLAG)],
+}
+
+# FIXME make sure that the platform-specific configs are added!
+mac_config = {
+    "Interface":
+    [ConfigField('useMacBrushedMetalStyle', True, bool, ConfigType.ON_OFF)]
+}
+
+win_config = { }
+
+linux_config = {
+    "General":
+    [ConfigField('handlerCheck', None, str, ConfigType.INTERNAL,
+                 widget_type="linuxext",
+                 widget_options={'label': 'Extension Handler'}),
+     ConfigField('handlerDontAsk', None, bool)]
+}
+
+all_configs = [base_config, mac_config, win_config, linux_config]
+
+def build_config_obj(d):
+    new_d = {}
+    for category, fields in d.iteritems():
+        for field in fields:
+            if isinstance(field, ConfigFieldParent):
+                new_d[field.name] = build_config_obj({category:
+                                                      field.sub_fields})
+            elif (field.field_type == ConfigType.SUBOBJECT or
+                  field.field_type == ConfigType.INTERNAL_SUBOBJECT):
+                new_d[field.name] = ConfigurationObject()
+            else:
+                v = field.default_val
+                if v is None:
+                    val_type = field.val_type
+                    if (field.val_type == ConfigPath or
+                        field.val_type == ConfigURL):
+                        val_type = basestring
+                    new_d[field.name] = (v, val_type)
+                else:
+                    new_d[field.name] = v
+    return ConfigurationObject(**new_d)
+
+def get_system_config():
+    config = {}
+    config.update((k, copy.copy(v)) for k, v in base_config.iteritems())
+    if system.systemType in ['Windows', 'Microsoft']:
+        sys_config = win_config
+    elif system.systemType in ['Linux']:
+        sys_config = linux_config
+    elif system.systemType in ['Darwin']:
+        sys_config = mac_config
+    else:
+        return config
+    for category, fields in sys_config.iteritems():
+        if category not in base_config:
+            config[category] = fields
+        else:
+            config[category].extend(fields)
+    return config
+
+def default():
+    config = get_system_config()
+    retval = build_config_obj(config)
+    return retval
+
+def parse_documentation():
+    line_iter = iter(_documentation.splitlines())
+    line_iter.next()
+    for line in line_iter:
+        arg_path, arg_type = line.strip().split(':', 1)
+        doc_lines = []
+        line = line_iter.next()
+        while True:
+            line = line_iter.next()
+            if not line.strip():
+                break
+            doc_lines.append(line.strip())
+        _docs[arg_path] = (arg_type, ' '.join(doc_lines))
+
+def parse_simple_docs():
+    line_iter = iter(_simple_documentation.splitlines())
+    line = line_iter.next()
+    for line in line_iter:
+        (arg, doc) = line.strip().split(':', 1)
+        _simple_docs[arg] = doc.strip()
+
+def find_help(arg_path):
+    if len(_docs) == 0:
+        parse_documentation()
+
+    if arg_path in _docs:
+        return _docs[arg_path][1]
+    return None
+
+def find_simpledoc(arg_path):
+    if len(_simple_docs) == 0:
+        parse_simple_docs()
+
+    if arg_path in _simple_docs:
+        return _simple_docs[arg_path]
+    return find_help(arg_path)
+
+def set_field_labels(fields, prefix=""):
+    for field in fields:
+        if isinstance(field, ConfigFieldParent):
+            prefix = "%s%s." % (prefix, field.name)
+            set_field_labels(field.sub_fields, prefix=prefix)
+        else:
+            full_field_name = "%s%s" % (prefix, field.name)
+            label = find_simpledoc(full_field_name)
+            if label is not None and 'label' not in field.widget_options:
+                field.widget_options['label'] = label
+
+for config in all_configs:
+    for field_list in config.itervalues():
+        set_field_labels(field_list)
+
+class VisTrailsHelpFormatter(argparse.HelpFormatter):
+    def add_usage(self, usage, actions, groups, prefix=None):
+        new_actions = []
+        new_actions.append(argparse.Action([], dest="__nowhere__",
+                                           metavar="[CONFIGURATION OPTIONS]"))
+        for action in actions:
+            if action.dest in _usage_args:
+                new_actions.append(action)
+        argparse.HelpFormatter.add_usage(self, usage, new_actions, groups,
+                                         prefix)
+
+class NestedSetKwargs(argparse.Action):
+    def __call__(self, parser, namespace, values, option_string=None):
+        orig_dest = self.dest
+        nesting = self.dest.split('.')
+        while len(nesting) > 1:
+            namespace = getattr(namespace, nesting.pop(0))
+        self.dest = nesting[0]
+
+        param_splitter = shlex.shlex(values, posix=True)
+        param_splitter.whitespace = ','
+        param_splitter.whitespace_split = True
+        for param in param_splitter:
+            key_val_split = param.split('=',1)
+            if len(key_val_split) < 2:
+                raise ValueError("Expected key=value comma-separated list")
+            key, val = key_val_split
+
+            dest = "%s.%s" % (self.dest, key)
+            namespace.set_deep_value(dest, val, True)
+        self.dest = orig_dest
+
+def nested_action(parser, action_type):
+    cls = parser._registry_get('action', action_type)
+    if cls is None:
+        raise ValueError('Action type "%s" is not defined' % action_type)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        orig_dest = self.dest
+        nesting = self.dest.split('.')
+        while len(nesting) > 1:
+            namespace = getattr(namespace, nesting.pop(0))
+        self.dest = nesting[0]
+        cls.__call__(self, parser, namespace, values, option_string=None)
+        self.dest = orig_dest
+
+    nested_name = "_Nested%s" % cls.__name__[1:]
+    nested_cls = type(nested_name, (cls,), {"__call__": __call__})
+    return nested_cls
+
+class RawVersionAction(argparse.Action):
+    """Variant of the default _VersionAction that doesn't reflow.
+    """
+    def __init__(self, option_strings, version,
+                 dest=argparse.SUPPRESS, default=argparse.SUPPRESS,
+                 help="show program's version and exit"):
+        argparse.Action.__init__(self, option_strings=option_strings,
+                                 dest=dest, default=default, nargs=0,
+                                 help=help)
+        self.version = version
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser.exit(message=self.version)
+
+def build_command_line_parser(d, parser=None, prefix="", **parser_args):
+    # if k is not a command-line-option, skip
+    # if k is show/hide, add --show-, --hide- options
+    # if k is an on/off, add --option, --no-option flags
+    # otherwise, run with k converted to dashed form and store res
+
+
+    def camel_to_dashes(s):
+        # from http://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-camel-case/1176023#1176023
+        s1 = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', s)
+        return re.sub('([a-z0-9])([A-Z])', r'\1-\2', s1).lower()
+
+
+    if parser is None:
+        parser = argparse.ArgumentParser(prog='vistrails',
+                                         **parser_args)
+        parser._my_arg_groups = {}
+        parser.add_argument('vistrails', metavar='vistrail', type=str,
+                            nargs='*', help="Vistrail to open")
+        _usage_args.add('vistrails')
+        parser.add_argument('--version', action=RawVersionAction,
+                            version=system.about_string())
+
+
+    prefix_dashes = ''
+    if prefix:
+        prefix_dashes = camel_to_dashes(prefix.replace('.', '-'))
+
+    for category, fields in d.iteritems():
+        if category == "Internal":
+            # don't deal with these
+            continue
+        if category == "Command-Line":
+            cat_group = parser
+        else:
+            if category not in parser._my_arg_groups:
+                parser._my_arg_groups[category] = \
+                                        parser.add_argument_group(category)
+            cat_group = parser._my_arg_groups[category]
+
+        for field in fields:
+            if isinstance(field, ConfigFieldParent):
+                build_command_line_parser({category: field.sub_fields},
+                                          parser,
+                                          '%s%s.' % (prefix, field.name),
+                                          **parser_args)
+                continue
+            k_dashes = camel_to_dashes(field.name)
+            help_str = find_help('%s%s' % (prefix, field.name))
+            dest_name = prefix + field.name
+
+            config_type = field.field_type
+            if config_type is None:
+                config_type = ConfigType.NORMAL
+            if (config_type == ConfigType.INTERNAL or \
+                config_type == ConfigType.STORAGE or
+                config_type == ConfigType.INTERNAL_SUBOBJECT):
+                # these are not in the command line
+                continue
+            elif config_type == ConfigType.ON_OFF:
+                k_dashes = camel_to_dashes(field.name)
+                group = cat_group.add_mutually_exclusive_group()
+                group.add_argument('--%s%s' % (prefix_dashes, k_dashes),
+                                   # action="store_true",
+                                   action=nested_action(group, "store_true"),
+                                   dest=dest_name, help=help_str,
+                                   default=argparse.SUPPRESS)
+                group.add_argument('--no-%s%s' % (prefix_dashes, k_dashes),
+                                   # action="store_false",
+                                   action=nested_action(group, "store_false"),
+                                   dest=dest_name,
+                                   help=("Inverse of --%s%s" %
+                                         (prefix_dashes, k_dashes)),
+                                   default=argparse.SUPPRESS)
+            elif config_type == ConfigType.SHOW_HIDE:
+                k_dashes = camel_to_dashes(field.name[4:])
+                group = cat_group.add_mutually_exclusive_group()
+                group.add_argument('--show-%s%s' % (prefix_dashes, k_dashes),
+                                   # action="store_true",
+                                   action = nested_action(group, "store_true"),
+                                   dest=dest_name, help=help_str,
+                                   default=argparse.SUPPRESS)
+                group.add_argument('--hide-%s%s' % (prefix_dashes, k_dashes),
+                                   # action="store_false",
+                                   action=nested_action(group, "store_false"),
+                                   dest=dest_name,
+                                   help=("Inverse of --show-%s%s" %
+                                         (prefix_dashes, k_dashes)),
+                                   default=argparse.SUPPRESS)
+            else:
+                k_dashes = camel_to_dashes(field.name)
+                long_arg = '--%s%s' % (prefix_dashes, k_dashes)
+                if field.flag is not None:
+                    args = (field.flag, long_arg)
+                else:
+                    args = (long_arg,)
+                kwargs = {'dest': dest_name,
+                          'help': help_str,
+                          'default': argparse.SUPPRESS}
+                if (field.val_type != ConfigPath and
+                    field.val_type != ConfigURL and
+                    field.val_type != str and
+                    field.val_type != bool):
+                    kwargs["type"] = field.val_type
+                if config_type == ConfigType.SUBOBJECT:
+                    kwargs["action"] = NestedSetKwargs
+                elif config_type == ConfigType.COMMAND_LINE_FLAG:
+                    kwargs["action"] = nested_action(cat_group, "store_true")
+                else:
+                    kwargs["action"] = nested_action(cat_group, "store")
+                if field.val_type == ConfigPath:
+                    kwargs["metavar"] = "DIR"
+                elif field.val_type == ConfigURL:
+                    kwargs["metavar"] = "URL"
+                if field.nargs is not None:
+                    kwargs["nargs"] = field.nargs
+
+                cat_group.add_argument(*args, **kwargs)
+                if category == "Command-Line":
+                    _usage_args.add(field.name)
+    return parser
+
+def build_default_parser():
+    parser_args = {"formatter_class": VisTrailsHelpFormatter,
+                   "argument_default": argparse.SUPPRESS}
+    return build_command_line_parser(get_system_config(), **parser_args)
+
+def build_sphinx_parser():
+    # FIXME add system-specific config options somehow
+    return build_command_line_parser(base_config)
+
+class ConfigValue(object):
+    @staticmethod
+    def create(value):
+        if isinstance(value, bool):
+            obj = ConfigBool()
+        elif isinstance(value, basestring):
+            obj = ConfigStr()
+        elif isinstance(value, int):
+            obj = ConfigInt()
+        elif isinstance(value, float):
+            obj = ConfigFloat()
+        elif isinstance(value, list):
+            obj = ConfigList()
+        elif isinstance(value, ConfigurationObject):
+            obj = value
+        elif value is None:
+            obj = None
+        else:
+            raise Exception('Cannot create ConfigValue from value "%s"' % value)
+        if obj is not None:
+            obj.set_value(value)
+        return obj
+
+    def get_value(self):
+        return self.db_value
+
+    def set_value(self, val):
+        self.db_value = val
+
+class ConfigBool(DBConfigBool, ConfigValue):
+    def __copy__(self):
+        """ __copy__() -> ConfigBool - Returns a clone of itself """
+        return ConfigBool.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigBool.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ConfigBool
+        return cp
+
+    @staticmethod
+    def convert(_val):
+        _val.__class__ = ConfigBool
+
+    def get_value(self):
+        return self.db_value.lower() == "true"
+
+    def set_value(self, val):
+        self.db_value = unicode(val)
+
+class ConfigInt(DBConfigInt, ConfigValue):
+    def __copy__(self):
+        """ __copy__() -> ConfigInt - Returns a clone of itself """
+        return ConfigInt.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigInt.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ConfigInt
+        return cp
+
+    @staticmethod
+    def convert(_val):
+        _val.__class__ = ConfigInt
+
+class ConfigStr(DBConfigStr, ConfigValue):
+    def __copy__(self):
+        """ __copy__() -> ConfigStr - Returns a clone of itself """
+        return ConfigStr.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigStr.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ConfigStr
+        return cp
+
+    @staticmethod
+    def convert(_val):
+        _val.__class__ = ConfigStr
+
+class ConfigFloat(DBConfigFloat, ConfigValue):
+    def __copy__(self):
+        """ __copy__() -> ConfigFloat - Returns a clone of itself """
+        return ConfigFloat.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigFloat.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ConfigFloat
+        return cp
+
+    @staticmethod
+    def convert(_val):
+        _val.__class__ = ConfigFloat
+
+class ConfigList(DBConfigStr, ConfigValue):
+    def __copy__(self):
+        """ __copy__() -> ConfigList - Returns a clone of itself """
+        return ConfigList.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigStr.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ConfigList
+        return cp
+
+    @staticmethod
+    def convert(_val):
+        _val.__class__ = ConfigList
+
+    def get_value(self):
+        return ast.literal_eval(self.db_value)
+
+    def set_value(self, val):
+        self.db_value = unicode(val)
+
+class ConfigKey(DBConfigKey):
+    def __init__(self, name, value):
+        if isinstance(value, tuple):
+            DBConfigKey.__init__(self, name=name)
+            self.set_type(value[1])
+        else:
+            DBConfigKey.__init__(self, name=name,
+                                 value=ConfigValue.create(value))
+            self.set_type(type(value))
+
+    def __copy__(self):
+        """ __copy__() -> ConfigKey - Returns a clone of itself """
+        return ConfigKey.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigKey.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ConfigKey
+        cp._type = self._type
+        return cp
+
+    @staticmethod
+    def convert(_key):
+        _key.__class__ = ConfigKey
+        if isinstance(_key.db_value, DBConfiguration):
+            ConfigurationObject.convert(_key.db_value)
+        elif isinstance(_key.db_value, DBConfigBool):
+            ConfigBool.convert(_key.db_value)
+        elif isinstance(_key.db_value, DBConfigStr):
+            ConfigStr.convert(_key.db_value)
+        elif isinstance(_key.db_value, DBConfigInt):
+            ConfigInt.convert(_key.db_value)
+        elif isinstance(_key.db_value, DBConfigFloat):
+            ConfigFloat.convert(_key.db_value)
+        #FIXME add ConfigList to db and here
+        _key.set_type(type(_key.value))
+
+    def _get_value(self):
+        if self.db_value is not None:
+            return self.db_value.get_value()
+        return None
+    def _set_value(self, val):
+        if not self.check_type(val):
+            raise TypeError('Value "%s" does not match type %s' %
+                            (val, self._type))
+        self.db_value = ConfigValue.create(val)
+    value = property(_get_value, _set_value)
+
+    def set_type(self, t):
+        if issubclass(t, basestring):
+            t = basestring
+        self._type = t
+
+    def check_type(self, val):
+        return val is None or isinstance(val, self._type)
+
+class ConfigurationObject(DBConfiguration):
     """A ConfigurationObject is an InstanceObject that respects the
     following convention: values that are not 'present' in the object
     should have value (None, type), where type is the type of the
@@ -62,57 +1240,219 @@ class ConfigurationObject(InstanceObject):
 
     """
 
-    def __init__(self, *args, **kwargs):
-        InstanceObject.__init__(self, *args, **kwargs)
-        self.__subscribers__ = {}
-   
+
+    def __init__(self, **kwargs):
+        self._in_init = True
+        self._unset_keys = {}
+        DBConfiguration.__init__(self)
+        self._in_init = False
+        for k, v in kwargs.iteritems():
+            if type(v) == tuple:
+                self._unset_keys[k] = v
+            else:
+                key = ConfigKey(name=k, value=v)
+                self.db_add_config_key(key)
+
+        # InstanceObject.__init__(self, *args, **kwargs)
+        self._subscribers = {}
+        self.vistrails = []
+
+    def __copy__(self):
+        """ __copy__() -> ConfigurationObject - Returns a clone of itself """
+        return ConfigurationObject.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfiguration.do_copy(self, new_ids, id_scope, id_remap)
+        cp._in_init = False
+        cp.__class__ = ConfigurationObject
+        cp._unset_keys = copy.copy(self._unset_keys)
+        cp._subscribers = copy.copy(self._subscribers)
+        cp.vistrails = copy.copy(self.vistrails)
+        return cp
+
+    @staticmethod
+    def convert(_config_obj):
+        _config_obj._in_init = False
+        _config_obj.__class__ = ConfigurationObject
+        for _key in _config_obj.db_config_keys:
+            ConfigKey.convert(_key)
+        _config_obj._subscribers = {}
+        _config_obj._unset_keys = {}
+        _config_obj.vistrails = []
+
+    def get_value(self):
+        return self
+
+    def set_value(self, val):
+        # it itself is the value already
+        pass
+
+    def matches_type(self, value, t):
+        if t == str:
+            t = basestring
+        return isinstance(value, t)
+
+    def __getattr__(self, name):
+        try:
+            return object.__getattribute__(self, name)
+        except AttributeError:
+            try:
+                return self.get(name)
+            except:
+                raise AttributeError(name)
+
     def __setattr__(self, name, value):
-        object.__setattr__(self, name, value)
-        if name == '__subscribers__':
-            return
-        if name in self.__subscribers__:
-            to_remove = []
-            for subscriber in self.__subscribers__[name]:
-                obj = subscriber()
-                if obj:
-                    obj(name, value)
+        if name == '_subscribers' or name == '_unset_keys' or name == '_in_init' or name == 'is_dirty' or name == 'vistrails' or self._in_init:
+            object.__setattr__(self, name, value)
+        else:
+            if name in self.db_config_keys_name_index:
+                config_key = self.db_config_keys_name_index[name]
+                if value is None:
+                    self.db_delete_config_key(config_key)
+                    self._unset_keys[name] = (None, type(config_key.value))
                 else:
-                    to_remove.append(obj)
-            for ref in to_remove:
-                self.__subscribers__[name].remove(ref)
+                    config_key.value = value
+            else:
+                if name not in self._unset_keys:
+                    self._unset_keys[name] = (None, type(value))
+                    # raise AttributeError('Key "%s" was not defined when '
+                    #                      'ConfigurationObject was created' %
+                    #                      name)
+                if (value is not None and
+                      not self.matches_type(value, self._unset_keys[name][1])):
+                    raise TypeError('Value "%s" does match type "%s" for "%s"' %
+                                    (value, self._unset_keys[name][1], name))
+                if value is not None:
+                    del self._unset_keys[name]
+                    config_key = ConfigKey(name=name, value=value)
+                    self.db_add_config_key(config_key)
+            if name in self._subscribers:
+                to_remove = []
+                for subscriber in self._subscribers[name]:
+                    obj = subscriber()
+                    if obj:
+                        obj(name, value)
+                    else:
+                        to_remove.append(obj)
+                for ref in to_remove:
+                    self._subscribers[name].remove(ref)
+
+    def __eq__(self, other):
+        if type(self) != type(other):
+            return False
+        seen_keys = set()
+        for name in self.keys():
+            if self.is_unset(name):
+                continue
+            seen_keys.add(name)
+            if name not in other.keys():
+                return False
+            val1 = getattr(self, name)
+            val2 = getattr(other, name)
+            if type(val1) != type(val2):
+                return False
+            if val1 != val2:
+                return False
+        for name in other.keys():
+            if other.is_unset(name):
+                continue
+            if name not in seen_keys:
+                return False
+        return True
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __contains__(self, k):
+        return self.has(k)
+
+    def __getitem__(self, k):
+        return self.get(k)
+
+    def __setitem__(self, k, v):
+        return self.__setattr__(k, v)
+
+    def update(self, other):
+        for name, other_key in other.db_config_keys_name_index.iteritems():
+            if (isinstance(other_key.value, ConfigurationObject) and
+                    self.has(name)):
+                self.get(name).update(other_key.value)
+            else:
+                self.__setattr__(name, other_key.value)
 
     def unsubscribe(self, field, callable_):
         """unsubscribe(field, callable_): remove observer from subject
         """
-        self.__subscribers__[field].remove(weakref.ref(callable_))
-        
+        self._subscribers[field].remove(weakref.ref(callable_))
+
     def subscribe(self, field, callable_):
         """subscribe(field, callable_): call observer callable_ when
         self.field is set.
         """
-        append_to_dict_of_lists(self.__subscribers__, field,
+        append_to_dict_of_lists(self._subscribers, field,
                                 Ref(callable_))
-                  
+
     def has(self, key):
         """has(key) -> bool.
 
         Returns true if key has valid value in the object.
         """
-        
-        if not hasattr(self, key):
-            return False
-        v = getattr(self, key)
-        if isinstance(v, tuple) and v[0] is None and isinstance(v[1], type):
-            return False
+
+        return key in self.db_config_keys_name_index
+
+    def get(self, key):
+        if key in self._unset_keys:
+            return self._unset_keys[key]
+        config_key = self.db_config_keys_name_index[key]
+        return config_key.value
+
+    def is_unset(self, keys_str):
+        keys = keys_str.split('.')
+        config = self
+        for key in keys[:-1]:
+            config = config.get(key)
+        return keys[-1] in config._unset_keys
+
+    def get_deep_value(self, keys_str):
+        # keys_str is something like "thmbs.cacheDir"
+        keys = keys_str.split('.')
+        config = self
+        for key in keys:
+            config = config.get(key)
+        return config
+
+    def has_deep_value(self, keys_str):
+        # keys_str is something like "thmbs.cacheDir"
+        keys = keys_str.split('.')
+        config = self
+        for key in keys:
+            if config.has(key):
+                config = config.get(key)
+            else:
+                return False
         return True
 
+    def set_deep_value(self, keys_str, value, create_if_missing=False):
+        keys = keys_str.split('.')
+        config = self
+        for key in keys[:-1]:
+            if config.has(key):
+                config = config.get(key)
+            elif create_if_missing:
+                new_config = ConfigurationObject()
+                config.__setattr__(key, new_config)
+                config = new_config
+            else:
+                raise ValueError('No path for key "%s"' % keys_str)
+        config.__setattr__(keys[-1], value)
+
     def check(self, key):
         """check(key) -> obj
 
         Returns False if key is absent in object, and returns object
         otherwise.
         """
-        
+
         return self.has(key) and getattr(self, key)
 
     def allkeys(self):
@@ -120,193 +1460,153 @@ class ConfigurationObject(InstanceObject):
 
         Returns all options stored in this object.
         """
-        
-        return self.__dict__.keys()
+
+        return self.db_config_keys_name_index.keys() + self._unset_keys.keys()
 
     def keys(self):
         """keys(self) -> list of strings
         Returns all public options stored in this object.
         Public options are keys that do not start with a _
         """
-        return [k for k in self.__dict__.keys() if not k.startswith('_')]
-    
-    def write_to_dom(self, dom, element):
-        conf_element = dom.createElement('configuration')
-        element.appendChild(conf_element)
-        for (key, value) in self.__dict__.iteritems():
-            if key == '__subscribers__':
-                continue
-            key_element = dom.createElement('key')
-            key_element.setAttribute('name', key)
-            if isinstance(value, (int, long, basestring, bool, float)):
-                conf_element.appendChild(key_element)
-                value_element = quote_xml_value(dom, value)
-                key_element.appendChild(value_element)
-            elif isinstance(value, tuple):
-                pass
-            else:
-                assert isinstance(value, ConfigurationObject)
-                conf_element.appendChild(key_element)
-                value.write_to_dom(dom, key_element)
-
-    def set_from_dom_node(self, node):
-        assert str(node.nodeName) == 'configuration'
-        for key in elements_filter(node, lambda node: node.nodeName == 'key'):
-            key_name = str(key.attributes['name'].value)
-            value = [x for x in
-                     elements_filter(key, lambda node: node.nodeName in
-                                    ['unicode', 'bool', 'str', 'int', 'float', 'configuration'])][0]
-            value_type = value.nodeName
-            if value_type == 'configuration':
-                if hasattr(self,key_name):
-                    getattr(self, key_name).set_from_dom_node(value)
-            elif value_type in ['bool', 'str', 'int', 'float']:
-                setattr(self, key_name, eval_xml_value(value))
-        
+        return [k for k in itertools.chain(self.db_config_keys_name_index,
+                                           self._unset_keys)
+                if not k.startswith('_')]
 
-    def __copy__(self):
-        result = ConfigurationObject()
-        for (key, value) in self.__dict__.iteritems():
-            setattr(result, key, copy.copy(value))
-        return result
+# def default():
+#     """ default() -> ConfigurationObject
+#     Returns the default configuration of VisTrails
 
-def default():
-    """ default() -> ConfigurationObject
-    Returns the default configuration of VisTrails
-    
-    """
+#     """
 
-    base_dir = {
-        'abstractionsDirectory': (None, str),
-        'alwaysShowDebugPopup': False,
-        'autoConnect': True,
-        'autosave': True,
-        'dataDirectory': (None, str),
-        'dbDefault': False,
-#        'debugSignals': False,
-        'defaultFileType':system.vistrails_default_file_type(),
-        'detachHistoryView': False,
-        'dotVistrails': system.default_dot_vistrails(),
-        'enablePackagesSilently': False,
-        'errorOnConnectionTypeerror': False,
-        'errorOnVariantTypeerror': True,
-        'executeWorkflows': False,
-        'fileDirectory': (None, str),
-#        'evolutionGraph': (None, str),
-        'handlerDontAsk': False,
-        'installBundles': True,
-        'installBundlesWithPip': False,
-        'interactiveMode': True,
-        'logFile': (None, str),
-        'logger': default_logger(),
-        'maxMemory': (None, int),
-        'maximizeWindows': False,
-        'maxRecentVistrails': 5,
-        'migrateTags': False,
-        'minMemory': (None, int),
-        'multiHeads': False,
-        'nologger': True,
-        'nologfile': False,
-        'packageDirectory': (None, str),
-        'pythonPrompt': False,
-        'recentVistrailList': (None, str),
-        'repositoryLocalPath': (None, str),
-        'repositoryHTTPURL': "http://www.vistrails.org/packages",
-        'reviewMode': False,
-        'rootDirectory': (None, str),
-        'runningJobsList': (None, str),
-        'shell': default_shell(),
-        'showHistoryViewOnLoad': False,
-        'showPipelineViewOnLoad': False,
-        'showScrollbars': True,
-        'showMovies': True,
-        'showSplash': True,
-        'showSpreadsheetOnly': False,
-        'singleInstance': True,
-        'spawned': False,
-        'spreadsheetDumpCells': (None, str),
-        'spreadsheetDumpPDF': False,
-        'staticRegistry': (None, str),
-        'stopOnError': True,
-        'temporaryDirectory': (None, str),
-        'thumbs': default_thumbs(),
-        'upgradeOn': True,
-        'upgradeDelay': True,
-        'upgradeModuleFailPrompt': True,
-        'useCache': True,
-        'userPackageDirectory': (None, str),
-        'verbosenessLevel': (None, int),
-#        'workflowGraph': (None, str),
-#        'workflowInfo': (None, str),
-        'webRepositoryLogin': (None, str),
-        'webRepositoryURL': "http://www.crowdlabs.org",
-        'isInServerMode': False,
-        }
-    specific_dir = add_specific_config(base_dir)
-    return ConfigurationObject(**specific_dir)
-
-def default_logger():
-    """default_logger() -> ConfigurationObject
-    Returns the default configuration for the VisTrails logger
-    
-    """
-    logger_dir = {
-        'dbHost': '',
-        'dbName': '',
-        'dbPasswd': '',
-        'dbPort': 0,
-        'dbUser': '',
-        }
-    return ConfigurationObject(**logger_dir)
-
-def default_shell():
-    """default_shell() -> ConfigurationObject
-    Returns the default configuration for the VisTrails shell
-    
-    """
-    if system.systemType == 'Linux':
-        shell_dir = {
-            'font_face': 'Fixed',
-            'font_size': 12,
-            }
-    elif system.systemType in ['Windows', 'Microsoft']:
-        shell_dir = {
-            'font_face': 'Courier New',
-            'font_size': 8,
-            }
-    elif system.systemType == 'Darwin':
-        shell_dir = {
-            'font_face': 'Monaco',
-            'font_size': 12,
-            }
-    else:
-        raise VistrailsInternalError('system type not recognized')
-    return ConfigurationObject(**shell_dir)
+#     base_dir = {
+#         'abstractionsDirectory': os.path.join("$DOT_VISTRAILS",
+#                                               "subworkflows"),
+#         'alwaysShowDebugPopup': False,
+#         'autoConnect': True,
+#         'autosave': True,
+#         'dataDirectory': (None, str),
+#         'dbDefault': False,
+# #        'debugSignals': False,
+#         'defaultFileType':system.vistrails_default_file_type(),
+#         'detachHistoryView': False,
+#         'dotVistrails': system.default_dot_vistrails(),
+#         'enablePackagesSilently': False,
+#         'errorOnConnectionTypeerror': False,
+#         'errorOnVariantTypeerror': True,
+#         'executeWorkflows': False,
+#         'fileDirectory': (None, str),
+#         'fixedSpreadsheetCells': False,
+# #        'evolutionGraph': (None, str),
+#         'installBundles': True,
+#         'installBundlesWithPip': False,
+#         'interactiveMode': True,
+#         'logFile': os.path.join("$DOT_VISTRAILS", "vistrails.log"),
+#         'logger': default_logger(),
+#         'maxMemory': (None, int),
+#         'maximizeWindows': False,
+#         'maxRecentVistrails': 5,
+#         'migrateTags': False,
+#         'minMemory': (None, int),
+#         'multiHeads': False,
+#         'nologger': False,
+#         'packageDirectory': (None, str),
+#         'pythonPrompt': False,
+#         'recentVistrailList': (None, str),
+#         'repositoryLocalPath': (None, str),
+#         'repositoryHTTPURL': "http://www.vistrails.org/packages",
+#         'reviewMode': False,
+#         'rootDirectory': (None, str),
+#         'runningJobsList': (None, str),
+#         'shell': default_shell(),
+#         'showScrollbars': True,
+#         'showMovies': True,
+#         'showSplash': True,
+#         'showSpreadsheetOnly': False,
+#         'singleInstance': True,
+#         'spreadsheetDumpCells': (None, str),
+#         'spreadsheetDumpPDF': False,
+#         'staticRegistry': (None, str),
+#         'stopOnError': True,
+#         'temporaryDirectory': (None, str),
+#         'thumbs': default_thumbs(),
+#         'upgradeOn': True,
+#         'upgradeDelay': True,
+#         'upgradeModuleFailPrompt': True,
+#         'useCache': True,
+#         'userPackageDirectory': os.path.join("$DOT_VISTRAILS", "userpackages"),
+#         'verbosenessLevel': (None, int),
+# #        'workflowGraph': (None, str),
+# #        'workflowInfo': (None, str),
+#         'webRepositoryLogin': (None, str),
+#         'webRepositoryURL': "http://www.crowdlabs.org",
+#         'isInServerMode': False,
+#         }
+#     specific_dir = add_specific_config(base_dir)
+#     return ConfigurationObject(**specific_dir)
 
-def default_thumbs():
-    """default_thumbs() -> ConfigurationObject
-    Returns the default configuration for VisTrails Pipelines Thumbnails    
-    """
-    thumbs_dir = {
-                  'autoSave': True,
-                  'cacheDirectory': (None, str),
-                  'cacheSize': 20,
-                  'mouseHover': False,
-                  'tagsOnly': False,
-                }
-    return ConfigurationObject(**thumbs_dir)
+# def default_logger():
+#     """default_logger() -> ConfigurationObject
+#     Returns the default configuration for the VisTrails logger
+
+#     """
+#     logger_dir = {
+#         'dbHost': '',
+#         'dbName': '',
+#         'dbPasswd': '',
+#         'dbPort': 0,
+#         'dbUser': '',
+#         }
+#     return ConfigurationObject(**logger_dir)
+
+# def default_shell():
+#     """default_shell() -> ConfigurationObject
+#     Returns the default configuration for the VisTrails shell
+#
+#     """
+#     if system.systemType == 'Linux':
+#         shell_dir = {
+#             'font_face': 'Fixed',
+#             'font_size': 12,
+#             }
+#     elif system.systemType in ['Windows', 'Microsoft']:
+#         shell_dir = {
+#             'font_face': 'Courier New',
+#             'font_size': 8,
+#             }
+#     elif system.systemType == 'Darwin':
+#         shell_dir = {
+#             'font_face': 'Monaco',
+#             'font_size': 12,
+#             }
+#     else:
+#         raise VistrailsInternalError('system type not recognized')
+#     return ConfigurationObject(**shell_dir)
+
+# def default_thumbs():
+#     """default_thumbs() -> ConfigurationObject
+#     Returns the default configuration for VisTrails Pipelines Thumbnails
+#     """
+#     thumbs_dir = {
+#                   'autoSave': True,
+#                   'cacheDirectory': os.path.join("$DOT_VISTRAILS", "thumbs"),
+#                   'cacheSize': 20,
+#                   'mouseHover': False,
+#                   'tagsOnly': False,
+#                 }
+#     return ConfigurationObject(**thumbs_dir)
 
 def add_specific_config(base_dir):
-     """add_specific_config() -> dict
-    Returns a dict with other specific configuration
-    to the current platform added to base_dir
-    
+    """add_specific_config() -> dict
+
+    Returns a dict with other specific configuration to the current
+    platform added to base_dir
+
     """
-     newdir = dict(base_dir)
-     if system.systemType == 'Darwin':
-         newdir['useMacBrushedMetalStyle'] = True
-         
-     return newdir
+    newdir = dict(base_dir)
+    if system.systemType == 'Darwin':
+        newdir['useMacBrushedMetalStyle'] = True
+
+    return newdir
 
 def get_vistrails_persistent_configuration():
     """get_vistrails_persistent_configuration() -> ConfigurationObject or None
@@ -324,31 +1624,15 @@ def get_vistrails_persistent_configuration():
         return app.configuration
     else:
         return None
-    
-def get_vistrails_configuration():
-    """get_vistrails_configuration() -> ConfigurationObject or None
-    Returns the current configuration of the application. It returns None if
-    configuration was not found (when running as a bogus application
-    for example. This configuration is the one that is used just for the
-    current session and is not persistent. To make changes persistent, 
-    use get_vistrails_persistent_configuration() instead.
-    
-    """
-    from vistrails.core.application import get_vistrails_application
-    app = get_vistrails_application()
-    if hasattr(app, 'temp_configuration'):
-        return app.temp_configuration
-    else:
-        return None
 
 def get_vistrails_temp_configuration():
     """get_vistrails_temp_configuration() -> ConfigurationObject or None
     Returns the temp configuration of the application. It returns None if
     configuration was not found (when running as a bogus application
     for example. The temp configuration is the one that is used just for the
-    current session and is not persistent. To make changes persistent, 
+    current session and is not persistent. To make changes persistent,
     use get_vistrails_persistent_configuration() instead.
-    
+
     """
     from vistrails.core.application import get_vistrails_application
     app = get_vistrails_application()
@@ -356,3 +1640,158 @@ def get_vistrails_temp_configuration():
         return app.temp_configuration
     else:
         return None
+
+get_vistrails_configuration = get_vistrails_temp_configuration
+
+import tempfile
+import unittest
+
+class TestConfiguration(unittest.TestCase):
+    def test_config(self):
+        conf = ConfigurationObject(a="blah", b=3.45, c=1, d=True)
+        self.assertEqual(conf.a, "blah")
+        self.assertAlmostEqual(conf.b, 3.45)
+        self.assertEqual(conf.c, 1)
+        self.assertEqual(conf.d, True)
+
+    def test_default(self):
+        conf = default()
+        self.assertEqual(conf.showWindow, True)
+        self.assertEqual(conf.maxRecentVistrails, 5)
+
+    def test_has(self):
+        conf = default()
+        self.assertTrue(conf.has("showWindow"))
+        self.assertFalse(conf.has("reallyDoesNotExist"))
+
+    def test_check(self):
+        conf = default()
+        self.assertTrue(conf.check("showWindow"))
+        self.assertFalse(conf.check("showDebugPopups"))
+        self.assertFalse(conf.check("thumbs.mouseHover"))
+
+    def test_update(self):
+        conf1 = default()
+        conf2 = ConfigurationObject(showDebugPopups=True,
+                                    logDir="/tmp",
+                                    thumbs=ConfigurationObject(
+                                        autoSave=True,
+                                        cacheDir="/tmp",
+                                        cacheSize=10,
+                                        mouseHover=True,
+                                        tagsOnly=False))
+
+        conf1.update(conf2)
+        self.assertTrue(conf1.showDebugPopups)
+        self.assertEqual(conf1.logDir, "/tmp")
+        self.assertEqual(conf1.thumbs.mouseHover, True)
+
+        conf2.showWindow = False
+        self.assertTrue(conf1.showWindow)
+
+    def test_unset_params(self):
+        conf = ConfigurationObject(test_field=(None, str))
+        self.assertTrue(conf.is_unset("test_field"))
+        self.assertIn("test_field", conf.keys())
+
+    def test_type_mismatch(self):
+        conf = default()
+        with self.assertRaises(TypeError):
+            conf.showWindow = 1
+
+        # allowing this now
+        # with self.assertRaises(AttributeError):
+        #     conf.reallyDoesNotExist = True
+
+    def test_serialize(self):
+        from vistrails.db.persistence import DAOList
+        conf1 = default()
+        (fd, fname) = tempfile.mkstemp()
+        os.close(fd)
+        try:
+            dao = DAOList()
+            dao.save_to_xml(conf1, fname, {})
+            conf2 = dao.open_from_xml(fname, ConfigurationObject.vtType)
+            ConfigurationObject.convert(conf2)
+        finally:
+            os.unlink(fname)
+
+        self.assertEqual(conf1, conf2)
+
+    def test_copy(self):
+        conf1 = default()
+        conf2 = copy.copy(conf1)
+        self.assertEqual(conf1, conf2)
+        self.assertItemsEqual(conf1._unset_keys.keys(),
+                              conf2._unset_keys.keys())
+
+    def test_parser(self):
+        if sys.version_info < (2, 7):
+            self.skipTest("argparse on Python 2.6: bug 10680")
+        from vistrails.tests.utils import capture_stdout, capture_stderr
+        p = build_command_line_parser(base_config)
+        err = []
+        try:
+            with capture_stdout() as err:
+                with self.assertRaises(SystemExit) as e:
+                    p.parse_args(["-h"])
+            self.assertEqual(e.exception.code, 0)
+            self.assertGreater(len(err), 20)
+        except:
+            sys.stdout.write('\n'.join(err))
+            raise
+        try:
+            with capture_stderr() as err:
+                with self.assertRaises(SystemExit) as e:
+                    p.parse_args(["--db-default", "--no-db-default"])
+            self.assertEqual(e.exception.code, 2)
+        except:
+            sys.stderr.write('\n'.join(err))
+            raise
+
+    def test_parse_into_config(self):
+        p = build_command_line_parser(base_config)
+        config = default()
+        self.assertFalse(config.dbDefault)
+        p.parse_args(args=["--db-default", "--dot-vistrails", "/tmp"],
+                     namespace=config)
+        self.assertTrue(config.dbDefault)
+        self.assertEqual(config.dotVistrails, "/tmp")
+
+    def test_parse_output_settings(self):
+        p = build_command_line_parser(base_config)
+        config = default()
+        p.parse_args(args=["-p", "file.series=false"],
+                     namespace=config)
+        self.assertTrue(config.outputSettings.has("file"))
+        self.assertTrue(config.outputSettings.file.has("series"))
+        self.assertEqual(config.outputSettings.file.series, "false")
+
+    def test_multiple_params(self):
+        p = build_command_line_parser(base_config)
+        config = default()
+        p.parse_args(args=["-p", "file.series=false",
+                           "-p", "file.suffix=.png"],
+                     namespace=config)
+        self.assertTrue(config.outputSettings.has("file"))
+        self.assertTrue(config.outputSettings.file.has("series"))
+        self.assertTrue(config.outputSettings.file.has("suffix"))
+        self.assertEqual(config.outputSettings.file.series, "false")
+        self.assertEqual(config.outputSettings.file.suffix, ".png")
+
+    def test_comma_sep_params(self):
+        p = build_command_line_parser(base_config)
+        config = default()
+        p.parse_args(args=["-p", 'file.series=false,other.separator=","'],
+                     namespace=config)
+        self.assertTrue(config.outputSettings.has("file"))
+        self.assertTrue(config.outputSettings.file.has("series"))
+        self.assertEqual(config.outputSettings.file.series, "false")
+        self.assertTrue(config.outputSettings.has("other"))
+        self.assertTrue(config.outputSettings.other.has("separator"))
+        self.assertEqual(config.outputSettings.other.separator, ",")
+
+
+if __name__ == '__main__':
+    unittest.main()
+
diff --git a/vistrails/core/console_mode.py b/vistrails/core/console_mode.py
index bcc4314..79fe80a 100644
--- a/vistrails/core/console_mode.py
+++ b/vistrails/core/console_mode.py
@@ -1,41 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ Module used when running  vistrails uninteractively """
-from __future__ import absolute_import
+from __future__ import absolute_import, division
 import os.path
-import uuid
+import unittest
+
 from vistrails.core.application import is_running_gui
 from vistrails.core.configuration import get_vistrails_configuration
 import vistrails.core.interpreter.default
@@ -43,23 +45,24 @@ import vistrails.core.db.io
 from vistrails.core.db.io import load_vistrail
 from vistrails.core.db.locator import XMLFileLocator, ZIPFileLocator
 from vistrails.core import debug
-from vistrails.core.utils import VistrailsInternalError, expression
+import vistrails.core.interpreter.cached
+from vistrails.core.vistrail.job import Workflow as JobWorkflow
+import vistrails.core.vistrail.pipeline
+from vistrails.core.utils import VistrailsInternalError
 from vistrails.core.vistrail.controller import VistrailController
-from vistrails.core.vistrail.vistrail import Vistrail
-
 import vistrails.core.packagemanager
 import vistrails.core.system
-import unittest
 import vistrails.core.vistrail
 import vistrails.db
 
+
 ################################################################################
     
-def run_and_get_results(w_list, parameters='', workflow_info=None, 
+def run_and_get_results(w_list, parameters='', output_dir=None, 
                         update_vistrail=True, extra_info=None, 
                         reason='Console Mode Execution'):
     """run_and_get_results(w_list: list of (locator, version), parameters: str,
-                           workflow_info:str, update_vistrail: boolean,
+                           output_dir:str, update_vistrail: boolean,
                            extra_info:dict)
     Run all workflows in w_list, and returns an interpreter result object.
     version can be a tag name or a version id.
@@ -71,7 +74,7 @@ def run_and_get_results(w_list, parameters='', workflow_info=None,
     result = []
     for locator, workflow in w_list:
         (v, abstractions , thumbnails, mashups)  = load_vistrail(locator)
-        controller = VistrailController(v, locator, abstractions, thumbnails, 
+        controller = VistrailController(v, locator, abstractions, thumbnails,
                                         mashups, auto_save=update_vistrail)
         if isinstance(workflow, basestring):
             version = v.get_version_number(workflow)
@@ -100,34 +103,52 @@ def run_and_get_results(w_list, parameters='', workflow_info=None,
                             c = mashup.getAliasByName(key).component
                             params.append((c.vttype, c.vtid, value))
 
-        if workflow_info is not None and controller.current_pipeline is not None:
+        if output_dir is not None and controller.current_pipeline is not None:
             # FIXME DAK: why is this always done?!? there is a flag for it...
             if is_running_gui():
                 controller.updatePipelineScene()
                 base_fname = "%s_%s_pipeline.pdf" % (locator.short_filename, version)
-                filename = os.path.join(workflow_info, base_fname)
+                filename = os.path.join(output_dir, base_fname)
                 controller.current_pipeline_scene.saveToPDF(filename)
             else:
                 debug.critical("Cannot save pipeline figure when not "
                                "running in gui mode")
             base_fname = "%s_%s_pipeline.xml" % (locator.short_filename, version)
-            filename = os.path.join(workflow_info, base_fname)
+            filename = os.path.join(output_dir, base_fname)
             vistrails.core.db.io.save_workflow(controller.current_pipeline, filename)
         if not update_vistrail:
             conf = get_vistrails_configuration()
             if conf.has('thumbs'):
                 conf.thumbs.autoSave = False
         
-        (results, _) = \
+        jobMonitor = controller.jobMonitor
+        current_workflow = jobMonitor.currentWorkflow()
+        if not current_workflow:
+            for job in jobMonitor.workflows.itervalues():
+                try:
+                    job_version = int(job.version)
+                except ValueError:
+                    job_version =  v.get_version_number(job.version)
+                if version == job_version:
+                    current_workflow = job
+                    jobMonitor.startWorkflow(job)
+            if not current_workflow:
+                current_workflow = JobWorkflow(version)
+                jobMonitor.startWorkflow(current_workflow)
+
+        try:
+            (results, _) = \
             controller.execute_current_workflow(custom_aliases=aliases,
                                                 custom_params=params,
                                                 extra_info=extra_info,
                                                 reason=reason)
+        finally:
+            jobMonitor.finishWorkflow()
         new_version = controller.current_version
         if new_version != version:
-            debug.warning("Version '%s' (%s) was upgraded. The actual "
-                          "version executed was %s" % \
-                              (workflow, version, new_version))
+            debug.log("Version '%s' (%s) was upgraded. The actual "
+                      "version executed was %s" % (
+                      workflow, version, new_version))
         run = results[0]
         run.workflow_info = (locator.name, new_version)
         run.pipeline = controller.current_pipeline
@@ -135,14 +156,23 @@ def run_and_get_results(w_list, parameters='', workflow_info=None,
         if update_vistrail:
             controller.write_vistrail(locator)
         result.append(run)
+        if current_workflow.jobs:
+            if current_workflow.completed():
+                run.job = "COMPLETED"
+            else:
+                run.job = "RUNNING: %s" % current_workflow.id
+                for job in current_workflow.jobs.itervalues():
+                    if not job.finished:
+                        run.job += "\n  %s %s %s" % (job.start, job.name, job.description())
+            print run.job
     return result
 
 ################################################################################
 
-def get_wf_graph(w_list, workflow_info=None, pdf=False):
+def get_wf_graph(w_list, output_dir=None, pdf=False):
     """run_and_get_results(w_list: list of (locator, version), 
-                           workflow_info:str, pdf:bool)
-    Load all workflows in wf_list and dump their graph to workflow_info.
+                           output_dir:str, pdf:bool)
+    Load all workflows in wf_list and dump their graph to output_dir.
     
     """
     result = []
@@ -166,22 +196,22 @@ def get_wf_graph(w_list, workflow_info=None, pdf=False):
                     msg = "Invalid version tag or number: %s" % workflow
                     raise VistrailsInternalError(msg)
             
-                if (workflow_info is not None and 
+                if (output_dir is not None and 
                     controller.current_pipeline is not None):
                     controller.updatePipelineScene()
                     if pdf:
                         base_fname = "%s_%s_pipeline.pdf" % \
                                      (locator.short_filename, version)
-                        filename = os.path.join(workflow_info, base_fname)
+                        filename = os.path.join(output_dir, base_fname)
                         controller.current_pipeline_scene.saveToPDF(filename)
                     else:
                         base_fname = "%s_%s_pipeline.png" % \
                                      (locator.short_filename, version)
-                        filename = os.path.join(workflow_info, base_fname)
+                        filename = os.path.join(output_dir, base_fname)
                         controller.current_pipeline_scene.saveToPNG(filename)
                     result.append((True, ""))
             except Exception, e:
-                result.append((False, str(e)))
+                result.append((False, debug.format_exception(e)))
     else:
         error_str = "Cannot save pipeline figure when not " \
             "running in gui mode"
@@ -206,21 +236,21 @@ def get_vt_graph(vt_list, tree_info, pdf=False):
                 controller = GUIVistrailController(v, locator, abstractions, 
                                                    thumbnails, mashups)
                 if tree_info is not None:
-                        from vistrails.gui.version_view import QVersionTreeView
-                        version_view = QVersionTreeView()
-                        version_view.scene().setupScene(controller)
-                        if pdf:
-                            base_fname = "graph_%s.pdf" % locator.short_filename
-                            filename = os.path.join(tree_info, base_fname)
-                            version_view.scene().saveToPDF(filename)
-                        else:
-                            base_fname = "graph_%s.png" % locator.short_filename
-                            filename = os.path.join(tree_info, base_fname)
-                            version_view.scene().saveToPNG(filename)
-                        del version_view
-                        result.append((True, ""))
+                    from vistrails.gui.version_view import QVersionTreeView
+                    version_view = QVersionTreeView()
+                    version_view.scene().setupScene(controller)
+                    if pdf:
+                        base_fname = "graph_%s.pdf" % locator.short_filename
+                        filename = os.path.join(tree_info, base_fname)
+                        version_view.scene().saveToPDF(filename)
+                    else:
+                        base_fname = "graph_%s.png" % locator.short_filename
+                        filename = os.path.join(tree_info, base_fname)
+                        version_view.scene().saveToPNG(filename)
+                    del version_view
+                    result.append((True, ""))
             except Exception, e:
-                result.append((False, str(e)))
+                result.append((False, debug.format_exception(e)))
     else:
         error_str = "Cannot save version tree figure when not " \
             "running in gui mode"
@@ -230,14 +260,14 @@ def get_vt_graph(vt_list, tree_info, pdf=False):
 
 ################################################################################
 
-def run(w_list, parameters='', workflow_info=None, update_vistrail=True,
+def run(w_list, parameters='', output_dir=None, update_vistrail=True,
         extra_info=None, reason="Console Mode Execution"):
     """run(w_list: list of (locator, version), parameters: str) -> boolean
     Run all workflows in w_list, version can be a tag name or a version id.
     Returns list of errors (empty list if there are no errors)
     """
     all_errors = []
-    results = run_and_get_results(w_list, parameters, workflow_info, 
+    results = run_and_get_results(w_list, parameters, output_dir, 
                                   update_vistrail,extra_info, reason)
     for result in results:
         (objs, errors, executed) = (result.objects,
@@ -271,8 +301,8 @@ def run_parameter_exploration(locator, pe_id, extra_info = {},
             controller.executeParameterExploration(pe, extra_info=extra_info,
                                                    showProgress=False)
         except Exception, e:
-            import traceback
-            return (locator, pe_id, str(e), traceback.format_exc())
+            return (locator, pe_id,
+                    debug.format_exception(e), debug.format_exc())
 
 def run_parameter_explorations(w_list, extra_info = {},
                        reason="Console Mode Parameter Exploration Execution"):
@@ -314,10 +344,21 @@ class TestConsoleMode(unittest.TestCase):
             manager.late_disable_package('console_mode_test')
             
     def test1(self):
-        locator = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
-                                 '/tests/resources/dummy.xml')
-        result = run([(locator, "int chain")], update_vistrail=False)
-        self.assertEqual(len(result), 0)
+        from vistrails.core.modules.basic_modules import StandardOutput
+        values = []
+        def mycompute(s):
+            v = s.get_input('value')
+            values.append(v)
+        orig_compute = StandardOutput.compute
+        StandardOutput.compute = mycompute
+        try:
+            locator = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
+                                     '/tests/resources/dummy.xml')
+            result = run([(locator, "int chain")], update_vistrail=False)
+            self.assertEqual(len(result), 0)
+            self.assertEqual(values, [2])
+        finally:
+            StandardOutput.compute = orig_compute
 
     def test_tuple(self):
         from vistrails.core.vistrail.module_param import ModuleParam
@@ -348,14 +389,13 @@ class TestConsoleMode(unittest.TestCase):
                            package='org.vistrails.vistrails.console_mode_test',
                            version='0.9.1')
         module.add_function(function)
-        
+
         p.add_module(module)
-        
-        kwargs = {'locator': XMLFileLocator('foo'),
-                  'current_version': 1L,
-                  'view': v,
-                  }
-        interpreter.execute(p, **kwargs)
+
+        interpreter.execute(p,
+                            locator=XMLFileLocator('foo'),
+                            current_version=1L,
+                            view=v)
 
     def test_python_source(self):
         locator = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
diff --git a/vistrails/core/data_structures/__init__.py b/vistrails/core/data_structures/__init__.py
index 210957e..70e79c3 100644
--- a/vistrails/core/data_structures/__init__.py
+++ b/vistrails/core/data_structures/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -41,4 +42,6 @@ VisTrails."""
 # from core.data_structures.queue import Queue
 # from core.data_structures.stack import Stack
 # from core.data_structures.bijectivedict import Bidict
+from __future__ import division
+
 pass
diff --git a/vistrails/core/data_structures/bijectivedict.py b/vistrails/core/data_structures/bijectivedict.py
index 617d8b5..4c074dc 100644
--- a/vistrails/core/data_structures/bijectivedict.py
+++ b/vistrails/core/data_structures/bijectivedict.py
@@ -1,47 +1,52 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class Bidict(dict):
-    """Subclass of mapping that automatically keeps track of the
-inverse mapping. Note: self.inverse is a simple dict, so it won't keep
-track of deletions directly to self.inverse and things like that. Use
-this for lookups ONLY!. Also, if mapping is not bijective, there's no
-guarantee the inverse mapping will be consistent (particularly in the
-presence of deletions.)"""
+    """Subclass of mapping that automatically keeps track of the inverse
+    mapping. Note: self.inverse is a simple dict, so it won't keep
+    track of deletions directly to self.inverse and things like
+    that. Use this for lookups ONLY!. Also, if mapping is not
+    bijective, there's no guarantee the inverse mapping will be
+    consistent (particularly in the presence of deletions.)
+
+    """
 
     def __init__(self, *args, **kwargs):
 
@@ -68,10 +73,10 @@ presence of deletions.)"""
         return r
 
     def update(self, other):
-        try:
+        if hasattr(other, 'iterkeys'):
             for i in other.iterkeys():
                 self[i] = other[i]
-        except:
+        else:
             for (k,v) in other:
                 self[k] = v
 
diff --git a/vistrails/core/data_structures/graph.py b/vistrails/core/data_structures/graph.py
index 3dae82b..5b1cabf 100644
--- a/vistrails/core/data_structures/graph.py
+++ b/vistrails/core/data_structures/graph.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import math
 import random
 import copy
@@ -83,7 +86,7 @@ class Graph(object):
 
     @staticmethod
     def map_vertices(graph, vertex_map=None, edge_map=None):
-        """ map_verices(graph: Graph, vertex_map: dict): Graph
+        """ map_vertices(graph: Graph, vertex_map: dict): Graph
 
         Creates a new graph that is a mapping of vertex ids through
         vertex_map.
@@ -311,13 +314,16 @@ class Graph(object):
         new_id    -- 'immutable' edge id (default None)
         """
         
-        if old_id == None:
+        if old_id is None:
             efroom = self.adjacency_list[old_froom]
+            forward_idx = None
             for i, edge in enumerate(efroom):
                 if edge[0] == old_to:
                     old_id = edge[1]
                     forward_idx = i
                     break
+            if forward_idx is None:
+                raise ValueError("No edge to %r" % old_to)
         else:
             forward_idx = self.adjacency_list[old_froom].index((old_to, old_id))
 
@@ -678,14 +684,15 @@ class Graph(object):
         """
         vs = self.vertices.keys()
         vs.sort()
-        al = []
-        for i in [map(lambda (t, i): (f, t, i), l)
-                  for (f, l) in self.adjacency_list.items()]:
-            al.extend(i)
+        al = [(vfrom, vto, edgeid)
+              for vfrom, lto in self.adjacency_list.iteritems()
+              for vto, edgeid in lto]
         al.sort()
-        return "digraph G { " \
-               + ";".join([str(s) for s in vs]) + ";" \
-               + ";".join(["%s -> %s [label=\"%s\"]" % s for s in al]) + "}"
+        return ("digraph G {\n"
+                + ";".join([str(s) for s in vs])
+                + ";\n"
+                + "\n".join(["%s -> %s [label=\"%s\"];" % s for s in al])
+                + "\n}")
 
     def __repr__(self):
         """ __repr__() -> str
@@ -727,362 +734,362 @@ class Graph(object):
 
 
 class TestGraph(unittest.TestCase):
-     """ Class to test Graph
+    """ Class to test Graph
 
-     It tests vertex addition, the out_degree of a sink and in_degree of a
-     source consistencies.
+    It tests vertex addition, the out_degree of a sink and in_degree of a
+    source consistencies.
     
-     """
-
-     def make_complete(self, v):
-         """returns a complete graph with v verts."""
-         g = Graph()
-         for x in xrange(v):
-             g.add_vertex(x)
-         for f in xrange(v):
-             for t in xrange(f+1, v):
-                 g.add_edge(f, t, f * v + t)
-         return g
-
-     def make_linear(self, v, bw=False):
-         """returns a linear graph with v verts. if bw=True, add
-         backward links."""
-         g = Graph()
-         for x in xrange(v):
-             g.add_vertex(x)
-         for x,y in izip(xrange(v-1), xrange(1, v)):
-             g.add_edge(x, y, x)
-             if bw:
-                 g.add_edge(y, x, x + v)
-         return g
-
-     def get_default_graph(self):
-         g = Graph()
-         g.add_vertex(0)
-         g.add_vertex(1)
-         g.add_vertex(2)
-         g.add_vertex(3)
-         g.add_vertex(4)
-         g.add_edge(0,1,0)
-         g.add_edge(1,2,1)
-         g.add_edge(0,3,2)
-         g.add_edge(3,2,3)
-         g.add_edge(2,4,4)
-         return g
-     
-     def test1(self):
-         """Test adding edges and vertices"""
-         g = Graph()
-         g.add_vertex('0')
-         g.add_vertex('1')
-         g.add_vertex('2')
-         g.add_vertex('3')
-         g.add_edge('0', '1', 0)
-         g.add_edge('1', '2', 1)
-         g.add_edge('2', '3', 2)
-         parent = g.bfs('0')
-         self.assertEquals(parent['3'], '2')
-         self.assertEquals(parent['2'], '1')
-         self.assertEquals(parent['1'], '0')
-
-     def test2(self):
-         """Test bread-first-search"""
-         g = self.get_default_graph()
-         p = g.bfs(0)
-         k = p.keys()
-         k.sort()
-         self.assertEquals(k, [1, 2, 3, 4])
-         inv = g.inverse()
-         p_inv = inv.bfs(4)
-         k2 = p_inv.keys()
-         k2.sort()
-         self.assertEquals(k2, [0, 1, 2, 3])
-         
-     def test3(self):
-         """Test sink and source degree consistency"""
-         g = Graph()
-         for i in xrange(100):
-             g.add_vertex(i);
-         for i in xrange(1000):
-             v1 = random.randint(0,99)
-             v2 = random.randint(0,99)
-             g.add_edge(v1, v2, i)
-         sinkResult = [None for i in g.sinks() if g.out_degree(i) == 0]
-         sourceResult = [None for i in g.sources() if g.in_degree(i) == 0]
-         if len(sinkResult) <> len(g.sinks()):
-             assert False
-         if len(sourceResult) <> len(g.sources()):
-             assert False
-
-     def test_remove_vertices(self):
-         g = self.make_linear(5)
-         g.delete_vertex(1)
-         g.delete_vertex(2)
-     
-     def test_DFS(self):
-         """Test DFS on graph."""
-         g = self.get_default_graph()
-         g.dfs()
-
-     def test_topological_sort(self):
-         """Test toposort on graph."""
-         g = self.get_default_graph()
-         g.vertices_topological_sort()
-
-         g = self.make_linear(10)
-         r = g.vertices_topological_sort()
-         assert r == [0,1,2,3,4,5,6,7,8,9]
-
-         g = Graph()
-         g.add_vertex('a')
-         g.add_vertex('b')
-         g.add_vertex('c')
-         g.add_edge('a', 'b')
-         g.add_edge('b', 'c')
-         assert g.vertices_topological_sort() == ['a', 'b', 'c']
-
-     def test_limited_DFS(self):
-         """Test DFS on graph using a limited set of starting vertices."""
-         g = self.get_default_graph()
-         g.dfs(vertex_set=[1])
-         g.dfs(vertex_set=[1,3])
-         g.dfs(vertex_set=[1,2])
-
-     def test_limited_topological_sort(self):
-         """Test toposort on graph using a limited set of starting vertices."""
-         g = self.get_default_graph()
-         g.vertices_topological_sort(vertex_set=[1])
-         g.vertices_topological_sort(vertex_set=[1,3])
-         g.vertices_topological_sort(vertex_set=[1,2])
-
-     def test_print_empty_graph(self):
-         """Test print on empty graph"""
-         g = Graph()
-         g.__str__()
-
-     def test_delete(self):
-         """Tests consistency of data structure after deletion."""
-         g = Graph()
-         g.add_vertex(0)
-         g.add_vertex(1)
-         g.add_vertex(2)
-         g.add_edge(0, 1, 0)
-         g.add_edge(1, 2, 1)
-         g.delete_vertex(2)
-         self.assertEquals(g.adjacency_list[1], [])
-
-     def test_raising_DFS(self):
-         """Tests if DFS with cycle-checking will raise exceptions."""
-         g = Graph()
-         g.add_vertex(0)
-         g.add_vertex(1)
-         g.add_vertex(2)
-         g.add_edge(0, 1)
-         g.add_edge(1, 2)
-         g.add_edge(2, 0)
-         with self.assertRaises(Graph.GraphContainsCycles):
-             g.dfs(raise_if_cyclic=True)
-
-     def test_call_inverse(self):
-         """Test if calling inverse methods work."""
-         g = Graph()
-         g.add_vertex(0)
-         g.add_vertex(1)
-         g.add_vertex(2)
-         g.add_edge(0, 1)
-         g.add_edge(1, 2)
-         g.add_edge(2, 0)
-         g2 = g.inverse()
-         g3 = g.inverse_immutable()
-     
-     def test_subgraph(self):
-         """Test subgraph routines."""
-         g = self.make_complete(5)
-         sub = g.subgraph([0,1])
-         assert 0 in sub.vertices
-         assert 1 in sub.vertices
-         assert (1,1) in sub.adjacency_list[0]
-         assert (0,1) in sub.inverse_adjacency_list[1]
-
-         g = self.make_linear(3)
-         sub = g.subgraph([0, 2])
-         assert 0 in sub.vertices
-         assert 2 in sub.vertices
-         assert sub.adjacency_list[0] == []
-         assert sub.adjacency_list[2] == []
-         
-     def test_connections_to_subgraph(self):
-         """Test connections_to_subgraph."""
-         g = self.make_linear(5)
-         sub = g.subgraph([3])
-         assert len(g.connections_to_subgraph(sub)) == 1
-         g = self.make_linear(5, True)
-         sub = g.subgraph([3])
-         assert len(g.connections_to_subgraph(sub)) == 2
-
-     def test_connections_from_subgraph(self):
-         """Test connections_from_subgraph."""
-         g = self.make_linear(5)
-         sub = g.subgraph([3])
-         assert len(g.connections_from_subgraph(sub)) == 1
-         g = self.make_linear(5, True)
-         sub = g.subgraph([3])
-         assert len(g.connections_from_subgraph(sub)) == 2
-
-     def test_topologically_contractible(self):
-         """Test topologically_contractible."""
-         g = self.make_linear(5)
-         sub = g.subgraph([1, 2])
-         assert g.topologically_contractible(sub)
-         sub = g.subgraph([1, 3])
-         assert not g.topologically_contractible(sub)
-
-         g = Graph()
-         g.add_vertex(0)
-         g.add_vertex(1)
-         g.add_vertex(2)
-         g.add_vertex(3)
-         g.add_edge(0, 1)
-         g.add_edge(2, 3)
-         for i in xrange(1, 16):
-             s = []
-             for j in xrange(4):
-                 if i & (1 << j): s.append(j)
-             assert g.topologically_contractible(g.subgraph(s))
-
-     def test_iter_vertices(self):
-         g = self.get_default_graph()
-         l = list(g.iter_vertices())
-         l.sort()
-         assert l == [0,1,2,3,4]
-
-     def test_iter_edges(self):
-         g = self.get_default_graph()
-         l = [v for v in g.iter_all_edges()]
-         l.sort()
-         assert l == [(0,1,0), (0,3,2), (1, 2, 1), (2, 4, 4), (3, 2, 3)]
-
-     def test_iter_edges_empty(self):
-         """Test iterators on empty parts of the graph."""
-         g = Graph()
-         for a in g.iter_vertices():
-             assert False
-         g.add_vertex(0)
-         for a in g.iter_edges_from(0):
-             assert False
-         for a in g.iter_edges_to(0):
-             assert False
-         for a in g.iter_all_edges():
-             assert False
-
-     def test_get_edge_none(self):
-         g = Graph()
-         g.add_vertex(0)
-         g.add_vertex(1)
-         assert g.get_edge(0, 1) == None
-
-     def test_dfs_before(self):
-         g = self.make_linear(10)
-         inc = []
-         dec = []
-         def before(id): inc.append(id)
-         def after(id): dec.append(id)
-         g.dfs(enter_vertex=before,
-               leave_vertex=after)
-         assert inc == [0,1,2,3,4,5,6,7,8,9]
-         assert inc == list(reversed(dec))
-         assert all(a < b for a, b in izip(inc[:-1], inc[1:]))
-         assert all(a > b for a, b in izip(dec[:-1], dec[1:]))
-
-     def test_parent_source(self):
-         g = self.make_linear(10)
-         self.assertRaises(g.VertexHasNoParentError,
-                           lambda: g.parent(0))
-         for i in xrange(1, 10):
-             assert g.parent(i) == i-1
-
-     def test_rename_vertex(self):
-         g = self.make_linear(10)
-         self.assertRaises(g.RenameVertexError,
-                           lambda: g.rename_vertex(0, 1))
-         assert g.get_edge(0, 1) is not None
-         assert g.get_edge(0, 11) is None
-         g.rename_vertex(1, 11)
-         assert g.get_edge(0, 1) is None
-         assert g.get_edge(0, 11) is not None
-         g.rename_vertex(11, 1)
-         assert g.get_edge(0, 1) is not None
-         assert g.get_edge(0, 11) is None
-
-     def test_delete_get_edge(self):
-         g = self.make_linear(10)
-         self.assertRaises(GraphException, lambda: g.delete_edge(7, 9))
-         assert g.has_edge(7, 8)
-         g.delete_edge(7, 8)
-         assert not g.has_edge(7, 8)
-
-     def test_bfs(self):
-         g = self.make_linear(5)
-         lst = g.bfs(0).items()
-         lst.sort()
-         assert lst == [(1, 0), (2, 1), (3, 2), (4, 3)]
-         lst = g.bfs(2).items()
-         lst.sort()
-         assert lst == [(3, 2), (4, 3)]
-
-     def test_undirected(self):
-         g = self.make_linear(5).undirected_immutable()
-         lst = g.bfs(0).items()
-         lst.sort()
-         assert lst == [(1, 0), (2, 1), (3, 2), (4, 3)]
-         lst = g.bfs(2).items()
-         lst.sort()
-         assert lst == [(0, 1), (1, 2), (3, 2), (4, 3)]
-
-     def test_closest_vertex(self):
-         g = self.make_linear(10)
-         g.delete_edge(7, 8)
-         g = g.undirected_immutable()
-         self.assertRaises(GraphException, lambda: g.closest_vertex(1, [9]))
-         assert g.closest_vertex(3, [2, 6, 7]) == 2
-         assert g.closest_vertex(3, [2, 3, 6, 7]) == 3
-         # Test using dictionary as target_list
-
-         d1 = {2:True, 6:True, 7:False}
-         d2 = {2:True, 6:True, 7:False, 3:False}
-         d3 = {9:True}
-         self.assertRaises(GraphException, lambda: g.closest_vertex(1, d3))
-         assert g.closest_vertex(3, d1) == 2
-         assert g.closest_vertex(3, d2) == 3
-
-     def test_copy_not_share(self):
-         g = self.make_linear(10)
-         g2 = copy.copy(g)
-         for v in g.vertices:
-             assert id(g.adjacency_list[v]) <> id(g2.adjacency_list[v])
-             assert id(g.inverse_adjacency_list[v]) <> id(g2.inverse_adjacency_list[v])
-
-     def test_copy_works(self):
-         g = self.make_linear(10)
-         g2 = copy.copy(g)
-         for v in g.vertices:
-             assert v in g2.vertices
-             assert g2.adjacency_list[v] == g.adjacency_list[v]
-             assert g2.inverse_adjacency_list[v] == g.inverse_adjacency_list[v]
-
-     def test_equals(self):
-         g = self.make_linear(5)
-         assert copy.copy(g) == g
-         g2 = copy.copy(g)
-         g2.add_vertex(10)
-         assert g2 <> g
-
-     def test_map_vertices(self):
-         g = self.make_linear(5)
-         m = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
-         assert g == Graph.map_vertices(g, m)
-         m = {0: 5, 1: 6, 2: 7, 3: 8, 4: 9}
-         assert g <> Graph.map_vertices(g, m)
-         
+    """
+
+    def make_complete(self, v):
+        """returns a complete graph with v verts."""
+        g = Graph()
+        for x in xrange(v):
+            g.add_vertex(x)
+        for f in xrange(v):
+            for t in xrange(f+1, v):
+                g.add_edge(f, t, f * v + t)
+        return g
+
+    def make_linear(self, v, bw=False):
+        """returns a linear graph with v verts. if bw=True, add
+        backward links."""
+        g = Graph()
+        for x in xrange(v):
+            g.add_vertex(x)
+        for x,y in izip(xrange(v-1), xrange(1, v)):
+            g.add_edge(x, y, x)
+            if bw:
+                g.add_edge(y, x, x + v)
+        return g
+
+    def get_default_graph(self):
+        g = Graph()
+        g.add_vertex(0)
+        g.add_vertex(1)
+        g.add_vertex(2)
+        g.add_vertex(3)
+        g.add_vertex(4)
+        g.add_edge(0,1,0)
+        g.add_edge(1,2,1)
+        g.add_edge(0,3,2)
+        g.add_edge(3,2,3)
+        g.add_edge(2,4,4)
+        return g
+    
+    def test1(self):
+        """Test adding edges and vertices"""
+        g = Graph()
+        g.add_vertex('0')
+        g.add_vertex('1')
+        g.add_vertex('2')
+        g.add_vertex('3')
+        g.add_edge('0', '1', 0)
+        g.add_edge('1', '2', 1)
+        g.add_edge('2', '3', 2)
+        parent = g.bfs('0')
+        self.assertEquals(parent['3'], '2')
+        self.assertEquals(parent['2'], '1')
+        self.assertEquals(parent['1'], '0')
+
+    def test2(self):
+        """Test bread-first-search"""
+        g = self.get_default_graph()
+        p = g.bfs(0)
+        k = p.keys()
+        k.sort()
+        self.assertEquals(k, [1, 2, 3, 4])
+        inv = g.inverse()
+        p_inv = inv.bfs(4)
+        k2 = p_inv.keys()
+        k2.sort()
+        self.assertEquals(k2, [0, 1, 2, 3])
+        
+    def test3(self):
+        """Test sink and source degree consistency"""
+        g = Graph()
+        for i in xrange(100):
+            g.add_vertex(i)
+        for i in xrange(1000):
+            v1 = random.randint(0,99)
+            v2 = random.randint(0,99)
+            g.add_edge(v1, v2, i)
+        sinkResult = [None for i in g.sinks() if g.out_degree(i) == 0]
+        sourceResult = [None for i in g.sources() if g.in_degree(i) == 0]
+        if len(sinkResult) <> len(g.sinks()):
+            assert False
+        if len(sourceResult) <> len(g.sources()):
+            assert False
+
+    def test_remove_vertices(self):
+        g = self.make_linear(5)
+        g.delete_vertex(1)
+        g.delete_vertex(2)
+    
+    def test_DFS(self):
+        """Test DFS on graph."""
+        g = self.get_default_graph()
+        g.dfs()
+
+    def test_topological_sort(self):
+        """Test toposort on graph."""
+        g = self.get_default_graph()
+        g.vertices_topological_sort()
+
+        g = self.make_linear(10)
+        r = g.vertices_topological_sort()
+        assert r == [0,1,2,3,4,5,6,7,8,9]
+
+        g = Graph()
+        g.add_vertex('a')
+        g.add_vertex('b')
+        g.add_vertex('c')
+        g.add_edge('a', 'b')
+        g.add_edge('b', 'c')
+        assert g.vertices_topological_sort() == ['a', 'b', 'c']
+
+    def test_limited_DFS(self):
+        """Test DFS on graph using a limited set of starting vertices."""
+        g = self.get_default_graph()
+        g.dfs(vertex_set=[1])
+        g.dfs(vertex_set=[1,3])
+        g.dfs(vertex_set=[1,2])
+
+    def test_limited_topological_sort(self):
+        """Test toposort on graph using a limited set of starting vertices."""
+        g = self.get_default_graph()
+        g.vertices_topological_sort(vertex_set=[1])
+        g.vertices_topological_sort(vertex_set=[1,3])
+        g.vertices_topological_sort(vertex_set=[1,2])
+
+    def test_print_empty_graph(self):
+        """Test print on empty graph"""
+        g = Graph()
+        g.__str__()
+
+    def test_delete(self):
+        """Tests consistency of data structure after deletion."""
+        g = Graph()
+        g.add_vertex(0)
+        g.add_vertex(1)
+        g.add_vertex(2)
+        g.add_edge(0, 1, 0)
+        g.add_edge(1, 2, 1)
+        g.delete_vertex(2)
+        self.assertEquals(g.adjacency_list[1], [])
+
+    def test_raising_DFS(self):
+        """Tests if DFS with cycle-checking will raise exceptions."""
+        g = Graph()
+        g.add_vertex(0)
+        g.add_vertex(1)
+        g.add_vertex(2)
+        g.add_edge(0, 1)
+        g.add_edge(1, 2)
+        g.add_edge(2, 0)
+        with self.assertRaises(Graph.GraphContainsCycles):
+            g.dfs(raise_if_cyclic=True)
+
+    def test_call_inverse(self):
+        """Test if calling inverse methods work."""
+        g = Graph()
+        g.add_vertex(0)
+        g.add_vertex(1)
+        g.add_vertex(2)
+        g.add_edge(0, 1)
+        g.add_edge(1, 2)
+        g.add_edge(2, 0)
+        g2 = g.inverse()
+        g3 = g.inverse_immutable()
+    
+    def test_subgraph(self):
+        """Test subgraph routines."""
+        g = self.make_complete(5)
+        sub = g.subgraph([0,1])
+        assert 0 in sub.vertices
+        assert 1 in sub.vertices
+        assert (1,1) in sub.adjacency_list[0]
+        assert (0,1) in sub.inverse_adjacency_list[1]
+
+        g = self.make_linear(3)
+        sub = g.subgraph([0, 2])
+        assert 0 in sub.vertices
+        assert 2 in sub.vertices
+        assert sub.adjacency_list[0] == []
+        assert sub.adjacency_list[2] == []
+        
+    def test_connections_to_subgraph(self):
+        """Test connections_to_subgraph."""
+        g = self.make_linear(5)
+        sub = g.subgraph([3])
+        assert len(g.connections_to_subgraph(sub)) == 1
+        g = self.make_linear(5, True)
+        sub = g.subgraph([3])
+        assert len(g.connections_to_subgraph(sub)) == 2
+
+    def test_connections_from_subgraph(self):
+        """Test connections_from_subgraph."""
+        g = self.make_linear(5)
+        sub = g.subgraph([3])
+        assert len(g.connections_from_subgraph(sub)) == 1
+        g = self.make_linear(5, True)
+        sub = g.subgraph([3])
+        assert len(g.connections_from_subgraph(sub)) == 2
+
+    def test_topologically_contractible(self):
+        """Test topologically_contractible."""
+        g = self.make_linear(5)
+        sub = g.subgraph([1, 2])
+        assert g.topologically_contractible(sub)
+        sub = g.subgraph([1, 3])
+        assert not g.topologically_contractible(sub)
+
+        g = Graph()
+        g.add_vertex(0)
+        g.add_vertex(1)
+        g.add_vertex(2)
+        g.add_vertex(3)
+        g.add_edge(0, 1)
+        g.add_edge(2, 3)
+        for i in xrange(1, 16):
+            s = []
+            for j in xrange(4):
+                if i & (1 << j): s.append(j)
+            assert g.topologically_contractible(g.subgraph(s))
+
+    def test_iter_vertices(self):
+        g = self.get_default_graph()
+        l = list(g.iter_vertices())
+        l.sort()
+        assert l == [0,1,2,3,4]
+
+    def test_iter_edges(self):
+        g = self.get_default_graph()
+        l = [v for v in g.iter_all_edges()]
+        l.sort()
+        assert l == [(0,1,0), (0,3,2), (1, 2, 1), (2, 4, 4), (3, 2, 3)]
+
+    def test_iter_edges_empty(self):
+        """Test iterators on empty parts of the graph."""
+        g = Graph()
+        for a in g.iter_vertices():
+            assert False
+        g.add_vertex(0)
+        for a in g.iter_edges_from(0):
+            assert False
+        for a in g.iter_edges_to(0):
+            assert False
+        for a in g.iter_all_edges():
+            assert False
+
+    def test_get_edge_none(self):
+        g = Graph()
+        g.add_vertex(0)
+        g.add_vertex(1)
+        assert g.get_edge(0, 1) is None
+
+    def test_dfs_before(self):
+        g = self.make_linear(10)
+        inc = []
+        dec = []
+        def before(id): inc.append(id)
+        def after(id): dec.append(id)
+        g.dfs(enter_vertex=before,
+              leave_vertex=after)
+        assert inc == [0,1,2,3,4,5,6,7,8,9]
+        assert inc == list(reversed(dec))
+        assert all(a < b for a, b in izip(inc[:-1], inc[1:]))
+        assert all(a > b for a, b in izip(dec[:-1], dec[1:]))
+
+    def test_parent_source(self):
+        g = self.make_linear(10)
+        self.assertRaises(g.VertexHasNoParentError,
+                          lambda: g.parent(0))
+        for i in xrange(1, 10):
+            assert g.parent(i) == i-1
+
+    def test_rename_vertex(self):
+        g = self.make_linear(10)
+        self.assertRaises(g.RenameVertexError,
+                          lambda: g.rename_vertex(0, 1))
+        assert g.get_edge(0, 1) is not None
+        assert g.get_edge(0, 11) is None
+        g.rename_vertex(1, 11)
+        assert g.get_edge(0, 1) is None
+        assert g.get_edge(0, 11) is not None
+        g.rename_vertex(11, 1)
+        assert g.get_edge(0, 1) is not None
+        assert g.get_edge(0, 11) is None
+
+    def test_delete_get_edge(self):
+        g = self.make_linear(10)
+        self.assertRaises(GraphException, lambda: g.delete_edge(7, 9))
+        assert g.has_edge(7, 8)
+        g.delete_edge(7, 8)
+        assert not g.has_edge(7, 8)
+
+    def test_bfs(self):
+        g = self.make_linear(5)
+        lst = g.bfs(0).items()
+        lst.sort()
+        assert lst == [(1, 0), (2, 1), (3, 2), (4, 3)]
+        lst = g.bfs(2).items()
+        lst.sort()
+        assert lst == [(3, 2), (4, 3)]
+
+    def test_undirected(self):
+        g = self.make_linear(5).undirected_immutable()
+        lst = g.bfs(0).items()
+        lst.sort()
+        assert lst == [(1, 0), (2, 1), (3, 2), (4, 3)]
+        lst = g.bfs(2).items()
+        lst.sort()
+        assert lst == [(0, 1), (1, 2), (3, 2), (4, 3)]
+
+    def test_closest_vertex(self):
+        g = self.make_linear(10)
+        g.delete_edge(7, 8)
+        g = g.undirected_immutable()
+        self.assertRaises(GraphException, lambda: g.closest_vertex(1, [9]))
+        assert g.closest_vertex(3, [2, 6, 7]) == 2
+        assert g.closest_vertex(3, [2, 3, 6, 7]) == 3
+        # Test using dictionary as target_list
+
+        d1 = {2:True, 6:True, 7:False}
+        d2 = {2:True, 6:True, 7:False, 3:False}
+        d3 = {9:True}
+        self.assertRaises(GraphException, lambda: g.closest_vertex(1, d3))
+        assert g.closest_vertex(3, d1) == 2
+        assert g.closest_vertex(3, d2) == 3
+
+    def test_copy_not_share(self):
+        g = self.make_linear(10)
+        g2 = copy.copy(g)
+        for v in g.vertices:
+            assert id(g.adjacency_list[v]) <> id(g2.adjacency_list[v])
+            assert id(g.inverse_adjacency_list[v]) <> id(g2.inverse_adjacency_list[v])
+
+    def test_copy_works(self):
+        g = self.make_linear(10)
+        g2 = copy.copy(g)
+        for v in g.vertices:
+            assert v in g2.vertices
+            assert g2.adjacency_list[v] == g.adjacency_list[v]
+            assert g2.inverse_adjacency_list[v] == g.inverse_adjacency_list[v]
+
+    def test_equals(self):
+        g = self.make_linear(5)
+        assert copy.copy(g) == g
+        g2 = copy.copy(g)
+        g2.add_vertex(10)
+        assert g2 <> g
+
+    def test_map_vertices(self):
+        g = self.make_linear(5)
+        m = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
+        assert g == Graph.map_vertices(g, m)
+        m = {0: 5, 1: 6, 2: 7, 3: 8, 4: 9}
+        assert g <> Graph.map_vertices(g, m)
+        
 if __name__ == '__main__':
     unittest.main()
diff --git a/vistrails/core/data_structures/point.py b/vistrails/core/data_structures/point.py
index 9534d2e..c7ba0b3 100644
--- a/vistrails/core/data_structures/point.py
+++ b/vistrails/core/data_structures/point.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import math
 
 ################################################################################
@@ -190,7 +193,7 @@ class TestPoint(unittest.TestCase):
         a = Point(0, 1)
         b = Point(0, 1)
         assert a == b
-        assert a != None
+        assert a is not None
         b = Point(0, 0.1)
         assert a != b
 
diff --git a/vistrails/core/data_structures/queue.py b/vistrails/core/data_structures/queue.py
index 634869c..3dabca1 100644
--- a/vistrails/core/data_structures/queue.py
+++ b/vistrails/core/data_structures/queue.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 ################################################################################
 
+from __future__ import division
+
 class Queue(object):
 
     def __init__(self, capacity=8):
@@ -106,8 +109,8 @@ class Queue(object):
         self.__begin += 1
         if self.__begin == self.__capacity:
             self.__begin = 0
-        if self.__capacity > 8 and (self.__capacity / len(self)) >= 4:
-            self.__rebuffer(self.__capacity / 2)
+        if self.__capacity > 8 and self.__capacity >= 4 * len(self):
+            self.__rebuffer(self.__capacity // 2)
         # nlen = len(self)
         # assert olen == nlen + 1
         return r
diff --git a/vistrails/core/data_structures/rect.py b/vistrails/core/data_structures/rect.py
index 806042f..a74da4c 100644
--- a/vistrails/core/data_structures/rect.py
+++ b/vistrails/core/data_structures/rect.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.core.data_structures.point import Point
 
@@ -48,12 +51,12 @@ class Rect(object):
         a copy of the given points. Return a Rect
 
         """        
-        if lower_left == None:
+        if lower_left is None:
             self.lower_left = Point()
         else:
             self.lower_left = copy.copy(lower_left)
 
-        if upper_right == None:
+        if upper_right is None:
             self.upper_right = Point()
         else:
             self.upper_right = copy.copy(upper_right)
diff --git a/vistrails/core/data_structures/stack.py b/vistrails/core/data_structures/stack.py
index a4da378..96c3a23 100644
--- a/vistrails/core/data_structures/stack.py
+++ b/vistrails/core/data_structures/stack.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 
 ###############################################################################
 
+from __future__ import division
+
 class EmptyStack(Exception):
     pass
 
diff --git a/vistrails/core/db/__init__.py b/vistrails/core/db/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/db/__init__.py
+++ b/vistrails/core/db/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/db/action.py b/vistrails/core/db/action.py
index be6c209..03fc02a 100644
--- a/vistrails/core/db/action.py
+++ b/vistrails/core/db/action.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.vistrail.location import Location
 import vistrails.db.services.action
 
diff --git a/vistrails/core/db/io.py b/vistrails/core/db/io.py
index 589e5c6..7d8cfc4 100644
--- a/vistrails/core/db/io.py
+++ b/vistrails/core/db/io.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.vistrail.action import Action
 from vistrails.core.log.log import Log
 from vistrails.core.vistrail.operation import AddOp, ChangeOp, DeleteOp
@@ -125,12 +128,14 @@ def get_workflow_diff(vt_pair_1, vt_pair_2):
     """
 
     from vistrails.core.vistrail.pipeline import Pipeline
-    (v1, v2, pairs, heuristic_pairs, v1_only, v2_only, param_changes, \
-         _, _, _, _) = \
-         vistrails.db.services.vistrail.getWorkflowDiff(vt_pair_1, vt_pair_2, True)
+    (v1, v2, pairs, heuristic_pairs, v1_only, v2_only, param_changes,
+     cparam_changes, annot_changes, _, _, _, _) = \
+         vistrails.db.services.vistrail.getWorkflowDiff(vt_pair_1, vt_pair_2,
+                                                        True)
     Pipeline.convert(v1)
     Pipeline.convert(v2)
-    return (v1, v2, pairs, heuristic_pairs, v1_only, v2_only, param_changes)
+    return (v1, v2, pairs, heuristic_pairs, v1_only, v2_only, param_changes,
+            cparam_changes, annot_changes)
 
 def get_workflow_diff_with_connections(vt_pair_1, vt_pair_2):
     """get_workflow_diff_with_connections
@@ -139,13 +144,15 @@ def get_workflow_diff_with_connections(vt_pair_1, vt_pair_2):
     """
 
     from vistrails.core.vistrail.pipeline import Pipeline
-    (v1, v2, m_pairs, m_heuristic, v1_only, v2_only, param_changes, \
-         c_pairs, c_heuristic, c1_only, c2_only) = \
-         vistrails.db.services.vistrail.getWorkflowDiff(vt_pair_1, vt_pair_2, False)
+    (v1, v2, m_pairs, m_heuristic, v1_only, v2_only, param_changes,
+     cparam_changes, annot_changes, c_pairs, c_heuristic, c1_only, c2_only) =\
+         vistrails.db.services.vistrail.getWorkflowDiff(vt_pair_1, vt_pair_2,
+                                                        False)
     Pipeline.convert(v1)
     Pipeline.convert(v2)
-    return (v1, v2, m_pairs, m_heustric, v1_only, v2_only, param_changes,
-            c_pairs, c_heuristic, c1_only, c2_only)
+    return (v1, v2, m_pairs, m_heuristic, v1_only, v2_only, param_changes,
+            cparam_changes, annot_changes, c_pairs, c_heuristic, c1_only,
+            c2_only)
 
 def getPathAsAction(vt, v1, v2, do_copy=False):
     a = vistrails.db.services.vistrail.getPathAsAction(vt, v1, v2, do_copy)
@@ -224,3 +231,14 @@ def create_temp_folder(prefix='vt_save'):
 
 def remove_temp_folder(temp_dir):
     vistrails.db.services.io.remove_temp_folder(temp_dir)
+
+def load_startup(startup_fname):
+    from vistrails.core.startup import VistrailsStartup
+    startup = vistrails.db.services.io.open_startup_from_xml(startup_fname)
+    VistrailsStartup.convert(startup)
+    return startup
+
+def save_startup(startup, fname):
+    startup = vistrails.db.services.io.save_startup_to_xml(startup, fname)
+    return startup
+    
diff --git a/vistrails/core/db/locator.py b/vistrails/core/db/locator.py
index 7a54f0c..d702ad9 100644
--- a/vistrails/core/db/locator.py
+++ b/vistrails/core/db/locator.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import base64
 import getpass
 import os.path
@@ -255,8 +258,9 @@ class DBLocator(_DBLocator, CoreLocator):
                     shutil.copyfile(thumbnail, cachedir_thumbnail)
                     new_thumbnails.append(cachedir_thumbnail)
                 except Exception, e:
-                    debug.critical('copying %s -> %s failed: %s' % \
-                                       (thumbnail, cachedir_thumbnail, str(e)))
+                    debug.critical("copying %s -> %s failed" % (
+                                   thumbnail, cachedir_thumbnail),
+                                   e)
         save_bundle.thumbnails = new_thumbnails
         # Need to update thumbnail cache in case some references have changed
         thumb_cache.add_entries_from_files(save_bundle.thumbnails)
@@ -303,7 +307,7 @@ class DBLocator(_DBLocator, CoreLocator):
                 f.write("\nConnect to db with username [%s]: "%self._user)
                 f.close()
                 user = raw_input()
-            except:
+            except IOError:
                 debug.warning("Couldn't write to terminal. Will try stdout")
                 user = raw_input("Connecting to db with username[%s]: "%self._user)
             try:
@@ -322,10 +326,10 @@ class DBLocator(_DBLocator, CoreLocator):
                 config['name'] = '%s@%s'%(self._user,self._host)
                 config['id'] = -1
             except VistrailsDBException, e:
-                debug.critical('VisTrails DB Exception',  str(e))
+                debug.critical('VisTrails DB Exception',  e)
                 config['succeeded'] = False
             except Exception, e2:
-                debug.critical('VisTrails Exception', str(e2))
+                debug.critical('VisTrails Exception', e2)
                 config['succeeded'] = False
         if config is not None:
             if config['succeeded'] == False:
@@ -343,7 +347,7 @@ class DBLocator(_DBLocator, CoreLocator):
                     config['succeeded'] = True
                     config['passwd'] = self._passwd
                 except VistrailsDBException, e:
-                    debug.critical('VisTrails DB Exception',  str(e))
+                    debug.critical('VisTrails DB Exception', e)
                     config['succeeded'] = False
             
             if config['succeeded'] == True:
@@ -372,7 +376,7 @@ class DBLocator(_DBLocator, CoreLocator):
         """get_connection_info(id: int) -> dict
         Returns info of ExtConnection """
         conn = self.__list.get_connection(id)
-        if conn != None:
+        if conn is not None:
             succeeded = False
             key = str(conn.id) + "." + conn.name + "." + conn.host
             passwd = DBLocator.keyChain.get_key(key)
@@ -400,20 +404,13 @@ class DBLocator(_DBLocator, CoreLocator):
         If the connection exists it will update it, else it will add it
 
         """
-        if kwargs.has_key("id"):
-            id = kwargs["id"]
-        if kwargs.has_key("name"):
-            name = kwargs["name"]
-        if kwargs.has_key("host"):
-            host = kwargs["host"]
-        if kwargs.has_key("port"):
-            port = kwargs["port"]
-        if kwargs.has_key("user"):
-            user = kwargs["user"]
-        if kwargs.has_key("passwd"):
-            passwd = kwargs["passwd"]
-        if kwargs.has_key("db"):
-            db = kwargs["db"]
+        id = kwargs["id"]
+        name = kwargs["name"]
+        host = kwargs["host"]
+        port = kwargs["port"]
+        user = kwargs["user"]
+        passwd = kwargs["passwd"]
+        db = kwargs["db"]
 
         conn = DBConnection(id=id,
                             name=name,
@@ -676,17 +673,17 @@ class FileLocator(CoreLocator):
             showSpreadsheetOnly = False
         try:
             version = int(version)
-        except:
+        except (ValueError, TypeError):
             pass
 
         if tag is None:
-            tag = '';
+            tag = ''
             
         ## execute and showSpreadsheetOnly should be written to the current
         ## configuration
         config = get_vistrails_configuration()
-        config.executeWorkflows = execute
-        config.showSpreadsheetOnly = showSpreadsheetOnly
+        config.execute = execute
+        config.showWindow = not showSpreadsheetOnly
         if not forceDB:
             if vtcontent is not None:
                 if url is not None:
@@ -752,9 +749,3 @@ class FileLocator(CoreLocator):
                                mashuptrail=mashuptrail,
                                mashupVersion=mashupVersion,
                                parameterExploration=parameterExploration)
-        
-        
-    ##########################################################################
-
-def untitled_locator():
-    return UntitledLocator()
diff --git a/vistrails/core/debug.py b/vistrails/core/debug.py
index d48826b..dba1fb4 100644
--- a/vistrails/core/debug.py
+++ b/vistrails/core/debug.py
@@ -1,50 +1,174 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+import inspect
 import logging
 import logging.handlers
-import inspect
 import os
-import os.path
+import pdb
 import re
+import sys
 import time
-import vistrails.core
+import traceback
+
+###############################################################################
+
+
+def format_exception(e):
+    """Formats an exception as a single-line (no traceback).
+
+    Use this instead of str() which might drop the exception type.
+    """
+    return traceback._format_final_exc_line(type(e).__name__, e)
+
+
+def unexpected_exception(e, tb=None, frame=None):
+    """Marks an exception that we might want to debug.
+
+    Before logging an exception or showing a message (potentially with
+    format_exception()), you might want to call this. It's a no-op unless
+    debugging is enabled in the configuration, in which case it will start a
+    debugger.
+    """
+    if tb is None:
+        tb = sys.exc_info()[2]
+    if frame is None:
+        tb_it = tb
+        while tb_it.tb_next is not None:
+            tb_it = tb_it.tb_next
+        frame = tb_it.tb_frame
+
+    # Whether to use the debugger
+    try:
+        from vistrails.core.configuration import get_vistrails_configuration
+        debugger = getattr(get_vistrails_configuration(),
+                           'developerDebugger',
+                           False)
+    except Exception:
+        debugger = False
+    if not debugger:
+        return
+
+    # Removes PyQt's input hook
+    try:
+        from PyQt4 import QtCore
+    except ImportError:
+        pass
+    else:
+        QtCore.pyqtRemoveInputHook()
+
+    # Prints the exception and traceback
+    print >>sys.stderr, "!!!!!!!!!!"
+    print >>sys.stderr, "Got unexpected exception, starting debugger"
+    print_exception(None, e, tb, 3, file=sys.stderr)
+
+    # Starts the debugger
+    print >>sys.stderr, "!!!!!!!!!!"
+    # pdb.post_mortem()
+    p = pdb.Pdb()
+    p.reset()
+    p.interaction(frame, tb)
+
+###############################################################################
+
+def _format_exception(etype, value, etb, rtb):
+    yield "Traceback (most recent call last):\n"
+    if isinstance(rtb, (int, long)):
+        try:
+            raise ZeroDivisionError
+        except ZeroDivisionError:
+            f = sys.exc_info()[2].tb_frame
+            while rtb > 0:
+                f = f.f_back
+                rtb -= 1
+            rtb = f
+    for line in traceback.format_stack(rtb):
+        yield line
+    yield "--- Exception caught here ---\n"
+    if etb:
+        for line in traceback.format_tb(etb):
+            yield line
+    if value is not None:
+        if etype is None:
+            etype = type(value)
+        lines = traceback.format_exception_only(etype, value)
+        for line in lines:
+            yield line
+
+def print_exception(etype, value, etb, rtb=2, file=None):
+    """Like :func:`traceback.print_exception` but prints the full stack.
+
+    In addition to the stack frames between the exception and the point it is
+    caught, this prints the stack frames above the catching location.
+
+    `etb` is the traceback object from the exception, which will be printed
+    below the ``Exception caught here`` line. `rtb` is either a frame object at
+    which to start, or an integer specifying the depth.
+    """
+    if file is None:
+        file = sys.stderr
+    for line in _format_exception(etype, value, etb, rtb + 1):
+        file.write(line)
+
+def format_exc():
+    """Like :func:`traceback.format_exc` but uses the full stack.
+
+    In addition to the stack frames between the exception and the point it is
+    caught, this prints the stack frames above the catching location.
+    """
+    try:
+        etype, value, tb = sys.exc_info()
+        return ''.join(_format_exception(etype, value, tb, 3))
+    finally:
+        etype = value = tb = None
+
+def print_exc(file=None):
+    """Like :func:`traceback.print_exc` but prints the full stack.
 
-# from core.utils import VersionTooLow
-# from core import system
+    In addition to the stack frames between the exception and the point it is
+    caught, this prints the stack frames above the catching location.
+    """
+    try:
+        etype, value, tb = sys.exc_info()
+        print_exception(etype, value, tb, 3, file)
+    finally:
+        etype = value = tb = None
 
-################################################################################
+###############################################################################
 
 _warningformat = re.compile(
         '^(.+):'
@@ -66,7 +190,7 @@ class EmitWarnings(logging.Handler):
     def emit(self, record):
         # Here we basically do the contrary of warnings:formatwarning()
         m = _warningformat.match(record.args[0])
-        if m == None:
+        if m is None:
             self.logger.warning("(File info not available)\n" +
                            record.args[0])
         else:
@@ -75,9 +199,22 @@ class EmitWarnings(logging.Handler):
             self.logger.warning('%s, line %s\n%s: %s' % (filename, lineno,
                                                     category, message))
 
-################################################################################
+###############################################################################
+
+class LoggerHandler(logging.Handler):
+    """A logging Handler Handler re-logs on a specified Logger.
+    """
+    def __init__(self, logger):
+        logging.Handler.__init__(self)
+        self.logger = logger
+
+    def emit(self, record):
+        if self.logger.isEnabledFor(record.levelno):
+            self.logger.handle(record)
+
+###############################################################################
 
-class DebugPrint:
+class DebugPrint(object):
     """ Class to be used for debugging information.
 
     Verboseness can be set in the following way:
@@ -96,7 +233,7 @@ class DebugPrint:
     so it will only get information of who called the DebugPrint functions.
 
     Example of usage:
-        >>> from core import debug
+        >>> from vistrails.core import debug
         >>> debug.DebugPrint.getInstance().set_message_level(
                     debug.DebugPrint.WARNING)
         # the following messages will be shown
@@ -112,25 +249,23 @@ class DebugPrint:
                                        logging.DEBUG) # python logging levels
     #Singleton technique
     _instance = None
-    class DebugPrintSingleton():
-        def __call__(self, *args, **kw):
-            if DebugPrint._instance is None:
-                obj = DebugPrint(*args, **kw)
-                DebugPrint._instance = obj
-            return DebugPrint._instance
-
-    getInstance = DebugPrintSingleton()
+    @staticmethod
+    def getInstance(*args, **kwargs):
+        if DebugPrint._instance is None:
+            DebugPrint._instance = DebugPrint(*args, **kwargs)
+        return DebugPrint._instance
 
     def make_logger(self, f=None):
         self.fhandler = None
-        """self.make_logger_240(file) -> logger. Creates a logging object to
+        """self.make_logger(file) -> logger. Creates a logging object to
         be used within the DebugPrint class that sends the debugging
         output to file.
         We will configure log so it outputs to both stderr and a file.
 
         """
-        # Setup root logger
-        self.logger = logging.getLogger('VisLog')
+        # Internal logger, the one we log on
+        self.logger = logging.getLogger('vistrails.logger')
+
         self.logger.setLevel(logging.DEBUG)
         self.format = logging.Formatter("%(asctime)s %(levelname)s:\n%(message)s")
 
@@ -145,14 +280,16 @@ class DebugPrint:
         if f:
             self.set_logfile(f)
 
-        #then we define a handler to log to the console
+        # Then we define a handler to log to the console
         self.console = logging.StreamHandler()
         self.console.setFormatter(self.format)
-        self.console.setLevel(logging.WARNING)
-        self.logger.addHandler(self.console)
+        self.console.setLevel(logging.DEBUG)
 
-#    if system.python_version() <= (2,4,0,'',0):
-#        raise VersionTooLow('Python', '2.4.0')
+        # We also propagate to a second logger, that API users might want to
+        # configure
+        self.visible_logger = logging.getLogger('vistrails')
+        self.logger.propagate = False
+        self.logger.addHandler(LoggerHandler(self.visible_logger))
 
     def __init__(self):
         self.make_logger()
@@ -211,13 +348,19 @@ class DebugPrint:
             self.logger.addHandler(handler)
 
         except Exception, e:
-            self.critical("Could not set log file %s: %s"%(f,str(e)))
+            self.critical("Could not set log file %s:" % f, e)
+
+    def log_to_console(self, enable=True):
+        if enable:
+            logging.getLogger().addHandler(self.console)
+        else:
+            logging.getLogger().removeHandler(self.console)
 
     def set_message_level(self,level):
         """self.set_message_level(level) -> None. Sets the logging
         verboseness.  level must be one of (DebugPrint.CRITICAL,
         DebugPrint.WARNING, DebugPrint.INFO, DebugPrint.DEBUG)."""
-        self.console.setLevel(level)
+        self.visible_logger.setLevel(level)
 
     def register_splash(self, app):
         """ register_splash(self, classname)
@@ -232,12 +375,17 @@ class DebugPrint:
         if self.app:
             self.app.splashMessage(msg)
 
-    def message(self, caller, msg, details=''):
-        """self.message(caller, str, str) -> str. Returns a string with a
+    def message(self, caller, msg, *details):
+        """self.message(caller, str, ...) -> str. Returns a string with a
         formatted message to be send to the debugging output. This
         should not be called explicitly from userland. Consider using
         self.log(), self.warning() or self.critical() instead."""
-        msg = (msg + '\n' + details) if details else msg
+        for d in details:
+            if isinstance(d, Exception):
+                d = format_exception(d)
+                msg = '%s\n%s' % (msg, d)
+            else:
+                msg = '%s\n%s' % (msg, d)
         source = inspect.getsourcefile(caller)
         line = caller.f_lineno
         if source and line:
@@ -245,29 +393,29 @@ class DebugPrint:
         else:
             return "(File info not available)\n" + msg
 
-    def debug(self, msg, details = ''):
-        """self.log(str, str) -> None. Send information message (low
+    def debug(self, msg, *details):
+        """self.log(str, ...) -> None. Send information message (low
         importance) to log with appropriate call site information."""
         caller = inspect.currentframe().f_back # who called us?
-        self.logger.debug(self.message(caller, msg, details))
+        self.logger.debug(self.message(caller, msg, *details))
 
-    def log(self, msg, details = ''):
-        """self.log(str, str) -> None. Send information message (low
+    def log(self, msg, *details):
+        """self.log(str, ...) -> None. Send information message (low
         importance) to log with appropriate call site information."""
         caller = inspect.currentframe().f_back # who called us?
-        self.logger.info(self.message(caller, msg, details))
+        self.logger.info(self.message(caller, msg, *details))
 
-    def warning(self, msg, details = ''):
-        """self.warning(str, str) -> None. Send warning message (medium
+    def warning(self, msg, *details):
+        """self.warning(str, ...) -> None. Send warning message (medium
         importance) to log with appropriate call site information."""
         caller = inspect.currentframe().f_back # who called us?
-        self.logger.warning(self.message(caller, msg, details))
+        self.logger.warning(self.message(caller, msg, *details))
 
-    def critical(self, msg, details = ''):
-        """self.critical(str, str) -> None. Send critical message (high
+    def critical(self, msg, *details):
+        """self.critical(str, ...) -> None. Send critical message (high
         importance) to log with appropriate call site information."""
         caller = inspect.currentframe().f_back # who called us?
-        self.logger.critical(self.message(caller, msg, details))
+        self.logger.critical(self.message(caller, msg, *details))
 
 splashMessage = DebugPrint.getInstance().splashMessage
 critical = DebugPrint.getInstance().critical
@@ -280,13 +428,12 @@ debug    = DebugPrint.getInstance().debug
 #   log : shown if -V 1
 #   debug : shown if -V 2
 
-################################################################################
+###############################################################################
 
 def timecall(method):
     """timecall is a method decorator that wraps any call in timing calls
     so we get the total time taken by a function call as a debugging message."""
     def call(self, *args, **kwargs):
-        caller = inspect.currentframe().f_back
         start = time.time()
         method(self, *args, **kwargs)
         end = time.time()
@@ -294,7 +441,7 @@ def timecall(method):
     call.__doc__ = method.__doc__
     return call
 
-################################################################################
+###############################################################################
 
 def object_at(desc):
     """object_at(id) -> object
@@ -307,8 +454,68 @@ def object_at(desc):
         target_id = desc
     elif isinstance(desc, basestring):
         target_id = int(desc, 16) # Reads desc as the hex address
+    else:
+        raise TypeError
     import gc
     for obj in gc.get_objects():
         if id(obj) == target_id:
             return obj
     raise KeyError("Couldn't find object")
+
+###############################################################################
+
+import unittest
+
+class TestStack(unittest.TestCase):
+    @staticmethod
+    def do_in_stack(catch_, raise_):
+        def a():
+            b()
+        def b():
+            c()
+        def c():
+            catch_(d)
+        def d():
+            e()
+        def e():
+            raise_()
+        a()
+
+    def test_print_exc(self):
+        import itertools
+        from StringIO import StringIO
+
+        sio = StringIO()
+
+        def catch_(d):
+            try:
+                d()
+            except RuntimeError:
+                return print_exc(file=sio)
+
+        def raise_():
+            raise RuntimeError("message here")
+
+        self.do_in_stack(catch_, raise_)
+        result = sio.getvalue().splitlines()
+        expected = (
+r'^ +a\(\)',
+r'^  File .+, line \d+, in a',
+r'^    b\(\)',
+r'^  File .+, line \d+, in b',
+r'^    c\(\)',
+r'^  File .+, line \d+, in c',
+r'^    catch_\(d\)',
+r'^--- Exception caught here ---',
+r'^  File .+, line \d+, in catch_',
+r'^    d\(\)',
+r'^  File .+, line \d+, in d',
+r'^    e\(\)',
+r'^  File .+, line \d+, in e',
+r'^    raise_\(\)',
+r'^  File .+, line \d+, in raise_',
+r'^    raise RuntimeError\("message here"\)',
+r'^RuntimeError: message here')
+        for a, e in itertools.izip(result[-len(expected):], expected):
+            self.assertIsNotNone(re.search(e, a),
+                                 "%r doesn't match %r" % (a, e))
diff --git a/vistrails/core/external_connection.py b/vistrails/core/external_connection.py
index 277e18b..8c18a82 100644
--- a/vistrails/core/external_connection.py
+++ b/vistrails/core/external_connection.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -40,6 +41,8 @@ classes:
  - DBConnection
  - ExtConnectionList
 """
+from __future__ import division
+
 import os
 import tempfile
 import unittest
@@ -143,7 +146,7 @@ class DBConnection(ExtConnection):
         operator. 
         
         """
-        if other == None:
+        if other is None:
             return False
         if self.type != other.type:
             return False
@@ -175,14 +178,12 @@ class ExtConnectionList(XMLWrapper):
 
     """
     _instance = None
-    class ExtConnectionListSingleton(object):
-        def __call__(self, *args, **kw):
-            if ExtConnectionList._instance is None:
-                obj = ExtConnectionList(*args, **kw)
-                ExtConnectionList._instance = obj
-            return ExtConnectionList._instance
-    
-    getInstance = ExtConnectionListSingleton()
+    @staticmethod
+    def getInstance(*args, **kwargs):
+        if ExtConnectionList._instance is None:
+            obj = ExtConnectionList(*args, **kwargs)
+            ExtConnectionList._instance = obj
+        return ExtConnectionList._instance
     
     def __init__(self, filename=''):
         """ __init__() -> ExtConnectionList """
diff --git a/vistrails/core/inspector.py b/vistrails/core/inspector.py
index 6533e04..d8525f0 100644
--- a/vistrails/core/inspector.py
+++ b/vistrails/core/inspector.py
@@ -1,42 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Helper classes for inspecting vistrails/pipelines at runtime"""
-from vistrails.core.vistrail.pipeline import Pipeline
+from __future__ import division
+
 from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.system import get_vistrails_default_pkg_prefix
 ################################################################################
 
 class PipelineInspector(object):
@@ -157,8 +158,7 @@ class PipelineInspector(object):
             if root_id is None:
                 root_id = []
             # Sometimes we run without the spreadsheet!
-            spreadsheet_pkg = \
-                '%s.spreadsheet' % get_vistrails_default_pkg_prefix()
+            spreadsheet_pkg = 'org.vistrails.vistrails.spreadsheet'
             if registry.has_module(spreadsheet_pkg, 'SpreadsheetCell'):
                 # First pass to check cells types
                 cellType = \
diff --git a/vistrails/core/interpreter/__init__.py b/vistrails/core/interpreter/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/interpreter/__init__.py
+++ b/vistrails/core/interpreter/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/interpreter/base.py b/vistrails/core/interpreter/base.py
index d0fc06c..ef60f54 100644
--- a/vistrails/core/interpreter/base.py
+++ b/vistrails/core/interpreter/base.py
@@ -1,49 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.core.data_structures.graph import Graph
-from vistrails.core.utils import expression
-from vistrails.core.utils import trace_method
+from __future__ import division
+
 from vistrails.core import debug
 import copy
-import parser
 
 ##############################################################################
 
 class InternalTuple(object):
     """Tuple used internally for constant tuples."""
 
+    list_depth = 0
+
     def _get_length(self, length):
         return len(self._values)
     def _set_length(self, length):
@@ -145,18 +146,20 @@ class BaseInterpreter(object):
 
     def evaluate_exp(self, atype, base, exps, aliases):
         # FIXME: eval should pretty much never be used
-        import datetime        
-        for e in exps: base = (base[:e[0]] +
-                               str(eval(e[1],
-                                        {'datetime':locals()['datetime']},
-                                        aliases)) +
-                               base[e[0]:])
+        import datetime
+        for e in exps:
+            base = (
+                    base[:e[0]] + str(eval(
+                        e[1],
+                        {'datetime': locals()['datetime']},
+                        aliases)) +
+                    base[e[0]:])
         if not atype in ['string', 'String']:
             if base=='':
                 base = '0'
             try:
-                base = eval(base,None,None)
-            except:
+                base = eval(base)
+            except Exception:
                 pass
         return base
 
@@ -208,7 +211,7 @@ class BaseInterpreter(object):
                     param = pipeline.db_get_object(vttype,oId)
                     param.strValue = str(strval)
                 except Exception, e:
-                    debug.debug("Problem when updating params: %s"%str(e))
+                    debug.debug("Problem when updating params", e)
 
     def resolve_variables(self, vistrail_variables, pipeline):
         for m in pipeline.module_list:
diff --git a/vistrails/core/interpreter/cached.py b/vistrails/core/interpreter/cached.py
index da79517..65e89d7 100644
--- a/vistrails/core/interpreter/cached.py
+++ b/vistrails/core/interpreter/cached.py
@@ -1,61 +1,202 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
+from __future__ import division
+
 import base64
 import copy
-import cPickle
 import gc
+import cPickle as pickle
 
-from vistrails.core.common import InstanceObject, lock_method, \
-    VistrailsInternalError
+from vistrails.core.common import InstanceObject, VistrailsInternalError
 from vistrails.core.data_structures.bijectivedict import Bidict
+from vistrails.core import debug
 import vistrails.core.interpreter.base
 from vistrails.core.interpreter.base import AbortExecution
 import vistrails.core.interpreter.utils
 from vistrails.core.log.controller import DummyLogController
-from vistrails.core.modules.basic_modules import identifier as basic_pkg
+from vistrails.core.modules.basic_modules import identifier as basic_pkg, \
+                                                 Generator
 from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.modules.vistrails_module import ModuleConnector, \
-    ModuleHadError, ModuleError, ModuleBreakpoint, ModuleErrors, \
-    ModuleWasSuspended
+from vistrails.core.modules.vistrails_module import ModuleBreakpoint, \
+    ModuleConnector, ModuleError, ModuleErrors, ModuleHadError, \
+    ModuleSuspended, ModuleWasSuspended
 from vistrails.core.utils import DummyView
 import vistrails.core.system
 import vistrails.core.vistrail.pipeline
 
-# from core.modules.module_utils import FilePool
 
-##############################################################################
+###############################################################################
+
+class ViewUpdatingLogController(object):
+    class Loop(object):
+        def __init__(self, logger, view):
+            self.log = logger
+            self.view = view
+
+        def end_loop_execution(self):
+            self.log.finish_loop_execution()
+
+        def begin_iteration(self, looped_obj, iteration):
+            self.log.start_iteration(looped_obj, iteration)
+
+        def end_iteration(self, looped_obj):
+            self.log.finish_iteration(looped_obj)
+
+    def __init__(self, logger, view, remap_id, ids,
+                 module_executed_hook=[]):
+        self.log = logger
+        self.view = view
+        self.remap_id = remap_id
+        self.ids = set(ids) # modules left to be executed
+        self.nb_modules = len(self.ids)
+        self.module_executed_hook = module_executed_hook
+
+        self.errors = {}
+        self.executed = {}
+        self.suspended = {}
+        self.cached = {}
+
+    def signalSuccess(self, obj):
+        self.executed[obj.id] = True
+        for callable_ in self.module_executed_hook:
+            callable_(obj.id)
+
+    def signalError(self, obj, error):
+        self.errors[obj.id] = error
+
+    def begin_update(self, obj):
+        i = self.remap_id(obj.id)
+        self.view.set_module_active(i)
+
+    def begin_compute(self, obj):
+        i = self.remap_id(obj.id)
+        self.view.set_module_computing(i)
+
+        reg = get_module_registry()
+        module_name = reg.get_descriptor(obj.__class__).name
+
+        self.log.start_execution(obj, i, module_name)
+
+    def update_progress(self, obj, progress=0.0):
+        i = self.remap_id(obj.id)
+        self.view.set_module_progress(i, progress)
+
+    def begin_loop_execution(self, obj, total_iterations=None):
+        return ViewUpdatingLogController.Loop(
+                self.log.start_loop_execution(obj, total_iterations),
+                self.view)
+
+    def _handle_suspended(self, obj, error):
+        """ _handle_suspended(obj: VistrailsModule, error: ModuleSuspended
+            ) -> None
+            Report module as suspended
+        """
+        # update job monitor because this may be an old-style job
+        jm = obj.job_monitor()
+        reg = get_module_registry()
+        name = reg.get_descriptor(obj.__class__).name
+        iteration = self.log.get_iteration_from_module(obj)
+        if iteration is not None:
+            name += '/%d' % iteration
+        # add to parent list for computing the module tree later
+        error.name = name
+        jm.addParent(error)
+
+    def end_update(self, obj, error=None, errorTrace=None,
+            was_suspended=False):
+        try:
+            i = self.remap_id(obj.id)
+        except KeyError:
+            # This happens with Groups: we get end_update for modules inside
+            # the Group, which we can't remap to the current pipeline
+            # It's ok, because that was already logged by the recursive
+            # execute_pipeline() call
+            return
+        if was_suspended:
+            self._handle_suspended(obj, error)
+            self.suspended[obj.id] = error
+            self.view.set_module_suspended(i, error)
+            if error.children:
+                for child in error.children:
+                    self.end_update(child.module, child, was_suspended=True)
+        elif error is None:
+            self.view.set_module_success(i)
+        else:
+            self.view.set_module_error(i, error)
+
+        if i in self.ids:
+            self.ids.remove(i)
+            self.view.set_execution_progress(
+                    1.0 - ((len(self.ids) + len(Generator.generators)) * 1.0 /
+                           (self.nb_modules + len(Generator.generators))))
+
+        msg = '' if error is None else error.msg
+        self.log.finish_execution(obj, msg, errorTrace,
+                                  was_suspended)
+
+    def update_cached(self, obj):
+        self.cached[obj.id] = True
+        i = self.remap_id(obj.id)
+
+        reg = get_module_registry()
+        module_name = reg.get_descriptor(obj.__class__).name
+
+        self.log.start_execution(obj, i, module_name,
+                                 cached=1)
+        self.view.set_module_not_executed(i)
+        self.log.finish_execution(obj, '')
+
+    def set_computing(self, obj):
+        i = self.remap_id(obj.id)
+        self.view.set_module_computing(i)
+
+    def annotate(self, obj, d):
+        self.log.insert_module_annotations(obj, d)
+
+    def add_machine(self, machine):
+        return self.log.add_machine(machine)
+
+    def add_exec(self, exec_):
+        return self.log.add_exec(exec_)
+
+###############################################################################
+
+Variant_desc = None
+InputPort_desc = None
 
 class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
 
@@ -70,16 +211,15 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         self._file_pool = FilePool()
         self._persistent_pipeline = vistrails.core.vistrail.pipeline.Pipeline()
         self._objects = {}
-        self._executed = {}
         self.filePool = self._file_pool
-        
+        self._streams = []
+
     def clear(self):
         self._file_pool.cleanup()
         self._persistent_pipeline.clear()
         for obj in self._objects.itervalues():
             obj.clear()
         self._objects = {}
-        self._executed = {}
 
     def __del__(self):
         self.clear()
@@ -103,12 +243,11 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         """clean_non_cacheable_modules() -> None
 
         Removes all modules that are not cacheable from the persistent
-        pipeline, and the modules that depend on them, and 
-        previously suspended modules """
+        pipeline, and the modules that depend on them.
+        """
         non_cacheable_modules = [i for
                                  (i, mod) in self._objects.iteritems()
-                                 if not mod.is_cacheable() or \
-                                 mod.suspended]
+                                 if not mod.is_cacheable()]
         self.clean_modules(non_cacheable_modules)
 
     def _clear_package(self, identifier):
@@ -122,6 +261,23 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
                    if mod.module_descriptor.identifier == identifier]
         self.clean_modules(modules)
 
+    def make_connection(self, conn, src, dst):
+        """make_connection(self, conn, src, dst)
+        Builds a execution-time connection between modules.
+
+        """
+        iport = conn.destination.name
+        oport = conn.source.name
+        src.enable_output_port(oport)
+        src.load_type_check_descs()
+        if isinstance(src, src.InputPort_desc.module):
+            typecheck = [False]
+        else:
+            typecheck = src.get_type_checks(conn.source.spec)
+        dst.set_input_port(iport,
+                           ModuleConnector(src, oport, conn.source.spec,
+                                           typecheck))
+
     def setup_pipeline(self, pipeline, **kwargs):
         """setup_pipeline(controller, pipeline, locator, currentVersion,
                           view, aliases, **kwargs)
@@ -129,12 +285,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         instances of modules that aren't in the cache.
         """
         def fetch(name, default):
-            r = kwargs.get(name, default)
-            try:
-                del kwargs[name]
-            except KeyError:
-                pass
-            return r
+            return kwargs.pop(name, default)
         controller = fetch('controller', None)
         locator = fetch('locator', None)
         current_version = fetch('current_version', None)
@@ -143,13 +294,14 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         aliases = fetch('aliases', None)
         params = fetch('params', None)
         extra_info = fetch('extra_info', None)
-        logger = fetch('logger', DummyLogController())
+        logger = fetch('logger', DummyLogController)
         sinks = fetch('sinks', None)
         reason = fetch('reason', None)
         actions = fetch('actions', None)
         done_summon_hooks = fetch('done_summon_hooks', [])
         module_executed_hook = fetch('module_executed_hook', [])
         stop_on_error = fetch('stop_on_error', True)
+        parent_exec = fetch('parent_exec', None)
 
         reg = get_module_registry()
 
@@ -159,7 +311,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
 
         def create_null():
             """Creates a Null value"""
-            getter = get_module_registry().get_descriptor_by_name
+            getter = reg.get_descriptor_by_name
             descriptor = getter(basic_pkg, 'Null')
             return descriptor.module()
         
@@ -209,7 +361,6 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
             obj = self._objects[persistent_id] = module.summon()
             obj.interpreter = self
             obj.id = persistent_id
-            obj.is_breakpoint = module.is_breakpoint
             obj.signature = module._signature
             
             # Checking if output should be stored
@@ -222,20 +373,22 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
             for f in module.functions:
                 connector = None
                 if len(f.params) == 0:
-                    connector = ModuleConnector(create_null(), 'value')
+                    connector = ModuleConnector(create_null(), 'value',
+                                                f.get_spec('output'))
                 elif len(f.params) == 1:
                     p = f.params[0]
                     try:
                         constant = create_constant(p, module)
-                        connector = ModuleConnector(constant, 'value')
-                    except ValueError, e:
-                        err = ModuleError(self, 'Cannot convert parameter '
-                                          'value "%s"\n' % p.strValue + str(e))
-                        errors[i] = err
-                        to_delete.append(obj.id)
+                        connector = ModuleConnector(constant, 'value',
+                                                    f.get_spec('output'))
                     except Exception, e:
-                        err = ModuleError(self, 'Uncaught exception: "%s"' % \
-                                              p.strValue + str(e))
+                        debug.unexpected_exception(e)
+                        err = ModuleError(
+                                module,
+                                "Uncaught exception creating Constant from "
+                                "%r: %s" % (
+                                p.strValue,
+                                debug.format_exception(e)))
                         errors[i] = err
                         to_delete.append(obj.id)
                 else:
@@ -245,20 +398,21 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
                         try:
                             constant = create_constant(p, module)
                             constant.update()
-                            connector = ModuleConnector(constant, 'value')
+                            connector = ModuleConnector(constant, 'value',
+                                                        f.get_spec('output'))
                             tupleModule.set_input_port(j, connector)
-                        except ValueError, e:
-                            err = ModuleError(self, "Cannot convert parameter "
-                                              "value '%s'\n" % p.strValue + \
-                                                  str(e))
-                            errors[i] = err
-                            to_delete.append(obj.id)
                         except Exception, e:
-                            err = ModuleError(self, 'Uncaught exception: '
-                                              '"%s"' % p.strValue + str(e))
+                            debug.unexpected_exception(e)
+                            err = ModuleError(
+                                    module,
+                                    "Uncaught exception creating Constant "
+                                    "from %r: %s" % (
+                                    p.strValue,
+                                    debug.format_exception(e)))
                             errors[i] = err
                             to_delete.append(obj.id)
-                    connector = ModuleConnector(tupleModule, 'value')
+                    connector = ModuleConnector(tupleModule, 'value',
+                                                f.get_spec('output'))
                 if connector:
                     obj.set_input_port(f.name, connector, is_method=True)
 
@@ -268,7 +422,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
             conn = self._persistent_pipeline.connections[persistent_id]
             src = self._objects[conn.sourceId]
             dst = self._objects[conn.destinationId]
-            conn.makeConnection(src, dst)
+            self.make_connection(conn, src, dst)
 
         if self.done_summon_hook:
             self.done_summon_hook(self._persistent_pipeline, self._objects)
@@ -284,12 +438,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
     def execute_pipeline(self, pipeline, tmp_id_to_module_map, 
                          persistent_to_tmp_id_map, **kwargs):
         def fetch(name, default):
-            r = kwargs.get(name, default)
-            try:
-                del kwargs[name]
-            except KeyError:
-                pass
-            return r
+            return kwargs.pop(name, default)
         controller = fetch('controller', None)
         locator = fetch('locator', None)
         current_version = fetch('current_version', None)
@@ -298,116 +447,30 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         aliases = fetch('aliases', None)
         params = fetch('params', None)
         extra_info = fetch('extra_info', None)
-        logger = fetch('logger', DummyLogController())
+        logger = fetch('logger', DummyLogController)
         sinks = fetch('sinks', None)
         reason = fetch('reason', None)
         actions = fetch('actions', None)
         module_executed_hook = fetch('module_executed_hook', [])
-        module_suspended_hook = fetch('module_suspended_hook', [])
         done_summon_hooks = fetch('done_summon_hooks', [])
         clean_pipeline = fetch('clean_pipeline', False)
         stop_on_error = fetch('stop_on_error', True)
-        # parent_exec = fetch('parent_exec', None)
+        parent_exec = fetch('parent_exec', None)
 
         if len(kwargs) > 0:
             raise VistrailsInternalError('Wrong parameters passed '
                                          'to execute_pipeline: %s' % kwargs)
 
-        errors = {}
-        executed = {}
-        suspended = {}
-        cached = {}
-
         # LOGGING SETUP
         def get_remapped_id(id):
             return persistent_to_tmp_id_map[id]
 
-        # the executed dict works on persistent ids
-        def add_to_executed(obj):
-            executed[obj.id] = True
-            for callable_ in module_executed_hook:
-                callable_(obj.id)
-
-        # the suspended dict works on persistent ids
-        def add_to_suspended(obj):
-            suspended[obj.id] = obj.suspended
-            for callable_ in module_suspended_hook:
-                callable_(obj.id)
-                
-        def set_computing(obj):
-            i = get_remapped_id(obj.id)
-            view.set_module_computing(i)
-
-        # views work on local ids
-        def begin_compute(obj):
-            i = get_remapped_id(obj.id)
-            view.set_module_computing(i)
-
-            reg = get_module_registry()
-            module_name = reg.get_descriptor(obj.__class__).name
-
-            # !!!self.parent_execs is mutated!!!
-            logger.start_execution(obj, i, module_name,
-                                   parent_execs=self.parent_execs)
-
-        # views and loggers work on local ids
-        def begin_update(obj):
-            i = get_remapped_id(obj.id)
-            view.set_module_active(i)
-
-        def update_cached(obj):
-            cached[obj.id] = True
-            i = get_remapped_id(obj.id)
-
-            reg = get_module_registry()
-            module_name = reg.get_descriptor(obj.__class__).name
-
-            # !!!self.parent_execs is mutated!!!
-            logger.start_execution(obj, i, module_name,
-                                   parent_execs=self.parent_execs,
-                                   cached=1)
-            view.set_module_not_executed(i)
-            num_pops = logger.finish_execution(obj,'', self.parent_execs)
-
-        # views and loggers work on local ids
-        def end_update(obj, error='', errorTrace=None, was_suspended = False):
-            i = get_remapped_id(obj.id)
-            if was_suspended:
-                view.set_module_suspended(i, error)
-                error = error.msg
-            elif not error:
-                view.set_module_success(i)
-            else:
-                view.set_module_error(i, error)
-
-            # !!!self.parent_execs is mutated!!!
-            logger.finish_execution(obj, error, self.parent_execs, errorTrace,
-                                    was_suspended)
-
-        # views and loggers work on local ids
-        def annotate(obj, d):
-            i = get_remapped_id(obj.id)
-            logger.insert_module_annotations(obj, d)
-
-        # views and loggers work on local ids
-        def update_progress(obj, percentage=0.0):
-            i = get_remapped_id(obj.id)
-            view.set_module_progress(i, percentage)
-            
-        def add_exec(exec_):
-            logger.add_exec(exec_, self.parent_execs)
-            
-        logging_obj = InstanceObject(signalSuccess=add_to_executed,
-                                     signalSuspended=add_to_suspended,
-                                     begin_update=begin_update,
-                                     begin_compute=begin_compute,
-                                     update_progress=update_progress,
-                                     end_update=end_update,
-                                     update_cached=update_cached,
-                                     set_computing=set_computing,
-                                     add_exec = add_exec,
-                                     annotate=annotate,
-                                     log=logger)
+        logging_obj = ViewUpdatingLogController(
+                logger=logger,
+                view=view,
+                remap_id=get_remapped_id,
+                ids=pipeline.modules.keys(),
+                module_executed_hook=module_executed_hook)
 
         # PARAMETER CHANGES SETUP
         parameter_changes = []
@@ -419,6 +482,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
 
         # Update **all** modules in the current pipeline
         for i, obj in tmp_id_to_module_map.iteritems():
+            obj.in_pipeline = True # set flag to indicate in pipeline
             obj.logging = logging_obj
             obj.change_parameter = make_change_parameter(obj)
             
@@ -446,6 +510,9 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
             persistent_sinks = [tmp_id_to_module_map[sink]
                                 for sink in pipeline.graph.sinks()]
 
+        self._streams.append(Generator.generators)
+        Generator.generators = []
+
         # Update new sinks
         for obj in persistent_sinks:
             abort = False
@@ -458,22 +525,61 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
                 pass
             except AbortExecution:
                 break
+            except ModuleSuspended, ms:
+                ms.module.logging.end_update(ms.module, ms,
+                                             was_suspended=True)
+                continue
             except ModuleErrors, mes:
                 for me in mes.module_errors:
-                    me.module.logging.end_update(me.module, me.msg)
-                    errors[me.module.id] = me
+                    me.module.logging.end_update(me.module, me)
+                    logging_obj.signalError(me.module, me)
                     abort = abort or me.abort
             except ModuleError, me:
-                me.module.logging.end_update(me.module, me.msg, me.errorTrace)
-                errors[me.module.id] = me
+                me.module.logging.end_update(me.module, me, me.errorTrace)
+                logging_obj.signalError(me.module, me)
                 abort = me.abort
             except ModuleBreakpoint, mb:
                 mb.module.logging.end_update(mb.module)
-                errors[mb.module.id] = mb
+                logging_obj.signalError(mb.module, mb)
                 abort = True
             if stop_on_error or abort:
                 break
 
+        # execute all generators until inputs are exhausted
+        # this makes sure branching and multiple sinks are executed correctly
+        if not logging_obj.errors and not logging_obj.suspended and \
+                                                          Generator.generators:
+            result = True
+            abort = False
+            while result is not None:
+                try:
+                    for m in Generator.generators:
+                        result = m.generator.next()
+                    continue
+                except AbortExecution:
+                    break
+                except ModuleErrors, mes:
+                    for me in mes.module_errors:
+                        me.module.logging.end_update(me.module, me)
+                        logging_obj.signalError(me.module, me)
+                        abort = abort or me.abort
+                except ModuleError, me:
+                    me.module.logging.end_update(me.module, me, me.errorTrace)
+                    logging_obj.signalError(me.module, me)
+                    abort = me.abort
+                except ModuleBreakpoint, mb:
+                    mb.module.logging.end_update(mb.module)
+                    logging_obj.signalError(mb.module, mb)
+                    abort = True
+                except Exception, e:
+                    import traceback
+                    traceback.print_exc()
+                    abort = True
+                if stop_on_error or abort:
+                    break
+
+        Generator.generators = self._streams.pop()
+
         if self.done_update_hook:
             self.done_update_hook(self._persistent_pipeline, self._objects)
                 
@@ -493,17 +599,23 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
             if clean_pipeline:
                 to_delete.append(obj.id)
             objs[tmp_id] = obj
-            if obj.id in errors:
-                errs[tmp_id] = errors[obj.id]
+            if obj.id in logging_obj.errors:
+                errs[tmp_id] = logging_obj.errors[obj.id]
                 if not clean_pipeline:
                     to_delete.append(obj.id)
-            if obj.id in executed:
-                execs[tmp_id] = executed[obj.id]
-            elif obj.id in suspended:
-                suspends[tmp_id] = suspended[obj.id]
-            elif obj.id in cached:
-                caches[tmp_id] = cached[obj.id]
-            else:
+            executed = False
+            if obj.id in logging_obj.executed:
+                execs[tmp_id] = logging_obj.executed[obj.id]
+                executed = True
+            if obj.id in logging_obj.suspended:
+                suspends[tmp_id] = logging_obj.suspended[obj.id]
+                if not clean_pipeline:
+                    to_delete.append(obj.id)
+                executed = True
+            if obj.id in logging_obj.cached:
+                caches[tmp_id] = logging_obj.cached[obj.id]
+                executed = True
+            if not executed:
                 # these modules didn't execute
                 execs[tmp_id] = False
 
@@ -512,59 +624,24 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
     def finalize_pipeline(self, pipeline, to_delete, objs, errs, execs,
                           suspended, cached, **kwargs):
         def fetch(name, default):
-            r = kwargs.get(name, default)
-            try:
-                del kwargs[name]
-            except KeyError:
-                pass
-            return r
-        view = fetch('view', DummyView())
+            return kwargs.pop(name, default)
         reset_computed = fetch('reset_computed', True)
-     
+        view = fetch('view', None)
+
         self.clean_modules(to_delete)
 
-        for i in objs:
-            if i in errs:
-                view.set_module_error(i, errs[i].msg, errs[i].errorTrace)
-            elif i in suspended and suspended[i]:
-                view.set_module_suspended(i, suspended[i])
-            elif i in execs and execs[i]:
-                view.set_module_success(i)
-            elif i in cached and cached[i]:
-                view.set_module_not_executed(i)
-            else:
+        def dict2set(s):
+            return set(k for k, v in s.iteritems() if v)
+        if view is not None:
+            persistent = set(objs) - (dict2set(errs) | dict2set(execs) |
+                                      dict2set(suspended) | dict2set(cached))
+            for i in persistent:
                 view.set_module_persistent(i)
 
         if reset_computed:
             for module in self._objects.itervalues():
                 module.computed = False
 
-    def unlocked_execute(self, pipeline, **kwargs):
-        """unlocked_execute(pipeline, **kwargs): Executes a pipeline using
-        caching. Caching works by reusing pipelines directly.  This
-        means that there exists one global pipeline whose parts get
-        executed over and over again. This allows nested execution."""
-
-        res = self.setup_pipeline(pipeline, **kwargs)
-        modules_added = res[2]
-        conns_added = res[3]
-        to_delete = res[4]
-        errors = res[5]
-        if len(errors) == 0:
-            res = self.execute_pipeline(pipeline, *(res[:2]), **kwargs)
-        else:
-            res = (to_delete, res[0], errors, {}, {}, {}, [])
-        self.finalize_pipeline(pipeline, *(res[:-1]), **kwargs)
-        
-        return InstanceObject(objects=res[1],
-                              errors=res[2],
-                              executed=res[3],
-                              suspended=res[4],
-                              parameter_changes=res[6],
-                              modules_added=modules_added,
-                              conns_added=conns_added)
-
-    @lock_method(vistrails.core.interpreter.utils.get_interpreter_lock())
     def execute(self, pipeline, **kwargs):
         """execute(pipeline, **kwargs):
 
@@ -576,7 +653,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
           aliases = fetch('aliases', None)
           params = fetch('params', None)
           extra_info = fetch('extra_info', None)
-          logger = fetch('logger', DummyLogController())
+          logger = fetch('logger', DummyLogController)
           reason = fetch('reason', None)
           actions = fetch('actions', None)
           done_summon_hooks = fetch('done_summon_hooks', [])
@@ -606,12 +683,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         # that positional parameter calls fail earlier
         new_kwargs = {}
         def fetch(name, default):
-            r = kwargs.get(name, default)
-            new_kwargs[name] = r
-            try:
-                del kwargs[name]
-            except KeyError:
-                pass
+            new_kwargs[name] = r = kwargs.pop(name, default)
             return r
         controller = fetch('controller', None)
         locator = fetch('locator', None)
@@ -621,20 +693,21 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         aliases = fetch('aliases', None)
         params = fetch('params', None)
         extra_info = fetch('extra_info', None)
-        logger = fetch('logger', DummyLogController())
+        logger = fetch('logger', DummyLogController)
         sinks = fetch('sinks', None)
         reason = fetch('reason', None)
         actions = fetch('actions', None)
         done_summon_hooks = fetch('done_summon_hooks', [])
         module_executed_hook = fetch('module_executed_hook', [])
         stop_on_error = fetch('stop_on_error', True)
+        parent_exec = fetch('parent_exec', None)
 
         if len(kwargs) > 0:
             raise VistrailsInternalError('Wrong parameters passed '
                                          'to execute: %s' % kwargs)
-
         self.clean_non_cacheable_modules()
 
+
 #         if controller is not None:
 #             vistrail = controller.vistrail
 #             (pipeline, module_remap) = \
@@ -648,12 +721,34 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         else:
             vistrail = None
 
-        self.parent_execs = [None]
-        logger.start_workflow_execution(vistrail, pipeline, current_version)
+        logger = logger.start_workflow_execution(
+                parent_exec,
+                vistrail, pipeline, current_version)
+        new_kwargs['logger'] = logger
         self.annotate_workflow_execution(logger, reason, aliases, params)
-        result = self.unlocked_execute(pipeline, **new_kwargs)
+
+        res = self.setup_pipeline(pipeline, **new_kwargs)
+        modules_added = res[2]
+        conns_added = res[3]
+        to_delete = res[4]
+        errors = res[5]
+        if len(errors) == 0:
+            res = self.execute_pipeline(pipeline, *(res[:2]), **new_kwargs)
+        else:
+            res = (to_delete, res[0], errors, {}, {}, {}, [])
+            for (i, error) in errors.iteritems():
+                view.set_module_error(i, error)
+        self.finalize_pipeline(pipeline, *(res[:-1]), **new_kwargs)
+
+        result = InstanceObject(objects=res[1],
+                              errors=res[2],
+                              executed=res[3],
+                              suspended=res[4],
+                              parameter_changes=res[6],
+                              modules_added=modules_added,
+                              conns_added=conns_added)
+
         logger.finish_workflow_execution(result.errors, suspended=result.suspended)
-        self.parent_execs = [None]
 
         return result
 
@@ -667,9 +762,9 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         d = {}
         d["__reason__"] = reason
         if aliases is not None and isinstance(aliases, dict):
-            d["__aliases__"] = cPickle.dumps(aliases)
+            d["__aliases__"] = pickle.dumps(aliases)
         if params is not None and isinstance(params, list):
-            d["__params__"] = cPickle.dumps(params)
+            d["__params__"] = pickle.dumps(params)
         logger.insert_workflow_exec_annotations(d)
         
     def add_to_persistent_pipeline(self, pipeline):
@@ -783,7 +878,7 @@ class CachedInterpreter(vistrails.core.interpreter.base.BaseInterpreter):
         if CachedInterpreter.__instance:
             CachedInterpreter.__instance._clear_package(identifier)
 
-##############################################################################
+###############################################################################
 # Testing
 
 import unittest
@@ -792,42 +887,49 @@ import unittest
 class TestCachedInterpreter(unittest.TestCase):
 
     def test_cache(self):
-        from vistrails.core.db.locator import XMLFileLocator
-        from vistrails.core.vistrail.controller import VistrailController
-        from vistrails.core.db.io import load_vistrail
-        
-        """Test if basic caching is working."""
-        locator = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
-                            '/tests/resources/dummy.xml')
-        (v, abstractions, thumbnails, mashups) = load_vistrail(locator)
-        
-        # the controller will take care of upgrades
-        controller = VistrailController(v, locator, abstractions, thumbnails, 
-                                        mashups)
-        p1 = v.getPipeline('int chain')
-        n = v.get_version_number('int chain')
-        controller.change_selected_version(n)
-        controller.flush_delayed_actions()
-        p1 = controller.current_pipeline
-        
-        view = DummyView()
-        interpreter = vistrails.core.interpreter.cached.CachedInterpreter.get()
-        result = interpreter.execute(p1, 
-                                     locator=v,
-                                     current_version=n,
-                                     view=view,
-                                     )
-        # to force fresh params
-        p2 = v.getPipeline('int chain')
-        controller.change_selected_version(n)
-        controller.flush_delayed_actions()
-        p2 = controller.current_pipeline
-        result = interpreter.execute(p2, 
-                                     locator=v,
-                                     current_version=n,
-                                     view=view,
-                                     )
-        assert len(result.modules_added) == 1
+        from vistrails.core.modules.basic_modules import StandardOutput
+        old_compute = StandardOutput.compute
+        StandardOutput.compute = lambda s: None
+
+        try:
+            from vistrails.core.db.locator import XMLFileLocator
+            from vistrails.core.vistrail.controller import VistrailController
+            from vistrails.core.db.io import load_vistrail
+
+            """Test if basic caching is working."""
+            locator = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
+                                '/tests/resources/dummy.xml')
+            (v, abstractions, thumbnails, mashups) = load_vistrail(locator)
+
+            # the controller will take care of upgrades
+            controller = VistrailController(v, locator, abstractions,
+                                            thumbnails,  mashups)
+            p1 = v.getPipeline('int chain')
+            n = v.get_version_number('int chain')
+            controller.change_selected_version(n)
+            controller.flush_delayed_actions()
+            p1 = controller.current_pipeline
+
+            view = DummyView()
+            interpreter = CachedInterpreter.get()
+            result = interpreter.execute(p1,
+                                         locator=v,
+                                         current_version=n,
+                                         view=view,
+                                         )
+            # to force fresh params
+            p2 = v.getPipeline('int chain')
+            controller.change_selected_version(n)
+            controller.flush_delayed_actions()
+            p2 = controller.current_pipeline
+            result = interpreter.execute(p2,
+                                         locator=v,
+                                         current_version=n,
+                                         view=view,
+                                         )
+            self.assertEqual(len(result.modules_added), 1)
+        finally:
+            StandardOutput.compute = old_compute
 
 
 if __name__ == '__main__':
diff --git a/vistrails/core/interpreter/default.py b/vistrails/core/interpreter/default.py
index d169973..615596f 100644
--- a/vistrails/core/interpreter/default.py
+++ b/vistrails/core/interpreter/default.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import vistrails.core.interpreter.cached
 import vistrails.core.interpreter.noncached
 
@@ -44,14 +47,14 @@ __default_interpreter = cached_interpreter
 ##############################################################################
 
 def set_cache_configuration(field, value):
-    assert field == 'useCache'
+    assert field == 'cache'
     if value:
         set_default_interpreter(cached_interpreter)
     else:
         set_default_interpreter(noncached_interpreter)
 
 def connect_to_configuration(configuration):
-    configuration.subscribe('useCache', set_cache_configuration)
+    configuration.subscribe('cache', set_cache_configuration)
 
 def get_default_interpreter():
     """Returns an instance of the default interpreter class."""
diff --git a/vistrails/core/interpreter/noncached.py b/vistrails/core/interpreter/noncached.py
index 2666b7d..e251e5a 100644
--- a/vistrails/core/interpreter/noncached.py
+++ b/vistrails/core/interpreter/noncached.py
@@ -1,50 +1,46 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.core import modules
-from vistrails.core.common import *
-from vistrails.core.data_structures.bijectivedict import Bidict
-from vistrails.core.modules.vistrails_module import ModuleConnector, ModuleError
-from vistrails.core.utils import DummyView
-import copy
+from __future__ import division
+
 import vistrails.core.interpreter.base
+import vistrails.core.interpreter.cached
 import vistrails.core.interpreter.utils
 import vistrails.core.vistrail.pipeline
 import atexit
 
-# from core.modules.module_utils import FilePool
-
 ################################################################################
 
 class Interpreter(vistrails.core.interpreter.cached.CachedInterpreter):
diff --git a/vistrails/core/interpreter/utils.py b/vistrails/core/interpreter/utils.py
index 2190f99..3cc08c9 100644
--- a/vistrails/core/interpreter/utils.py
+++ b/vistrails/core/interpreter/utils.py
@@ -1,42 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-
-import threading
-
-##############################################################################
-
-_lock = threading.Lock()
-def get_interpreter_lock():
-    return _lock
diff --git a/vistrails/core/keychain.py b/vistrails/core/keychain.py
index c0c2ccd..1f24da6 100644
--- a/vistrails/core/keychain.py
+++ b/vistrails/core/keychain.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -40,6 +41,8 @@ A value can only be retrieved by the same object that set it.
 Use this at your own risk!
 
 """
+from __future__ import division
+
 import inspect
 import os
 import sys
diff --git a/vistrails/core/layout/__init__.py b/vistrails/core/layout/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/layout/__init__.py
+++ b/vistrails/core/layout/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/layout/tree_layout.py b/vistrails/core/layout/tree_layout.py
index d38c6fd..484bc6d 100644
--- a/vistrails/core/layout/tree_layout.py
+++ b/vistrails/core/layout/tree_layout.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -52,7 +53,9 @@ The original paper is:
 
 """
 
-class TreeLW:
+from __future__ import division
+
+class TreeLW(object):
     """
     The input to the algorithm must be a tree
     in this format.
@@ -70,7 +73,7 @@ class TreeLW:
         self.nodes.append(newNode)
 
         # add
-        if parentNode != None:
+        if parentNode is not None:
             parentNode.addChild(newNode)
 
         # update max level
@@ -78,7 +81,7 @@ class TreeLW:
         return newNode
 
     def changeParentOfNodeWithNoParent(self, parentNode, childNode):
-        if childNode.parent != None:
+        if childNode.parent is not None:
             raise ValueError("Node already has a parent")
 
         parentNode.addChild(childNode)
@@ -88,12 +91,12 @@ class TreeLW:
         self.maxLevel = max(self.maxLevel, maxLevel)
 
     def __dfsUpdateLevel(self, node):
-        if node.parent == None:
+        if node.parent is None:
             node.level = 0
         else:
             node.level = node.parent.level + 1
         maxLevel = node.level
-        for child in node.childs:
+        for child in node.children:
             maxLevel = max(maxLevel, self.__dfsUpdateLevel(child))
         return maxLevel
 
@@ -131,7 +134,7 @@ class TreeLW:
             nodes.append(t.addNode(parent,width,height,i))
         return t            
 
-class KeepBoundingBox:
+class KeepBoundingBox(object):
     def __init__(self):
         self.minx = None
         self.miny = None
@@ -140,20 +143,20 @@ class KeepBoundingBox:
         self.size = 0
 
     def addPoint(self,x,y):
-        if self.minx == None or self.minx > x:
+        if self.minx is None or self.minx > x:
             self.minx = x
-        if self.miny == None or self.miny > y:
+        if self.miny is None or self.miny > y:
             self.miny = y
-        if self.maxx == None or self.maxx < x:
+        if self.maxx is None or self.maxx < x:
             self.maxx = x
-        if self.maxy == None or self.maxy < y:
+        if self.maxy is None or self.maxy < y:
             self.maxy = y
         self.size = self.size + 1
 
     def getBoundingBox(self):
         return [self.minx, self.miny, self.maxx-self.minx, self.maxy - self.miny]
 
-class NodeLW:
+class NodeLW(object):
     """
     Node of the tree with all the auxiliar
     variables needed to the LW algorithm.
@@ -168,7 +171,7 @@ class NodeLW:
         self.height = height
         self.object = object
 
-        self.childs = []
+        self.children = []
 
         self.parent = None
         self.index = 0
@@ -190,42 +193,42 @@ class NodeLW:
         self.y = 0
         
     def getNumChilds(self):
-        return len(self.childs)
+        return len(self.children)
         
     def hasChild(self):
-        return len(self.childs) > 0
+        return bool(self.children)
 
     def addChild(self, node):
-        self.childs.append(node)
-        node.index = len(self.childs) - 1
+        self.children.append(node)
+        node.index = len(self.children) - 1
         node.parent = self
         node.level = self.level + 1
 
     def isLeaf(self):
-        return len(self.childs) == 0
+        return not self.children
 
     def leftChild(self):
-        return self.childs[0]
+        return self.children[0]
 
     def rightChild(self):
-        return self.childs[len(self.childs)-1]
+        return self.children[-1]
 
     def leftSibling(self):
         if self.index > 0:
-            return self.parent.childs[self.index-1]
+            return self.parent.children[self.index-1]
         else:
             return None
 
     def leftMostSibling(self):
-        if self.parent != None:
-            return self.parent.childs[0]
+        if self.parent is not None:
+            return self.parent.children[0]
         else:
             return self
 
     def isSiblingOf(self, v):
-        return self.parent == v.parent and self.parent != None
+        return self.parent == v.parent and self.parent is not None
 
-class TreeLayoutLW:
+class TreeLayoutLW(object):
 
     """
     TreeLayoutLW: the LW stands for Linear Walker.
@@ -304,13 +307,13 @@ class TreeLayoutLW:
         if v.isLeaf():
             v.prelim = 0
             w = v.leftSibling()
-            if w != None:
+            if w is not None:
                 v.prelim = w.prelim + self.gap(w,v)
 
         else:
             
             defaultAncestor = v.leftChild()
-            for w in v.childs:
+            for w in v.children:
                 self.firstWalk(w)
                 defaultAncestor = self.apportion(w, defaultAncestor)
             self.executeShifts(v)
@@ -318,7 +321,7 @@ class TreeLayoutLW:
             midpoint = (v.leftChild().prelim + v.rightChild().prelim) / 2.0
 
             w = v.leftSibling()
-            if w != None:
+            if w is not None:
                 v.prelim = w.prelim + self.gap(w,v)
                 v.mod = v.prelim - midpoint
             else:
@@ -344,7 +347,7 @@ class TreeLayoutLW:
 
         """
         w = v.leftSibling()
-        if w != None:
+        if w is not None:
             # p stands for + or plus (right subtree)
             # m stands for - or minus (left subtree)
             # i stands for inside
@@ -358,7 +361,7 @@ class TreeLayoutLW:
             sop = vop.mod
             sim = vim.mod
             som = vom.mod
-            while self.nextRight(vim) != None and self.nextLeft(vip) != None:
+            while self.nextRight(vim) is not None and self.nextLeft(vip) is not None:
                 
                 vim = self.nextRight(vim)
                 vip = self.nextLeft(vip)
@@ -379,11 +382,11 @@ class TreeLayoutLW:
                 som += vom.mod
                 sop += vop.mod
 
-            if self.nextRight(vim) != None and self.nextRight(vop) == None:            
+            if self.nextRight(vim) is not None and self.nextRight(vop) is None:
                 vop.thread = self.nextRight(vim)
                 vop.mod += sim - sop
 
-            if self.nextLeft(vip) != None and self.nextLeft(vom) == None:            
+            if self.nextLeft(vip) is not None and self.nextLeft(vom) is None:
                 vom.thread = self.nextLeft(vip)
                 vom.mod += sip - som
                 defaultAncestor = v
@@ -414,7 +417,7 @@ class TreeLayoutLW:
         shift = 0
         change = 0
         for i in xrange(v.getNumChilds()-1,-1,-1):
-            w = v.childs[i]
+            w = v.children[i]
             w.prelim += shift
             w.mod += shift
             change += w.change
@@ -428,7 +431,7 @@ class TreeLayoutLW:
 
     def secondWalk(self,  v, m):
         v.x = v.prelim + m
-        for w in v.childs:
+        for w in v.children:
             self.secondWalk(w, m + v.mod)
 
 # graph
diff --git a/vistrails/core/layout/version_tree_layout.py b/vistrails/core/layout/version_tree_layout.py
index 4854381..cdd1edb 100644
--- a/vistrails/core/layout/version_tree_layout.py
+++ b/vistrails/core/layout/version_tree_layout.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,6 +38,8 @@ Interface Vistrails - TreeLayoutLW to align version trees.
 Originally written by Lauro D. Lins.
 
 """
+from __future__ import division
+
 from tree_layout import TreeLW, NodeLW, TreeLayoutLW
 from vistrails.core.data_structures.point import Point
 
@@ -143,12 +146,12 @@ class VistrailsTreeLayoutLW(object):
             mapTreeNodes[id] = tree.addNode(None,width,height,(id,tag))
 
         # preserve the order of the edges
-        # to add the childs to their parents
+        # to add the children to their parents
         for (parentId, childId) in edges:
             # print "add arc into tree %d -> %d" % (parentId, childId)
             parent = mapTreeNodes[parentId]
             child = mapTreeNodes[childId]
-#             if child.parent != None:
+#             if child.parent is not None:
 #                 print "child already has a parent!!! %d -> %d" % (parentId, childId)
 #                 raise ValueError("Node already has a parent")
             tree.changeParentOfNodeWithNoParent(parent, child)
diff --git a/vistrails/core/layout/workflow_layout.py b/vistrails/core/layout/workflow_layout.py
index 3b4e7e7..861e0bc 100644
--- a/vistrails/core/layout/workflow_layout.py
+++ b/vistrails/core/layout/workflow_layout.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,6 +40,8 @@ Originally written by Lauro D. Lins.
 
 ####################################################
 
+from __future__ import division
+
 def uniquify(seq, idfun=None): 
     # order preserving
     if idfun is None:
@@ -348,7 +351,7 @@ class Layers(object):
         # print "layers",self.layers
         
         if layer_number >= num_layers:
-           self.layers.extend([Layer(i) for i in xrange(num_layers,layer_number+1)])
+            self.layers.extend([Layer(i) for i in xrange(num_layers,layer_number+1)])
         
         layer = self.layers[layer_number]
         layer.addModule(module)
@@ -470,7 +473,7 @@ class WorkflowLayout(object):
         permutation = []
         while True:
             mod = iterator.next()
-            if mod == None:
+            if mod is None:
                 break
             permutation.append(mod)
         permutation.reverse()
diff --git a/vistrails/core/log/__init__.py b/vistrails/core/log/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/log/__init__.py
+++ b/vistrails/core/log/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/log/controller.py b/vistrails/core/log/controller.py
index bb44e6d..45205fe 100644
--- a/vistrails/core/log/controller.py
+++ b/vistrails/core/log/controller.py
@@ -1,40 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
+from __future__ import division
+
+import copy
+
+from vistrails.core import debug
 from vistrails.core.log.workflow_exec import WorkflowExec
 from vistrails.core.log.module_exec import ModuleExec
-from vistrails.core.log.loop_exec import LoopExec
+from vistrails.core.log.loop_exec import LoopExec, LoopIteration
 from vistrails.core.log.group_exec import GroupExec
 from vistrails.core.log.machine import Machine
 from vistrails.core.modules.sub_module import Group, Abstraction
@@ -43,113 +50,60 @@ from vistrails.core.vistrail.pipeline import Pipeline
 from vistrails.core.vistrail.vistrail import Vistrail
 import vistrails.core.system
 
+
+ at apply
 class DummyLogController(object):
     """DummyLogger is a class that has the entire interface for a logger
     but simply ignores the calls."""
-    def start_workflow_execution(self, *args, **kwargs): pass
+    def start_workflow_execution(self, *args, **kwargs): return self
+    def recursing(self, *args, **kwargs): return self
     def finish_workflow_execution(self, *args, **kwargs): pass
-    def create_module_exec(self, *args, **kwargs): pass
-    def create_group_exec(self, *args, **kwargs): pass
-    def create_loop_exec(self, *args, **kwargs): pass
+    def add_exec(self, *args, **kwargs): pass
     def start_execution(self, *args, **kwargs): pass
-    def finish_execution(self, *args, **kwargs): pass
-    def start_module_loop_execution(self, *args, **kwargs): pass
-    def finish_module_loop_execution(self, *args, **kwargs): pass
-    def start_group_loop_execution(self, *args, **kwargs): pass
-    def finish_group_loop_execution(self, *args, **kwargs): pass
-    def start_module_execution(self, *args, **kwargs): pass
-    def finish_module_execution(self, *args, **kwargs): pass
-    def start_group_execution(self, *args, **kwargs): pass
-    def finish_group_execution(self, *args, **kwargs): pass
-    def start_loop_execution(self, *args, **kwargs): pass
+    def start_loop_execution(self, *args, **kwargs): return self
     def finish_loop_execution(self, *args, **kwargs): pass
+    def start_iteration(self, *args, **kwargs): pass
+    def finish_iteration(self, *args, **kwargs): pass
+    def finish_execution(self, *args, **kwargs): pass
     def insert_module_annotations(self, *args, **kwargs): pass
     def insert_workflow_exec_annotations(self, *args, **kwargs): pass
-    def add_exec(self, *args, **kwargs): pass
+    def add_machine(self, *args, **kwargs): return -1
+    def get_iteration_from_module(self, *args, **kwargs): return None
+    def __call__(self): return self
 
-class LogControllerFactory(object):
-    _instance = None
-    class LogControllerFactorySingleton(object):
-        def __call__(self, *args, **kw):
-            if LogControllerFactory._instance is None:
-                obj = LogControllerFactory(*args, **kw)
-                LogControllerFactory._instance = obj
-            return LogControllerFactory._instance
-        
-    getInstance = LogControllerFactorySingleton()
-    
-    def __init__(self):
-        self.machine = Machine(id=-1,
-                               name=vistrails.core.system.current_machine(),
-                               os=vistrails.core.system.systemType,
-                               architecture=vistrails.core.system.current_architecture(),
-                               processor=vistrails.core.system.current_processor(),
-                               ram=vistrails.core.system.guess_total_memory())
-    
-    def create_logger(self, log):
-        return LogController(log, self.machine)
-
-LogControllerFactory.getInstance()
 
 class LogController(object):
-    def __init__(self, log, machine):
-        self.log = log
-        self.workflow_exec = None
-        self.machine = machine
-        to_add = True
-        for machine in self.log.machine_list:
-            if self.machine.equals_no_id(machine):
-                to_add = False
-                self.machine = machine
-        if to_add:
-            self.machine.id = self.log.id_scope.getNewId(Machine.vtType)
-            self.log.add_machine(self.machine)
-            
-    def start_workflow_execution(self, vistrail=None, pipeline=None, 
-                                 currentVersion=None):
-        if vistrail is not None:
-            parent_type = Vistrail.vtType
-            parent_id = vistrail.id
-        else:
-            parent_type = Pipeline.vtType
-            parent_id = pipeline.id
+    """The top-level log controller.
 
-        wf_exec_id = self.log.id_scope.getNewId(WorkflowExec.vtType)
-        if vistrail is not None:
-            session = vistrail.current_session
-        else:
-            session = None
-        self.workflow_exec = WorkflowExec(id=wf_exec_id,
-                                          user=vistrails.core.system.current_user(),
-                                          ip=vistrails.core.system.current_ip(),
-                                          vt_version= \
-                                              vistrails.core.system.vistrails_version(),
-                                          ts_start=vistrails.core.system.current_time(),
-                                          parent_type=parent_type,
-                                          parent_id=parent_id,
-                                          parent_version=currentVersion,
-                                          completed=0,
-                                          session=session)
-        self.log.add_workflow_exec(self.workflow_exec)
+    This holds a log.
+    """
+    _local_machine = None
 
-    def finish_workflow_execution(self, errors, suspended=False):
-        self.workflow_exec.ts_end = vistrails.core.system.current_time()
-        if suspended:
-            self.workflow_exec.completed = -2
-        elif len(errors) > 0:
-            self.workflow_exec.completed = -1
-        else:
-            self.workflow_exec.completed = 1
-            
-    def add_exec(self, exec_, parent_execs):
-        parent_exec = parent_execs[-1]
-        if parent_exec:
-            parent_exec.add_item_exec(exec_)
+    @classmethod
+    def get_local_machine(cls):
+        if cls._local_machine is None:
+            cls._local_machine = Machine(
+                    id=-1,
+                    name=vistrails.core.system.current_machine(),
+                    os=vistrails.core.system.systemType,
+                    architecture=vistrails.core.system.current_architecture(),
+                    processor=vistrails.core.system.current_processor(),
+                    ram=vistrails.core.system.guess_total_memory())
+        return copy.copy(cls._local_machine)
+
+    def __init__(self, log, machine=None):
+        self.log = log
+        self.module_execs = {}      # vistrails_module -> *Exec
+        self.parent_execs = {}      # vistrails_module -> *Exec
+        self.children_execs = {}    # vistrails_module -> [*Exec]
+        if machine is not None:
+            self.machine = machine
         else:
-            self.workflow_exec.add_item_exec(exec_)
+            self.machine = copy.copy(self.get_local_machine())
+            self.machine.id = self.log.id_scope.getNewId(Machine.vtType)
 
-    def create_module_exec(self, module, module_id, module_name,
-                           cached):
+    def _create_module_exec(self, module, module_id, module_name,
+                            cached):
         m_exec_id = self.log.id_scope.getNewId(ModuleExec.vtType)
         module_exec = ModuleExec(id=m_exec_id,
                                  machine_id=self.machine.id,
@@ -160,7 +114,7 @@ class LogController(object):
                                  completed=0)
         return module_exec
 
-    def create_group_exec(self, group, module_id, group_name, cached):
+    def _create_group_exec(self, group, module_id, group_name, cached):
         g_exec_id = self.log.id_scope.getNewId(GroupExec.vtType)
         if isinstance(group, Abstraction):
             group_type = 'SubWorkflow'
@@ -176,187 +130,266 @@ class LogController(object):
                                completed=0)
         return group_exec
 
-    def create_loop_exec(self, iteration):
+    def _create_loop_exec(self):
         l_exec_id = self.log.id_scope.getNewId(LoopExec.vtType)
         loop_exec = LoopExec(id=l_exec_id,
-                             iteration=iteration,
                              ts_start=vistrails.core.system.current_time())
         return loop_exec
 
-    def start_execution(self, module, module_id, module_name, parent_execs,
-                        cached=0):
-        parent_exec = parent_execs[-1]
-        if module.is_looping:
-            parent_exec = self.start_loop_execution(module, module_id, 
-                                                    module_name, 
-                                                    parent_exec, cached,
-                                                    module.loop_iteration)
-            parent_execs.append(parent_exec)
+    def start_workflow_execution(self, parent_exec,
+                                 vistrail=None, pipeline=None,
+                                 currentVersion=None):
+        """Signals the start of the execution of a pipeline.
+        """
+        return LogWorkflowExecController(self.log, self.machine, parent_exec,
+                                         vistrail, pipeline, currentVersion)
+
 
+class LogLoopController(object):
+    def __init__(self, controller, loop_exec, loop_module):
+        self.controller = controller
+        self.loop_exec = loop_exec
+        self.loop_module = loop_module
+
+    def _create_loop_iteration(self, iteration):
+        l_iteration_id = self.controller.log.id_scope.getNewId(
+                LoopIteration.vtType)
+        loop_iteration = LoopIteration(id=l_iteration_id,
+                                       ts_start=vistrails.core.system.current_time(),
+                                       iteration=iteration)
+        return loop_iteration
+
+    def finish_loop_execution(self):
+        """Signals that we are done looping.
+        """
+        self.loop_exec.ts_end = vistrails.core.system.current_time()
+        try:
+            execs = self.controller.children_execs[self.loop_module]
+            execs.discard(self.loop_exec)
+        except KeyError:
+            pass
+
+    def start_iteration(self, looped_module, iteration):
+        """Signals that we are executing a module as an iteration of the loop.
+        """
+        loop_iteration = self._create_loop_iteration(iteration)
+        self.loop_exec.add_loop_iteration(loop_iteration)
+        self.controller.parent_execs[looped_module] = loop_iteration
+
+    def finish_iteration(self, looped_module):
+        """Signals that the iteration is done.
+        """
+        loop_iteration = self.controller.parent_execs.get(looped_module)
+        assert loop_iteration is not None
+
+        loop_iteration.ts_end = vistrails.core.system.current_time()
+        loop_iteration.completed = 1
+
+
+class LogWorkflowController(LogController):
+    """A log controller for a specific workflow execution.
+
+    You get one of these by calling LogController#start_workflow_execution() or
+    LogWorkflowController#recursing(). You can then add execution items through
+    it.
+
+    How does this work:
+      * the interpreter sets a 'logging' attribute on summoned Module objects
+        before starting the execution. Through it, the module can log events.
+      * the interpreter directly uses the logger to record exceptions from the
+        pipeline
+      * while they are executing, the logger keeps a table mapping a Module to:
+         - module_execs has the execution entry for that module
+         - parent_execs is set via other modules to remember where the soon-to-
+           be-created module_exec should be added (for example, loop modules
+           and Group sets parent_exec on their dependent modules). If
+           parent_exec is not set, the parent exec or WorkflowExec will be used
+         - children_exec is a list of ongoing exec items, children of
+           module_exec, such as LoopExec. They are kept their to be marked as
+           finished with the same error as the module if it fails before they
+           end
+    """
+    def __init__(self, log, machine, parent_exec, workflow_exec):
+        super(LogWorkflowController, self).__init__(log, machine)
+        self.parent_exec = parent_exec
+        self.workflow_exec = workflow_exec
+
+    def recursing(self, parent_exec):
+        """Enters a recursing execution.
+
+        This returns a new log controller object for that execution context.
+        """
+        if parent_exec in self.module_execs:
+            parent_exec = self.module_execs[parent_exec]
+        return LogWorkflowController(self.log, self.machine, parent_exec,
+                                     self.workflow_exec)
+
+    def get_iteration_from_module(self, module):
+        """If executing this module as part of a loop, gets the iteration;
+
+        Else returns None. Used by the interpreter to know what failed when
+        getting an exception from a module.
+        """
+        try:
+            return self.parent_execs[module].iteration
+        except KeyError:
+            return None
+
+    def start_execution(self, module, module_id, module_name, cached=0):
+        """Signals the start of the execution of a module (before compute).
+        """
         if isinstance(module, Group):
-            ret = self.start_group_execution(module, module_id, module_name,
-                                             parent_exec, cached)
-            if ret is not None:
-                parent_execs.append(ret)
-        else:
-            ret = self.start_module_execution(module, module_id, module_name,
-                                              parent_exec, cached)
-            if ret is not None:
-                parent_execs.append(ret)
-        
-    def finish_execution(self, module, error, parent_execs, errorTrace=None,
-                         suspended=False):
-        if isinstance(module, Group):
-            if self.finish_group_execution(module, error, suspended):
-                parent_execs.pop()
+            module_exec = self._create_group_exec(module, module_id,
+                                                 module_name, cached)
         else:
-            if self.finish_module_execution(module, error, errorTrace, suspended):
-                parent_execs.pop()
-        if module.is_looping:
-            self.finish_loop_execution(module, error, parent_execs.pop(), suspended)
-
-    def start_module_execution(self, module, module_id, module_name,
-                               parent_exec, cached):
-        module_exec = self.create_module_exec(module, module_id,
-                                              module_name,
-                                              cached)
-        module.module_exec = module_exec
-        if parent_exec:
-            parent_exec.add_item_exec(module_exec)
+            module_exec = self._create_module_exec(module, module_id,
+                                                   module_name, cached)
+        if module in self.module_execs is not None:
+            debug.warning(
+                    "%s#start_execution(module=%r, module_id=%r, "
+                    "module_name=%r, cached=%r): module already has a "
+                    "module_exec! Overwriting" % (
+                    type(self).__name__,
+                    module, module_id, module_name, cached))
+        self.module_execs[module] = module_exec
+        for parent_exec in (self.parent_execs.get(module), self.parent_exec,
+                            self.workflow_exec):
+            if parent_exec is not None:
+                parent_exec.add_item_exec(module_exec)
+                return
+        assert False
+
+    def start_loop_execution(self, loop_module, total_iterations=None):
+        """Starts a loop.
+        """
+        loop_exec = self._create_loop_exec()
+        for parent_exec in (self.module_execs.get(loop_module),
+                            self.parent_exec):
+            if parent_exec is not None:
+                if isinstance(parent_exec, GroupExec):
+                    parent_exec.add_item_exec(loop_exec)
+                else:
+                    parent_exec.add_loop_exec(loop_exec)
+                break
         else:
-            self.workflow_exec.add_item_exec(module_exec)
-        if module.is_looping_module:
-            return module_exec
-        return None
-
-    def finish_module_execution(self, module, error, errorTrace=None,
-                                suspended=False):
-        if not hasattr(module,'module_exec'):
-            return False
-        module.module_exec.ts_end = vistrails.core.system.current_time()
+            self.workflow_exec.add_item_exec(loop_exec)
+        self.children_execs.setdefault(loop_module, set()).add(loop_exec)
+        return LogLoopController(self, loop_exec, loop_module)
+
+    def finish_execution(self, module, error, errorTrace=None, suspended=False):
+        """Signals the end of the execution of a module.
+
+        Called by a module after succeeded of suspended, or called by the
+        interpreter after an exception.
+        """
+        module_exec = self.module_execs.pop(module, None)
+        if module_exec is None:
+            # The module can finish execution without starting (if it was
+            # suspended, etc...)
+            return
+        module_exec.ts_end = vistrails.core.system.current_time()
         if suspended:
-            module.module_exec.completed = -2
-            module.module_exec.error = error
-        elif not error:
-            module.module_exec.completed = 1
-        else:
-            module.module_exec.completed = -1
-            module.module_exec.error = error
+            module_exec.completed = -2
+            module_exec.error = error
+        elif error:
+            module_exec.completed = -1
+            module_exec.error = error
             if errorTrace:
                 a_id = self.log.id_scope.getNewId(Annotation.vtType)
                 annotation = Annotation(id=a_id,
                                         key="errorTrace",
                                         value=errorTrace)
-                module.module_exec.add_annotation(annotation)
-        del module.module_exec
-        if module.is_looping_module:
-            return True
-
-    def start_group_execution(self, group, module_id, group_name,
-                              parent_exec, cached):
-        group_exec = self.create_group_exec(group, module_id,
-                                            group_name, cached)
-        group.group_exec = group_exec
-        if parent_exec:
-            parent_exec.add_item_exec(group_exec)
-        else:
-            self.workflow_exec.add_item_exec(group_exec)
-        return group_exec
-
-    def finish_group_execution(self, group, error, suspended=False):
-        if not hasattr(group,'group_exec'):
-            return False
-        group.group_exec.ts_end = vistrails.core.system.current_time()
-        if suspended:
-            group.group_exec.completed = -2
-            group.group_exec.error = error
-        elif not error:
-            group.group_exec.completed = 1
+                module_exec.add_annotation(annotation)
         else:
-#             if group.group_exec.module_execs and group.group_exec.\
-#                module_execs[-1].error:
-#                 error = 'Error in module execution with id %d.'%\
-#                         group.group_exec.module_execs[-1].id
-#             if group.group_exec.group_execs and group.group_exec.\
-#                group_execs[-1].error:
-#                 error = 'Error in group execution with id %d.'%\
-#                         group.group_exec.group_execs[-1].id
-            group.group_exec.completed = -1
-            group.group_exec.error = error
-        del group.group_exec
-        return True
-
-    def start_loop_execution(self, module, module_id, module_name, 
-                             parent_exec, cached, iteration):
-        loop_exec = self.create_loop_exec(iteration)
-        if parent_exec:
-            parent_exec.add_loop_exec(loop_exec)
-        else:
-            self.workflow_exec.add_item_exec(loop_exec)
-        return loop_exec
+            module_exec.completed = 1
 
-    def finish_loop_execution(self, module, error, loop_exec, suspended=True):
-        if not loop_exec:
-            return False
-        loop_exec.ts_end = vistrails.core.system.current_time()
-        if suspended:
-            loop_exec.completed = -2
-            loop_exec.error = error
-        elif not error:
-            loop_exec.completed = 1
-        else:
-            loop_exec.completed = -1
-            loop_exec.error = error
-        return True
-
-#         is_group = isinstance(module, Group)
-#         if is_group:
-#             module.group_exec.loop_execs[-1].ts_end = core.system.\
-#                                                       current_time()
-#             if not error:
-#                 module.group_exec.loop_execs[-1].completed = 1
-#             else:
-#                 if module.group_exec.loop_execs[-1].module_execs and\
-#                    module.group_exec.loop_execs[-1].module_execs[-1].error:
-#                     error = 'Error in module execution with id %d.'%\
-#                             module.group_exec.loop_execs[-1].\
-#                             module_execs[-1].id
-#                 if module.group_exec.loop_execs[-1].group_execs and\
-#                    module.group_exec.loop_execs[-1].group_execs[-1].error:
-#                     error = 'Error in group execution with id %d.'%\
-#                             module.group_exec.loop_execs[-1].\
-#                             group_execs[-1].id
-#                 module.group_exec.loop_execs[-1].completed = -1
-#                 module.group_exec.loop_execs[-1].error = error
-#         else:
-#             module.module_exec.loop_execs[-1].ts_end = core.system.\
-#                                                        current_time()
-#             if not error:
-#                 module.module_exec.loop_execs[-1].completed = 1
-#             else:
-#                 module.module_exec.loop_execs[-1].completed = -1
-#                 module.module_exec.loop_execs[-1].error = error
-#         return True
+        for child in self.children_execs.pop(module, ()):
+            child.ts_end = vistrails.core.system.current_time()
+            if suspended:
+                child.completed = -2
+                child.error = error
+            elif not error:
+                child.completed = 1
+            else:
+                child.completed = -1
+                child.error = error
 
     def insert_module_annotations(self, module, a_dict):
-        for k,v in a_dict.iteritems():
+        """Adds an annotation on the execution object for this module.
+        """
+        for k, v in a_dict.iteritems():
             a_id = self.log.id_scope.getNewId(Annotation.vtType)
             annotation = Annotation(id=a_id,
                                     key=k,
                                     value=v)
-            if hasattr(module, 'is_group'):
-                module.group_exec.add_annotation(annotation)
-            else:
-                module.module_exec.add_annotation(annotation)
-            
+            self.module_execs[module].add_annotation(annotation)
+
     def insert_workflow_exec_annotations(self, a_dict):
-        """insert_workflow_exec_annotations(a_dict)-> None
-        This will create an annotation for each pair in a_dict in 
-        self.workflow_exec"""
+        """Adds an annotation on the whole workflow log object.
+
+        The information is not associated with the execution of a specific
+        module but of the whole pipeline.
+        """
         if self.workflow_exec:
-            for k,v in a_dict.iteritems():
+            for k, v in a_dict.iteritems():
                 a_id = self.log.id_scope.getNewId(Annotation.vtType)
                 annotation = Annotation(id=a_id,
                                         key=k,
                                         value=v)
                 self.workflow_exec.add_annotation(annotation)
+
+    def add_machine(self, machine):
+        machine.id = self.log.id_scope.getNewId(Machine.vtType)
+        self.workflow_exec.add_machine(machine)
+        return machine.id
+
+    def add_exec(self, exec_):
+        self.workflow_exec.add_item_exec(exec_)
+
+
+class LogWorkflowExecController(LogWorkflowController):
+    """Top-level LogWorkflowController, returned by start_workflow_execution().
+
+    This one has finish_workflow_execution(). The LogWorkflowController,
+    obtained through recursing(), don't.
+    """
+    def __init__(self, log, machine, parent_exec, vistrail=None, pipeline=None,
+                 currentVersion=None):
+        if vistrail is not None:
+            parent_type = Vistrail.vtType
+            parent_id = vistrail.id
+        else:
+            parent_type = Pipeline.vtType
+            parent_id = pipeline.id
+
+        wf_exec_id = log.id_scope.getNewId(WorkflowExec.vtType)
+        if vistrail is not None:
+            session = vistrail.current_session
+        else:
+            session = None
+        workflow_exec = WorkflowExec(
+                id=wf_exec_id,
+                user=vistrails.core.system.current_user(),
+                ip=vistrails.core.system.current_ip(),
+                vt_version=vistrails.core.system.vistrails_version(),
+                ts_start=vistrails.core.system.current_time(),
+                parent_type=parent_type,
+                parent_id=parent_id,
+                parent_version=currentVersion,
+                completed=0,
+                session=session,
+                machines=[machine])
+        log.add_workflow_exec(workflow_exec)
+
+        super(LogWorkflowExecController, self).__init__(log, machine, parent_exec, workflow_exec)
+
+    def finish_workflow_execution(self, errors, suspended=False):
+        """Signals the end of the execution of a pipeline.
+        """
+        self.workflow_exec.ts_end = vistrails.core.system.current_time()
+        if suspended:
+            self.workflow_exec.completed = -2
+        elif len(errors) > 0:
+            self.workflow_exec.completed = -1
+        else:
+            self.workflow_exec.completed = 1
diff --git a/vistrails/core/log/group_exec.py b/vistrails/core/log/group_exec.py
index bd0a75d..400f995 100644
--- a/vistrails/core/log/group_exec.py
+++ b/vistrails/core/log/group_exec.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.log.module_exec import ModuleExec
 from vistrails.core.log.loop_exec import LoopExec
 from vistrails.core.vistrail.annotation import Annotation
diff --git a/vistrails/core/log/log.py b/vistrails/core/log/log.py
index db05bf2..79c0f9d 100644
--- a/vistrails/core/log/log.py
+++ b/vistrails/core/log/log.py
@@ -1,40 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 
-from vistrails.core.log.machine import Machine
 from vistrails.core.log.workflow_exec import WorkflowExec
 from vistrails.db.domain import DBLog
 
@@ -57,8 +59,6 @@ class Log(DBLog):
         if _log.__class__ == Log:
             return
         _log.__class__ = Log
-        for machine in _log.machine_list:
-            Machine.convert(machine)
         for workflow_exec in _log.workflow_execs:
             WorkflowExec.convert(workflow_exec)
 
@@ -72,15 +72,6 @@ class Log(DBLog):
         self.db_id = id
     id = property(_get_id, _set_id)
 
-    def _get_machines(self):
-        return self.db_machines_id_index
-    machines = property(_get_machines)
-    def _get_machine_list(self):
-        return self.db_machines
-    machine_list = property(_get_machine_list)
-    def add_machine(self, machine):
-        self.db_add_machine(machine)
-
     def _get_workflow_execs(self):
         return self.db_workflow_execs
     workflow_execs = property(_get_workflow_execs)
diff --git a/vistrails/core/log/loop_exec.py b/vistrails/core/log/loop_exec.py
index 3b1495b..7936a6e 100644
--- a/vistrails/core/log/loop_exec.py
+++ b/vistrails/core/log/loop_exec.py
@@ -1,44 +1,46 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.db.domain import DBLoopExec
+from __future__ import division
+
+from vistrails.db.domain import DBLoopExec, DBLoopIteration
 
-class LoopExec(DBLoopExec):
-    """ Class that stores info for logging a loop execution. """
 
-    def __init__(self, *args, **kwargs):
-        DBLoopExec.__init__(self, *args, **kwargs)
+class LoopExec(DBLoopExec):
+    """Class that stores info for logging a loop.
+    """
 
     def __copy__(self):
         return self.do_copy()
@@ -50,13 +52,49 @@ class LoopExec(DBLoopExec):
 
     @staticmethod
     def convert(_loop_exec):
+        if _loop_exec.__class__ == LoopExec:
+            return
+        _loop_exec.__class__ = LoopExec
+        for iteration in _loop_exec.loop_iterations:
+            LoopIteration.convert(iteration)
+
+    ##########################################################################
+    # Properties
+
+    id = DBLoopExec.db_id
+    ts_start = DBLoopIteration.db_ts_start
+    ts_end = DBLoopIteration.db_ts_end
+
+    def _get_loop_iterations(self):
+        return self.db_loop_iterations
+    def _set_loop_iterations(self, iterations):
+        self.db_loop_iterations = iterations
+    loop_iterations = property(_get_loop_iterations, _set_loop_iterations)
+    def add_loop_iteration(self, iteration):
+        self.db_add_loop_iteration(iteration)
+
+
+class LoopIteration(DBLoopIteration):
+    """Class that stores info for logging a single iteration of a loop.
+    """
+
+    def __copy__(self):
+        return self.do_copy()
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBLoopIteration.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = LoopIteration
+        return cp
+
+    @staticmethod
+    def convert(_loop_iteration):
         from vistrails.core.log.module_exec import ModuleExec
         from vistrails.core.log.group_exec import GroupExec
 
-        if _loop_exec.__class__ == LoopExec:
+        if _loop_iteration.__class__ == LoopIteration:
             return
-        _loop_exec.__class__ = LoopExec
-        for item_exec in _loop_exec.item_execs:
+        _loop_iteration.__class__ = LoopIteration
+        for item_exec in _loop_iteration.item_execs:
             if item_exec.vtType == ModuleExec.vtType:
                 ModuleExec.convert(item_exec)
             elif item_exec.vtType == GroupExec.vtType:
@@ -67,11 +105,12 @@ class LoopExec(DBLoopExec):
     ##########################################################################
     # Properties
 
-    id = DBLoopExec.db_id
-    ts_start = DBLoopExec.db_ts_start
-    ts_end = DBLoopExec.db_ts_end
-    completed = DBLoopExec.db_completed
-    error = DBLoopExec.db_error
+    id = DBLoopIteration.db_id
+    ts_start = DBLoopIteration.db_ts_start
+    ts_end = DBLoopIteration.db_ts_end
+    completed = DBLoopIteration.db_completed
+    error = DBLoopIteration.db_error
+    iteration = DBLoopIteration.db_iteration
 
     def _get_duration(self):
         if self.db_ts_end is not None:
diff --git a/vistrails/core/log/machine.py b/vistrails/core/log/machine.py
index 14842a1..6c650b5 100644
--- a/vistrails/core/log/machine.py
+++ b/vistrails/core/log/machine.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBMachine
 
 class Machine(DBMachine):
diff --git a/vistrails/core/log/module_exec.py b/vistrails/core/log/module_exec.py
index 789d044..7ac058f 100644
--- a/vistrails/core/log/module_exec.py
+++ b/vistrails/core/log/module_exec.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.vistrail.annotation import Annotation
 from vistrails.core.log.loop_exec import LoopExec
 from vistrails.db.domain import DBModuleExec
diff --git a/vistrails/core/log/opm_graph.py b/vistrails/core/log/opm_graph.py
index bd9a2b5..67318a1 100644
--- a/vistrails/core/log/opm_graph.py
+++ b/vistrails/core/log/opm_graph.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBOpmGraph
 
 class OpmGraph(DBOpmGraph):
diff --git a/vistrails/core/log/prov_document.py b/vistrails/core/log/prov_document.py
index b9c3117..7912984 100644
--- a/vistrails/core/log/prov_document.py
+++ b/vistrails/core/log/prov_document.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBProvDocument
 
 class ProvDocument(DBProvDocument):
diff --git a/vistrails/core/log/workflow_exec.py b/vistrails/core/log/workflow_exec.py
index 0ca9dc6..c2ed60e 100644
--- a/vistrails/core/log/workflow_exec.py
+++ b/vistrails/core/log/workflow_exec.py
@@ -1,37 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
+from __future__ import division
+
+from vistrails.core.log.machine import Machine
 from vistrails.core.log.module_exec import ModuleExec
 from vistrails.core.log.group_exec import GroupExec
 from vistrails.core.log.loop_exec import LoopExec
@@ -59,6 +64,8 @@ class WorkflowExec(DBWorkflowExec):
         _wf_exec.__class__ = WorkflowExec
         for annotation in _wf_exec.annotations:
             Annotation.convert(annotation)
+        for machine in _wf_exec.machine_list:
+            Machine.convert(machine)
         for item_exec in _wf_exec.item_execs:
             if item_exec.vtType == ModuleExec.vtType:
                 ModuleExec.convert(item_exec)
@@ -104,3 +111,12 @@ class WorkflowExec(DBWorkflowExec):
     item_execs = property(_get_item_execs, _set_item_execs)
     def add_item_exec(self, item_exec):
         self.db_add_item_exec(item_exec)
+
+    def _get_machines(self):
+        return self.db_machines_id_index
+    machines = property(_get_machines)
+    def _get_machine_list(self):
+        return self.db_machines
+    machine_list = property(_get_machine_list)
+    def add_machine(self, machine):
+        self.db_add_machine(machine)
diff --git a/vistrails/core/mashup/__init__.py b/vistrails/core/mashup/__init__.py
index 3376fe3..530a4e4 100644
--- a/vistrails/core/mashup/__init__.py
+++ b/vistrails/core/mashup/__init__.py
@@ -1,41 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import uuid
 from datetime import date, datetime
-from time import strptime
 ################################################################################                           
 
 def conv_to_bool(x):
@@ -94,9 +96,9 @@ def convert_symbols(val):
 #                elif type == 'bool':
 #                    return bool_conv(value)
 #                elif type == 'date':
-#                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+#                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
 #                elif type == 'datetime':
-#                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+#                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
 #                elif type == 'uuid':
 #                    return uuid.UUID(value)
 #        return None
@@ -107,7 +109,7 @@ def convert_symbols(val):
 #            if type == 'date':
 #                return value.isoformat()
 #            elif type == 'datetime':
-#                return value.strftime('%Y-%m-%d %H:%M:%S')
+#                return strftime(value, '%Y-%m-%d %H:%M:%S')
 #            else:
 #                return str(value)
 #        return ''
diff --git a/vistrails/core/mashup/action.py b/vistrails/core/mashup/action.py
index 357aec2..e6fb7d7 100644
--- a/vistrails/core/mashup/action.py
+++ b/vistrails/core/mashup/action.py
@@ -1,39 +1,43 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
 
-from datetime import date, datetime
-from time import strptime
+from datetime import datetime
+
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db.domain import DBMashupAction
 from vistrails.core.mashup.mashup import Mashup
 
@@ -50,14 +54,14 @@ class Action(DBMashupAction):
         
     def _get_date(self):
         if self.db_date is not None:
-            return self.db_date.strftime('%d %b %Y %H:%M:%S')
-        return datetime(1900,1,1).strftime('%d %b %Y %H:%M:%S')
+            return strftime(self.db_date, '%d %b %Y %H:%M:%S')
+        return strftime(datetime(1900,1,1), '%d %b %Y %H:%M:%S')
 
     def _set_date(self, date):
         if isinstance(date, datetime):
             self.db_date = date
         elif isinstance(date, basestring) and date.strip() != '':
-            newDate = datetime(*strptime(date, '%d %b %Y %H:%M:%S')[0:6])
+            newDate = datetime(*time_strptime(date, '%d %b %Y %H:%M:%S')[0:6])
             self.db_date = newDate
     date = property(_get_date, _set_date)
         
diff --git a/vistrails/core/mashup/action_annotation.py b/vistrails/core/mashup/action_annotation.py
index 6cfa589..0be6a36 100644
--- a/vistrails/core/mashup/action_annotation.py
+++ b/vistrails/core/mashup/action_annotation.py
@@ -1,39 +1,44 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+from datetime import datetime
+
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db.domain import DBMashupActionAnnotation
-from datetime import date, datetime
-from time import strptime
 
 class ActionAnnotation(DBMashupActionAnnotation):
     def __init__(self, id, action_id, key=None, value=None, user=None, date=None):
@@ -47,14 +52,14 @@ class ActionAnnotation(DBMashupActionAnnotation):
         
     def _get_date(self):
         if self.db_date is not None:
-            return self.db_date.strftime('%d %b %Y %H:%M:%S')
-        return datetime(1900,1,1).strftime('%d %b %Y %H:%M:%S')
+            return strftime(self.db_date, '%d %b %Y %H:%M:%S')
+        return strftime(datetime(1900,1,1), '%d %b %Y %H:%M:%S')
 
     def _set_date(self, date):
         if isinstance(date, datetime):
             self.db_date = date
         elif isinstance(date, basestring) and date.strip() != '':
-            newDate = datetime(*strptime(date, '%d %b %Y %H:%M:%S')[0:6])
+            newDate = datetime(*time_strptime(date, '%d %b %Y %H:%M:%S')[0:6])
             self.db_date = newDate
     date = property(_get_date, _set_date)
     
diff --git a/vistrails/core/mashup/alias.py b/vistrails/core/mashup/alias.py
index 4446cc3..d616f4d 100644
--- a/vistrails/core/mashup/alias.py
+++ b/vistrails/core/mashup/alias.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBMashupAlias
 from vistrails.core.mashup.component import Component
 
diff --git a/vistrails/core/mashup/component.py b/vistrails/core/mashup/component.py
index f29d76a..8da0142 100644
--- a/vistrails/core/mashup/component.py
+++ b/vistrails/core/mashup/component.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import urllib
 from vistrails.core.mashup import conv_from_bool, conv_to_bool, convert_symbols
 from vistrails.db.domain import DBMashupComponent
diff --git a/vistrails/core/mashup/controller.py b/vistrails/core/mashup/controller.py
index 14b378e..2a9e7df 100644
--- a/vistrails/core/mashup/controller.py
+++ b/vistrails/core/mashup/controller.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 import os.path
 from vistrails.core.system import current_user, current_time
@@ -107,8 +110,8 @@ class MashupController(object):
     def getVistrailName(self):
         name = ''
         locator = self.currentMashup.vtid
-        if locator != None:
-            if locator.name == None:
+        if locator is not None:
+            if locator.name is None:
                 name = ''
             else:
                 name = os.path.split(locator.name)[1]
diff --git a/vistrails/core/mashup/mashup.py b/vistrails/core/mashup/mashup.py
index ca77ffc..5b32307 100644
--- a/vistrails/core/mashup/mashup.py
+++ b/vistrails/core/mashup/mashup.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import IdScope
 from vistrails.db.domain import DBMashup
 from vistrails.core.mashup import conv_to_bool, conv_from_bool
@@ -48,13 +51,13 @@ class Mashup(DBMashup):
     def __init__(self, id, name, vtid=None, version=None, alias_list=None, 
                  t='vistrail', has_seq=None, layout='', geometry='', 
                  id_scope=IdScope()):
-        if has_seq == None:
+        if has_seq is None:
             has_seq = 0
             
         DBMashup.__init__(self, id, name, version, alias_list, t, vtid, layout, 
                           geometry, has_seq)
         self.id_scope = id_scope
-        if has_seq == None:
+        if has_seq is None:
             self.has_seq = False
             if isinstance(self.alias_list, list):
                 for v in self.alias_list:
@@ -189,9 +192,9 @@ class Mashup(DBMashup):
                 alias.component.vtparent_id = new_pid
                 new_id = id_remap[(alias.component.vttype,alias.component.vtid)]
                 alias.component.vtid = new_id
-            except:
+            except Exception:
                 pass
-            
+
     def validateForPipeline(self, pipeline):
         """validateForPipeline(pipeline) -> None
         This will make sure that the parameters in the alias list are present
@@ -202,7 +205,7 @@ class Mashup(DBMashup):
             try:
                 param = pipeline.db_get_object(alias.component.vttype,
                                                alias.component.vtid)
-            except:
+            except Exception:
                 to_remove.append(alias)
         for a in to_remove:
             self.alias_list.remove(a)    
diff --git a/vistrails/core/mashup/mashup_trail.py b/vistrails/core/mashup/mashup_trail.py
index b0e41d6..205e49a 100644
--- a/vistrails/core/mashup/mashup_trail.py
+++ b/vistrails/core/mashup/mashup_trail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from vistrails.db.domain import IdScope
 from vistrails.db.domain import DBMashuptrail
 from vistrails.core.mashup.action import Action
@@ -103,12 +106,11 @@ class Mashuptrail(DBMashuptrail):
         return cp
     
     def getLatestVersion(self):
-        try:
-            max_ver = max(a.id for a in self.actions)
-            return max_ver
-        except:
+        if not self.actions:
             return 0
-        
+        max_ver = max(a.id for a in self.actions)
+        return max_ver
+
     def getMashup(self, version):
         if version in self.actionMap.keys():
             return self.actionMap[version].mashup
diff --git a/vistrails/core/modules/__init__.py b/vistrails/core/modules/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/modules/__init__.py
+++ b/vistrails/core/modules/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/modules/abstraction.py b/vistrails/core/modules/abstraction.py
index aff73cc..42fb4aa 100644
--- a/vistrails/core/modules/abstraction.py
+++ b/vistrails/core/modules/abstraction.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import os
 import re
 from itertools import chain
@@ -42,7 +45,7 @@ from vistrails.core.modules.vistrails_module import Module, ModuleError
 from vistrails.core.modules.sub_module import read_vistrail, new_abstraction, \
     get_abstraction_dependencies, save_abstraction
 import vistrails.core.modules.module_registry
-from vistrails.core.system import vistrails_version
+from vistrails.core.system import vistrails_version, get_vistrails_directory
 from vistrails.core.utils import InvalidPipeline
 
 name = 'My SubWorkflows'
@@ -56,17 +59,6 @@ def initialize(*args, **kwargs):
     manager = vistrails.core.packagemanager.get_package_manager()
 
     reg = vistrails.core.modules.module_registry.get_module_registry()
-#     conf = get_vistrails_configuration()
-#     if conf.check("userPackageDirectory"):
-#         if conf.check('userPackageDirectory'):
-#             abstraction_dir = os.path.join(conf.userPackageDirectory,
-#                                            'abstractions')
-
-#     abs_fnames = []
-#     p = re.compile(r".*\.vt")
-#     for abstraction in os.listdir(abstraction_dir):
-#         if p.match(abstraction):
-#             abs_fnames.append(os.path.join(abstraction_dir, abstraction))
     abs_vistrails = my_vistrails
     last_count = len(my_vistrails) + 1
 
@@ -82,7 +74,7 @@ def initialize(*args, **kwargs):
                 if package != identifier:
                     if not manager.has_package(package):
                         add_abstraction = False
-                        cannot_load[abs_name] = abs_vistrail
+                        cannot_load[abs_name] = (abs_vistrail, "Missing package dependency: %s" % package)
                         break
                 else:
                     for descriptor_info in inter_depends:
@@ -146,15 +138,18 @@ def package_dependencies():
 
     reg = vistrails.core.modules.module_registry.get_module_registry()
     conf = get_vistrails_configuration()
-    if conf.check("abstractionsDirectory"):
-        abstraction_dir = conf.abstractionsDirectory
+
+    abstraction_dir = get_vistrails_directory("subworkflowsDir")
+    if abstraction_dir is None:
+        debug.log("Subworkflows directory unset, cannot add any abstractions")
+        return []
     p = re.compile(r".*\.xml")
     all_packages = set()
     for abstraction in os.listdir(abstraction_dir):
         if p.match(abstraction):
             abs_fname = os.path.join(abstraction_dir, abstraction)
+            vistrail = read_vistrail(abs_fname)
             try:
-                vistrail = read_vistrail(abs_fname)
                 dependencies = get_abstraction_dependencies(vistrail)
             except vistrails.core.modules.module_registry.MissingPackage, e:
                 dependencies = {e._identifier: set()}
diff --git a/vistrails/core/modules/basic_modules.py b/vistrails/core/modules/basic_modules.py
index cacd6dd..96107ca 100644
--- a/vistrails/core/modules/basic_modules.py
+++ b/vistrails/core/modules/basic_modules.py
@@ -1,54 +1,63 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """basic_modules defines basic VisTrails Modules that are used in most
 pipelines."""
+from __future__ import division
+
 import vistrails.core.cache.hasher
+from vistrails.core.debug import format_exception
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.modules.vistrails_module import Module, new_module, \
-     Converter, NotCacheable, ModuleError
+    Converter, NotCacheable, ModuleError
+from vistrails.core.modules.config import ConstantWidgetConfig, \
+    QueryWidgetConfig, ParamExpWidgetConfig, ModuleSettings, IPort, OPort, \
+    CIPort
 import vistrails.core.system
 from vistrails.core.utils import InstanceObject
 from vistrails.core import debug
 
 from abc import ABCMeta
+from ast import literal_eval
 from itertools import izip
+import mimetypes
 import os
 import pickle
 import re
 import shutil
-#import zipfile
+import zipfile
 import urllib
 
 try:
@@ -60,11 +69,47 @@ except ImportError:
 
 ###############################################################################
 
-version = '2.1'
+version = '2.1.1'
 name = 'Basic Modules'
 identifier = 'org.vistrails.vistrails.basic'
 old_identifiers = ['edu.utah.sci.vistrails.basic']
 
+constant_config_path = "vistrails.gui.modules.constant_configuration"
+query_config_path = "vistrails.gui.modules.query_configuration"
+paramexp_config_path = "vistrails.gui.modules.paramexplore"
+
+def get_port_name(port):
+    if hasattr(port, 'name'):
+        return port.name
+    else:
+        return port[0]
+
+class meta_add_value_ports(type):
+    def __new__(cls, name, bases, dct):
+        """This metaclass adds the 'value' input and output ports.
+        """
+        mod = type.__new__(cls, name, bases, dct)
+
+        if '_input_ports' in mod.__dict__:
+            input_ports = mod._input_ports
+            if not any(get_port_name(port_info) == 'value'
+                       for port_info in input_ports):
+                mod._input_ports = [('value', mod)]
+                mod._input_ports.extend(input_ports)
+        else:
+            mod._input_ports = [('value', mod)]
+
+        if '_output_ports' in mod.__dict__:
+            output_ports = mod._output_ports
+            if not any(get_port_name(port_info) == 'value'
+                       for port_info in output_ports):
+                mod._output_ports = [('value', mod)]
+                mod._output_ports.extend(output_ports)
+        else:
+            mod._output_ports = [('value', mod)]
+
+        return mod
+
 class Constant(Module):
     """Base class for all Modules that represent a constant value of
     some type.
@@ -99,25 +144,24 @@ class Constant(Module):
     See core/modules/constant_configuration.py for details.
     
     """
+    _settings = ModuleSettings(abstract=True)
+    _output_ports = [OPort("value_as_string", "String")]
+
+    __metaclass__ = meta_add_value_ports
+
     def compute(self):
         """Constant.compute() only checks validity (and presence) of
         input value."""
-        v = self.getInputFromPort("value")
+        v = self.get_input("value")
         b = self.validate(v)
         if not b:
             raise ModuleError(self, "Internal Error: Constant failed validation")
-        self.setResult("value", v)
-        self.setResult("value_as_string", self.translate_to_string(v))
+        self.set_output("value", v)
+        self.set_output("value_as_string", self.translate_to_string(v))
 
     def setValue(self, v):
-        self.setResult("value", self.translate_to_python(v))
+        self.set_output("value", self.translate_to_python(v))
         self.upToDate = True
-        
-    def serialize(self):
-        return self.outputPorts['value_as_string']
-    
-    def deserialize(self, v):
-        return self.translate_to_python(v)
 
     @staticmethod
     def translate_to_string(v):
@@ -129,14 +173,6 @@ class Constant(Module):
         return None
 
     @staticmethod
-    def get_query_widget_class():
-        return None
-
-    @staticmethod
-    def get_param_explore_widget_list():
-        return []
-
-    @staticmethod
     def query_compute(value_a, value_b, query_method):
         if query_method == '==' or query_method is None:
             return (value_a == value_b)
@@ -147,9 +183,7 @@ class Constant(Module):
 def new_constant(name, py_conversion=None, default_value=None, validation=None,
                  widget_type=None,
                  str_conversion=None, base_class=Constant,
-                 compute=None, query_widget_type=None,
-                 query_compute=None,
-                 param_explore_widget_list=None):
+                 compute=None, query_compute=None):
     """new_constant(name: str, 
                     py_conversion: callable,
                     default_value: python_type,
@@ -158,10 +192,7 @@ def new_constant(name, py_conversion=None, default_value=None, validation=None,
                     str_conversion: callable,
                     base_class: class,
                     compute: callable,
-                    query_widget_type: (path, name) tuple or QWidget type,
-                    query_compute: static callable,
-                    param_explore_widget_list: 
-                        list((path, name) tuple or QWidget type)) -> Module
+                    query_compute: static callable) -> Module
 
     new_constant dynamically creates a new Module derived from
     Constant with given py_conversion and str_conversion functions, a
@@ -177,20 +208,12 @@ def new_constant(name, py_conversion=None, default_value=None, validation=None,
         d["translate_to_python"] = py_conversion
     elif base_class == Constant:
         raise ValueError("Must specify translate_to_python for constant")
-    else:
-        d["translate_to_python"] = staticmethod(base_class.translate_to_python)
     if validation is not None:
         d["validate"] = validation
     elif base_class == Constant:
         raise ValueError("Must specify validation for constant")
-    else:
-        d["validate"] = staticmethod(base_class.validate)
     if default_value is not None:
         d["default_value"] = default_value
-    elif base_class == Constant:
-        d["default_value"] = None
-    else:
-        d["default_value"] = base_class.default_value
 
     if str_conversion is not None:
         d['translate_to_string'] = str_conversion
@@ -202,106 +225,153 @@ def new_constant(name, py_conversion=None, default_value=None, validation=None,
         @staticmethod
         def get_widget_class():
             return widget_type
-        d['get_widget_class'] = get_widget_class
-    if query_widget_type is not None:
-        @staticmethod
-        def get_query_widget_class():
-            return query_widget_type
-        d['get_query_widget_class'] = get_query_widget_class
-    if param_explore_widget_list is not None:
-        @staticmethod
-        def get_param_explore_widget_list():
-            return param_explore_widget_list
-        d['get_param_explore_widget_list'] = get_param_explore_widget_list
+        d['get_widget_class'] = get_widget_class            
 
     m = new_module(base_class, name, d)
     m._input_ports = [('value', m)]
     m._output_ports = [('value', m)]
     return m
 
-def bool_conv(x):
-    s = str(x).upper()
-    if s == 'TRUE':
-        return True
-    if s == 'FALSE':
-        return False
-    raise ValueError('Boolean from String in VisTrails should be either \
-"true" or "false", got "%s" instead' % x)
+class Boolean(Constant):
+    _settings = ModuleSettings(
+            constant_widget='%s:BooleanWidget' % constant_config_path)
+    default_value = False
 
-def int_conv(x):
-    if x.startswith('0x'):
-        return int(x, 16)
-    else:
-        return int(x)
-
- at staticmethod
-def numeric_compare(value_a, value_b, query_method):
-    value_a = float(value_a)
-    value_b = float(value_b)
-    if query_method == '==' or query_method is None:
-        return (value_a == value_b)
-    elif query_method == '<':
-        return (value_a < value_b)
-    elif query_method == '>':
-        return (value_a > value_b)
-    elif query_method == '<=':
-        return (value_a <= value_b)
-    elif query_method == '>=':
-        return (value_a >= value_b)
-
- at staticmethod
-def string_compare(value_a, value_b, query_method):
-    if query_method == '*[]*' or query_method is None:
-        return (value_b in value_a)
-    elif query_method == '==':
-        return (value_a == value_b)
-    elif query_method == '=~':
-        try:
-            m = re.match(value_b, value_a)
-            if m is not None:
-                return (m.end() ==len(value_a))
-        except:
-            pass
-    return False
-
-Boolean = new_constant('Boolean' , staticmethod(bool_conv),
-                       False, staticmethod(lambda x: isinstance(x, bool)),
-                       widget_type=('vistrails.gui.modules.constant_configuration', 
-                                    'BooleanWidget'))
-Float   = new_constant('Float'   , staticmethod(float), 0.0, 
-                       staticmethod(lambda x: isinstance(x, (int, long, float))),
-                       query_widget_type=('vistrails.gui.modules.query_configuration',
-                                          'NumericQueryWidget'),
-                       query_compute=numeric_compare,
-                       param_explore_widget_list=[('vistrails.gui.modules.paramexplore',
-                                                   'FloatExploreWidget')])
-Integer = new_constant('Integer' , staticmethod(int_conv), 0, 
-                       staticmethod(lambda x: isinstance(x, (int, long))),
-                       base_class=Float,
-                       query_widget_type=('vistrails.gui.modules.query_configuration',
-                                          'NumericQueryWidget'),
-                       query_compute=numeric_compare,
-                       param_explore_widget_list=[('vistrails.gui.modules.paramexplore',
-                                                   'IntegerExploreWidget')])
-String  = new_constant('String'  , staticmethod(str), "", 
-                       staticmethod(lambda x: isinstance(x, str)),
-                       query_widget_type=('vistrails.gui.modules.query_configuration',
-                                          'StringQueryWidget'),
-                       query_compute=string_compare,
-                       widget_type=('vistrails.gui.modules.constant_configuration',
-                                    'StringWidget'))
+    @staticmethod
+    def translate_to_python(x):
+        s = x.upper()
+        if s == 'TRUE':
+            return True
+        if s == 'FALSE':
+            return False
+        raise ValueError('Boolean from String in VisTrails should be either '
+                         '"true" or "false", got "%s" instead' % x)
+
+    @staticmethod
+    def validate(x):
+        return isinstance(x, bool)
+
+class Float(Constant):
+    _settings = ModuleSettings(constant_widgets=[
+        QueryWidgetConfig('%s:NumericQueryWidget' % query_config_path),
+        ParamExpWidgetConfig('%s:FloatExploreWidget' % paramexp_config_path)])
+    default_value = 0.0
+
+    @staticmethod
+    def translate_to_python(x):
+        return float(x)
+
+    @staticmethod
+    def validate(x):
+        return isinstance(x, (int, long, float))
+
+    @staticmethod
+    def query_compute(value_a, value_b, query_method):
+        value_a = float(value_a)
+        value_b = float(value_b)
+        if query_method == '==' or query_method is None:
+            return (value_a == value_b)
+        elif query_method == '<':
+            return (value_a < value_b)
+        elif query_method == '>':
+            return (value_a > value_b)
+        elif query_method == '<=':
+            return (value_a <= value_b)
+        elif query_method == '>=':
+            return (value_a >= value_b)
+
+class Integer(Float):
+    _settings = ModuleSettings(constant_widgets=[
+        QueryWidgetConfig('%s:NumericQueryWidget' % query_config_path),
+        ParamExpWidgetConfig('%s:IntegerExploreWidget' % paramexp_config_path)])
+    default_value = 0
+
+    @staticmethod
+    def translate_to_python(x):
+        if x.startswith('0x'):
+            return int(x, 16)
+        else:
+            return int(x)
+
+    @staticmethod
+    def validate(x):
+        return isinstance(x, (int, long))
+
+class String(Constant):
+    _settings = ModuleSettings(
+            configure_widget="vistrails.gui.modules.string_configure:TextConfigurationWidget",
+            constant_widgets=[
+                 ConstantWidgetConfig('%s:MultiLineStringWidget' % constant_config_path,
+                                      widget_type='multiline'),
+                 QueryWidgetConfig('%s:StringQueryWidget' % query_config_path)])
+    _output_ports = [OPort("value_as_string", "String", optional=True)]
+    default_value = ""
+
+    @staticmethod
+    def translate_to_python(x):
+        assert isinstance(x, (str, unicode))
+        return str(x)
+
+    @staticmethod
+    def validate(x):
+        return isinstance(x, str)
+
+    @staticmethod
+    def query_compute(value_a, value_b, query_method):
+        if query_method == '*[]*' or query_method is None:
+            return (value_b in value_a)
+        elif query_method == '==':
+            return (value_a == value_b)
+        elif query_method == '=~':
+            try:
+                m = re.match(value_b, value_a)
+                if m is not None:
+                    return (m.end() ==len(value_a))
+            except re.error:
+                pass
+        return False
 
 ##############################################################################
 
+# Rich display for IPython
+try:
+    from IPython import display
+except ImportError:
+    display = None
+
+class PathObject(object):
+    def __init__(self, name):
+        self.name = name
+        self._ipython_repr = None
+
+    def __repr__(self):
+        return "PathObject(%r)" % self.name
+    __str__ = __repr__
+
+    def __getattr__(self, name):
+        if name.startswith('_repr_') and name.endswith('_'):
+            if self._ipython_repr is None:
+                filetype, encoding = mimetypes.guess_type(self.name)
+                if not filetype:
+                    self._ipython_repr = False
+                elif filetype.startswith('image/'):
+                    self._ipython_repr = display.Image(filename=self.name)
+                else:
+                    self._ipython_repr = False
+            elif self._ipython_repr is not False:
+                return getattr(self._ipython_repr, name)
+        raise AttributeError
+
 class Path(Constant):
-    name = ""
+    _settings = ModuleSettings(constant_widget=("%s:PathChooserWidget" % \
+                                                constant_config_path))
+    _input_ports = [IPort("value", "Path"),
+                    IPort("name", "String", optional=True)]
+    _output_ports = [OPort("value", "Path")]
 
     @staticmethod
     def translate_to_python(x):
-        result = Path()
-        result.name = x
-        result.setResult("value", result)
-        return result
+        return PathObject(x)
 
     @staticmethod
     def translate_to_string(x):
@@ -309,78 +379,87 @@ class Path(Constant):
 
     @staticmethod
     def validate(v):
-        #print 'validating', v
-        #print 'isinstance', isinstance(v, Path)
-        return isinstance(v, Path)
+        return isinstance(v, PathObject)
 
     def get_name(self):
         n = None
-        if self.hasInputFromPort("value"):
-            n = self.getInputFromPort("value").name
+        if self.has_input("value"):
+            n = self.get_input("value").name
         if n is None:
-            self.checkInputPort("name")
-            n = self.getInputFromPort("name")
+            self.check_input("name")
+            n = self.get_input("name")
         return n
 
     def set_results(self, n):
-        self.name = n
-        self.setResult("value", self)
-        self.setResult("value_as_string", self.translate_to_string(self))
+        self.set_output("value", PathObject(n))
+        self.set_output("value_as_string", n)
 
     def compute(self):
         n = self.get_name()
         self.set_results(n)
 
-    @staticmethod
-    def get_widget_class():
-        return ("vistrails.gui.modules.constant_configuration",
-                "PathChooserWidget")
+Path.default_value = PathObject('')
 
-Path.default_value = Path()
+def path_parameter_hasher(p):
+    def get_mtime(path):
+        t = int(os.path.getmtime(path))
+        if os.path.isdir(path):
+            for subpath in os.listdir(path):
+                subpath = os.path.join(path, subpath)
+                if os.path.isdir(subpath):
+                    t = max(t, get_mtime(subpath))
+        return t
+
+    h = vistrails.core.cache.hasher.Hasher.parameter_signature(p)
+    try:
+        # FIXME: This will break with aliases - I don't really care that much
+        t = get_mtime(p.strValue)
+    except OSError:
+        return h
+    hasher = sha_hash()
+    hasher.update(h)
+    hasher.update(str(t))
+    return hasher.digest()
 
 class File(Path):
     """File is a VisTrails Module that represents a file stored on a
     file system local to the machine where VisTrails is running."""
-    @staticmethod
-    def translate_to_python(x):
-        result = File()
-        result.name = x
-        result.setResult("value", result)
-        return result
+
+    _settings = ModuleSettings(constant_signature=path_parameter_hasher,
+                               constant_widget=("%s:FileChooserWidget" % \
+                                                constant_config_path))
+    _input_ports = [IPort("value", "File"),
+                    IPort("create_file", "Boolean", optional=True)]
+    _output_ports = [OPort("value", "File"),
+                     OPort("local_filename", "String", optional=True)]
 
     def compute(self):
         n = self.get_name()
-        if (self.hasInputFromPort("create_file") and
-                self.getInputFromPort("create_file")):
+        if (self.has_input("create_file") and self.get_input("create_file")):
             vistrails.core.system.touch(n)
         if not os.path.isfile(n):
             raise ModuleError(self, 'File %r does not exist' % n)
         self.set_results(n)
-        self.setResult("local_filename", n)
+        self.set_output("local_filename", n)
 
-    @staticmethod
-    def get_widget_class():
-        return ("vistrails.gui.modules.constant_configuration",
-                "FileChooserWidget")
-
-File.default_value = File()
-    
 class Directory(Path):
-    @staticmethod
-    def translate_to_python(x):
-        result = Directory()
-        result.name = x
-        result.setResult("value", result)
-        return result
+
+    _settings = ModuleSettings(constant_signature=path_parameter_hasher,
+                               constant_widget=("%s:DirectoryChooserWidget" % \
+                                                constant_config_path))
+    _input_ports = [IPort("value", "Directory"),
+                    IPort("create_directory", "Boolean", optional=True)]
+    _output_ports = [OPort("value", "Directory"),
+                     OPort("itemList", "List")]
 
     def compute(self):
         n = self.get_name()
-        if (self.hasInputFromPort("create_directory") and
-                self.getInputFromPort("create_directory")):
+        if (self.has_input("create_directory") and 
+                self.get_input("create_directory")):
             try:
                 vistrails.core.system.mkdir(n)
             except Exception, e:
-                raise ModuleError(self, 'mkdir: ' + str(e))
+                raise ModuleError(self, 'mkdir: %s' % format_exception(e))
         if not os.path.isdir(n):
             raise ModuleError(self, 'Directory "%s" does not exist' % n)
         self.set_results(n)
@@ -389,73 +468,33 @@ class Directory(Path):
         output_list = []
         for item in dir_list:
             full_path = os.path.join(n, item)
-            if os.path.isfile(full_path):
-                file_item = File()
-                file_item.name = full_path
-                file_item.upToDate = True
-                output_list.append(file_item)
-            elif os.path.isdir(full_path):
-                dir_item = Directory()
-                dir_item.name = full_path
-                dir_item.upToDate = True
-                output_list.append(dir_item)
-        self.setResult('itemList', output_list)
-
-    @staticmethod
-    def get_widget_class():
-        return ("vistrails.gui.modules.constant_configuration",
-                "DirectoryChooserWidget")
-
-Directory.default_value = Directory()
-
-def path_parameter_hasher(p):
-    def get_mtime(path):
-        t = int(os.path.getmtime(path))
-        if os.path.isdir(path):
-            for subpath in os.listdir(path):
-                subpath = os.path.join(path, subpath)
-                if os.path.isdir(subpath):
-                    t = max(t, get_mtime(subpath))
-        return t
-
-    h = vistrails.core.cache.hasher.Hasher.parameter_signature(p)
-    try:
-        # FIXME: This will break with aliases - I don't really care that much
-        t = get_mtime(p.strValue)
-    except OSError:
-        return h
-    hasher = sha_hash()
-    hasher.update(h)
-    hasher.update(str(t))
-    return hasher.digest()
+            output_list.append(PathObject(full_path))
+        self.set_output('itemList', output_list)
 
 ##############################################################################
 
 class OutputPath(Path):
+    _settings = ModuleSettings(constant_widget=("%s:OutputPathChooserWidget" % \
+                                                constant_config_path))
+    _input_ports = [IPort("value", "OutputPath")]
+    _output_ports = [OPort("value", "OutputPath")]
+
     def get_name(self):
         n = None
-        if self.hasInputFromPort("value"):
-            n = self.getInputFromPort("value").name
+        if self.has_input("value"):
+            n = self.get_input("value").name
         if n is None:
-            self.checkInputPort("name")
-            n = self.getInputFromPort("name")
+            self.check_input("name")
+            n = self.get_input("name")
         return n
-        
+
     def set_results(self, n):
-        self.name = n
-        self.setResult("value", self)
-        self.setResult("value_as_string", self.translate_to_string(self))
+        self.set_output("value", PathObject(n))
+        self.set_output("value_as_string", n)
 
     def compute(self):
         n = self.get_name()
         self.set_results(n)
-        
-    @staticmethod
-    def get_widget_class():
-        return ("vistrails.gui.modules.constant_configuration", 
-                "OutputPathChooserWidget")
-
-OutputPath.default_value = OutputPath()
 
 class FileSink(NotCacheable, Module):
     """FileSink takes a file and writes it to a user-specified
@@ -463,30 +502,39 @@ class FileSink(NotCacheable, Module):
     specified by the outputPath.  The overwrite flag allows users to
     specify whether an existing path should be overwritten."""
 
+    _input_ports = [IPort("file", File),
+                    IPort("outputPath", OutputPath),
+                    IPort("overwrite", Boolean, optional=True, 
+                          default=True),
+                    IPort("publishFile", Boolean, optional=True)]
+    
     def compute(self):
-        input_file = self.getInputFromPort("file")
-        output_path = self.getInputFromPort("outputPath")
+        input_file = self.get_input("file")
+        output_path = self.get_input("outputPath")
         full_path = output_path.name
 
-        try:
-            vistrails.core.system.link_or_copy(input_file.name, full_path)
-        except OSError, e:
-            if self.hasInputFromPort("overwrite") and \
-                    self.getInputFromPort("overwrite"):
+        if os.path.isfile(full_path):
+            if self.get_input('overwrite'):
                 try:
-                    os.unlink(full_path)
-                    vistrails.core.system.link_or_copy(input_file.name, full_path)
-                except OSError:
-                    msg = "(override true) Could not create file '%s'" % \
-                        full_path
+                    os.remove(full_path)
+                except OSError, e:
+                    msg = ('Could not delete existing path "%s" '
+                           '(overwrite on)' % full_path)
                     raise ModuleError(self, msg)
             else:
-                msg = "Could not create file '%s': %s" % (full_path, e)
-                raise ModuleError(self, msg)
-            
-        if (self.hasInputFromPort("publishFile") and
-            self.getInputFromPort("publishFile") or 
-            not self.hasInputFromPort("publishFile")):
+                raise ModuleError(self,
+                                  "Could not copy file to '%s': file already "
+                                  "exists")
+
+        try:
+            vistrails.core.system.link_or_copy(input_file.name, full_path)
+        except OSError, e:
+            msg = "Could not create file '%s': %s" % (full_path, e)
+            raise ModuleError(self, msg)
+
+        if (self.has_input("publishFile") and
+            self.get_input("publishFile") or 
+            not self.has_input("publishFile")):
             if self.moduleInfo.has_key('extra_info'):
                 if self.moduleInfo['extra_info'].has_key('pathDumpCells'):
                     folder = self.moduleInfo['extra_info']['pathDumpCells']
@@ -502,12 +550,12 @@ class FileSink(NotCacheable, Module):
                         counter += 1
                     try:
                         vistrails.core.system.link_or_copy(input_file.name, filename)
-                    except OSError:
-                        msg = "Could not publish file '%s' \n   on  '%s': %s" % \
-                               (full_path, filename, e)
+                    except OSError, e:
+                        msg = "Could not publish file '%s' \n   on  '%s':" % (
+                                full_path, filename)
                         # I am not sure whether we should raise an error
                         # I will just print a warning for now (Emanuele)
-                        debug.warning("%s" % msg)
+                        debug.warning("%s" % msg, e)
 
 class DirectorySink(NotCacheable, Module):
     """DirectorySink takes a directory and writes it to a
@@ -516,14 +564,17 @@ class DirectorySink(NotCacheable, Module):
     flag allows users to specify whether an existing path should be
     overwritten."""
 
+    _input_ports = [IPort("dir", Directory),
+                    IPort("outputPath", OutputPath),
+                    IPort("overwrite", Boolean, optional=True, default="True")]
+
     def compute(self):
-        input_dir = self.getInputFromPort("dir")
-        output_path = self.getInputFromPort("outputPath")
+        input_dir = self.get_input("dir")
+        output_path = self.get_input("outputPath")
         full_path = output_path.name
 
         if os.path.exists(full_path):
-            if (self.hasInputFromPort("overwrite") and 
-                self.getInputFromPort("overwrite")):
+            if self.get_input("overwrite"):
                 try:
                     if os.path.isfile(full_path):
                         os.remove(full_path)
@@ -532,7 +583,9 @@ class DirectorySink(NotCacheable, Module):
                 except OSError, e:
                     msg = ('Could not delete existing path "%s" '
                            '(overwrite on)' % full_path)
-                    raise ModuleError(self, msg + '\n' + str(e))
+                    raise ModuleError(
+                            self,
+                            '%s\n%s' % (msg, format_exception(e)))
             else:
                 msg = ('Could not write to existing path "%s" '
                        '(overwrite off)' % full_path)
@@ -543,20 +596,46 @@ class DirectorySink(NotCacheable, Module):
         except OSError, e:
             msg = 'Could not copy path from "%s" to "%s"' % \
                 (input_dir.name, full_path)
-            raise ModuleError(self, msg + '\n' + str(e))
+            raise ModuleError(self, '%s\n%s' % (msg, format_exception(e)))
 
 ##############################################################################
 
 class WriteFile(Converter):
     """Writes a String to a temporary File.
     """
+    _input_ports = [IPort('in_value', String),
+                    IPort('suffix', String, optional=True, default=""),
+                    IPort('encoding', String, optional=True)]
+    _output_ports = [OPort('out_value', File)]
+
     def compute(self):
-        contents = self.getInputFromPort('in_value')
-        suffix = self.forceGetInputFromPort('suffix', '')
+        contents = self.get_input('in_value')
+        suffix = self.force_get_input('suffix', '')
         result = self.interpreter.filePool.create_file(suffix=suffix)
+        if self.has_input('encoding'):
+            contents = contents.decode('utf-8') # VisTrails uses UTF-8
+                                                # internally (I hope)
+            contents = contents.encode(self.get_input('encoding'))
         with open(result.name, 'wb') as fp:
             fp.write(contents)
-        self.setResult('out_value', result)
+        self.set_output('out_value', result)
+
+class ReadFile(Converter):
+    """Reads a File to a String.
+    """
+    _input_ports = [IPort('in_value', File),
+                    IPort('encoding', String, optional=True)]
+    _output_ports = [OPort('out_value', String)]
+
+    def compute(self):
+        filename = self.get_input('in_value').name
+        with open(filename, 'rb') as fp:
+            contents = fp.read()
+        if self.has_input('encoding'):
+            contents = contents.decode(self.get_input('encoding'))
+            contents = contents.encode('utf-8') # VisTrails uses UTF-8
+                                                # internally (for now)
+        self.set_output('out_value', contents)
 
 ##############################################################################
 
@@ -565,6 +644,22 @@ class Color(Constant):
     # contains a tuple because a tuple would be interpreted as a
     # type(tuple) which messes with the interpreter
 
+    _settings = ModuleSettings(constant_widgets=[
+        '%s:ColorWidget' % constant_config_path, 
+        ConstantWidgetConfig('%s:ColorEnumWidget' % \
+                             constant_config_path, 
+                             widget_type='enum'),
+        QueryWidgetConfig('%s:ColorQueryWidget' % \
+                          query_config_path),
+        ParamExpWidgetConfig('%s:RGBExploreWidget' % \
+                             paramexp_config_path,
+                             widget_type='rgb'),
+        ParamExpWidgetConfig('%s:HSVExploreWidget' % \
+                             paramexp_config_path,
+                             widget_type='hsv')])
+    _input_ports = [IPort("value", "Color")]
+    _output_ports = [OPort("value", "Color")]
+
     default_value = InstanceObject(tuple=(1,1,1))
 
     @staticmethod
@@ -582,20 +677,7 @@ class Color(Constant):
 
     @staticmethod
     def to_string(r, g, b):
-        return "%s,%s,%s" % (r,g,b)
-
-    @staticmethod
-    def get_widget_class():
-        return ("vistrails.gui.modules.constant_configuration", "ColorWidget")
-        
-    @staticmethod
-    def get_query_widget_class():
-        return ("vistrails.gui.modules.query_configuration", "ColorQueryWidget")
-
-    @staticmethod
-    def get_param_explore_widget_list():
-        return [('vistrails.gui.modules.paramexplore', 'RGBExploreWidget'),
-                ('vistrails.gui.modules.paramexplore', 'HSVExploreWidget')]
+        return "%s,%s,%s" % (r,g,b)        
 
     @staticmethod
     def query_compute(value_a, value_b, query_method):
@@ -674,10 +756,31 @@ class StandardOutput(NotCacheable, Module):
     """StandardOutput is a VisTrails Module that simply prints the
     value connected on its port to standard output. It is intended
     mostly as a debugging device."""
-    
+
+    _input_ports = [IPort("value", 'Variant')]
+
     def compute(self):
-        v = self.getInputFromPort("value")
-        print v
+        v = self.get_input("value")
+        if isinstance(v, PathObject):
+            try:
+                fp = open(v.name, 'rb')
+            except IOError:
+                print v
+            else:
+                try:
+                    CHUNKSIZE = 2048
+                    chunk = fp.read(CHUNKSIZE)
+                    if chunk:
+                        sys.stdout.write(chunk)
+                        while len(chunk) == CHUNKSIZE:
+                            chunk = fp.read(CHUNKSIZE)
+                            if chunk:
+                                sys.stdout.write(chunk)
+                        sys.stdout.write('\n')
+                finally:
+                    fp.close()
+        else:
+            print v
 
 ##############################################################################
 
@@ -689,38 +792,54 @@ class Tuple(Module):
     integrated with the rest of VisTrails, so don't use it unless
     you know what you're doing."""
 
+    _settings = ModuleSettings(configure_widget=
+        "vistrails.gui.modules.tuple_configuration:TupleConfigurationWidget")
+
     def __init__(self):
         Module.__init__(self)
         self.input_ports_order = []
         self.values = tuple()
 
+    def transfer_attrs(self, module):
+        Module.transfer_attrs(self, module)
+        self.input_ports_order = [p.name for p in module.input_port_specs]
+
     def compute(self):
-        values = tuple([self.getInputFromPort(p)
+        values = tuple([self.get_input(p)
                         for p in self.input_ports_order])
         self.values = values
-        self.setResult("value", values)
+        self.set_output("value", values)
 
 class Untuple(Module):
     """Untuple takes a tuple and returns the individual values.  It
     reverses the actions of Tuple.
 
     """
+
+    _settings = ModuleSettings(configure_widget=
+        "vistrails.gui.modules.tuple_configuration:UntupleConfigurationWidget")
+
     def __init__(self):
         Module.__init__(self)
         self.output_ports_order = []
 
+    def transfer_attrs(self, module):
+        Module.transfer_attrs(self, module)
+        self.output_ports_order = [p.name for p in module.output_port_specs]
+        # output_ports are reversed for display purposes...
+        self.output_ports_order.reverse()
+
     def compute(self):
-        if self.hasInputFromPort("tuple"):
-            tuple = self.getInputFromPort("tuple")
+        if self.has_input("tuple"):
+            tuple = self.get_input("tuple")
             values = tuple.values
         else:
-            values = self.getInputFromPort("value")
+            values = self.get_input("value")
         for p, value in izip(self.output_ports_order, values):
-            self.setResult(p, value)
+            self.set_output(p, value)
 
 ##############################################################################
 
-# TODO: Create a better Module for ConcatenateString.
 class ConcatenateString(Module):
     """ConcatenateString takes many strings as input and produces the
     concatenation as output. Useful for constructing filenames, for
@@ -730,32 +849,33 @@ class ConcatenateString(Module):
     future."""
 
     fieldCount = 4
+    _input_ports = [IPort("str%d" % i, "String")
+                    for i in xrange(1, 1 + fieldCount)]
+    _output_ports = [OPort("value", "String")]
 
     def compute(self):
-        result = ""
-        for i in xrange(self.fieldCount):
-            v = i+1
-            port = "str%s" % v
-            if self.hasInputFromPort(port):
-                inp = self.getInputFromPort(port)
-                result += inp
-        self.setResult("value", result)
+        result = "".join(self.force_get_input('str%d' % i, '')
+                         for i in xrange(1, 1 + self.fieldCount))
+        self.set_output('value', result)
 
 ##############################################################################
 
 class Not(Module):
     """Not inverts a Boolean.
     """
+    _input_ports = [IPort('input', 'Boolean')]
+    _output_ports = [OPort('value', 'Boolean')]
 
     def compute(self):
-        value = self.getInputFromPort('input')
-        self.setResult('value', not value)
+        value = self.get_input('input')
+        self.set_output('value', not value)
 
 ##############################################################################
+
 # List
 
 # If numpy is available, we consider numpy arrays to be lists as well
-class ListType:
+class ListType(object):
     __metaclass__ = ABCMeta
 
 ListType.register(list)
@@ -767,19 +887,30 @@ else:
     ListType.register(numpy.ndarray)
 
 class List(Constant):
+    _settings = ModuleSettings(configure_widget=
+        "vistrails.gui.modules.list_configuration:ListConfigurationWidget")
+    _input_ports = [IPort("value", "List"),
+                    IPort("head", "Variant", depth=1),
+                    IPort("tail", "List")]
+    _output_ports = [OPort("value", "List")]
+
     default_value = []
 
     def __init__(self):
         Constant.__init__(self)
         self.input_ports_order = []
 
+    def transfer_attrs(self, module):
+        Module.transfer_attrs(self, module)
+        self.input_ports_order = [p.name for p in module.input_port_specs]
+
     @staticmethod
     def validate(x):
         return isinstance(x, ListType)
 
     @staticmethod
     def translate_to_python(v):
-        return eval(v)
+        return literal_eval(v)
 
     @staticmethod
     def translate_to_string(v, dims=None):
@@ -799,70 +930,77 @@ class List(Constant):
         head, middle, items, tail = [], [], [], []
         got_value = False
 
-        if self.hasInputFromPort('value'):
+        if self.has_input('value'):
             # run the regular compute here
             Constant.compute(self)
             middle = self.outputPorts['value']
             got_value = True
-        if self.hasInputFromPort('head'):
-            head = self.getInputListFromPort('head')
+        if self.has_input('head'):
+            head = self.get_input('head')
             got_value = True
         if self.input_ports_order:
-            items = [self.getInputFromPort(p)
+            items = [self.get_input(p)
                      for p in self.input_ports_order]
             got_value = True
-        if self.hasInputFromPort('tail'):
-            tail = self.getInputFromPort('tail')
+        if self.has_input('tail'):
+            tail = self.get_input('tail')
             got_value = True
 
         if not got_value:
-            self.getInputFromPort('value')
-        self.setResult('value', head + middle + items + tail)
-
-List._input_ports = [('value', List)]
-List._output_ports = [('value', List)]
+            self.get_input('value')
+        self.set_output('value', head + middle + items + tail)
 
 ##############################################################################
 # Dictionary
-                    
-def dict_conv(v):
-    v_dict = eval(v)
-    return v_dict
 
-def dict_compute(self):
-    d = {}
-    if self.hasInputFromPort('value'):
-        Constant.compute(self)
-        d.update(self.outputPorts['value'])
-    if self.hasInputFromPort('addPair'):
-        pairs_list = self.getInputListFromPort('addPair')
-        d.update(pairs_list)
-    if self.hasInputFromPort('addPairs'):
-        d.update(self.getInputFromPort('addPairs'))
-        
-    self.setResult("value", d)
-        
-Dictionary = new_constant('Dictionary', staticmethod(dict_conv),
-                          {}, staticmethod(lambda x: isinstance(x, dict)),
-                          compute=dict_compute)
+class Dictionary(Constant):
+    default_value = {}
+    _input_ports = [CIPort("addPair", "Module, Module"),
+                    IPort("addPairs", "List")]
+
+    @staticmethod
+    def translate_to_python(v):
+        return literal_eval(v)
+
+    @staticmethod
+    def validate(x):
+        return isinstance(x, dict)
+
+    def compute(self):
+        d = {}
+        if self.has_input('value'):
+            Constant.compute(self)
+            d.update(self.outputPorts['value'])
+        if self.has_input('addPair'):
+            pairs_list = self.get_input_list('addPair')
+            d.update(pairs_list)
+        if self.has_input('addPairs'):
+            d.update(self.get_input('addPairs'))
+
+        self.set_output("value", d)
 
 ##############################################################################
 
 # TODO: Null should be a subclass of Constant?
 class Null(Module):
     """Null is the class of None values."""
-    
+    _settings = ModuleSettings(hide_descriptor=True)
+
     def compute(self):
-        self.setResult("value", None)
+        self.set_output("value", None)
 
 ##############################################################################
 
 class Unpickle(Module):
     """Unpickles a string.
     """
+    _settings = ModuleSettings(hide_descriptor=True)
+    _input_ports = [IPort('input', 'String')]
+    _output_ports = [OPort('result', 'Variant')]
+
     def compute(self):
-        value = self.getInputFromPort('input')
-        self.setResult('result', pickle.loads(value))
+        value = self.get_input('input')
+        self.set_output('result', pickle.loads(value))
 
 ##############################################################################
 
@@ -871,6 +1009,12 @@ class CodeRunnerMixin(object):
         self.output_ports_order = []
         super(CodeRunnerMixin, self).__init__()
 
+    def transfer_attrs(self, module):
+        Module.transfer_attrs(self, module)
+        self.output_ports_order = [p.name for p in module.output_port_specs]
+        # output_ports are reversed for display purposes...
+        self.output_ports_order.reverse()
+
     def run_code(self, code_str,
                  use_input=False,
                  use_output=False):
@@ -886,7 +1030,7 @@ class CodeRunnerMixin(object):
         locals_ = locals()
         if use_input:
             for k in self.inputPorts:
-                locals_[k] = self.getInputFromPort(k)
+                locals_[k] = self.get_input(k)
         if use_output:
             for output_portname in self.output_ports_order:
                 locals_[output_portname] = None
@@ -899,11 +1043,12 @@ class CodeRunnerMixin(object):
                         'self': self})
         if 'source' in locals_:
             del locals_['source']
-        exec code_str in locals_, locals_
+        # Python 2.6 needs code to end with newline
+        exec code_str + '\n' in locals_, locals_
         if use_output:
             for k in self.output_ports_order:
-                if locals_.get(k) != None:
-                    self.setResult(k, locals_[k])
+                if locals_.get(k) is not None:
+                    self.set_output(k, locals_[k])
 
 ##############################################################################
 
@@ -920,165 +1065,100 @@ class PythonSource(CodeRunnerMixin, NotCacheable, Module):
     If you want a PythonSource execution to be cached, call
     cache_this().
     """
+    _settings = ModuleSettings(
+        configure_widget=("vistrails.gui.modules.python_source_configure:"
+                             "PythonSourceConfigurationWidget"))
+    _input_ports = [IPort('source', 'String', optional=True, default="")]
+    _output_pors = [OPort('self', 'Module')]
 
     def compute(self):
-        s = urllib.unquote(str(self.getInputFromPort('source')))
-        self.run_code(s, use_input=True, use_output=True)
-
-##############################################################################
-
-class SmartSource(NotCacheable, Module):
-
-    def run_code(self, code_str,
-                 use_input=False,
-                 use_output=False):
-        import vistrails.core.packagemanager
-        def fail(msg):
-            raise ModuleError(self, msg)
-        def cache_this():
-            self.is_cacheable = lambda *args, **kwargs: True
-        locals_ = locals()
-
-        def smart_input_entry(k):
-            v = self.getInputFromPort(k)
-            if isinstance(v, Module) and hasattr(v, 'get_source'):
-                v = v.get_source()
-            return (k, v)
-
-        def get_mro(v):
-            # Tries to get the mro from strange class hierarchies like VTK's
-            try:
-                return v.mro()
-            except AttributeError:
-                def yield_all(v):
-                    b = v.__bases__
-                    yield v
-                    for base in b:
-                        g = yield_all(base)
-                        while 1: yield g.next()
-                return [x for x in yield_all(v)]
-            
-        if use_input:
-            inputDict = dict([smart_input_entry(k)
-                              for k in self.inputPorts])
-            locals_.update(inputDict)
-        if use_output:
-            for output_portname in self.output_ports_order:
-                locals_[output_portname] = None
-        _m = vistrails.core.packagemanager.get_package_manager()
-        locals_.update({'fail': fail,
-                        'package_manager': _m,
-                        'cache_this': cache_this,
-                        'self': self})
-        del locals_['source']
-        exec code_str in locals_, locals_
-        if use_output:
-            oports = self.registry.get_descriptor(SmartSource).output_ports
-            for k in self.output_ports_order:
-                if locals_.get(k) != None:
-                    v = locals_[k]
-                    spec = oports.get(k, None)
-
-                    if spec:
-                        # See explanation of algo in doc/smart_source_resolution_algo.txt
-                        # changed from spec.types()[0]
-                        port_vistrail_base_class = spec.descriptors()[0].module
-                        mro = get_mro(type(v))
-                        source_types = self.registry.python_source_types
-                        found = False
-                        for python_class in mro:
-                            if python_class in source_types:
-                                vistrail_classes = [x for x in source_types[python_class]
-                                                    if issubclass(x, port_vistrail_base_class)]
-                                if len(vistrail_classes) == 0:
-                                    # FIXME better error handling
-                                    raise ModuleError(self, "Module Registry inconsistent")
-                                vt_class = vistrail_classes[0]
-                                found = True
-                                break
-                        if found:
-                            vt_instance = vt_class()
-                            vt_instance.set_source(v)
-                            v = vt_instance
-                    self.setResult(k, v)
-
-    def compute(self):
-        s = urllib.unquote(str(self.forceGetInputFromPort('source', '')))
+        s = urllib.unquote(str(self.get_input('source')))
         self.run_code(s, use_input=True, use_output=True)
 
 ##############################################################################
 
 def zip_extract_file(archive, filename_in_archive, output_filename):
-    return os.system(
-            "%s > %s" % (
-                    vistrails.core.system.list2cmdline([
-                            'unzip',
-                            '-p', archive,
-                            filename_in_archive]),
-                    vistrails.core.system.list2cmdline([output_filename])))
+    z = zipfile.ZipFile(archive)
+    try:
+        fileinfo = z.getinfo(filename_in_archive) # Might raise KeyError
+        output_dirname, output_filename = os.path.split(output_filename)
+        fileinfo.filename = output_filename
+        z.extract(fileinfo, output_dirname)
+    finally:
+        z.close()
 
 
 def zip_extract_all_files(archive, output_path):
-    return os.system(
-            vistrails.core.system.list2cmdline([
-                    'unzip',
-                    archive,
-                    '-d', output_path]))
+    z = zipfile.ZipFile(archive)
+    try:
+        z.extractall(output_path)
+    finally:
+        z.close()
 
 
 class Unzip(Module):
     """Unzip extracts a file from a ZIP archive."""
+    _input_ports = [IPort('archive_file', 'File'),
+                    IPort('filename_in_archive', 'String')]
+    _output_ports = [OPort('file', 'File')]
 
     def compute(self):
-        self.checkInputPort("archive_file")
-        self.checkInputPort("filename_in_archive")
-        filename_in_archive = self.getInputFromPort("filename_in_archive")
-        archive_file = self.getInputFromPort("archive_file")
+        self.check_input("archive_file")
+        self.check_input("filename_in_archive")
+        filename_in_archive = self.get_input("filename_in_archive")
+        archive_file = self.get_input("archive_file")
         if not os.path.isfile(archive_file.name):
             raise ModuleError(self, "archive file does not exist")
         suffix = self.interpreter.filePool.guess_suffix(filename_in_archive)
         output = self.interpreter.filePool.create_file(suffix=suffix)
-        s = zip_extract_file(archive_file.name,
-                             filename_in_archive,
-                             output.name)
-        if s != 0:
-            raise ModuleError(self, "unzip command failed with status %d" % s)
-        self.setResult("file", output)
+        zip_extract_file(archive_file.name,
+                         filename_in_archive,
+                         output.name)
+        self.set_output("file", output)
 
 
 class UnzipDirectory(Module):
     """UnzipDirectory extracts every file from a ZIP archive."""
+    _input_ports = [IPort('archive_file', 'File')]
+    _output_ports = [OPort('directory', 'Directory')]
 
     def compute(self):
-        self.checkInputPort("archive_file")
-        archive_file = self.getInputFromPort("archive_file")
+        self.check_input("archive_file")
+        archive_file = self.get_input("archive_file")
         if not os.path.isfile(archive_file.name):
             raise ModuleError(self, "archive file does not exist")
         output = self.interpreter.filePool.create_directory()
-        s = zip_extract_all_files(archive_file.name,
-                                  output.name)
-        if s != 0:
-            raise ModuleError(self, "unzip command failed with status %d" % s)
-        self.setResult("directory", output)
+        zip_extract_all_files(archive_file.name,
+                              output.name)
+        self.set_output("directory", output)
 
 ##############################################################################
 
 class Round(Converter):
     """Turns a Float into an Integer.
     """
+    _settings = ModuleSettings(hide_descriptor=True)
+    _input_ports = [IPort('in_value', 'Float'),
+                    IPort('floor', 'Boolean', optional=True, default="True")]
+    _output_ports = [OPort('out_value', 'Integer')]
+
     def compute(self):
-        fl = self.getInputFromPort('in_value')
-        floor = self.getInputFromPort('floor')
+        fl = self.get_input('in_value')
+        floor = self.get_input('floor')
         if floor:
             integ = int(fl)         # just strip the decimals
         else:
             integ = int(fl + 0.5)   # nearest
-        self.setResult('out_value', integ)
+        self.set_output('out_value', integ)
 
 
 class TupleToList(Converter):
     """Turns a Tuple into a List.
     """
+    _settings = ModuleSettings(hide_descriptor=True)
+    _input_ports = [IPort('in_value', 'Variant')]
+    _output_ports = [OPort('out_value', 'List')]
+    
     @classmethod
     def can_convert(cls, sub_descs, super_descs):
         if len(sub_descs) <= 1:
@@ -1087,10 +1167,10 @@ class TupleToList(Converter):
         return super_descs == [reg.get_descriptor(List)]
 
     def compute(self):
-        tu = self.getInputFromPort('in_value')
+        tu = self.get_input('in_value')
         if not isinstance(tu, tuple):
             raise ModuleError(self, "Input is not a tuple")
-        self.setResult('out_value', list(tu))
+        self.set_output('out_value', list(tu))
 
 ##############################################################################
     
@@ -1100,7 +1180,62 @@ class Variant(Module):
     output port. For input port, Module type should be used
     
     """
-    pass
+    _settings = ModuleSettings(abstract=True)
+
+##############################################################################
+
+class Generator(object):
+    """
+    Used to keep track of list iteration, it will execute a module once for
+    each input in the list/generator.
+    """
+    _settings = ModuleSettings(abstract=True)
+
+    generators = []
+    def __init__(self, size=None, module=None, generator=None, port=None,
+                 accumulated=False):
+        self.module = module
+        self.generator = generator
+        self.port = port
+        self.size = size
+        self.accumulated = accumulated
+        if generator and module not in Generator.generators:
+            # add to global list of generators
+            # they will be topologically ordered
+            module.generator = generator
+            Generator.generators.append(module)
+            
+    def next(self):
+        """ return next value - the generator """
+        value = self.module.get_output(self.port)
+        if isinstance(value, Generator):
+            value = value.all()
+        return value
+    
+    def all(self):
+        """ exhausts next() for Streams
+        
+        """
+        items = []
+        item = self.next()
+        while item is not None:
+            items.append(item)
+            item = self.next()
+        return items
+
+    @staticmethod
+    def stream():
+        """ executes all generators until inputs are exhausted
+            this makes sure branching and multiple sinks are executed correctly
+
+        """
+        result = True
+        if not Generator.generators:
+            return
+        while result is not None:
+            for g in Generator.generators:
+                result = g.next()
+        Generator.generators = []
 
 ##############################################################################
 
@@ -1108,8 +1243,10 @@ class Assert(Module):
     """
     Assert is a simple module that conditionally stops the execution.
     """
+    _input_ports = [IPort('condition', 'Boolean')]
+
     def compute(self):
-        condition = self.getInputFromPort('condition')
+        condition = self.get_input('condition')
         if not condition:
             raise ModuleError(self, "Assert: condition is False",
                               abort=True)
@@ -1121,11 +1258,19 @@ class AssertEqual(Module):
 
     It is provided for convenience.
     """
+
+    _input_ports = [IPort('value1', 'Variant'),
+                    IPort('value2', 'Variant')]
+
     def compute(self):
-        values = (self.getInputFromPort('value1'),
-                  self.getInputFromPort('value2'))
+        values = (self.get_input('value1'),
+                  self.get_input('value2'))
         if values[0] != values[1]:
-            raise ModuleError(self, "AssertEqual: values are different",
+            reprs = tuple(repr(v) for v in values)
+            reprs = tuple('%s...' % v[:17] if len(v) > 20 else v
+                          for v in reprs)
+            raise ModuleError(self, "AssertEqual: values are different: "
+                                    "%r, %r" % reprs,
                               abort=True)
 
 ##############################################################################
@@ -1134,6 +1279,12 @@ class StringFormat(Module):
     """
     Builds a string from objects using Python's str.format().
     """
+    _settings = ModuleSettings(configure_widget=
+        'vistrails.gui.modules.stringformat_configuration:'
+            'StringFormatConfigurationWidget')
+    _input_ports = [IPort('format', String)]
+    _output_ports = [OPort('value', String)]
+
     @staticmethod
     def list_placeholders(fmt):
         placeholders = set()
@@ -1167,13 +1318,13 @@ class StringFormat(Module):
         return nb, placeholders
 
     def compute(self):
-        fmt = self.getInputFromPort('format')
+        fmt = self.get_input('format')
         args, kwargs = StringFormat.list_placeholders(fmt)
-        f_args = [self.getInputFromPort('_%d' % n)
+        f_args = [self.get_input('_%d' % n)
                   for n in xrange(args)]
-        f_kwargs = dict((n, self.getInputFromPort(n))
+        f_kwargs = dict((n, self.get_input(n))
                         for n in kwargs)
-        self.setResult('value', fmt.format(*f_args, **f_kwargs))
+        self.set_output('value', fmt.format(*f_args, **f_kwargs))
 
 ##############################################################################
 
@@ -1183,221 +1334,138 @@ def init_constant(m):
     reg.add_module(m)
     reg.add_input_port(m, "value", m)
     reg.add_output_port(m, "value", m)
-    
-def initialize(*args, **kwargs):
-    reg = get_module_registry()
-
-    # !!! is_root should only be set for Module !!!
-    reg.add_module(Module, is_root=True, abstract=True)
-    reg.add_output_port(Module, "self", Module, optional=True)
-
-    reg.add_module(Converter, abstract=True)
-    reg.add_input_port(Converter, 'in_value', Module)
-    reg.add_output_port(Converter, 'out_value', Module)
-
-    reg.add_module(Constant, abstract=True)
 
-    reg.add_module(Boolean)
-    reg.add_module(Float)
-    reg.add_module(Integer)
-    reg.add_module(String,
-                   configureWidgetType=("vistrails.gui.modules.string_configure",
-                                        "TextConfigurationWidget"))
-    
-    reg.add_output_port(Constant, "value_as_string", String)
-    reg.add_output_port(String, "value_as_string", String, True)
-
-    reg.add_module(List,
-                   configureWidgetType=(
-                           "vistrails.gui.modules.list_configuration",
-                           "ListConfigurationWidget"))
-    reg.add_input_port(List, "head", Module)
-    reg.add_input_port(List, "tail", List)
-
-    reg.add_module(Path)
-    reg.add_input_port(Path, "value", Path)
-    reg.add_output_port(Path, "value", Path)
-    reg.add_input_port(Path, "name", String, True)
-
-    reg.add_module(File, constantSignatureCallable=path_parameter_hasher)
-    reg.add_input_port(File, "value", File)
-    reg.add_output_port(File, "value", File)
-    reg.add_output_port(File, "self", File, True)
-    reg.add_input_port(File, "create_file", Boolean, True)
-    reg.add_output_port(File, "local_filename", String, True)
-
-    reg.add_module(Directory, constantSignatureCallable=path_parameter_hasher)
-    reg.add_input_port(Directory, "value", Directory)
-    reg.add_output_port(Directory, "value", Directory)
-    reg.add_output_port(Directory, "itemList", List)
-    reg.add_input_port(Directory, "create_directory", Boolean, True)
-
-    reg.add_module(OutputPath)
-    reg.add_output_port(OutputPath, "value", OutputPath)
-
-    reg.add_module(FileSink)
-    reg.add_input_port(FileSink, "file", File)
-    reg.add_input_port(FileSink, "outputPath", OutputPath)
-    reg.add_input_port(FileSink, "overwrite", Boolean, True, 
-                       defaults="('True',)")
-    reg.add_input_port(FileSink,  "publishFile", Boolean, True)
-    
-    reg.add_module(DirectorySink)
-    reg.add_input_port(DirectorySink, "dir", Directory)
-    reg.add_input_port(DirectorySink, "outputPath", OutputPath)
-    reg.add_input_port(DirectorySink, "overwrite", Boolean, True, 
-                       defaults="('True',)")
-
-    reg.add_module(WriteFile)
-    reg.add_input_port(WriteFile, 'in_value', String)
-    reg.add_input_port(WriteFile, 'suffix', String, True, defaults='[""]')
-    reg.add_output_port(WriteFile, 'out_value', File)
-
-    reg.add_module(Color)
-    reg.add_input_port(Color, "value", Color)
-    reg.add_output_port(Color, "value", Color)
-
-    reg.add_module(StandardOutput)
-    reg.add_input_port(StandardOutput, "value", Module)
-
-    reg.add_module(Tuple, 
-                   configureWidgetType=("vistrails.gui.modules.tuple_configuration",
-                                        "TupleConfigurationWidget"))
-
-    reg.add_module(Untuple, 
-                   configureWidgetType=("vistrails.gui.modules.tuple_configuration",
-                                        "UntupleConfigurationWidget"))
-
-    reg.add_module(ConcatenateString)
-    for i in xrange(ConcatenateString.fieldCount):
-        j = i+1
-        port = "str%s" % j
-        reg.add_input_port(ConcatenateString, port, String)
-    reg.add_output_port(ConcatenateString, "value", String)
-
-    reg.add_module(Not)
-    reg.add_input_port(Not, 'input', Boolean)
-    reg.add_output_port(Not, 'value', Boolean)
-
-    reg.add_module(Dictionary)
-    reg.add_input_port(Dictionary, "addPair", [Module, Module])
-    reg.add_input_port(Dictionary, "addPairs", List)
-
-    reg.add_module(Null, hide_descriptor=True)
-
-    reg.add_module(Variant, abstract=True)
-
-    reg.add_module(Assert)
-    reg.add_input_port(Assert, 'condition', Boolean)
-
-    reg.add_module(AssertEqual)
-    reg.add_input_port(AssertEqual, 'value1', Module)
-    reg.add_input_port(AssertEqual, 'value2', Module)
-
-    reg.add_module(Unpickle, hide_descriptor=True)
-    reg.add_input_port(Unpickle, 'input', String)
-    reg.add_output_port(Unpickle, 'result', Variant)
-
-    reg.add_module(PythonSource,
-                   configureWidgetType=("vistrails.gui.modules.python_source_configure",
-                                        "PythonSourceConfigurationWidget"))
-    reg.add_input_port(PythonSource, 'source', String, True, defaults=str(['']))
-    reg.add_output_port(PythonSource, 'self', Module)
-
-    reg.add_module(SmartSource,
-                   configureWidgetType=("vistrails.gui.modules.python_source_configure",
-                                        "PythonSourceConfigurationWidget"))
-    reg.add_input_port(SmartSource, 'source', String, True, defaults=str(['']))
-
-    reg.add_module(Unzip)
-    reg.add_input_port(Unzip, 'archive_file', File)
-    reg.add_input_port(Unzip, 'filename_in_archive', String)
-    reg.add_output_port(Unzip, 'file', File)
-
-    reg.add_module(UnzipDirectory)
-    reg.add_input_port(UnzipDirectory, 'archive_file', File)
-    reg.add_output_port(UnzipDirectory, 'directory', Directory)
-
-    reg.add_module(Round, hide_descriptor=True)
-    reg.add_input_port(Round, 'in_value', Float)
-    reg.add_output_port(Round, 'out_value', Integer)
-    reg.add_input_port(Round, 'floor', Boolean, optional=True,
-                       defaults="('True',)")
-
-    reg.add_module(TupleToList, hide_descriptor=True)
-    reg.add_input_port(TupleToList, 'in_value', Variant)
-    reg.add_output_port(TupleToList, 'out_value', List)
-
-    reg.add_module(StringFormat,
-                   configureWidgetType=(
-                           "vistrails.gui.modules.stringformat_configuration",
-                           "StringFormatConfigurationWidget"))
-    reg.add_input_port(StringFormat, 'format', String)
-    reg.add_output_port(StringFormat, 'value', String)
+_modules = [Module, Converter, Constant, Boolean, Float, Integer, String, List,
+            Path, File, Directory, OutputPath,
+            FileSink, DirectorySink, WriteFile, ReadFile, StandardOutput,
+            Tuple, Untuple, ConcatenateString, Not, Dictionary, Null, Variant,
+            Unpickle, PythonSource, Unzip, UnzipDirectory, Color,
+            Round, TupleToList, Assert, AssertEqual, StringFormat]
 
+def initialize(*args, **kwargs):
     # initialize the sub_module modules, too
     import vistrails.core.modules.sub_module
-    vistrails.core.modules.sub_module.initialize(*args, **kwargs)
+    import vistrails.core.modules.output_modules
+    _modules.extend(vistrails.core.modules.sub_module._modules)
+    _modules.extend(vistrails.core.modules.output_modules._modules)
 
 
 def handle_module_upgrade_request(controller, module_id, pipeline):
-   from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
-   reg = get_module_registry()
-
-   def outputName_remap(old_conn, new_module):
-       ops = []
-       old_src_module = pipeline.modules[old_conn.source.moduleId]
-       op_desc = reg.get_descriptor(OutputPath)
-       new_x = (old_src_module.location.x + new_module.location.x) / 2.0
-       new_y = (old_src_module.location.y + new_module.location.y) / 2.0
-       op_module = \
-           controller.create_module_from_descriptor(op_desc, new_x, new_y)
-       ops.append(('add', op_module))
-       create_new_connection = UpgradeWorkflowHandler.create_new_connection
-       new_conn_1 = create_new_connection(controller,
-                                          old_src_module,
-                                          old_conn.source,
-                                          op_module,
-                                          "name")
-       ops.append(('add', new_conn_1))
-       new_conn_2 = create_new_connection(controller,
-                                          op_module,
-                                          "value",
-                                          new_module,
-                                          "outputPath")
-       ops.append(('add', new_conn_2))
-       return ops
-
-   module_remap = {'FileSink':
-                       [(None, '1.6', None,
-                         {'dst_port_remap':
-                              {'overrideFile': 'overwrite',
-                               'outputName': outputName_remap},
-                          'function_remap':
-                              {'overrideFile': 'overwrite',
-                               'outputName': 'outputPath'}})],
-                   'GetItemsFromDirectory':
-                       [(None, '1.6', 'Directory',
-                         {'dst_port_remap':
-                              {'dir': 'value'},
-                          'src_port_remap':
-                              {'itemlist': 'itemList'},
-                          })],
-                   'InputPort':
-                       [(None, '1.6', None,
-                         {'dst_port_remap': {'old_name': None}})],
-                   'OutputPort':
-                       [(None, '1.6', None,
-                         {'dst_port_remap': {'old_name': None}})],
-                   'PythonSource':
-                       [(None, '1.6', None, {})],
-                   'Tuple':
-                       [(None, '2.1', None, {})],
-                   }
-
-   return UpgradeWorkflowHandler.remap_module(controller, module_id, pipeline,
-                                              module_remap)
+    from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
+    reg = get_module_registry()
 
+    def outputName_remap(old_conn, new_module):
+        ops = []
+        old_src_module = pipeline.modules[old_conn.source.moduleId]
+        op_desc = reg.get_descriptor(OutputPath)
+        new_x = (old_src_module.location.x + new_module.location.x) / 2.0
+        new_y = (old_src_module.location.y + new_module.location.y) / 2.0
+        op_module = \
+            controller.create_module_from_descriptor(op_desc, new_x, new_y)
+        ops.append(('add', op_module))
+        create_new_connection = UpgradeWorkflowHandler.create_new_connection
+        new_conn_1 = create_new_connection(controller,
+                                           old_src_module,
+                                           old_conn.source,
+                                           op_module,
+                                           "name")
+        ops.append(('add', new_conn_1))
+        new_conn_2 = create_new_connection(controller,
+                                           op_module,
+                                           "value",
+                                           new_module,
+                                           "outputPath")
+        ops.append(('add', new_conn_2))
+        return ops
+
+    module_remap = {'FileSink':
+    [(None, '1.6', None,
+                          {'dst_port_remap':
+                               {'overrideFile': 'overwrite',
+                                'outputName': outputName_remap},
+                           'function_remap':
+                               {'overrideFile': 'overwrite',
+                                'outputName': 'outputPath'}})],
+                    'GetItemsFromDirectory':
+                        [(None, '1.6', 'Directory',
+                          {'dst_port_remap':
+                               {'dir': 'value'},
+                           'src_port_remap':
+                               {'itemlist': 'itemList'},
+                           })],
+                    'InputPort':
+                        [(None, '1.6', None,
+                          {'dst_port_remap': {'old_name': None}})],
+                    'OutputPort':
+                        [(None, '1.6', None,
+                          {'dst_port_remap': {'old_name': None}})],
+                    'PythonSource':
+                        [(None, '1.6', None, {})],
+                    'Tuple':
+                        [(None, '2.1.1', None, {})],
+                    'StandardOutput':
+                        [(None, '2.1.1', None, {})],
+                    'List':
+                        [(None, '2.1.1', None, {})],
+                    'AssertEqual':
+                        [(None, '2.1.1', None, {})],
+                    'Converter':
+                        [(None, '2.1.1', None, {})],
+                    }
+
+    return UpgradeWorkflowHandler.remap_module(controller, module_id, pipeline,
+                                               module_remap)
+
+###############################################################################
+
+class NewConstant(Constant):
+    """
+    A new Constant module to be used inside the FoldWithModule module.
+    """
+    def setValue(self, v):
+        self.set_output("value", v)
+        self.upToDate = True
+
+def create_constant(value):
+    """
+    Creates a NewConstant module, to be used for the ModuleConnector.
+    """
+    constant = NewConstant()
+    constant.setValue(value)
+    return constant
+
+def get_module(value, signature=None):
+    """
+    Creates a module for value, in order to do the type checking.
+    """
+    if isinstance(value, Constant):
+        return type(value)
+    elif isinstance(value, bool):
+        return Boolean
+    elif isinstance(value, str):
+        return String
+    elif isinstance(value, int):
+        return Integer
+    elif isinstance(value, float):
+        return Float
+    if isinstance(value, list):
+        return List
+    elif isinstance(value, tuple):
+        # Variant supports signatures of any length
+        if signature is None or \
+           (len(signature) == 1 and signature[0][0] == Variant):
+            return (Variant,)*len(value)
+        v_modules = ()
+        for element in xrange(len(value)):
+            v_modules += (get_module(value[element], signature[element]),)
+        if None in v_modules: # Identification failed
+            return None
+        return v_modules
+    else: # pragma: no cover
+        debug.warning("Could not identify the type of the list element.")
+        debug.warning("Type checking is not going to be done inside "
+                      "iterated module.")
+        return None
 
 ###############################################################################
 
@@ -1526,7 +1594,8 @@ class TestList(unittest.TestCase):
 
         # Multiple values on 'value'
         res = self.build_list(value=['["a", "b"]', '["c", "d"]'])
-        self.assertIn(res, [["a", "b"], ["c", "d"]])
+        # Connections of List type are merged
+        self.assertEqual(res, ["a", "b", "c", "d"])
 
     def test_items(self):
         """Tests the multiple 'itemN' ports"""
@@ -1653,20 +1722,20 @@ class TestTypechecking(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         conf = get_vistrails_configuration()
-        cls.error_all = conf.errorOnConnectionTypeerror
-        cls.error_variant = conf.errorOnVariantTypeerror
+        cls.error_all = conf.showConnectionErrors
+        cls.error_variant = conf.showVariantErrors
 
     @classmethod
     def tearDownClass(cls):
         conf = get_vistrails_configuration()
-        conf.errorOnConnectionTypeerror = cls.error_all
-        conf.errorOnVariantTypeerror = cls.error_variant
+        conf.showConnectionErrors = cls.error_all
+        conf.showVariantErrors = cls.error_variant
 
     @staticmethod
     def set_settings(error_all, error_variant):
         conf = get_vistrails_configuration()
-        conf.errorOnConnectionTypeerror = error_all
-        conf.errorOnVariantTypeerror = error_variant
+        conf.showConnectionErrors = error_all
+        conf.showVariantErrors = error_variant
 
     def run_test_pipeline(self, result, expected_results, *args, **kwargs):
         from vistrails.tests.utils import execute, intercept_result
@@ -1711,7 +1780,7 @@ class TestTypechecking(unittest.TestCase):
     def test_fake(self):
         import urllib2
         # A module is lying, declaring a String but returning an int
-        # This should fail with errorOnConnectionTypeerror=True (not the
+        # This should fail with showConnectionErrors=True (not the
         # default)
         self.run_test_pipeline(
             (PythonSource, 'r'),
@@ -1793,10 +1862,9 @@ class TestStringFormat(unittest.TestCase):
                         a=('Integer', '42'),
                         c=('Integer', '12'))
 
+    # Python 2.6 doesn't support {}
+    @unittest.skipIf(sys.version_info < (2, 7), "No {} support on 2.6")
     def test_format_27(self):
-        # Python 2.6 doesn't support {}
-        if (sys.version_info < (2, 7)):
-            raise unittest.SkipTest("No {} support on 2.6")
         self.run_format('{} {}', 'a b',
                         _0=('String', 'a'), _1=('String', 'b'))
         self.run_format('{{ {a} {} {b!s}', '{ 42 b 12',
@@ -1806,3 +1874,27 @@ class TestStringFormat(unittest.TestCase):
                         _0=('String', 'hello'), _1=('String', 'dear'),
                         _2=('String', 'world'), _3=('Float', '1.333333333'),
                         ponc=('String', '!'))
+
+
+class TestConstantMetaclass(unittest.TestCase):
+    def test_meta(self):
+        """Tests the __metaclass__ for Constant.
+        """
+        mod1_in = [('value', 'basic:String'), IPort('other', 'basic:Float')]
+        mod1_out = [('someport', 'basic:Integer')]
+        class Mod1(Constant):
+            _input_ports = mod1_in
+            _output_ports = mod1_out
+        self.assertEqual(Mod1._input_ports, mod1_in)
+        self.assertEqual(Mod1._output_ports, [('value', Mod1)] + mod1_out)
+
+        mod2_in = [('another', 'basic:String')]
+        class Mod2(Mod1):
+            _input_ports = mod2_in
+        self.assertEqual(Mod2._input_ports, [('value', Mod2)] + mod2_in)
+        self.assertEqual(Mod2._output_ports, [('value', Mod2)])
+
+        class Mod3(Mod1):
+            _output_ports = []
+        self.assertEqual(Mod3._input_ports, [('value', Mod3)])
+        self.assertEqual(Mod3._output_ports, [('value', Mod3)])
diff --git a/vistrails/core/modules/config.py b/vistrails/core/modules/config.py
new file mode 100644
index 0000000..335298b
--- /dev/null
+++ b/vistrails/core/modules/config.py
@@ -0,0 +1,540 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from collections import namedtuple as _namedtuple, Mapping
+from itertools import izip
+
+_docs = {}
+
+def get_field_name(v):
+    if isinstance(v[0], tuple):
+        return v[0][0]
+    return v[0]
+
+def namedtuple(typename, fields):
+    field_names = [get_field_name(f) for f in fields]
+    default_values = []
+    default_found = False
+    field_types = []
+    docstrings = []
+
+    new_fields = []
+    for f in fields:
+        field_name = get_field_name(f)
+        field_key = (typename, field_name)
+        field_type = None
+        docstring = None
+        default_value = None
+        if field_key in _docs:
+            (field_type, docstring) = _docs[field_key]
+        else:
+            if len(f) > 1 and f[1]:
+                field_type = f[1]
+            if len(f) > 2 and f[2]:
+                docstring = f[2]
+
+        if isinstance(f[0], tuple):
+            default_found = True
+            default_value = f[0][1]
+            default_values.append(default_value)
+        elif default_found:
+            raise Exception('Field "%s" must have default value since the '
+                            'preceding field does.' % f[0])
+        if field_type:
+            field_types.append("(%s)" % field_type)
+        else:
+            field_types.append("")
+        if docstring:
+            docstrings.append("\n        %s\n" % docstring)
+        else:
+            docstrings.append("")
+
+        new_fields.append(((field_name, default_value), field_type, docstring))
+    
+    fields = new_fields
+
+    T = _namedtuple(typename, field_names)
+    args = []
+    if len(default_values) > 0:
+        T.__new__.__defaults__ = tuple(default_values)
+        args.extend("%s=%s" % (field_name, '"%s"' % default_val \
+                               if isinstance(default_val, basestring) \
+                               else default_val) \
+                    for (field_name, default_val) in \
+                    izip(reversed(field_names), reversed(default_values)))
+        args.reverse()
+        args = field_names[:len(field_names)-len(default_values)] + args
+    else:
+        args = field_names
+    
+    init_docstring = ""
+    for (field_name, field_type, docstring) in \
+        izip(field_names, field_types, docstrings):
+        init_docstring += "    .. py:attribute:: %s %s\n%s\n" % \
+                          (field_name, field_type, docstring)
+
+    init_template = "def __init__(self, %s): pass" % ', '.join(args)
+    d = {}
+    exec init_template in d
+    T.__init__ = d['__init__']
+    T.__init__.im_func.__doc__ = init_docstring
+    T._vistrails_fields = fields
+
+    return T
+    
+
+def subnamedtuple(typename, cls, new_fields=[], override_fields=[]):
+    override_dict = dict((get_field_name(f), f) for f in override_fields)
+    fields = []
+    for f in cls._vistrails_fields:
+        field_name = get_field_name(f)
+        if field_name in override_dict:
+            fields.append(override_dict[field_name])
+        else:
+            fields.append(f)
+    fields.extend(new_fields)
+
+    return namedtuple(typename, fields)
+    
+_documentation = \
+"""
+   ConstantWidgetConfig.widget: QWidget | String
+
+      The widget to be used either as the class itself or a string of
+      the form ``<py_module>:<class>``
+      (e.g. "vistrails.gui.modules.constant_configuration:BooleanWidget")
+
+   ConstantWidgetConfig.widget_type: String
+
+      A developer-available type that links a widget to a port entry_type
+
+   ConstantWidgetConfig.widget_use: String
+
+      Intended to differentiate widgets for different purposes in
+      VisTrails.  Currently uses the values None, "query", and
+      "paramexp" to define widget uses in parameter, query, and
+      parameter exploration configurations, repsectively.
+
+   QueryWidgetConfig.widget_use: String
+
+      Like :py:attr:`ConstantWidgetConfig.widget_use`, just defaulted
+      to "query"
+
+   ParamExpWidgetConfig.widget_use: String
+
+      Like :py:attr:`ConstantWidgetConfig.widget_use`, just defaulted
+      to "paramexp"
+
+   ModuleSettings.name: String
+
+      An optional string that will identify the module (defaults to
+      the module class's ``__name__``).
+
+   ModuleSettings.configure_widget: QWidget | PathString
+
+      An optional module configuration widget that is provided so that
+      users can configure the module (e.g. PythonSource uses a widget
+      to display a code editor more suited for writing code).
+
+   ModuleSettings.constant_widget: ConstantWidgetConfig | QWidget | PathString
+
+      If not None, the registry will use the specified widget(s) or
+      import path string(s) of the form "<module>:<class>" to import
+      the widget.  A tuple allows a user to specify the widget_type
+      (e.g. "default", "enum", etc.)  as the second item and the
+      widget_use (e.g. "default", "query", "paramexp").  If the plural
+      form is used, we expect a list, the singular form is used for a
+      single item.
+
+   ModuleSettings.constant_widgets: List(constant_widget)
+
+      See :py:attr:`ModuleSettings.constant_widget`
+
+   ModuleSettings.signature: Callable
+
+      If not None, then the cache uses this callable as the function
+      to generate the signature for the module in the cache. The
+      function should take three parameters: the pipeline (of type
+      vistrails.core.vistrail.Pipeline), the module (of type
+      vistrails.core.vistrail.Module), and a dict that stores
+      parameter hashers. This dict is supposed to be passed to
+      vistrails/core/cache/hasher.py:Hasher, in case that needs to be
+      called.
+
+   ModuleSettings.constant_signature: Callable
+
+      If not None, the cache uses this callable as the function used
+      to generate the signature for parameters of the associated
+      module's type.  This function should take a single argument (of
+      type vistrials.core.vistrail.module_param.ModuleParam) and
+      returns a SHA hash.
+
+   ModuleSettings.color: (Float, Float, Float)
+
+      In the GUI, the module will be colored according to the
+      specified RGB tuple where each value is a float in [0,1.0].
+
+   ModuleSettings.fringe: List((Float, Float))
+
+      If not None, generates custom lateral fringes for the module
+      boxes.  module_fringe must be a list of pairs of floats.  The
+      first point must be (0.0, 0.0), and the last must be (0.0,
+      1.0). This will be used to generate custom lateral fringes for
+      module boxes. All x values must be positive, and all y values
+      must be between 0.0 and 1.0. Alternatively, the user can set
+      :py:attr:`ModuleSettings.left_fringe` and
+      :py:attr:`ModuleSettings.right_fringe` to set two different
+      fringes.
+
+   ModuleSettings.left_fringe: List((Float, Float))
+
+      See :py:attr:`ModuleSettings.fringe`.
+
+   ModuleSettings.right_fringe: List((Float, Float))
+
+      See :py:attr:`ModuleSettings.fringe`.
+
+   ModuleSettings.abstract: Boolean
+
+      If True, means the module only serves as a base class for other
+      modules.  It will not appear in the module palette but may be
+      used as a input or output port type.
+
+   ModuleSettings.package: String
+
+      If not None, then we use this package instead of the current
+      one.  This is only intended to be used with local per-module
+      module registries (in other words: if you don't know what a
+      local per-module registry is, you can ignore this option).
+
+   ModuleSettings.namespace: String
+
+      If not None, then we associate a namespace with the module. A
+      namespace is essentially appended to the package identifier so
+      that multiple modules inside the same package can share the same
+      name.  Namespaces may be nested using the "|" separator.  For
+      example, "Tools|Mathematical" specified the Mathematical
+      namespace inside of the Tools namespace.
+
+   ModuleSettings.version: String
+
+      The module version.  This is usually used with subworkflows
+      where the underlying module may have different versions.  Not
+      recommended for general use at this time.
+
+   ModuleSettings.package_version: String
+
+      The current package version for the module.  As with
+      :py:attr:`ModuleSettings.package`, you shuold not use this
+      unless you know what you are doing as VisTrails will
+      automatically fill in this information for any normal package.
+
+   ModuleSettings.hide_namespace: Boolean
+
+      If True, the module palette will not display the namespace for
+      the module.  Used for subworkflows, otherwise it may be
+      confusing for users.
+
+   ModuleSettings.hide_descriptor: Boolean
+
+      If True, the module palette will not display that module in its
+      list (similar to abstract, but can be used when the module is
+      not truly abstract).
+
+   ModuleSettings.is_root: Boolean
+
+      Internal use only.  This is used to designate the base Module
+      class and should not be used by any other module.
+
+   ModuleSettings.ghost_package: String
+
+      If not None, then the 'ghost_identifier' is set on the
+      descriptor, which will cause the module to be displayed under
+      that package in the module palette, rather than the package
+      specified by the package argument (or current package).
+
+   ModuleSettings.ghost_package_version: String
+
+      If not None, then the attribute 'ghost_package_version' is set
+      on the descriptor.  Currently this value is unused, but
+      eventually if multiple packages with the same identifier but
+      different package versions are loaded simultaneously, this will
+      allow overriding the package_version to clean up the module
+      palette.
+
+   ModuleSettings.ghost_namespace: String
+
+      If not None, the descriptor will be displayed under the
+      specified namespace instead of the 'namespace' attribute of the
+      descriptor.
+
+   Port.name: String
+
+      The name of the of the port
+
+   Port.signature: String
+
+      The signature of the of the port (e.g. "basic:Float")
+
+   Port.optional: Boolean
+
+      Whether the port should be visible by default (defaults to True)
+
+   Port.sort_key: Integer
+
+      An integer value that indicates where, relative to other ports,
+      this port should appear visually
+
+   Port.docstring: String
+
+      Documentation for the port
+
+   Port.shape: "triangle" | "diamond" | "circle" | [(Float,Float)]
+
+      The shape of the port.  If triangle, appending an angle (in
+      degrees) rotates the triangle.  If a list of (x,y) tuples,
+      specifies points of a polygon in the [0,1] x [0,1] region
+
+   Port.min_conns: Integer
+
+      The minimum number of values required for the port
+
+   Port.max_conns: Integer
+
+      The maximum number of values allowed for the port
+
+   Port.depth: Integer
+
+      The list depth of the port. Default is 0 (no list)
+      
+   InputPort.label: String
+
+      A label to be shown with a port
+
+   InputPort.default:
+
+      The default value for a constant-typed port
+
+   InputPort.values: List
+
+      A list of enumerated values that a
+      :py:class:`.ConstantWidgetConfig` uses to configure the widget.
+      For example, the "enum" widget uses the entries to present an
+      exclusive list of choices.
+
+   InputPort.entry_type: String
+
+      The type of the configuration widget that should be used with
+      this port. Developers may use custom widgets on a port-by-port
+      basis by adding widgets with different
+      :py:attr:`ConstantWidgetConfig.widget_type` values and defining
+      the port\'s entry_type to match.
+
+   CompoundInputPort.labels: List(String)
+
+      A list of :py:attr:`InputPort.label`
+
+   CompoundInputPort.defaults: List
+
+      A list of :py:attr:`InputPort.default`
+
+   CompoundInputPort.values: List(List)
+
+      A list of :py:attr:`InputPort.values`
+
+   CompoundInputPort.entry_types: List(String)
+
+      A list of :py:attr:`InputPort.entry_type`
+
+   CompoundInputPort.items: List(InputPortItem)
+
+      Either use this field and break individual
+      labels/defaults/values/entry_types into
+      :py:class:`.InputPortItem` components or use the other four
+      fields.
+
+   CompoundInputPort.signature: String
+
+      The signature of the port (e.g. "basic:Integer, basic:Float").
+      Note that for compound ports, this may be instead included on a
+      per-component basis in :py:attr:`InputPortItem.signature`.
+
+   CompoundOutputPort.items: List(OutputPortItem)
+
+      Either use this field and break individual signatures into
+      :py:class:`.OutputPortItem` components or use the signature
+      field.
+
+   CompoundOutputPort.signature: String
+
+      The signature of the port (e.g. "basic:Integer, basic:Float").
+      Note that for compound ports, this may be instead included on a
+      per-component basis in :py:attr:`OutputPortItem.signature`.
+
+   PortItem.signature: String
+
+      See :py:attr:`InputPort.signature`
+
+   InputPortItem.label: String
+
+      See :py:attr:`InputPort.label`
+
+   InputPortItem.default:
+
+      See :py:attr:`InputPort.default`
+
+   InputPortItem.values: List
+
+      See :py:attr:`InputPort.values`
+
+   InputPortItem.entry_type: String
+
+      See :py:attr:`InputPort.entry_type`
+
+"""
+
+def parse_documentation():
+    line_iter = iter(_documentation.splitlines())
+    line_iter.next()
+    for line in line_iter:
+        field, field_type = line.strip().split(':', 1)
+        (cls_name, field_name) = field.split('.')
+        doc_lines = []
+        line = line_iter.next()
+        while True:
+            line = line_iter.next()
+            if not line.strip():
+                break
+            doc_lines.append(line.strip())
+        _docs[(cls_name, field_name)] = (field_type, ' '.join(doc_lines))
+
+parse_documentation()
+
+ConstantWidgetConfig = \
+    namedtuple('ConstantWidgetConfig', 
+               [('widget',),
+                (('widget_type', None),),
+                (('widget_use', None),)])
+QueryWidgetConfig = subnamedtuple('QueryWidgetConfig', ConstantWidgetConfig, 
+    override_fields=[(('widget_use', 'query'),)])
+ParamExpWidgetConfig = subnamedtuple('ParamExpWidgetConfig', 
+    ConstantWidgetConfig,
+    override_fields=[(('widget_use', 'paramexp'),)])
+
+ModuleSettings = namedtuple('ModuleSettings',
+                          [(('name', None),),
+                           (('configure_widget', None),),
+                           (('constant_widget', None),),
+                           (('constant_widgets', None),),
+                           (('signature', None),),
+                           (('constant_signature', None),),
+                           (('color', None),),
+                           (('fringe', None),),
+                           (('left_fringe', None),),
+                           (('right_fringe', None),),
+                           (('abstract', False),),
+                           (('package', None),),
+                           (('namespace', None),),
+                           (('version', None),),
+                           (('package_version', None),),
+                           (('hide_namespace', False),),
+                           (('hide_descriptor', False),),
+                           (('is_root', False),),
+                           (('ghost_package', None),),
+                           (('ghost_package_version', None),),
+                           (('ghost_namespace', None),),])
+
+Port = namedtuple('Port', 
+                     [("name",),
+                      ("signature",),
+                      (("optional", False),),
+                      (("sort_key", -1),),
+                      (("docstring", None),),
+                      (("shape", None),),
+                      (("min_conns", 0),),
+                      (("max_conns", -1),),
+                      (("depth", 0),),
+                      ])
+
+InputPort = subnamedtuple('InputPort', Port,
+                          [(('label', None),),
+                           (('default', None),),
+                           (('values', None),),
+                           (('entry_type', None),)])
+OutputPort = subnamedtuple('OutputPort', Port)
+
+CompoundPort = subnamedtuple('CompoundPort', Port,
+                             [(('items', None),)],
+                             [(('signature', None),)])
+CompoundInputPort = subnamedtuple('CompoundInputPort', CompoundPort,
+                                  [(('labels', None),), 
+                                   (('defaults', None),),
+                                   (('values', None),),
+                                   (('entry_types', None),)])
+CompoundOutputPort = subnamedtuple('CompoundOutputPort', CompoundPort)
+
+PortItem = namedtuple('PortItem', [('signature', None)])
+InputPortItem = subnamedtuple('InputPortItem', PortItem,
+                              [(('label', None),),
+                               (('default', None),),
+                               (('values', None),),
+                               (('entry_type', None),)])
+OutputPortItem = subnamedtuple('OutputPortItem', PortItem)
+
+DeprecatedInputPort = \
+                      namedtuple('DeprecatedInputPort',
+                                 [("name", "String",),
+                                  ("signature", "String",),
+                                  (("optional", True),),
+                                  (("sort_key", -1),),
+                                  (('labels', None),), 
+                                  (('defaults', None),),
+                                  (('values', None),),
+                                  (('entry_types', None),),
+                                  (("docstring", None),),
+                                  (("shape", None),),
+                                  (("min_conns", 0),),
+                                  (("max_conns", -1),),
+                              ])
+
+IPort = InputPort
+OPort = OutputPort
+CIPort = CompoundInputPort
+COPort = CompoundOutputPort
+IPItem = InputPortItem
+OPItem = OutputPortItem
diff --git a/vistrails/core/modules/constant_configuration.py b/vistrails/core/modules/constant_configuration.py
index ca9064b..aba6ebc 100644
--- a/vistrails/core/modules/constant_configuration.py
+++ b/vistrails/core/modules/constant_configuration.py
@@ -1,39 +1,43 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # *** MOVED *** to gui.modules.constant_configuration
+from __future__ import division
+
 import traceback
 from vistrails.core import debug
 
diff --git a/vistrails/core/modules/module_configure.py b/vistrails/core/modules/module_configure.py
index fa576d4..50b3df5 100644
--- a/vistrails/core/modules/module_configure.py
+++ b/vistrails/core/modules/module_configure.py
@@ -1,39 +1,43 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # *** MOVED *** to gui.modules.module_configure
+from __future__ import division
+
 import traceback
 from vistrails.core import debug
 
diff --git a/vistrails/core/modules/module_descriptor.py b/vistrails/core/modules/module_descriptor.py
index be535ab..40a5809 100644
--- a/vistrails/core/modules/module_descriptor.py
+++ b/vistrails/core/modules/module_descriptor.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 import pydoc
 
@@ -139,6 +142,7 @@ class ModuleDescriptor(DBModuleDescriptor):
             self._widget_item = None
             self._is_hidden = False
             self._namespace_hidden = False
+            self._widget_classes = {}
             self.children = []
             # The ghost attributes represent the original values
             # for the descriptor of an upgraded package subworkflow
@@ -163,6 +167,8 @@ class ModuleDescriptor(DBModuleDescriptor):
             self._hasher_callable = other._hasher_callable
             self._widget_item = other._widget_item
             self._is_hidden = other._is_hidden
+            self._widget_classes = dict((k,copy.copy(v)) for k, v in \
+                                         other._widget_classes.iteritems())
             self._namespace_hidden = other._namespace_hidden
             self.ghost_identifier = other.ghost_identifier
             self.ghost_package_version = other.ghost_package_version
@@ -250,6 +256,26 @@ class ModuleDescriptor(DBModuleDescriptor):
     def configuration_widget(self):
         return self._configuration_widget
 
+    def set_constant_config_widget(self, widget_class, widget_use, 
+                                   widget_type):
+        if widget_use not in self._widget_classes:
+            self._widget_classes[widget_use] = {}
+        self._widget_classes[widget_use][widget_type] = widget_class
+
+    def has_constant_config_widget(self, widget_use, widget_type):
+        return widget_use in self._widget_classes and \
+            widget_type in self._widget_classes[widget_use]
+
+    def get_constant_config_widget(self, widget_use, widget_type):
+        if self.has_constant_config_widget(widget_use, widget_type):
+            return self._widget_classes[widget_use][widget_type]
+        return None
+
+    def get_all_constant_config_widgets(self, widget_use):
+        if widget_use in self._widget_classes:
+            return self._widget_classes[widget_use]
+        return {}
+
     def set_module_color(self, color):
         if color:
             assert isinstance(color, tuple)
@@ -283,8 +309,9 @@ class ModuleDescriptor(DBModuleDescriptor):
             try:
                 doc = self.module.get_documentation(doc, module)
             except Exception, e:
-                import traceback
-                debug.critical(str(e), traceback.format_exc())
+                debug.critical("Exception calling get_documentation on %r" %
+                               self.module,
+                               e)
                 doc = doc or "(Error getting documentation)"
         doc = doc or "(No documentation available)"
         return doc
@@ -327,7 +354,7 @@ class ModuleDescriptor(DBModuleDescriptor):
                 "version=%s, base_descriptor_id=%s)" % \
                     (self.id, self.package, self.name, self.namespace,
                      self.version, self.base_descriptor_id))
- 
+
     ##########################################################################
     # Abstract module detection support
 
diff --git a/vistrails/core/modules/module_registry.py b/vistrails/core/modules/module_registry.py
index acdbc02..aa27ae2 100644
--- a/vistrails/core/modules/module_registry.py
+++ b/vistrails/core/modules/module_registry.py
@@ -1,57 +1,67 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from itertools import izip, chain
+from ast import literal_eval
+import collections
 import copy
 import os
 import tempfile
 import traceback
 import uuid
+import warnings
 
 from vistrails.core import debug, get_vistrails_application
 from vistrails.core.data_structures.graph import Graph
 import vistrails.core.modules
+from vistrails.core.modules.config import ConstantWidgetConfig, \
+    ModuleSettings, InputPort, OutputPort, CompoundInputPort, \
+    CompoundOutputPort, DeprecatedInputPort
 import vistrails.core.modules.vistrails_module
 from vistrails.core.modules.module_descriptor import ModuleDescriptor
 from vistrails.core.modules.package import Package
+from vistrails.core.requirements import MissingRequirement
 import vistrails.core.modules.utils
+from vistrails.core.modules.utils import create_port_spec_item_string
 from vistrails.core.utils import VistrailsInternalError, memo_method, \
-     InvalidModuleClass, ModuleAlreadyExists, append_to_dict_of_lists, \
-     all, profile, versions_increasing, InvalidPipeline
+    InvalidModuleClass, ModuleAlreadyExists, append_to_dict_of_lists, \
+    all, profile, versions_increasing, InvalidPipeline, VistrailsDeprecation
 from vistrails.core.system import vistrails_root_directory, vistrails_version, \
     get_vistrails_basic_pkg_id
-from vistrails.core.vistrail.port import Port, PortEndPoint
 from vistrails.core.vistrail.port_spec import PortSpec
 from vistrails.core.vistrail.port_spec_item import PortSpecItem
 import vistrails.core.cache.hasher
@@ -280,6 +290,7 @@ class ModuleRegistryException(Exception):
 
         return "RegistryException: %s%s%s" % (self._identifier,
                                               p_version_str, m_str)
+    __repr__ = __str__
 
     def __eq__(self, other):
         return type(self) == type(other) and \
@@ -314,6 +325,7 @@ class MissingPackage(ModuleRegistryException):
 
     def __str__(self):
         return "Missing package: %s" % self._identifier
+    __repr__ = __str__
 
     def _get_module_id(self):
         return None
@@ -331,6 +343,7 @@ class MissingModule(ModuleRegistryException):
     def __str__(self):
         return "Missing module %s in package %s" % (self._module_name,
                                                     self._package_name)
+    __repr__ = __str__
 
 class MissingPackageVersion(ModuleRegistryException):
     def __init__(self, identifier, version):
@@ -340,6 +353,7 @@ class MissingPackageVersion(ModuleRegistryException):
     def __str__(self):
         return "Missing version %s of package %s" % \
             (self._package_version, self._identifier)
+    __repr__ = __str__
 
 class MissingModuleVersion(ModuleRegistryException):
     def __init__(self, identifier, name, namespace, module_version, 
@@ -350,6 +364,7 @@ class MissingModuleVersion(ModuleRegistryException):
     def __str__(self):
         return "Missing version %s of module %s from package %s" % \
             (self._module_version, self._module_name, self._package_name)
+    __repr__ = __str__
 
 class AmbiguousResolution(ModuleRegistryException):
     def __init__(self, name, namespace, matches):
@@ -361,6 +376,7 @@ class AmbiguousResolution(ModuleRegistryException):
         return ("Ambiguous resolution of module %s.  Could resolve to:\n%s" % \
                     (self._module_name, 
                      ',\n'.join(str(m) for m in self.matches)))
+    __repr__ = __str__
 
 class MissingPort(ModuleRegistryException):
     def __init__(self, descriptor, port_name, port_type):
@@ -375,6 +391,7 @@ class MissingPort(ModuleRegistryException):
         return "Missing %s port %s from module %s in package %s" % \
             (self._port_type, self._port_name, self._module_name, 
              self._package_name)
+    __repr__ = __str__
 
 class PortMismatch(MissingPort):
     def __init__(self, identifier, name, namespace, port_name, port_type, port_sigstring):
@@ -392,6 +409,7 @@ class PortMismatch(MissingPort):
                 " in module %s of package %s") % \
                 (self._port_type.capitalize(), self._port_name,
                  self._port_sigstring, self._module_name, self._package_name)
+    __repr__ = __str__
 
 class PortsIncompatible(ModuleRegistryException):
 
@@ -423,6 +441,7 @@ class PortsIncompatible(ModuleRegistryException):
                                                        out_name,
                                                        self._input_port,
                                                        in_name))
+    __repr__ = __str__
 
 class DuplicateModule(ModuleRegistryException):
     def __init__(self, old_descriptor, new_identifier, new_name, 
@@ -443,6 +462,7 @@ class DuplicateModule(ModuleRegistryException):
                 "%s in package %s") % \
                 (self._module_name, self._package_name, old_name, 
                  self.old_descriptor.identifier)
+    __repr__ = __str__
 
 class DuplicateIdentifier(ModuleRegistryException):
     def __init__(self, identifier, name, namespace=None,
@@ -453,6 +473,7 @@ class DuplicateIdentifier(ModuleRegistryException):
     def __str__(self):
         return "There is already a module %s in package %s" % \
             (self._module_name, self._package_name)
+    __repr__ = __str__
 
 class InvalidPortSpec(ModuleRegistryException):
     def __init__(self, descriptor, port_name, port_type, exc):
@@ -469,6 +490,7 @@ class InvalidPortSpec(ModuleRegistryException):
                 'has bad specification\n  %s' % \
             (self._port_type, self._port_name, self._module_name,
              self._package_name, str(self._exc)))
+    __repr__ = __str__
 
 class MissingBaseClass(Exception):
     def __init__(self, base):
@@ -477,6 +499,7 @@ class MissingBaseClass(Exception):
 
     def __str__(self):
         return "Base class has not been registered : %s" % (self._base.__name__)
+    __repr__ = __str__
 
 class ModuleRegistry(DBRegistry):
     """ModuleRegistry serves as a registry of VisTrails modules.
@@ -636,24 +659,7 @@ class ModuleRegistry(DBRegistry):
         # this can be slow
         self.setup_indices()
 
-    def create_default_package(self):
-        basic_pkg = get_vistrails_basic_pkg_id()
-        default_codepath = os.path.join(vistrails_root_directory(), 
-                                        "core", "modules", "basic_modules.py")
-        self._default_package = \
-            Package(id=self.idScope.getNewId(Package.vtType),
-                    codepath=default_codepath,
-                    load_configuration=False,
-                    identifier=basic_pkg,
-                    name='Basic Modules',
-                    version=vistrails_version(),
-                    description="Basic modules for VisTrails")
-        # FIXME need to serialize old_identifiers!
-        self._default_package.old_identifiers = ['edu.utah.sci.vistrails.basic']
-        self.add_package(self._default_package)
-        return self._default_package
-
-    def has_abs_upgrade(self, identifier, name, namespace='', 
+    def has_abs_upgrade(self, identifier, name, namespace='',
                         package_version='', module_version=''):
 
         # if this fails, we want to raise the exception
@@ -682,28 +688,6 @@ class ModuleRegistry(DBRegistry):
     ##########################################################################
     # Per-module registry functions
 
-    def add_hierarchy(self, global_registry, module):
-        # a per-module registry needs to have all the module hierarchy
-        # registered there so that add_module doesn't fail with
-        # missing base class. We do _NOT_ add the ports, so watch out!
-        
-        reg = global_registry
-        d = reg.get_descriptor_by_name(module.package, module.name, 
-                                       module.namespace)
-        # we exclude the first module in the hierarchy because it's Module
-        # which we know exists (constructor adds)
-        hierarchy = reg.get_module_hierarchy(d)
-        for desc in reversed(hierarchy[:-1]):
-            old_base = desc.base_descriptor
-            base_descriptor = self.get_descriptor_by_name(old_base.package,
-                                                          old_base.name,
-                                                          old_base.namespace)
-            # FIXME: this package_version should live on descriptor?
-            package = self.get_package_by_name(desc.package)
-            self.update_registry(base_descriptor, desc.module, desc.package, 
-                                 desc.name, desc.namespace, package.version,
-                                 desc.version)
-
     def get_package_by_name(self, identifier, package_version=''):
         package_version = package_version or ''
         package_version_key = (identifier, package_version)
@@ -774,32 +758,28 @@ class ModuleRegistry(DBRegistry):
 
         try:
             package = self.packages[identifier]
-            if package_version:
-                package_version_key = (identifier, package_version)
-                package = self.package_versions[package_version_key]
-            if not module_version:
+        except KeyError:
+            raise MissingPackage(identifier)
+        if package_version:
+            try:
+                package = self.package_versions[(identifier, package_version)]
+            except KeyError:
+                raise MissingPackageVersion(identifier, package_version)
+        if not module_version:
+            try:
                 descriptor = package.descriptors[(name, namespace)]
-            else:
-                descriptor_version_key = (name, namespace, module_version)
+            except KeyError:
+                raise MissingModule(identifier, name, namespace,
+                                    package_version)
+        else:
+            descriptor_version_key = (name, namespace, module_version)
+            try:
                 descriptor = \
                     package.descriptor_versions[descriptor_version_key]
-            return descriptor
-        except KeyError:
-            if identifier not in self.packages:
-                raise MissingPackage(identifier)
-            elif (name, namespace) not in package.descriptors:
-                raise MissingModule(identifier, name, namespace, 
-                                    package_version)
-            elif package_version and \
-                    package_version_key not in self.package_versions:
-                raise MissingPackageVersion(identifier, package_version)
-            elif module_version and descriptor_version_key not in \
-                    package.descriptor_versions:
+            except KeyError:
                 raise MissingModuleVersion(identifier, name, namespace,
                                            module_version, package_version)
-            else:
-                raise ModuleRegistryException(identifier, name, namespace,
-                                              package_version, module_version)
+        return descriptor
 
     def get_similar_descriptor(self, identifier, name, namespace=None,
                                package_version=None, module_version=None):
@@ -812,10 +792,6 @@ class ModuleRegistry(DBRegistry):
         except MissingModuleVersion:
             return self.get_similar_descriptor(identifier, name, namespace,
                                                package_version, None)
-#         except Exception:
-#             raise
-
-        return None
             
     def get_descriptor(self, module):
         """get_descriptor(module: class) -> ModuleDescriptor
@@ -974,39 +950,134 @@ class ModuleRegistry(DBRegistry):
                                             package_version, version)
         return descriptor
 
+    def convert_port_val(self, val, sig=None, cls=None):
+        basic_pkg = get_vistrails_basic_pkg_id()
+        if sig is None and cls is None:
+            raise ValueError("One of sig or cls must be set")
+        try:
+            if sig is not None:
+                desc = self.get_descriptor_by_name(*sig)
+            else:
+                desc = self.get_descriptor(cls)
+        except Exception, e:
+            debug.unexpected_exception(e)
+            raise VistrailsInternalError("Cannot convert value %r due to "
+                                         "missing descriptor for port" % val)
+        constant_desc = self.get_descriptor_by_name(basic_pkg, 'Constant')
+        if not self.is_descriptor_subclass(desc, constant_desc):
+            raise TypeError("Cannot convert value for non-constant type")
+        if desc.module is None:
+            return None
+        
+        if not isinstance(val, basestring):
+            retval = desc.module.translate_to_string(val)
+        else:
+            checkval = desc.module.translate_to_python(val)
+            retval = desc.module.translate_to_string(checkval)
+            if isinstance(checkval, basestring) and retval != val:
+                # we have a string -> string conversion that doesn't
+                # match
+                retval = desc.module.translate_to_string(val)
+        return retval
+
+    def decode_port(self, port_info, simple_t, compound_t, deprecated_t,
+                    is_input):
+        if (not isinstance(port_info, simple_t) and
+                not isinstance(port_info, compound_t)):
+            port_name = port_info[0]
+            port_sig = port_info[1]
+            if len(port_info) > 2:
+                if isinstance(port_info[2], dict):
+                    port_info = compound_t(port_info[0],
+                                                port_info[1],
+                                                **port_info[2])
+
+                else:
+                    dep_port_info = deprecated_t(*port_info)
+                    port_info = \
+                        compound_t(**dep_port_info._asdict())
+            else:
+                port_info = compound_t(*port_info)
+
+        # convert simple ports to compound ones
+        kwargs = port_info._asdict()
+        port_name = kwargs.pop('name')
+        port_sig = kwargs.pop('signature')
+        if is_input and isinstance(port_info, simple_t):
+            kwargs['labels'] = [kwargs.pop('label')]
+            kwargs['defaults'] = [kwargs.pop('default')]
+            kwargs['values'] = [kwargs.pop('values')]
+            kwargs['entry_types'] = [kwargs.pop('entry_type')]
+        elif isinstance(port_info, compound_t):
+            # have compound port
+            port_items = kwargs.pop('items')
+            if port_items is not None:
+                sig_items = []
+                labels = []
+                defaults = []
+                values = []
+                entry_types = []
+                for item in port_info.items:
+                    if not isinstance(item.signature,
+                                      basestring):
+                        d = self.get_descriptor(item.signature)
+                        sig_items.append(create_port_spec_item_string(
+                            d.package, d.name, d.namespace))
+                    else:
+                        sig_items.append(item.signature)
+                    labels.append(item.label)
+                    defaults.append(item.default)
+                    values.append(item.values)
+                    entry_types.append(item.entry_type)
+                kwargs['signature'] = ','.join(sig_items)
+                if is_input:
+                    kwargs['labels'] = labels
+                    kwargs['defaults'] = defaults
+                    kwargs['values'] = values
+                    kwargs['entry_types'] = entry_types
+
+        return port_name, port_sig, kwargs
+
+    def decode_input_port(self, port_info):
+        return self.decode_port(
+                port_info,
+                InputPort, CompoundInputPort, DeprecatedInputPort,
+                True)
+
+    def decode_output_port(self, port_info):
+        return self.decode_port(
+                port_info,
+                OutputPort, CompoundOutputPort, OutputPort,
+                False)
+
     def auto_add_ports(self, module):
-        """auto_add_module(module or (module, kwargs)): add
+        """auto_add_ports(module or (module, kwargs)): add
         input/output ports to registry. Don't call this directly - it is
         meant to be used by the packagemanager, when inspecting the package
         contents."""
-        for (port_key, adder_f) in [('_input_ports', self.add_input_port),
-                                    ('_output_ports', self.add_output_port)]:
-            if port_key in module.__dict__:
-                for port_info in module.__dict__[port_key]:
-                    added = False
-                    if isinstance(port_info, PortSpec):
-                        # force port type to match list it occurs in
-                        # we just need "input" or "output"
-                        port_info.type = port_key[1:-6]
-                        descriptor = self.get_descriptor(module)
-                        self.add_port_spec(descriptor, port_info)
-                        added = True
-                    elif len(port_info) >= 2:
-                        port_name, port_sig = port_info[:2]
-                        if len(port_info) > 2 and \
-                                isinstance(port_info[2], dict):
-                            kwargs = port_info[2]
-                            adder_f(module, port_name, port_sig, **kwargs)
-                            added = True
-                        else:
-                            args = port_info[2:]
-                            adder_f(module, port_name, port_sig, *args)
-                            added = True
-                        
-                    if not added:
-                        raise TypeError("Expected (port_name, port_signature, "
-                                        "kwargs_dict) or (port_name, "
-                                        "port_signature, *args)")
+        if '_input_ports' in module.__dict__:
+            for port_info in module._input_ports:
+                try:
+                    name, sig, kwargs = self.decode_input_port(port_info)
+                    self.add_input_port(module, name, sig, **kwargs)
+                except Exception, e:
+                    debug.unexpected_exception(e)
+                    debug.critical('Failed to add input port "%s" to module '
+                                   '"%s"' % (name, module.__name__),
+                                   e)
+                    raise
+
+        if '_output_ports' in module.__dict__:
+            for port_info in module._output_ports:
+                try:
+                    name, sig, kwargs = self.decode_output_port(port_info)
+                    self.add_output_port(module, name, sig, **kwargs)
+                except Exception, e:
+                    debug.unexpected_exception(e)
+                    debug.critical('Failed to add output port "%s" to module '
+                                   '"%s"' % (name, module.__name__),
+                                   e)
+                    raise
 
     def auto_add_module(self, module):
         """auto_add_module(module or (module, kwargs)): add module
@@ -1025,136 +1096,82 @@ class ModuleRegistry(DBRegistry):
             raise TypeError("Expected module or (module, kwargs)")
 
     def add_module(self, module, **kwargs):
-        """add_module(module: class, **kwargs) -> Tree
-
-        kwargs:
-          name=None,
-          configureWidgetType=None,
-          signatureCallable=None,
-          moduleColor=None,
-          moduleFringe=None,
-          moduleLeftFringe=None,
-          moduleRightFringe=None,
-          abstract=None,
-          package=None,
-          namespace=None,
-          version=None,
-          package_version=None,
-          hide_namespace=False,
-          hide_descriptor=False,
-          is_root=False,
-          ghost_package=None,
-          ghost_package_version=None,
-          ghost_namespace=None,
-
-        Registers a new module with VisTrails. Receives the class
-        itself and an optional name that will be the name of the
-        module (if not given, uses module.__name__).  This module will
-        be available for use in pipelines.
-
-        If moduleColor is not None, then registry stores it so that
-        the gui can use it correctly. moduleColor must be a tuple of
-        three floats between 0 and 1.
-
-        if moduleFringe is not None, then registry stores it so that
-        the gui can use it correctly. moduleFringe must be a list of
-        pairs of floating points.  The first point must be (0.0, 0.0),
-        and the last must be (0.0, 1.0). This will be used to generate
-        custom lateral fringes for module boxes. It must be the case
-        that all x values must be positive, and all y values must be
-        between 0.0 and 1.0. Alternatively, the user can set
-        moduleLeftFringe and moduleRightFringe to set two different
-        fringes.
-
-        if package is not None, then we override the current package
-        to be the given one. This is only intended to be used with
-        local per-module module registries (in other words: if you
-        don't know what a local per-module registry is, you can ignore
-        this, and never use the 'package' option).        
-
-        If namespace is not None, then we associate a namespace with
-        the module. A namespace is essentially appended to the package
-        identifier so that multiple modules inside the same package
-        can share the same name.
-
-        If signatureCallable is not None, then the cache uses this
-        callable as the function to generate the signature for the
-        module in the cache. The function should take three
-        parameters: the pipeline (of type core.vistrail.Pipeline), the
-        module (of type core.vistrail.Module), and a dict that stores
-        parameter hashers. This dict is supposed to be passed to
-        core/cache/hasher.py:Hasher, in case that needs to be called.
-
-        If constantSignatureCallable is not None, then the cache uses
-        this callable as the funciton to generate the signature for
-        the given constant.  If this is not None, then the added
-        module must be a subclass of Constant.
-
-        If hide_namespace is True, the ModulePalette will not display
-        the namespace for that module.  If hide_descriptor is True,
-        the ModulePalette will not display that module in its list
-        (similar to abstract).
-
-        If is_root is True, the added module will become the root
-        module.  Note that this is only possible for the first module
-        added.
-        
-        If ghost_package is not None, then the 'ghost_identifier'
-        'ghost_identifier' is set on the descriptor, which will cause
-        the module to be displayed under that package in the module
-        palette, rather than the package specified by the
-        'identifier' attribute of the descriptor.
-        
-        If ghost_package_version is not None, then the attribute
-        'ghost_package_version' is set on the descriptor.  Currently
-        this value is unused, but eventually if multiple packages
-        with the same identifier but different package versions
-        are loaded simultaneously, this will allow overriding of
-        the package_version to associate with in the module palette.
+        """add_module(module: class, **kwargs) -> ModuleDescriptor
 
-        If ghost_namespace is not None, the descriptor will be
-        displayed under the specified namespace instead of the
-        'namespace' attribute of the descriptor.
+        See :py:class:`vistrails.core.modules.config.ModuleSettings`.
+        All of its attributes may also be used as kwargs to
+        add_module.
 
-        Notice: in the future, more named parameters might be added to
-        this method, and the order is not specified. Always call
-        add_module with named parameters.
+        """
+        def remap_dict(d):
+            remap = {'configureWidgetType': 'configure_widget',
+                     'constantWidget': 'constant_widget',
+                     'constantWidgets': 'constant_widgets',
+                     'signatureCallable': 'signature',
+                     'constantSignatureCallable': 'constant_signature',
+                     'moduleColor': 'color',
+                     'moduleFringe': 'fringe',
+                     'moduleLeftFringe': 'left_fringe',
+                     'moduleRightFringe': 'right_fringe',
+                     'is_abstract': 'abstract'}
+            remapped_d = {}
+            for k, v in d.iteritems():
+                if k in remap:
+                    remapped_d[remap[k]] = v
+                else:
+                    remapped_d[k] = v
+            return remapped_d
+
+        module_settings = None
+        if '_settings' in module.__dict__:
+            settings = module.__dict__['_settings']
+            if isinstance(settings, ModuleSettings):
+                module_settings = settings
+            elif isinstance(settings, dict):
+                module_settings = ModuleSettings(**remap_dict(settings))
+            else:
+                raise TypeError("Expected module._settings to be "
+                                "ModuleSettings or dict")
+                
+        remapped_kwargs = remap_dict(kwargs)
+        if module_settings is not None:
+            module_settings = module_settings._replace(**remapped_kwargs)
+        else:
+            module_settings = ModuleSettings(**remapped_kwargs)
+        return self.add_module_from_settings(module, module_settings)
+
+    def add_module_from_settings(self, module, settings):
+        """add_module(module: class, settings) -> ModuleDescriptor
+
+        See :py:class:`vistrails.core.modules.config.ModuleSettings`.
+        All of its attributes may also be used as kwargs to
+        add_module.
 
         """
-        # Setup named arguments. We don't use named parameters so
-        # that positional parameter calls fail earlier
-        def fetch(name, default):
-            r = kwargs.get(name, default)
-            try:
-                del kwargs[name]
-            except KeyError:
-                pass
-            return r
-        name = fetch('name', module.__name__)
-        configureWidgetType = fetch('configureWidgetType', None)
-        signatureCallable = fetch('signatureCallable', None)
-        constantSignatureCallable = fetch('constantSignatureCallable', None)
-        moduleColor = fetch('moduleColor', None)
-        moduleFringe = fetch('moduleFringe', None)
-        moduleLeftFringe = fetch('moduleLeftFringe', None) 
-        moduleRightFringe = fetch('moduleRightFringe', None)
-        is_abstract = fetch('abstract', False)
-        identifier = fetch('package', self._current_package.identifier)
-        namespace = fetch('namespace', None)
-        version = fetch('version', None)
-        package_version = fetch('package_version', 
-                                self._current_package.version)
-        hide_namespace = fetch('hide_namespace', False)
-        hide_descriptor = fetch('hide_descriptor', False)
-        is_root = fetch('is_root', False)
-        ghost_identifier = fetch('ghost_package', None)
-        ghost_package_version = fetch('ghost_package_version', None)
-        ghost_namespace = fetch('ghost_namespace', None)
-
-        if len(kwargs) > 0:
-            raise VistrailsInternalError(
-                'Wrong parameters passed to addModule: %s' % kwargs)
-        
+
+        def get_setting(attr, default_val):
+            val = getattr(settings, attr)
+            if val is None:
+                return default_val
+            return val
+
+        name = get_setting('name', module.__name__)
+
+        default_identifier = None
+        default_version = ""
+        if self._current_package is not None:
+            default_identifier = self._current_package.identifier
+            default_version = self._current_package.version
+        identifier = get_setting('package', default_identifier)
+        package_version = get_setting('package_version', default_version)
+        namespace = settings.namespace
+        version = settings.version
+
+        if identifier is None:
+            raise VistrailsInternalError("No package is currently being "
+                                         "loaded and arugment 'package' is "
+                                         "not specified.")
+
         package = self.package_versions[(identifier, package_version)]
         desc_key = (name, namespace, version)
         if desc_key in package.descriptor_versions:
@@ -1162,16 +1179,16 @@ class ModuleRegistry(DBRegistry):
 
         # We allow multiple inheritance as long as only one of the superclasses
         # is a subclass of Module.
-        if is_root:
+        if settings.is_root:
             base_descriptor = None
         else:
             candidates = self.get_subclass_candidates(module)
             if len(candidates) != 1:
                 raise InvalidModuleClass(module)
-            baseClass = candidates[0]
-            if not self._module_key_map.has_key(baseClass) :
-                raise MissingBaseClass(baseClass)
-            base_descriptor = self.get_descriptor(baseClass)
+            base_class = candidates[0]
+            if base_class not in self._module_key_map:
+                raise MissingBaseClass(base_class)
+            base_descriptor = self.get_descriptor(base_class)
 
         if module in self._module_key_map:
             # This is really obsolete as having two descriptors
@@ -1187,47 +1204,66 @@ class ModuleRegistry(DBRegistry):
         descriptor = self.update_registry(base_descriptor, module, identifier, 
                                           name, namespace, package_version,
                                           version)
-        if is_root:
+        if settings.is_root:
             self.root_descriptor = descriptor
 
-        descriptor.set_module_abstract(is_abstract)
-        descriptor.set_configuration_widget(configureWidgetType)
-        descriptor.is_hidden = hide_descriptor
-        descriptor.namespace_hidden = hide_namespace
+        descriptor.set_module_abstract(settings.abstract)
+        descriptor.set_configuration_widget(settings.configure_widget)
+        # descriptor.set_configuration_widget(configureWidget)
+        descriptor.is_hidden = settings.hide_descriptor
+        descriptor.namespace_hidden = settings.hide_namespace
 
-        if signatureCallable:
-            descriptor.set_hasher_callable(signatureCallable)
+        if settings.signature:
+            descriptor.set_hasher_callable(settings.signature)
 
-        if constantSignatureCallable:
-            try:
-                basic_pkg = get_vistrails_basic_pkg_id()
-                c = self.get_descriptor_by_name(basic_pkg, 'Constant').module
-            except ModuleRegistryException:
-                msg = "Constant not found - can't set constantSignatureCallable"
-                raise VistrailsInternalError(msg)
-            if not issubclass(module, c):
-                raise TypeError("To set constantSignatureCallable, module " +
+        if settings.constant_signature:
+            if not self.is_constant_module(module):
+                raise TypeError("To set constant_signature, module "
                                 "must be a subclass of Constant")
+                
             # FIXME, currently only allow one per hash, no versioning
             hash_key = (identifier, name, namespace)
-            self._constant_hasher_map[hash_key] = constantSignatureCallable
-        descriptor.set_module_color(moduleColor)
-
-        if moduleFringe:
-            _check_fringe(moduleFringe)
-            leftFringe = list(reversed([(-x, 1.0-y) for (x, y) in moduleFringe]))
-            descriptor.set_module_fringe(leftFringe, moduleFringe)
-        elif moduleLeftFringe and moduleRightFringe:
-            _check_fringe(moduleLeftFringe)
-            _check_fringe(moduleRightFringe)
-            descriptor.set_module_fringe(moduleLeftFringe, moduleRightFringe)
+            self._constant_hasher_map[hash_key] = settings.constant_signature
         
-        if ghost_identifier:
-            descriptor.ghost_identifier = ghost_identifier
-        if ghost_package_version:
-            descriptor.ghost_package_version = ghost_package_version
-        if ghost_namespace:
-            descriptor.ghost_namespace = ghost_namespace
+        constant_widgets = []
+        if settings.constant_widget:
+            constant_widgets += [settings.constant_widget]
+        if settings.constant_widgets is not None:
+            constant_widgets += settings.constant_widgets
+        if len(constant_widgets) > 0:
+            if not self.is_constant_module(module):
+                raise TypeError("To set constant widgets, module " +
+                                "must be a subclass of Constant")
+            for widget_t in constant_widgets:
+                if isinstance(widget_t, tuple):
+                    widget_t = ConstantWidgetConfig(*widget_t)
+                else:
+                    widget_t = ConstantWidgetConfig(widget_t)
+                if widget_t.widget is not None:
+                    self.set_constant_config_widget(descriptor, 
+                                                    widget_t.widget,
+                                                    widget_t.widget_type, 
+                                                    widget_t.widget_use)
+
+        descriptor.set_module_color(settings.color)
+
+        if settings.fringe:
+            _check_fringe(settings.fringe)
+            left_fringe = list(reversed([(-x, 1.0-y) for (x, y) in \
+                                    settings.fringe]))
+            descriptor.set_module_fringe(left_fringe, settings.fringe)
+        elif settings.left_fringe and settings.right_fringe:
+            _check_fringe(settings.left_fringe)
+            _check_fringe(settings.right_fringe)
+            descriptor.set_module_fringe(settings.left_fringe, 
+                                         settings.right_fringe)
+        
+        if settings.ghost_package:
+            descriptor.ghost_identifier = settings.ghost_package
+        if settings.ghost_package_version:
+            descriptor.ghost_package_version = settings.ghost_package_version
+        if settings.ghost_namespace:
+            descriptor.ghost_namespace = settings.ghost_namespace
                  
         self.signals.emit_new_module(descriptor)
         if self.is_abstraction(descriptor):
@@ -1268,7 +1304,7 @@ class ModuleRegistry(DBRegistry):
         else:
             name = _parse_abstraction_name(vt_fname)
             kwargs['name'] = name
- 
+
         package = self.package_versions[(identifier, package_version)]
         if not os.path.isabs(vt_fname):
             vt_fname = os.path.join(package.package_dir, vt_fname)
@@ -1364,11 +1400,73 @@ class ModuleRegistry(DBRegistry):
                          optional=False, sort_key=-1, labels=None, 
                          defaults=None, values=None, entry_types=None,
                          docstring=None, shape=None, 
-                         min_conns=0, max_conns=-1):
+                         min_conns=0, max_conns=-1, depth=0):
         if signature is None and sigstring is None:
             raise VistrailsInternalError("create_port_spec: one of signature "
                                          "and sigstring must be specified")
         spec_id = self.idScope.getNewId(PortSpec.vtType)
+
+        # convert values of defaults and values if necessary
+        if defaults is not None or values is not None:
+            parse_port_spec_string = \
+                            vistrails.core.modules.utils.parse_port_spec_string
+            # parse port specs as necessary
+            if sigstring is not None:
+                sigstrings = parse_port_spec_string(sigstring)
+                sig_cls_list = [None,] * len(sigstrings)
+            else:
+                if isinstance(signature, collections.Sequence):
+                    sig_cls_list = signature
+                    sigstrings = [None,] * len(sig_cls_list)
+                else:
+                    sig_cls_list = [signature]
+                    sigstrings = [None,]
+            if defaults is not None:
+                new_defaults = []
+                if isinstance(defaults, basestring):
+                    defaults = literal_eval(defaults)
+                if not isinstance(defaults, list):
+                    raise ValueError('Defaults for port "%s" must be a list' %
+                                     name)
+                for i, default_val in enumerate(defaults):
+                    if default_val is not None:
+                        default_conv = self.convert_port_val(default_val,
+                                                             sigstrings[i], 
+                                                             sig_cls_list[i])
+                        if default_conv is not None:
+                            new_defaults.append(default_conv)
+                        else:
+                            new_defaults.append(None)
+                    else:
+                        new_defaults.append(None)
+                defaults = new_defaults
+            if values is not None:
+                new_values = []
+                if isinstance(values, basestring):
+                    values = literal_eval(values)
+                if not isinstance(values, list):
+                    raise ValueError('Values for port "%s" must be a list '
+                                     'of lists' % name)
+                for i, values_list in enumerate(values):
+                    if isinstance(values_list, basestring):
+                        values_list = literal_eval(values_list)
+                    if values_list is not None:
+                        if not isinstance(values_list, list):
+                            raise ValueError('Values for port "%s" must be '
+                                             'a list of lists' % name)
+                        new_values_list = []
+                        for val in values_list:
+                            if val is not None:
+                                val_conv = self.convert_port_val(val, 
+                                                                 sigstrings[i],
+                                                                 sig_cls_list[i])
+                                if val_conv is not None:
+                                    new_values_list.append(val_conv)
+                        new_values.append(new_values_list)
+                    else:
+                        new_values.append(None)
+                values = new_values        
+        
         spec = PortSpec(id=spec_id,
                         name=name,
                         type=type,
@@ -1383,7 +1481,8 @@ class ModuleRegistry(DBRegistry):
                         docstring=docstring,
                         shape=shape,
                         min_conns=min_conns,
-                        max_conns=max_conns)
+                        max_conns=max_conns,
+                        depth=depth)
 
         # don't know how many port spec items are created until after...
         for psi in spec.port_spec_items:
@@ -1434,19 +1533,20 @@ class ModuleRegistry(DBRegistry):
     def add_port(self, descriptor, port_name, port_type, port_sig=None, 
                  port_sigstring=None, optional=False, sort_key=-1,
                  labels=None, defaults=None, values=None, entry_types=None, 
-                 docstring=None, shape=None, min_conns=0, max_conns=-1):
+                 docstring=None, shape=None, min_conns=0, max_conns=-1,
+                 depth=0):
         spec = self.create_port_spec(port_name, port_type, port_sig,
                                      port_sigstring, optional, sort_key,
                                      labels, defaults, values, entry_types,
                                      docstring, shape,
-                                     min_conns, max_conns)
+                                     min_conns, max_conns, depth)
 
         self.add_port_spec(descriptor, spec)
 
     def add_input_port(self, module, portName, portSignature, optional=False, 
-                       sort_key=-1, labels=None, defaults=None, values=None,
-                       entry_types=None, docstring=None, shape=None, 
-                       min_conns=0, max_conns=-1):
+                       sort_key=-1, labels=None, defaults=None,
+                       values=None, entry_types=None, docstring=None,
+                       shape=None, min_conns=0, max_conns=-1, depth=0):
         """add_input_port(module: class,
                           portName: string,
                           portSignature: string,
@@ -1459,7 +1559,8 @@ class ModuleRegistry(DBRegistry):
                           docstring: string,
                           shape: tuple,
                           min_conns: int,
-                          max_conns: int) -> None
+                          max_conns: int,
+                          depth: int) -> None
 
         Registers a new input port with VisTrails. Receives the module
         that will now have a certain port, a string representing the
@@ -1468,18 +1569,20 @@ class ModuleRegistry(DBRegistry):
         input port is optional."""
         descriptor = self.get_descriptor(module)
         if isinstance(portSignature, basestring):
-            self.add_port(descriptor, portName, 'input', None, portSignature, 
+            self.add_port(descriptor, portName, 'input', None, portSignature,
                           optional, sort_key, labels, defaults, values,
-                          entry_types, docstring, shape, min_conns, max_conns)
+                          entry_types, docstring, shape, min_conns, max_conns,
+                          depth)
         else:
             self.add_port(descriptor, portName, 'input', portSignature, None, 
                           optional, sort_key, labels, defaults, values,
-                          entry_types, docstring, shape, min_conns, max_conns)
+                          entry_types, docstring, shape, min_conns, max_conns,
+                          depth)
 
 
     def add_output_port(self, module, portName, portSignature, optional=False, 
                         sort_key=-1, docstring=None, shape=None, 
-                        min_conns=0, max_conns=-1):
+                        min_conns=0, max_conns=-1, depth=0):
         """add_output_port(module: class,
                            portName: string,
                            portSignature: string,
@@ -1488,7 +1591,8 @@ class ModuleRegistry(DBRegistry):
                            docstring: string,
                            shape: tuple,
                            min_conns: int,
-                           max_conns: int) -> None
+                           max_conns: int,
+                           depth: int) -> None
 
         Registers a new output port with VisTrails. Receives the
         module that will now have a certain port, a string
@@ -1499,17 +1603,19 @@ class ModuleRegistry(DBRegistry):
         if isinstance(portSignature, basestring):
             self.add_port(descriptor, portName, 'output', None, portSignature, 
                           optional, sort_key, None, None, None, None, 
-                          docstring, shape, min_conns, max_conns)
+                          docstring, shape, min_conns, max_conns, depth)
         else:
             self.add_port(descriptor, portName, 'output', portSignature, None, 
                           optional, sort_key, None, None, None, None, 
-                          docstring, shape, min_conns, max_conns)
+                          docstring, shape, min_conns, max_conns, depth)
 
-    def create_package(self, codepath, load_configuration=True):
+    def create_package(self, codepath, load_configuration=True, prefix=None):
         package_id = self.idScope.getNewId(Package.vtType)
         package = Package(id=package_id,
                           codepath=codepath,
                           load_configuration=load_configuration)
+        if prefix is not None:
+            package.prefix = prefix
         return package
 
     def initialize_package(self, package):
@@ -1533,6 +1639,11 @@ class ModuleRegistry(DBRegistry):
                             if isinstance(module, tuple):
                                 m_dict.update(module[1])
                                 module_list.append((module[0], m_dict))
+                            elif '_settings' in module.__dict__:
+                                kwargs = module._settings._asdict()
+                                kwargs.update(m_dict)
+                                module._settings = ModuleSettings(**kwargs)
+                                module_list.append(module)
                             else:
                                 module_list.append((module, m_dict))
                 else:
@@ -1561,6 +1672,8 @@ class ModuleRegistry(DBRegistry):
                     if hasattr(descriptor, 'module'):
                         self.auto_add_ports(descriptor.module)
                         added_descriptors.add(descriptor)
+        except MissingRequirement:
+            raise
         except Exception, e:
             raise package.InitializationFailed(package, 
                                                [traceback.format_exc()])
@@ -1680,6 +1793,12 @@ class ModuleRegistry(DBRegistry):
                 for d in port_spec.descriptors())
     is_constant = is_method
 
+    def is_constant_module(self, module):
+        basic_pkg = get_vistrails_basic_pkg_id()
+        constant_cls = \
+                    self.get_descriptor_by_name(basic_pkg, 'Constant').module
+        return issubclass(module, constant_cls)
+
     def method_ports(self, module_descriptor):
         """method_ports(module_descriptor: ModuleDescriptor) 
               -> [PortSpec]}
@@ -1760,14 +1879,35 @@ class ModuleRegistry(DBRegistry):
         self._conversions[key] = converters
         return converters
 
+    def is_descriptor_list_subclass(self, sub_descs, super_descs):
+        basic_pkg = get_vistrails_basic_pkg_id()
+        variant_desc = self.get_descriptor_by_name(basic_pkg, 'Variant')
+        module_desc = self.get_descriptor_by_name(basic_pkg, 'Module')
+
+        for (sub_desc, super_desc) in izip(sub_descs, super_descs):
+            if sub_desc == variant_desc or super_desc == variant_desc:
+                continue
+            if super_desc == module_desc and sub_desc != module_desc:
+                warnings.warn(
+                        "Connecting any type on a Module input port is "
+                        "deprecated\nPlease make the output port a Variant to "
+                        "get this behavior.",
+                        category=VistrailsDeprecation)
+                #return False
+            if not self.is_descriptor_subclass(sub_desc, super_desc):
+                return False
+        return True
+
     def are_specs_matched(self, sub, super, allow_conversion=False,
                           out_converters=None):
         """ are_specs_matched(sub: Port, super: Port) -> bool        
         Check if specs of sub and super port are matched or not
         
         """
+        # For a connection, this gets called for sub -> super
         basic_pkg = get_vistrails_basic_pkg_id()
         variant_desc = self.get_descriptor_by_name(basic_pkg, 'Variant')
+        list_desc = self.get_descriptor_by_name(basic_pkg, 'List')
         # sometimes sub is coming None
         # I don't know if this is expected, so I will put a test here
         sub_descs = []
@@ -1784,17 +1924,20 @@ class ModuleRegistry(DBRegistry):
             return False
         elif super_descs == [variant_desc]:
             return True
-
-        def check_types(sub_descs, super_descs):
-            for (sub_desc, super_desc) in izip(sub_descs, super_descs):
-                if (sub_desc == variant_desc or super_desc == variant_desc):
-                    continue
-                if not self.is_descriptor_subclass(sub_desc, super_desc):
-                    return False
+        elif [list_desc] in [super_descs, sub_descs]:
+            # Allow Lists to connect to anything
             return True
+        #elif super_descs == [list_desc] and sub_descs != [list_desc] \
+        #     and sub.depth > 0:
+        #    # List is handled as Variant with depth 1
+        #    return True
+        #elif sub_descs == [list_desc] and super_descs != [list_desc] \
+        #     and super.depth > 0:
+        #    # List is handled as Variant with depth 1
+        #    return True
 
         if (len(sub_descs) == len(super_descs) and
-                check_types(sub_descs, super_descs)):
+                self.is_descriptor_list_subclass(sub_descs, super_descs)):
             return True
 
         if allow_conversion:
@@ -1821,6 +1964,15 @@ class ModuleRegistry(DBRegistry):
         return [self.get_descriptor(klass)
                 for klass in descriptor.module.mro()
                 if issubclass(klass, vistrails.core.modules.vistrails_module.Module)]
+
+    def get_descriptor_subclasses(self, descriptor):
+        # need to find all descriptors that are subdescriptors of descriptor
+        sub_list = []
+        for pkg in self.package_versions.itervalues():
+            for d in pkg.descriptor_list:
+                if self.is_descriptor_subclass(d, descriptor):
+                    sub_list.append(d)
+        return sub_list
         
     def get_input_port_spec(self, module, portName):
         """ get_input_port_spec(module: Module, portName: str) ->
@@ -1884,12 +2036,48 @@ class ModuleRegistry(DBRegistry):
 
     def get_configuration_widget(self, identifier, name, namespace):
         descriptor = self.get_descriptor_by_name(identifier, name, namespace)
-        klass = descriptor.configuration_widget()
-        if isinstance(klass, tuple):
-            (path, klass_name) = klass
-            module = __import__(path, globals(), locals(), [klass_name])
-            klass = getattr(module, klass_name)            
-        return klass
+        package = self.get_package_by_name(identifier)
+        prefix = None
+        if package.prefix is not None and package.codepath is not None:
+            prefix = package.prefix + package.codepath
+        cls = descriptor.configuration_widget()
+        return vistrails.core.modules.utils.load_cls(cls, prefix)
+
+    def get_constant_config_params(self, widget_type=None, widget_use=None):
+        if widget_type is None:
+            widget_type = 'default'
+        if widget_use is None:
+            widget_use = 'default'
+        return (widget_type, widget_use)
+
+    def get_constant_config_widget(self, descriptor, widget_type=None, 
+                                   widget_use=None):
+        widget_type, widget_use = self.get_constant_config_params(widget_type,
+                                                                  widget_use)
+        for desc in self.get_module_hierarchy(descriptor):
+            if desc.has_constant_config_widget(widget_use, widget_type):
+                return desc.get_constant_config_widget(widget_use, widget_type)
+        return None
+
+    def get_all_constant_config_widgets(self, descriptor, widget_use=None):
+        widget_use = self.get_constant_config_params(None, widget_use)[1]
+        widgets = {}
+        for desc in reversed(self.get_module_hierarchy(descriptor)):
+            widgets.update(desc.get_all_constant_config_widgets(widget_use))
+        return widgets.values()
+
+    def set_constant_config_widget(self, descriptor, widget_class, 
+                                   widget_type=None, widget_use=None):
+        widget_type, widget_use = self.get_constant_config_params(widget_type,
+                                                                  widget_use)
+        basic_pkg = get_vistrails_basic_pkg_id()
+        constant_desc = self.get_descriptor_by_name(basic_pkg, 'Constant')
+        if not self.is_descriptor_subclass(descriptor, constant_desc):
+            raise Exception('Descriptor "%s" must be a subclass of Constant '
+                            'to use a constant configuration widget.' % \
+                            descriptor.sigstring)
+        descriptor.set_constant_config_widget(widget_class,
+                                              widget_use, widget_type)
 
     def is_descriptor_subclass(self, sub, super):
         """is_descriptor_subclass(sub : ModuleDescriptor, 
@@ -1976,13 +2164,11 @@ class ModuleRegistry(DBRegistry):
 # get_descriptor           = registry.get_descriptor
 
 def get_module_registry():
-    global registry
     if not registry:
         raise VistrailsInternalError("Registry not constructed yet.")
     return registry
 
 def module_registry_loaded():
-    global registry
     return registry is not None
 
 ##############################################################################
diff --git a/vistrails/core/modules/module_utils.py b/vistrails/core/modules/module_utils.py
index 893a0da..2cbbbba 100644
--- a/vistrails/core/modules/module_utils.py
+++ b/vistrails/core/modules/module_utils.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # Utilities for user-defined Modules
+from __future__ import division
+
 import os
 import tempfile
 from vistrails.core.modules import basic_modules
@@ -48,12 +51,14 @@ import unittest
 class FilePool(object):
 
     """FilePool provides a convenient interface for Module developers to
-use temporary files. """
+    use temporary files.
+
+    """
     
     def __init__(self):
         d = {'prefix':'vt_tmp'}
-        if get_vistrails_configuration().check('temporaryDirectory'):
-            dir = get_vistrails_configuration().temporaryDirectory
+        if get_vistrails_configuration().check('temporaryDir'):
+            dir = get_vistrails_configuration().temporaryDir
             if os.path.exists(dir):
                 d['dir'] = dir
             else:
@@ -65,9 +70,11 @@ use temporary files. """
     def cleanup(self):
         """cleanup() -> None
 
-Cleans up the file pool, by removing all temporary files
-and the directory they existed in. Module developers should never
-call this directly."""
+        Cleans up the file pool, by removing all temporary files and
+        the directory they existed in. Module developers should never
+        call this directly.
+
+        """
         if not os.path.isdir(self.directory):
             # cleanup has already happened
             return
@@ -79,36 +86,38 @@ call this directly."""
                     os.rmdir(os.path.join(root, name))
             os.rmdir(self.directory)
         except OSError, e:
+            debug.unexpected_exception(e)
             raise VistrailsInternalError("Can't remove %s: %s" %
                                          (self.directory,
-                                          str(e)))
+                                          debug.format_exception(e)))
 
     def create_file(self, suffix = '', prefix = 'vt_tmp'):
-        """create_file(suffix='', prefix='vt_tmp') -> File.
+        """create_file(suffix='', prefix='vt_tmp') -> PathObject.
+
+        Returns a File module representing a writable file for use in
+        modules. To avoid race conditions, this file will already
+        exist in the file system.
 
-Returns a File module representing a writable file for use in modules. To
-avoid race conditions, this file will already exist in the file system."""
+        """
         (fd, name) = tempfile.mkstemp(suffix=suffix,
                                       prefix=prefix,
                                       dir=self.directory)
         os.close(fd)
-        result = basic_modules.File()
-        result.name = name
-        result.upToDate = True
+        result = basic_modules.PathObject(name)
         self.files[name] = result
         return result
 
     def create_directory(self, suffix = '', prefix = 'vt_tmp'):
-        """create_directory(suffix='', prefix='vt_tmp') -> Directory.
+        """create_directory(suffix='', prefix='vt_tmp') -> PathObject.
+
+        Returns a writable directory for use in modules. To avoid race
+        conditions, this directory will already exist in the file system.
 
-Returns a Directory module representing a writable directory for use in modules. To
-avoid race conditions, this directory will already exist in the file system."""
+        """
         name = tempfile.mkdtemp(suffix=suffix,
                                       prefix=prefix,
                                       dir=self.directory)
-        result = basic_modules.Directory()
-        result.name = name
-        result.upToDate = True
+        result = basic_modules.PathObject(name)
         self.files[name] = result
         return result
 
@@ -120,22 +129,22 @@ avoid race conditions, this directory will already exist in the file system."""
         return os.path.splitext(file_name)[1]
 
     def make_local_copy(self, src):
-        """make_local_copy(src) -> File
+        """make_local_copy(src) -> PathObject
 
-Returns a file in the filePool that's either a link or a copy of the
-given file path. This ensures the file's longevity when
-necessary. Since it might use a hardlink for speed, modules should
-only use this method if the file is not going to be changed in the
-future."""
+        Returns a file in the filePool that's either a link or a copy
+        of the given file path. This ensures the file's longevity when
+        necessary. Since it might use a hardlink for speed, modules
+        should only use this method if the file is not going to be
+        changed in the future.
+
+        """
         (fd, name) = tempfile.mkstemp(suffix=self.guess_suffix(src),
                                       dir=self.directory)
         os.close(fd)
         # FIXME: Watch out for race conditions
         os.unlink(name)
         link_or_copy(src, name)
-        result = basic_modules.File()
-        result.name = name
-        result.upToDate = True
+        result = basic_modules.PathObject(name)
         self.files[name] = result
         return result
         
diff --git a/vistrails/core/modules/output_modules.py b/vistrails/core/modules/output_modules.py
new file mode 100644
index 0000000..04538d0
--- /dev/null
+++ b/vistrails/core/modules/output_modules.py
@@ -0,0 +1,666 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+##############################################################################
+
+from __future__ import division
+
+from copy import copy
+import os
+import sys
+import unittest
+
+from vistrails.core.configuration import ConfigurationObject, ConfigField, ConfigPath, get_vistrails_persistent_configuration, get_vistrails_temp_configuration
+from vistrails.core.modules.vistrails_module import Module, NotCacheable, ModuleError
+from vistrails.core.modules.config import IPort, ModuleSettings
+import vistrails.core.system
+
+class OutputMode(object):
+    mode_type = None
+    priority = -1  # -1 prevents the mode from being selected automatically
+
+    @staticmethod
+    def can_compute():
+        return False
+
+    @classmethod
+    def get_config(cls):
+        return cls.config_cls
+
+    def compute_output(self, output_module, configuration=None):
+        raise NotImplementedError("Subclass of OutputMode should implement "
+                                  "this")
+
+# Ideally, these are globally and locally configurable so that we use
+# global settings if nothing is set locally (e.g. output directory)
+class OutputModeConfig(dict):
+    mode_type = None
+    _fields = []
+    def __init__(self, *args, **kwargs):
+        dict.__init__(self, *args, **kwargs)
+        for k, v in self.iteritems():
+            if not self.has_field(k):
+                raise ValueError('Field "%s" is not declared for class "%s"' %
+                                 (k, self.__class__.__name__))
+
+    @classmethod
+    def ensure_field_dict(cls):
+        if '_field_dict' not in cls.__dict__:
+            if '_fields' in cls.__dict__:
+                cls._field_dict = dict((f.name, f) for f in cls._fields)
+            else:
+                cls._field_dict = {}
+
+    @classmethod
+    def has_field(cls, k):
+        cls_list = [cls]
+        while len(cls_list) > 0:
+            c = cls_list.pop(0)
+            if issubclass(c, OutputModeConfig):
+                c.ensure_field_dict()
+                if k in c._field_dict:
+                    return True
+                cls_list.extend(c.__bases__)
+        return False
+            
+    @classmethod
+    def get_field(cls, k):
+        cls_list = [cls]
+        while len(cls_list) > 0:
+            c = cls_list.pop(0)
+            if issubclass(c, OutputModeConfig):
+                c.ensure_field_dict()
+                if k in c._field_dict:
+                    return c._field_dict[k]
+                cls_list.extend(c.__bases__)
+        return None
+
+    @classmethod
+    def get_all_fields(cls):
+        field_dicts = []
+        cls_list = [cls]
+        while len(cls_list) > 0:
+            c = cls_list.pop(0)
+            if issubclass(c, OutputModeConfig):
+                c.ensure_field_dict()
+                field_dicts.append(c._field_dict)
+                cls_list.extend(c.__bases__)
+        field_dict = {}
+        for fd in reversed(field_dicts):
+            field_dict.update(fd)
+        fields = field_dict.values()
+        fields.sort()
+        return fields
+
+    @classmethod
+    def get_default(cls, k):
+        f = cls.get_field(k)
+        if f is not None:
+            return f.default_val
+        return None
+
+    @classmethod
+    def has_from_config(cls, config, k):
+        if hasattr(cls, 'mode_type'):
+            mode_type = cls.mode_type
+            if config.has(mode_type):
+                subconfig = getattr(config, mode_type)
+                if subconfig.has(k):
+                    return True
+        return False
+
+    @classmethod
+    def get_from_config(cls, config, k):
+        if hasattr(cls, 'mode_type'):
+            mode_type = cls.mode_type
+            if config.has(mode_type):
+                subconfig = getattr(config, mode_type)
+                if subconfig.has(k):
+                    return getattr(subconfig, k)
+        return None
+
+    @classmethod
+    def has_override(cls, k):
+        config = get_vistrails_temp_configuration().outputSettings
+        return cls.has_from_config(config, k)
+
+    @classmethod
+    def get_override(cls, k):
+        config = get_vistrails_temp_configuration().outputSettings
+        str_val = cls.get_from_config(config, k)
+        return cls.get_field(k).from_string(str_val)
+
+    @classmethod
+    def has_global_setting(cls, k):
+        config = get_vistrails_persistent_configuration().outputDefaultSettings
+        return cls.has_from_config(config, k)
+
+    @classmethod
+    def get_global_setting(cls, k):
+        config = get_vistrails_persistent_configuration().outputDefaultSettings
+        return cls.get_from_config(config, k)
+
+    @classmethod
+    def has_config_setting(cls, k):
+        return cls.has_override(k) or cls.has_global_setting(k)
+
+    def __setitem__(self, k, v):
+        if not self.has_field(k):
+            raise ValueError('Setting "%s" is not declared for class "%s"' %
+                             (k, self.__class__.__name__))
+        dict.__setitem__(self, k, v)
+
+    def __getitem__(self, k):
+        if self.has_override(k):
+            return self.get_override(k)
+        try:
+            return dict.__getitem__(self, k)
+        except KeyError, e:
+            if self.has_global_setting(k):
+                return self.get_global_setting(k)
+            else:
+                if self.has_field(k):
+                    return self.get_default(k)
+            raise e
+
+    def __hasitem__(self, k):
+        return (self.has_field(k) or dict.__hasitem__(self, k) or 
+                self.has_override(k) or self.has_global_setting(k))
+
+class OutputModule(NotCacheable, Module):
+    _input_ports = [IPort('value', "Variant"),
+                    IPort('mode_type', "String"),
+                    IPort('configuration', "Dictionary")]
+    _settings = ModuleSettings(abstract=True)
+
+    # configuration is a dictionary of dictionaries where root-level
+    # keys are mode_types and the inner dictionaries are
+    # workflow-specific settings
+
+    # want to have mode inheritance here...
+
+    @classmethod
+    def ensure_mode_dict(cls):
+        if '_output_modes_dict' not in cls.__dict__:
+            cls._output_modes_dict = {}
+            if '_output_modes' in cls.__dict__:
+                for mcls in cls._output_modes:
+                    if isinstance(mcls, tuple):
+                        mcls, prio = mcls
+                    else:
+                        prio = mcls.priority
+                    cls._output_modes_dict[mcls.mode_type] = mcls, prio
+
+    @classmethod
+    def register_output_mode(cls, mode_cls, priority=None):
+        if mode_cls.mode_type is None:
+            raise ValueError("mode_cls.mode_type must not be None")
+        if priority is None:
+            priority = mode_cls.priority
+        cls.ensure_mode_dict()
+        if '_output_modes' not in cls.__dict__:
+            cls._output_modes = []
+        cls._output_modes.append(mode_cls)
+        cls._output_modes_dict[mode_cls.mode_type] = (mode_cls, priority)
+
+    @classmethod
+    def set_mode_priority(cls, mode_type, priority):
+        cls.ensure_mode_dict()
+
+        if mode_type not in cls._output_modes_dict:
+            raise ValueError('mode_type "%s" is not set for this module' % 
+                             mode_type)
+        cls._output_modes_dict[mode_type][1] = priority
+
+    @classmethod
+    def get_mode_class(cls, mode_type):
+        cls_list = [cls]
+        while len(cls_list) > 0:
+            c = cls_list.pop(0)
+            if issubclass(c, OutputModule):
+                c.ensure_mode_dict()
+                if mode_type in c._output_modes_dict:
+                    return c._output_modes_dict[mode_type][0]
+                cls_list.extend(c.__bases__)
+        return None
+
+    @classmethod
+    def get_sorted_mode_list(cls):
+        cls_list = [cls]
+        idx = 0
+        while idx < len(cls_list):
+            for c in cls_list[idx].__bases__:
+                if issubclass(c, OutputModule):
+                    c.ensure_mode_dict()
+                    cls_list.append(c)
+            idx += 1
+
+        mode_dict = {}
+        for c in reversed(cls_list):
+            mode_dict.update(c._output_modes_dict)
+
+        # Iterator over (mode_cls, priority)
+        modes = mode_dict.itervalues()
+        # Drop if priority < 0
+        modes = ((c, p) for (c, p) in modes if p >= 0)
+        # Sort by descending priority
+        modes = sorted(modes, key=lambda x: -x[1])
+        # Build list of mode_cls (drop priority)
+        return [c for c, _ in modes]
+
+    @classmethod
+    def get_mode_tree(cls):
+        cls_list = [cls]
+        idx = 0
+        while idx < len(cls_list):
+            for c in cls_list[idx].__bases__:
+                if issubclass(c, OutputModule):
+                    c.ensure_mode_dict()
+                    cls_list.append(c)
+            idx += 1
+
+        mode_tree = {}
+        for c in reversed(cls_list):
+            c.ensure_mode_dict()
+
+    def get_mode_config(self, mode):
+        mode_config_cls = mode.get_config()
+        mode_config_dict = {}
+        configuration = self.force_get_input('configuration')
+        if configuration is not None:
+            # want to search through all mode classes in case we have
+            # base class settings that should trump
+            cls_list = [mode_config_cls]
+            mode_config_cls_list = []
+            while len(cls_list) > 0:
+                c = cls_list.pop(0)
+                if issubclass(c, OutputModeConfig):
+                    mode_config_cls_list.append(c)
+                    cls_list.extend(c.__bases__)
+            mode_config_cls_list.reverse()
+
+            for mode_config_cls in mode_config_cls_list:
+                for k, v in configuration.iteritems():
+                    if k == mode_config_cls.mode_type:
+                        mode_config_dict.update(v)
+        mode_config = mode_config_cls(mode_config_dict)
+        return mode_config
+
+    def compute(self):
+        mode_cls = None
+        self.ensure_mode_dict()
+        if self.has_input("mode_type"):
+            # use user-specified mode_type
+            mode_type = self.get_input("mode_type")
+            mode_cls = self.get_mode_class(mode_type)
+            if mode_cls is None:
+                raise ModuleError(self, 'Cannot output in mode "%s" because '
+                                  'that mode has not been defined' % mode_type)
+        else:
+            # FIXME should have user-setable priorities!
+
+            # determine mode_type based on registered modes by priority,
+            # checking if each is possible
+            for mcls in self.get_sorted_mode_list():
+                if mcls.can_compute():
+                    mode_cls = mcls
+                    break
+
+        if mode_cls is None:
+            raise ModuleError(self, "No output mode is valid, output cannot "
+                              "be generated")
+
+        mode = mode_cls()
+        mode_config = self.get_mode_config(mode)
+        self.annotate({"output_mode": mode.mode_type})
+        mode.compute_output(self, mode_config)
+
+class StdoutModeConfig(OutputModeConfig):
+    mode_type = "stdout"
+    _fields = []
+
+class StdoutMode(OutputMode):
+    mode_type = "stdout"
+    priority = 200
+    config_cls = StdoutModeConfig
+
+    @staticmethod
+    def can_compute():
+        return True
+
+class FileModeConfig(OutputModeConfig):
+    mode_type = "file"
+    _fields = [ConfigField('file', None, ConfigPath),
+               ConfigField('basename', None, str),
+               ConfigField('prefix', None, str),
+               ConfigField('suffix', None, str),
+               ConfigField('dir', None, ConfigPath),
+               ConfigField('series', False, bool),
+               ConfigField('overwrite', True, bool),
+               ConfigField('seriesPadding', 3, int),
+               ConfigField('seriesStart', 0, int),
+               ConfigField('format', None, str, widget_type='combo')]
+
+class FileMode(OutputMode):
+    mode_type = "file"
+    priority = 100
+    config_cls = FileModeConfig
+    formats = []
+    
+    # TODO: need to reset this after each execution!
+    series_next = 0
+
+    @staticmethod
+    def can_compute():
+        return True
+
+    @classmethod
+    def get_config(cls):
+        if '_config_cls_with_formats' in cls.__dict__:
+            return cls.__dict__['_config_cls_with_formats']
+        else:
+            dct = {}
+            orig_config_cls = super(FileMode, cls).get_config()
+            format_field = orig_config_cls.get_field('format')
+            if format_field.widget_type == 'combo':
+                format_field = copy(format_field)
+                opts = dict(format_field.widget_options)
+                opts['allowed_values'] = cls.get_formats()
+                format_field.widget_options = opts
+                dct['_fields'] = [format_field]
+            config_cls = type('%s_WithFormats' % orig_config_cls.__name__,
+                              (orig_config_cls,),
+                              dct)
+            cls._config_cls_with_formats = config_cls
+            return config_cls
+
+    @classmethod
+    def get_formats(cls):
+        formats = []
+        cls_list = [cls]
+        while len(cls_list) > 0:
+            c = cls_list.pop(0)
+            if issubclass(c, FileMode):
+                if 'formats' in c.__dict__:
+                    return c.formats
+                cls_list.extend(c.__bases__)
+        return []
+
+    def get_format(self, configuration=None):
+        format_map = {'png': 'png',
+                      'jpeg': 'jpg',
+                      'jpg': 'jpg',
+                      'tif': 'tif',
+                      'tiff': 'tif'}
+        if configuration is not None and 'format' in configuration:
+            conf_format = configuration['format']
+            if conf_format.lower() in format_map:
+                return format_map[conf_format.lower()]
+            return conf_format
+
+        # default is the first listed if it exists
+        format_list = self.get_formats()
+        if len(format_list) > 0:
+            return format_list[0]
+        return None
+
+    def get_series_num(self):
+        retval = FileMode.series_next 
+        FileMode.series_next += 1
+        return retval
+        
+    # FIXME should add format into this computation
+    def get_filename(self, configuration, full_path=None, filename=None,
+                     dirname=None, basename=None, prefix=None, suffix=None,
+                     overwrite=True, series=False, series_padding=3):
+        # if prefix/suffix/series are overridden, want to use them
+        # instead of name...
+        if full_path is None:
+            # use file if overridden or none of the file params are
+            # overridden and the file is not None
+
+            overwrite = configuration['overwrite']
+            if (configuration.has_override('file') or
+                (not (configuration.has_override('basename') or
+                      configuration.has_override('prefix') or
+                      configuration.has_override('suffix') or
+                      configuration.has_override('dir') or
+                      configuration.has_override('series') or
+                      configuration.has_override('seriesPadding') or
+                      configuration.has_override('seriesStart')) and
+                 'file' in configuration and
+                 configuration['file'] is not None)):
+                full_path = configuration['file']
+            else:
+                if configuration['basename'] is not None:
+                    basename = configuration['basename']
+                if configuration['prefix'] is not None:
+                    prefix = configuration['prefix']
+                if configuration['suffix'] is not None:
+                    suffix = configuration['suffix']
+                if configuration['dir'] is not None:
+                    dirname = configuration['dir']
+                if configuration['series'] is not None:
+                    series = configuration['series']
+                if configuration['seriesPadding'] is not None:
+                    series_padding = configuration['seriesPadding']
+
+        if full_path is None:                
+            # should any of these necessitate series=True?
+            if basename is None:
+                basename = 'vt_out'
+            if prefix is None:
+                prefix = ''
+            if suffix is None:
+                suffix = ''
+            if dirname is None:
+                # FIXME should unify with VisTrails output
+                # directory global!  should check for abspath (if
+                # not, use relative to global output directory)
+                dirname = ''
+
+            # seriesPadding and series have defaults so no
+            # need to default them
+
+            if not overwrite and series:
+                # need to find first open slot
+                full_path = None
+                while full_path is None or os.path.exists(full_path):
+                    series_str = (("%%0%dd" % series_padding) % 
+                                  self.get_series_num())
+                    full_path = os.path.join(dirname, "%s%s%s%s" % 
+                                             (prefix, basename, 
+                                              series_str, suffix))
+            else:
+                if series:
+                    series_str = (("%%0%dd" % series_padding) % 
+                                  self.get_series_num())
+                else:
+                    series_str = ""
+                full_path = os.path.join(dirname, "%s%s%s%s" % 
+                                         (prefix, basename, series_str, 
+                                          suffix))
+            if not overwrite and os.path.exists(full_path):
+                raise IOError('File "%s" exists and overwrite is False' % full_path)
+
+        return full_path
+
+class FileToFileMode(FileMode):
+    default_file_extension = None
+
+    def compute_output(self, output_module, configuration=None):
+        old_fname = output_module.get_input('value').name
+        full_path = self.get_filename(configuration,
+                                      suffix=(os.path.splitext(old_fname)[1] or
+                                              self.default_file_extension))
+        # we know we are in overwrite mode because it would have been
+        # flagged otherwise
+        if os.path.exists(full_path):
+            try:
+                os.remove(full_path)
+            except OSError, e:
+                raise ModuleError(output_module, 
+                                  ('Could not delete existing '
+                                   'path "%s"' % full_path))
+        try:
+            vistrails.core.system.link_or_copy(old_fname, full_path)
+        except OSError, e:
+            msg = "Could not create file '%s': %s" % (full_path, e)
+            raise ModuleError(output_module, msg)
+
+class FileToStdoutMode(StdoutMode):
+    def compute_output(self, output_module, configuration=None):
+        fname = output_module.get_input('value').name
+        with open(fname, 'r') as f:
+            for line in f:
+                sys.stdout.write(line)
+
+class GenericToStdoutMode(StdoutMode):
+    def compute_output(self, output_module, configuration=None):
+        value = output_module.get_input('value')
+        print >>sys.stdout, value
+
+class GenericToFileMode(FileMode):
+    def compute_output(self, output_module, configuration=None):
+        value = output_module.get_input('value')
+        filename = self.get_filename(configuration)
+        with open(filename, 'w') as f:
+            print >>f, value
+
+class GenericOutput(OutputModule):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules.output_configuration:OutputModuleConfigurationWidget")
+    _output_modes = [GenericToStdoutMode, GenericToFileMode]
+
+class FileOutput(OutputModule):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules.output_configuration:OutputModuleConfigurationWidget")
+    _input_ports = [('value', 'File')]
+    # Stdout is low priority, probably a bad plan
+    _output_modes = [(FileToStdoutMode, 50), (FileToFileMode, 200)]
+
+class ImageFileModeConfig(FileModeConfig):
+    mode_type = "file"
+    _fields = [ConfigField('width', 800, int),
+               ConfigField('height', 600, int)]
+
+class ImageFileMode(FileMode):
+    config_cls = ImageFileModeConfig
+    mode_type = "file"
+
+class ImageOutput(FileOutput):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules.output_configuration:OutputModuleConfigurationWidget")
+    _input_ports = [('value', 'File')]
+    # FileToStdoutMode is disabled, since it's definitely binary
+    _output_modes = [FileToFileMode, (FileToStdoutMode, -1)]
+
+class IPythonModeConfig(OutputModeConfig):
+    mode_type = "ipython"
+    _fields = []
+
+class IPythonMode(OutputMode):
+    mode_type = "ipython"
+    priority = 400
+    config_cls = IPythonModeConfig
+
+    @staticmethod
+    def can_compute():
+        try:
+            import __main__ as main
+            if hasattr(main, '__file__'):
+                return False
+            import IPython.core.display
+            return True
+        except ImportError:
+            return False
+
+    def compute_output(self, output_module, configuration=None):
+        from IPython.core.display import display
+
+        value = output_module.get_input('value')
+        display(value)
+
+class IPythonHtmlMode(IPythonMode):
+    mode_type = "ipython"
+
+    def compute_output(self, output_module, configuration=None):
+        from IPython.core.display import display, HTML
+
+        value = output_module.get_input('value')
+        display(HTML(filename=value.name))
+
+class HtmlToFileMode(FileToFileMode):
+    default_file_extension = '.html'
+
+class RichTextOutput(FileOutput):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules.output_configuration:OutputModuleConfigurationWidget")
+    _input_ports = [('value', 'File')]
+    _output_modes = [HtmlToFileMode, (FileToStdoutMode, 50), IPythonHtmlMode]
+
+_modules = [OutputModule, GenericOutput, FileOutput, ImageOutput, RichTextOutput]
+
+# need to put WebOutput, ImageOutput, RichTextOutput, SVGOutput, etc. elsewhere
+
+class TestOutputModeConfig(unittest.TestCase):
+    def test_fields(self):
+        class AlteredFileModeConfig(FileModeConfig):
+            _fields = [ConfigField("newattr", 3, int)]
+            
+        self.assertTrue(AlteredFileModeConfig.has_field("overwrite"))
+        self.assertTrue(AlteredFileModeConfig.has_field("newattr"))
+
+    def test_config(self):
+        config_obj = ConfigurationObject(file=ConfigurationObject(seriesStart=5))
+        self.assertTrue(FileModeConfig.has_from_config(config_obj, 
+                                                       "seriesStart"))
+        self.assertEqual(FileModeConfig.get_from_config(config_obj, 
+                                                        "seriesStart"), 5)
+        
+    def test_subclass_config(self):
+        class AlteredFileModeConfig(FileModeConfig):
+            mode_type = "file"
+            _fields = [ConfigField("newattr", 3, int)]
+        config_obj = ConfigurationObject(file=ConfigurationObject(seriesStart=5))
+        self.assertEqual(AlteredFileModeConfig.get_from_config(config_obj, 
+                                                        "seriesStart"), 5)
+
+    def test_get_item(self):
+        config = FileModeConfig()
+        self.assertEqual(config["seriesStart"], 0)        
+
+    def test_get_default(self):
+        self.assertEqual(FileModeConfig.get_default("seriesStart"), 0)
+
+if __name__ == '__main__':
+    import vistrails.core.application
+    app = vistrails.core.application.init()
+    unittest.main()
diff --git a/vistrails/core/modules/package.py b/vistrails/core/modules/package.py
index 348fb9e..805044d 100644
--- a/vistrails/core/modules/package.py
+++ b/vistrails/core/modules/package.py
@@ -1,54 +1,58 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 import inspect
-from itertools import chain
 import os
 import re
 import sys
 import traceback
-import xml.dom
 
+import vistrails
 from vistrails.core import debug
 from vistrails.core import get_vistrails_application
+from vistrails.core.configuration import get_vistrails_configuration
 from vistrails.core.modules.module_descriptor import ModuleDescriptor
 from vistrails.core.utils import versions_increasing, VistrailsInternalError
-from vistrails.core.utils.uxml import (named_elements, enter_named_element)
-
 from vistrails.db.domain import DBPackage
 
+
+vistrails_dir = os.path.dirname(os.path.realpath(vistrails.__file__))
+
 ##############################################################################
 
 class Package(DBPackage):
@@ -138,6 +142,8 @@ class Package(DBPackage):
             self.prefix = None
             self.py_dependencies = set()
             self.old_identifiers = []
+            self._default_configuration = None
+            self._persistent_configuration = None
         else:
             self._module = other._module
             self._init_module = other._init_module
@@ -148,6 +154,11 @@ class Package(DBPackage):
             self.prefix = other.prefix
             self.py_dependencies = copy.copy(other.py_dependencies)
             self.old_identifiers = [i for i in self.old_identifiers]
+            self._default_configuration = \
+                                        copy.copy(other._default_configuration)
+            self._persistent_configuration = \
+                                    copy.copy(other._persistent_configuration)
+
         # FIXME decide whether we want None or ''
         if self.version is None:
             self.version = ''
@@ -271,6 +282,8 @@ class Package(DBPackage):
                 pkg_fname = pkg.__file__
             except AttributeError:
                 return True
+            if os.path.realpath(pkg_fname).startswith(vistrails_dir):
+                return False
             if "site-packages" in pkg_fname:
                 return True
             if os.sep != '/':
@@ -340,9 +353,6 @@ class Package(DBPackage):
     def get_py_deps(self):
         return self.py_dependencies
 
-    def remove_py_deps(self, deps):
-        self.py_dependencies.difference_update(deps)
-
     def load(self, prefix=None):
         """load(module=None). Loads package's module.
 
@@ -399,18 +409,8 @@ class Package(DBPackage):
         if r:
             raise self.InitializationFailed(self, errors)
 
-        # Sometimes we don't want to change startup.xml, for example
-        # when peeking at a package that's on the available package list
-        # on edit -> preferences. That's what the load_configuration field
-        # is for
-        if self.load_configuration:
-            if hasattr(self._module, 'configuration'):
-                # hold a copy of the initial configuration so it can be reset
-                self._initial_configuration = \
-                    copy.copy(self._module.configuration)
-            self.load_persistent_configuration()
-
         self.set_properties()
+        self.do_load_configuration()
 
     def initialize(self):
         if not self._loaded:
@@ -448,17 +448,19 @@ class Package(DBPackage):
 
             if hasattr(self._init_module, 'initialize'):
                 self._init_module.initialize()
-        except Exception:
+        except Exception, e:
+            debug.unexpected_exception(e)
             self.unload()
             raise
 
     def unload(self):
         for path in self.py_dependencies:
             if path not in sys.modules:
-                # print "skipping %s" % path
                 pass
-            else:
-                # print 'deleting path:', path, path in sys.modules
+            elif not getattr(get_vistrails_configuration(),
+                             'dontUnloadModules',
+                             False):
+                debug.debug("deleting from sys.modules: %s" % path)
                 del sys.modules[path]
         self.py_dependencies.clear()
         self._loaded = False
@@ -623,18 +625,19 @@ class Package(DBPackage):
                 debug.critical("Couldn't finalize %s: %s: %s" % (
                                self.name, type(e).__name__, ', '.join(e.args)))
         # Save configuration
-        if self.configuration:
-            self.set_persistent_configuration()
+        if self.load_configuration and self.configuration is not None:
+            self.persist_configuration()
         self.unload()
         self._module = None
         self._init_module = None
         self._initialized = False
 
     def dependencies(self):
+        deps = []
         try:
             callable_ = self._module.package_dependencies
         except AttributeError:
-            deps = []
+            pass
         else:
             try:
                 deps = callable_()
@@ -647,119 +650,54 @@ class Package(DBPackage):
             deps.extend(self._module._dependencies)
         return deps
 
-    def loaded(self):
-        return self._loaded
-
     def initialized(self):
         return self._initialized
 
     ##########################################################################
     # Configuration
 
-    def _get_package_node(self, dom, create):
-        doc = dom.documentElement
-        packages = enter_named_element(doc, 'packages')
-        for package_node in named_elements(packages, 'package'):
-            if package_node.attributes['name'].value == self.codepath:
-                return package_node, 'enabled'
-        oldpackages = enter_named_element(doc, 'disabledpackages')
-        for package_node in named_elements(oldpackages, 'package'):
-            if package_node.attributes['name'].value == self.codepath:
-                return package_node, 'disabled'
-
-        if create is None:
-            return None, None
-        else:
-            package_node = dom.createElement('package')
-            package_node.setAttribute('name', self.codepath)
-            if create == 'enabled':
-                packages.appendChild(package_node)
-            elif create == 'disabled':
-                oldpackages.appendChild(package_node)
-            else:
-                raise ValueError
-            get_vistrails_application().vistrailsStartup.write_startup_dom(dom)
-            return package_node, create
-
-    def _move_package_node(self, dom, where, node):
-        doc = dom.documentElement
-        packages = enter_named_element(doc, 'packages')
-        oldpackages = enter_named_element(doc, 'disabledpackages')
-        if where == 'enabled':
-            oldpackages.removeChild(node)
-            packages.appendChild(node)
-        elif where == 'disabled':
-            packages.removeChild(node)
-            oldpackages.appendChild(node)
-        else:
-            raise ValueError
-        get_vistrails_application().vistrailsStartup.write_startup_dom(dom)
+    def _get_persistent_configuration(self):
+        return self._persistent_configuration
+    def _set_persistent_configuration(self, config):
+        self._persistent_configuration = config
+    persistent_configuration = property(_get_persistent_configuration,
+                                        _set_persistent_configuration)
 
-    def remove_own_dom_element(self):
-        """Moves the node to the <disabledpackages> section.
-        """
-        dom = get_vistrails_application().vistrailsStartup.startup_dom()
+    def do_load_configuration(self):
+        # Sometimes we don't want to change startup.xml, for example
+        # when peeking at a package that's on the available package list
+        # on edit -> preferences. That's what the load_configuration field
+        # is for
+        if self.load_configuration:
+            if self.configuration is not None:
+                # hold a copy of the initial configuration so it can be reset
+                self._default_configuration = copy.copy(self.configuration)
+
+                # now we update the actual configuration in place so it is
+                # available to the package itself
+                if self.persistent_configuration is not None:
+                    self.configuration.update(self.persistent_configuration)
+                else:
+                    # we don't have a persisted configuration so we
+                    # should create one
+                    self.persistent_configuration = \
+                                                copy.copy(self.configuration)
+                    self.persist_configuration(True)
 
-        node, section = self._get_package_node(dom, create='disabled')
-        if section == 'enabled':
-            self._move_package_node(dom, 'disabled', node)
+        
+    def persist_configuration(self, no_update=False):
+        if self.load_configuration:
+            if not no_update:
+                self.persistent_configuration.update(self.configuration)
+            # make sure startup is updated to reflect changes
+            get_vistrails_application().startup.persist_pkg_configuration(
+                self.codepath, self.persistent_configuration)
 
     def reset_configuration(self):
         """Reset package configuration to original package settings.
-        """
-
-        (dom, element) = self.find_own_dom_element()
-        doc = dom.documentElement
-        configuration = enter_named_element(element, 'configuration')
-        if configuration:
-            element.removeChild(configuration)
-        self.configuration = copy.copy(self._initial_configuration)
-
-        startup = get_vistrails_application().vistrailsStartup
-        startup.write_startup_dom(dom)
-
-    def find_own_dom_element(self):
-        """find_own_dom_element() -> (DOM, Node)
 
-        Opens the startup DOM, looks for the element that belongs to the package,
-        and returns DOM and node. Creates a new one in the <disabledpackages>
-        section if none is found.
         """
-        dom = get_vistrails_application().vistrailsStartup.startup_dom()
-
-        node, section = self._get_package_node(dom, create='disabled')
-        return (dom, node)
-
-    def load_persistent_configuration(self):
-        (dom, element) = self.find_own_dom_element()
-
-        configuration = enter_named_element(element, 'configuration')
-        if configuration and self.configuration is not None:
-            self.configuration.set_from_dom_node(configuration)
-        dom.unlink()
-
-    def set_persistent_configuration(self):
-        (dom, element) = self.find_own_dom_element()
-        child = enter_named_element(element, 'configuration')
-        if child:
-            element.removeChild(child)
-        self.configuration.write_to_dom(dom, element)
-        get_vistrails_application().vistrailsStartup.write_startup_dom(dom)
-        dom.unlink()
-
-    def create_startup_package_node(self):
-        """Writes the node to the <packages> section.
-
-        If it was in the <disabledpackages> section, move it, else, create it.
-        """
-        dom = get_vistrails_application().vistrailsStartup.startup_dom()
-
-        node, section = self._get_package_node(dom, create='enabled')
-        if section == 'disabled':
-            self._move_package_node(dom, 'enabled', node)
-
-        configuration = enter_named_element(node, 'configuration')
-        if configuration:
-            self.configuration.set_from_dom_node(configuration)
-
-        dom.unlink()
+        self.configuration = copy.copy(self._default_configuration)
+        if self.load_configuration:
+            self.persistent_configuration = copy.copy(self.configuration)
+            self.persist_configuration(True)
diff --git a/vistrails/core/modules/paramexplore.py b/vistrails/core/modules/paramexplore.py
index d95d612..8af77a6 100644
--- a/vistrails/core/modules/paramexplore.py
+++ b/vistrails/core/modules/paramexplore.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from vistrails.core import debug
 from vistrails.core.modules.basic_modules import Color
 from vistrails.core.utils.color import rgb2hsv, hsv2rgb
@@ -168,11 +171,11 @@ class UserDefinedFunctionInterpolator(object):
             def evaluate(i):
                 try:
                     v = d['value'](i)
-                    if v == None:
+                    if v is None:
                         return self._ptype.default_value
                     return v
                 except Exception, e:
-                    return str(e)
+                    return debug.format_exception(e)
             return [evaluate(i) for i in xrange(self._steps)]
         result = get()
 
diff --git a/vistrails/core/modules/python_source_configure.py b/vistrails/core/modules/python_source_configure.py
index a711b79..260c612 100644
--- a/vistrails/core/modules/python_source_configure.py
+++ b/vistrails/core/modules/python_source_configure.py
@@ -1,39 +1,43 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # *** MOVED *** to gui.modules.python_source_configure
+from __future__ import division
+
 import traceback
 from vistrails.core import debug
 
diff --git a/vistrails/core/modules/query_configuration.py b/vistrails/core/modules/query_configuration.py
index 3d1279a..a0a152c 100644
--- a/vistrails/core/modules/query_configuration.py
+++ b/vistrails/core/modules/query_configuration.py
@@ -1,39 +1,43 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # *** MOVED *** to gui.modules.query_configuration
+from __future__ import division
+
 import traceback
 from vistrails.core import debug
 
diff --git a/vistrails/core/modules/source_configure.py b/vistrails/core/modules/source_configure.py
index 5f804d3..3deaee1 100644
--- a/vistrails/core/modules/source_configure.py
+++ b/vistrails/core/modules/source_configure.py
@@ -1,39 +1,43 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # *** MOVED *** to gui.modules.source_configure
+from __future__ import division
+
 import traceback
 from vistrails.core import debug
 
diff --git a/vistrails/core/modules/sub_module.py b/vistrails/core/modules/sub_module.py
index f6ad512..4d0b47e 100644
--- a/vistrails/core/modules/sub_module.py
+++ b/vistrails/core/modules/sub_module.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """ Define facilities for setting up SubModule Module in VisTrails """
+from __future__ import division
+
 from itertools import izip
 import random
 import uuid
@@ -41,13 +44,12 @@ import uuid
 from vistrails.core.cache.hasher import Hasher
 from vistrails.core.cache.utils import hash_list
 from vistrails.core.modules import module_registry
-from vistrails.core.modules.basic_modules import String, Boolean, Variant, \
-    NotCacheable, identifier as basic_pkg
+from vistrails.core.modules.basic_modules import identifier as basic_pkg
+from vistrails.core.modules.config import ModuleSettings, IPort, OPort
 from vistrails.core.modules.vistrails_module import Module, InvalidOutput, new_module, \
     ModuleError, ModuleSuspended
-from vistrails.core.utils import ModuleAlreadyExists, DummyView, VistrailsInternalError
+from vistrails.core.utils import VistrailsInternalError
 import os.path
-import vistrails.db
 
 try:
     import hashlib
@@ -58,100 +60,195 @@ except ImportError:
 
 ##############################################################################
 
+def random_signature(pipeline, obj, chm):
+    hasher = sha_hash()
+    hasher.update(str(random.random()))
+    return hasher.digest()
+
+def input_port_signature(pipeline, obj, chm):
+    if hasattr(obj, '_input_port_signature') and \
+            obj._input_port_signature is not None:
+        return obj._input_port_signature
+    return random_signature(pipeline, obj, chm)
+
 class InputPort(Module):
-    
+    _settings = ModuleSettings(signature=input_port_signature)
+    _input_ports = [IPort("name", "String", optional=True),
+                    IPort("optional", "Boolean", optional=True),
+                    IPort("spec", "String"),
+                    IPort("ExternalPipe", "Variant", optional=True),
+                    IPort("Default", "Variant")]
+    _output_ports = [OPort("InternalPipe", "Variant")]
+                    
     def compute(self):
-        exPipe = self.forceGetInputFromPort('ExternalPipe')
+        exPipe = self.force_get_input('ExternalPipe')
         if exPipe is not None:
-            self.setResult('InternalPipe', exPipe)
+            self.set_output('InternalPipe', exPipe)
         else:
-            if self.hasInputFromPort('Default'):
-                self.setResult('InternalPipe',
-                               self.getInputFromPort('Default'))
+            if self.has_input('Default'):
+                self.set_output('InternalPipe',
+                               self.get_input('Default'))
             else:
-                self.setResult('InternalPipe', InvalidOutput)
+                self.set_output('InternalPipe', InvalidOutput)
 
 ###############################################################################
     
 class OutputPort(Module):
+    _input_ports = [IPort("name", "String", optional=True),
+                    IPort("optional", "Boolean", optional=True),
+                    IPort("spec", "String"),
+                    IPort("InternalPipe", "Variant")]
+    _output_ports = [OPort("ExternalPipe", "Variant", optional=True)]
     
     def compute(self):
-        inPipe = self.getInputFromPort('InternalPipe')
-        self.setResult('ExternalPipe', inPipe)
+        inPipe = self.get_input('InternalPipe')
+        self.set_output('ExternalPipe', inPipe)
     
 ###############################################################################
 
+def group_signature(pipeline, module, chm):
+    if module._port_specs is None:
+        module.make_port_specs()
+    input_conns = {}
+    input_functions = {}
+    for from_module, c_id in pipeline.graph.edges_to(module.id):
+        conn = pipeline.connections[c_id]
+        if conn.destination.name not in input_conns:
+            input_conns[conn.destination.name] = []
+        input_conns[conn.destination.name].append((from_module, conn))
+    for function in module.functions:
+        if function.name not in input_functions:
+            input_functions[function.name] = []
+        input_functions[function.name].append(function)
+    covered_modules = dict((k, False) for k in module._input_remap)
+    for input_port_name, conn_list in input_conns.iteritems():
+        covered_modules[input_port_name] = True
+        input_module = module._input_remap[input_port_name]
+        upstream_sigs = [(pipeline.subpipeline_signature(m) +
+                          Hasher.connection_signature(c))
+                         for (m, c) in conn_list]
+        module_sig = Hasher.module_signature(input_module, chm)
+        sig = Hasher.subpipeline_signature(module_sig, upstream_sigs)
+        if input_port_name in input_functions:
+            function_sig = hash_list(input_functions[input_port_name], 
+                                     Hasher.function_signature, chm)
+            sig = Hasher.compound_signature([sig, function_sig])
+        input_module._input_port_signature = sig
+    for input_port_name, done in covered_modules.iteritems():
+        if done:
+            continue
+        covered_modules[input_port_name] = True
+        input_module = module._input_remap[input_port_name]
+        if input_port_name in input_functions:
+            module_sig = Hasher.module_signature(input_module, chm)
+            function_sig = hash_list(input_functions[input_port_name], 
+                                     Hasher.function_signature, chm)
+            sig = Hasher.compound_signature([module_sig, function_sig])
+        else:
+            sig = Hasher.module_signature(input_module, chm)
+        input_module._input_port_signature = sig
+
+    module.pipeline.refresh_signatures()
+
+    sig_list = []
+    sig_list.append(Hasher.module_signature(module, chm))
+    for m_id in module.pipeline.graph.sinks():
+        sig_list.append(module.pipeline.subpipeline_signature(m_id))
+    return Hasher.compound_signature(sig_list)
+
 class Group(Module):
+    _settings = ModuleSettings(signature=group_signature,
+                               hide_descriptor=True)
+    _output_ports = [OPort("self", "Group", optional=True)]
+
     def __init__(self):
         Module.__init__(self)
         self.is_group = True
         self.persistent_modules = []
 
     def compute(self):
+        # Check required attributes
         if not hasattr(self, 'pipeline') or self.pipeline is None:
-            raise VistrailsInternalError("%s cannot execute--" % \
-                                             self.__class__.__name__ + \
-                                         "pipeline doesn't exist")
-        elif not hasattr(self, 'input_remap') or self.input_remap is None or \
-                not hasattr(self, 'output_remap') or self.output_remap is None:
-            raise VistrailsInternalError("%s cannot execute--" % \
-                                             self.__class__.__name__ + \
-                                         "remap dictionaries don't exist")
-            
+            raise VistrailsInternalError(
+                    "%s cannot execute -- pipeline doesn't exist" %
+                    self.__class__.__name__)
+        elif (not hasattr(self, 'output_remap') or self.output_remap is None or
+                not hasattr(self, 'input_remap') or self.input_remap is None):
+            raise VistrailsInternalError(
+                    "%s cannot execute -- remap dictionaries don't exist" %
+                    self.__class__.__name__)
+
+        # Setup pipeline for execution
         res = self.interpreter.setup_pipeline(self.pipeline)
         self.persistent_modules = res[0].values()
         if len(res[5]) > 0:
-            raise ModuleError(self, 'Error(s) inside group:\n' +
-                              '\n'.join(me.msg for me in res[5].itervalues()))
+            raise ModuleError(self, "Error(s) inside group:\n" +
+                              "\n".join(me.msg for me in res[5].itervalues()))
         tmp_id_to_module_map = res[0]
+
+        # Connect Group's external input ports to internal InputPort modules
         for iport_name, conn in self.inputPorts.iteritems():
             iport_module = self.input_remap[iport_name]
             iport_obj = tmp_id_to_module_map[iport_module.id]
             iport_obj.set_input_port('ExternalPipe', conn[0])
-        
-        kwargs = {'logger': self.logging.log, 'clean_pipeline': True,
+
+        # Execute pipeline
+        kwargs = {'logger': self.logging.log.recursing(self),
+                  'clean_pipeline': True,
                   'current_version': self.moduleInfo['version']}
         module_info_args = set(['locator', 'reason', 'extra_info', 'actions'])
         for arg in module_info_args:
             if arg in self.moduleInfo:
                 kwargs[arg] = self.moduleInfo[arg]
 
-#         if hasattr(self, 'group_exec'):
-#             kwargs['parent_exec'] = self.group_exec
-
-        res = self.interpreter.execute_pipeline(self.pipeline, *(res[:2]), 
+        res = self.interpreter.execute_pipeline(self.pipeline,
+                                                *res[:2],
                                                 **kwargs)
+
+        # Check and propagate errors
         if len(res[2]) > 0:
-            raise ModuleError(self, 'Error(s) inside group:\n' +
-                              '\n '.join(me.module.__class__.__name__ + ': ' + \
-                                            me.msg for me in res[2].itervalues()))
-        if len(res[4]) > 0:
-            # extract messages and previous ModuleSuspended exceptions
-            message = '\n'.join([msg for msg in res[4].itervalues()])
-            children = [tmp_id_to_module_map[module_id]._module_suspended
-                        for module_id in res[4]]
+            raise ModuleError(self, "Error(s) inside group:\n" +
+                              "\n".join("%s: %s" % (
+                                      me.module.__class__.__name__, me.msg)
+                              for me in res[2].itervalues()))
+
+        # Check and propagate ModuleSuspended exceptions
+        if res[4]:
+            message = "\n".join([ms.msg for ms in res[4].itervalues()])
+            children = list(res[4].values())
             raise ModuleSuspended(self, message, children=children)
-            
+
+        # Connect internal OutputPort modules to Group's external output ports
         for oport_name, oport_module in self.output_remap.iteritems():
             if oport_name is not 'self':
-                # oport_module = self.output_remap[oport_name]
                 oport_obj = tmp_id_to_module_map[oport_module.id]
-                self.setResult(oport_name, oport_obj.get_output('ExternalPipe'))
+                self.set_output(oport_name,
+                                oport_obj.get_output('ExternalPipe'))
+
         self.interpreter.finalize_pipeline(self.pipeline, *res[:-1],
-                                           **{'reset_computed': False})
+                                           reset_computed=False)
 
     def is_cacheable(self):
         return all(m.is_cacheable() for m in self.persistent_modules)
 
+    def transfer_attrs(self, module):
+        self.pipeline = module.pipeline
+        if module._port_specs is None:
+            module.make_port_specs()
+        self.input_remap = module._input_remap
+        self.output_remap = module._output_remap
+        Module.transfer_attrs(self, module)
+
 ###############################################################################
 
 def coalesce_port_specs(neighbors, type):
-    from vistrails.core.modules.basic_modules import identifier as basic_pkg
     reg = module_registry.get_module_registry()
     cur_descs = None
+    cur_depth = 0
+    Variant_desc = reg.get_descriptor_by_name(basic_pkg, 'Variant')
     if type == 'input':
         find_common = reg.find_descriptor_subclass
-        common_desc = reg.get_descriptor_by_name(basic_pkg, 'Variant')
+        common_desc = Variant_desc
     elif type == 'output':
         find_common = reg.find_descriptor_superclass
         common_desc = reg.get_descriptor_by_name(basic_pkg, 'Module')
@@ -162,37 +259,49 @@ def coalesce_port_specs(neighbors, type):
         if cur_descs is None:
             port_spec = module.get_port_spec(port_name, type)
             cur_descs = port_spec.descriptors()
+            cur_depth = port_spec.depth
         else:
             next_port_spec = module.get_port_spec(port_name, type)
             next_descs = next_port_spec.descriptors()
+            next_depth = next_port_spec.depth
             if len(cur_descs) != len(next_descs):
                 raise VistrailsInternalError("Cannot have single port "
                                              "connect to incompatible "
                                              "types")
+            if cur_depth != next_depth:
+                raise VistrailsInternalError("Cannot have single port "
+                                             "connect to types with "
+                                             "different list depth")
             descs = []
             for cur_desc, next_desc in izip(cur_descs, next_descs):
-                new_desc = find_common(cur_desc, next_desc)
+                if cur_desc is Variant_desc:
+                    new_desc = next_desc
+                elif next_desc is Variant_desc:
+                    new_desc = cur_desc
+                else:
+                    new_desc = find_common(cur_desc, next_desc)
                 if new_desc is None:
                     new_desc = common_desc
                 descs.append(new_desc)
             cur_descs = descs
+            
     if cur_descs:
         sigstring = '(' + ','.join(d.sigstring for d in cur_descs) + ')'
     else:
         sigstring = None
-    return sigstring
+    return (sigstring, cur_depth)
 
 def get_port_spec_info(pipeline, module):
     type_map = {'OutputPort': 'output', 'InputPort': 'input'}
     try:
         type = type_map[module.name]
     except KeyError:
-        raise VistrailsInternalError("cannot translate type '%s'" % type)
+        raise VistrailsInternalError("cannot translate type '%s'" % module.name)
     if type == 'input':
         get_edges = pipeline.graph.edges_from
         get_port_name = \
             lambda x: pipeline.connections[x].destination.name
-    elif type == 'output':
+    else:  # type == 'output'
         get_edges = pipeline.graph.edges_to
         get_port_name = \
             lambda x: pipeline.connections[x].source.name
@@ -205,8 +314,7 @@ def get_port_spec_info(pipeline, module):
     neighbors = [(pipeline.modules[m_id], get_port_name(c_id))
                  for (m_id, c_id) in get_edges(module.id)]
     port_name = neighbors[0][1]
-    sigstring = coalesce_port_specs(neighbors, type)
-    old_name = port_name
+    sigstring, depth = coalesce_port_specs(neighbors, type)
     # sigstring = neighbor.get_port_spec(port_name, type).sigstring
 
     # FIXME check old registry here?
@@ -217,11 +325,14 @@ def get_port_spec_info(pipeline, module):
         if function.name == 'optional':
             port_optional = function.params[0].strValue == 'True'
 #     print 'psi:', port_name, old_name, sigstring
-    return (port_name, sigstring, port_optional, neighbors)
+    return (port_name, sigstring, port_optional, depth, neighbors)
 
 ###############################################################################
 
 class Abstraction(Group):
+    _settings = ModuleSettings(name="SubWorkflow", 
+                               hide_descriptor=True)
+
     def __init__(self):
         Group.__init__(self)
 
@@ -335,19 +446,19 @@ def new_abstraction(name, vistrail, vt_fname=None, internal_version=-1L,
     input_remap = {}
     output_remap = {}
     for module in input_modules:
-        (port_name, sigstring, optional, _) = \
+        (port_name, sigstring, optional, depth, _) = \
             get_port_spec_info(pipeline, module)
-        input_ports.append((port_name, sigstring, optional))
+        input_ports.append((port_name, sigstring, optional, depth))
         input_remap[port_name] = module
     for module in output_modules:
-        (port_name, sigstring, optional, _) = \
+        (port_name, sigstring, optional, depth, _) = \
             get_port_spec_info(pipeline, module)
-        output_ports.append((port_name, sigstring, optional))
+        output_ports.append((port_name, sigstring, optional, depth))
         output_remap[port_name] = module
 
     # necessary for group
-    d['_input_ports'] = input_ports
-    d['_output_ports'] = output_ports
+    d['_input_ports'] = [IPort(*p[:3], depth=p[3]) for p in input_ports] 
+    d['_output_ports'] = [OPort(*p[:3], depth=p[3]) for p in output_ports] 
     d['input_remap'] = input_remap
     d['output_remap'] = output_remap
     d['pipeline'] = pipeline
@@ -389,67 +500,6 @@ def find_internal_abstraction_refs(pkg, vistrail, internal_version=-1L):
             abstractions.append((m.name, m.namespace))
     return abstractions
 
-def random_signature(pipeline, obj, chm):
-    hasher = sha_hash()
-    hasher.update(str(random.random()))
-    return hasher.digest()
-
-def input_port_signature(pipeline, obj, chm):
-    if hasattr(obj, '_input_port_signature') and \
-            obj._input_port_signature is not None:
-        return obj._input_port_signature
-    return random_signature(pipeline, obj, chm)
-
-def group_signature(pipeline, module, chm):
-    if module._port_specs is None:
-        module.make_port_specs()
-    input_conns = {}
-    input_functions = {}
-    for from_module, c_id in pipeline.graph.edges_to(module.id):
-        conn = pipeline.connections[c_id]
-        if conn.destination.name not in input_conns:
-            input_conns[conn.destination.name] = []
-        input_conns[conn.destination.name].append((from_module, conn))
-    for function in module.functions:
-        if function.name not in input_functions:
-            input_functions[function.name] = []
-        input_functions[function.name].append(function)
-    covered_modules = dict((k, False) for k in module._input_remap)
-    for input_port_name, conn_list in input_conns.iteritems():
-        covered_modules[input_port_name] = True
-        input_module = module._input_remap[input_port_name]
-        upstream_sigs = [(pipeline.subpipeline_signature(m) +
-                          Hasher.connection_signature(c))
-                         for (m, c) in conn_list]
-        module_sig = Hasher.module_signature(input_module, chm)
-        sig = Hasher.subpipeline_signature(module_sig, upstream_sigs)
-        if input_port_name in input_functions:
-            function_sig = hash_list(input_functions[input_port_name], 
-                                     Hasher.function_signature, chm)
-            sig = Hasher.compound_signature([sig, function_sig])
-        input_module._input_port_signature = sig
-    for input_port_name, done in covered_modules.iteritems():
-        if done:
-            continue
-        covered_modules[input_port_name] = True
-        input_module = module._input_remap[input_port_name]
-        if input_port_name in input_functions:
-            module_sig = Hasher.module_signature(input_module, chm)
-            function_sig = hash_list(input_functions[input_port_name], 
-                                     Hasher.function_signature, chm)
-            sig = Hasher.compound_signature([module_sig, function_sig])
-        else:
-            sig = Hasher.module_signature(input_module, chm)
-        input_module._input_port_signature = sig
-
-    module.pipeline.refresh_signatures()
-
-    sig_list = []
-    sig_list.append(Hasher.module_signature(module, chm))
-    for m_id in module.pipeline.graph.sinks():
-        sig_list.append(module.pipeline.subpipeline_signature(m_id))
-    return Hasher.compound_signature(sig_list)
-
 def parse_abstraction_name(filename, get_all_parts=False):
     # assume only 1 possible prefix or suffix
     import re
@@ -470,27 +520,4 @@ def parse_abstraction_name(filename, get_all_parts=False):
 
 ###############################################################################
 
-def initialize(*args, **kwargs):
-    # These are all from sub_module.py!
-    reg = module_registry.get_module_registry()
-
-    reg.add_module(InputPort, signatureCallable=input_port_signature)
-    reg.add_input_port(InputPort, "name", String, True)
-    reg.add_input_port(InputPort, "optional", Boolean, True)
-    reg.add_input_port(InputPort, "spec", String)
-    reg.add_input_port(InputPort, "ExternalPipe", Variant, True)
-    reg.add_input_port(InputPort, "Default", Variant)
-    reg.add_output_port(InputPort, "InternalPipe", Variant)
-
-    reg.add_module(OutputPort)
-    reg.add_input_port(OutputPort, "name", String, True)
-    reg.add_input_port(OutputPort, "optional", Boolean, True)
-    reg.add_input_port(OutputPort, "spec", String)
-    reg.add_input_port(OutputPort, "InternalPipe", Variant)
-    reg.add_output_port(OutputPort, "ExternalPipe", Variant, True)
-
-    reg.add_module(Group, signatureCallable=group_signature,
-                   hide_descriptor=True)
-    reg.add_output_port(Group, "self", Group, True)
-
-    reg.add_module(Abstraction, name="SubWorkflow", hide_descriptor=True)
+_modules = [InputPort, OutputPort, Group, Abstraction]
diff --git a/vistrails/core/modules/tuple_configuration.py b/vistrails/core/modules/tuple_configuration.py
index d03fb33..e717f7a 100644
--- a/vistrails/core/modules/tuple_configuration.py
+++ b/vistrails/core/modules/tuple_configuration.py
@@ -1,39 +1,43 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # *** MOVED *** to gui.modules.tuple_configuration
+from __future__ import division
+
 import traceback
 from vistrails.core import debug
 
diff --git a/vistrails/core/modules/utils.py b/vistrails/core/modules/utils.py
index 9083550..d4b5ff6 100644
--- a/vistrails/core/modules/utils.py
+++ b/vistrails/core/modules/utils.py
@@ -1,39 +1,59 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-import vistrails.core
-from vistrails.core.system import get_vistrails_default_pkg_prefix
+from __future__ import division
+
+from vistrails.core.system import _defaultPkgPrefix, \
+    get_vistrails_basic_pkg_id, get_module_registry
+
+def load_cls(cls_item, prefix=None):
+    path = None
+    if isinstance(cls_item, basestring):
+        (path, cls_name) = cls_item.split(':')[:2]
+    elif isinstance(cls_item, tuple):
+        (path, cls_name) = cls_item
+    if path is not None:
+        try:
+            module = __import__(path, globals(), locals(), [cls_name])
+        except ImportError:
+            if prefix is None:
+                raise
+            path = '.'.join([prefix, path])
+            module = __import__(path, globals(), locals(), [cls_name])
+        return getattr(module, cls_name)
+    return cls_item
 
 def create_descriptor_string(package, name, namespace=None,
                              use_package=True):
@@ -73,18 +93,15 @@ def parse_descriptor_string(d_string, cur_package=None):
         if '.' in parts[0]:
             package = parts[0]
         else:
-            package = '%s.%s' % (get_vistrails_default_pkg_prefix(), parts[0])
+            package = '%s.%s' % (_defaultPkgPrefix, parts[0])
     else:
         qual_name = d_string
         if cur_package is None:
-            from vistrails.core.modules.module_registry import get_module_registry
             reg = get_module_registry()
             if reg._current_package is not None:
                 package = reg._current_package.identifier
             else:
-                import vistrails.core.modules.basic_modules
-                basic_pkg = vistrails.core.modules.basic_modules.identifier
-                package = basic_pkg
+                package = get_vistrails_basic_pkg_id()
         else:
             package = cur_package
     qual_parts = qual_name.rsplit('|', 1)
@@ -129,9 +146,19 @@ def parse_port_spec_string(p_string, cur_package=None):
 
 
 def create_port_spec_string(specs_list, old_style=False):
-    return '(' + ','.join(create_port_spec_item_string(
-            *(specs + ((None, old_style) if len(specs) < 3 else (old_style,))))
-                          for specs in specs_list) + ')'
+    spec_items = []
+    for specs in specs_list:
+        if len(specs) == 3:
+            pkg, name, ns = specs
+        elif len(specs) == 2:
+            pkg, name = specs
+            ns = None
+        else:
+            raise TypeError("create_port_spec_string() got spec tuple "
+                            "with %d elements" % len(specs))
+        spec_items.append(create_port_spec_item_string(pkg, name, ns,
+                                                       old_style))
+    return '(%s)' % ','.join(spec_items)
 
 def expand_port_spec_string(p_string, cur_package=None, 
                             old_style=False):
diff --git a/vistrails/core/modules/vistrails_module.py b/vistrails/core/modules/vistrails_module.py
index d2dd47a..71b8e8c 100644
--- a/vistrails/core/modules/vistrails_module.py
+++ b/vistrails/core/modules/vistrails_module.py
@@ -1,41 +1,62 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+from base64 import b16encode, b16decode
 import copy
-from itertools import izip
+from itertools import izip, product
+import json
+import sys
+import time
+import traceback
+import warnings
 
 from vistrails.core.data_structures.bijectivedict import Bidict
+from vistrails.core import debug
+from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core.modules.config import ModuleSettings, IPort, OPort
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
+from vistrails.core.utils import VistrailsDeprecation, deprecated, \
+                                 xor, long2bytes
+try:
+    import hashlib
+    sha1_hash = hashlib.sha1
+except ImportError:
+    import sha
+    sha1_hash = sha.new
 
 class NeedsInputPort(Exception):
     def __init__(self, obj, port):
@@ -49,10 +70,6 @@ class IncompleteImplementation(Exception):
     def __str__(self):
         return "Module has incomplete implementation"
 
-
-class MissingModule(Exception):
-    pass
-
 class ModuleBreakpoint(Exception):
     def __init__(self, module):
         self.module = module
@@ -66,7 +83,7 @@ class ModuleBreakpoint(Exception):
 
         inputs = self.examine_inputs()
         retstr += "\nModule has inputs:\n"
-        
+
         for i in inputs.keys():
             retstr += "\t%s = %s\n" % (i, inputs[i])
 
@@ -76,7 +93,7 @@ class ModuleBreakpoint(Exception):
         in_ports = self.module.__dict__["inputPorts"]
         inputs = {}
         for p in in_ports:
-            inputs[p] = self.module.getInputListFromPort(p)
+            inputs[p] = self.module.get_input_list(p)
 
         return inputs
 
@@ -88,51 +105,66 @@ class ModuleHadError(Exception):
     def __init__(self, module):
         self.module = module
 
-class ModuleWasSuspended(ModuleHadError): 
-    """Exception occurring when a module that was suspended gets updated again. 
+class ModuleWasSuspended(ModuleHadError):
+    """Exception occurring when a module that was suspended gets updated again.
     """
 
 class ModuleError(Exception):
-
     """Exception representing a VisTrails module runtime error. This
-exception is recognized by the interpreter and allows meaningful error
-reporting to the user and to the logging mechanism."""
-    
-    def __init__(self, module, errormsg, abort=False):
+    exception is recognized by the interpreter and allows meaningful error
+    reporting to the user and to the logging mechanism.
+
+    """
+
+    def __init__(self, module, errormsg, abort=False, errorTrace=None):
         """ModuleError should be passed the module instance that signaled the
-error and the error message as a string."""
+        error and the error message as a string.
+
+        """
         Exception.__init__(self, errormsg)
         self.abort = abort # force abort even if stopOnError is False
         self.module = module
         self.msg = errormsg
-        import traceback
-        self.errorTrace = traceback.format_exc()
+        self.errorTrace = errorTrace
 
 class ModuleSuspended(ModuleError):
-    """Exception representing a VisTrails module being suspended. Raising 
-    ModuleSuspended flags that the module is not ready to finish yet and
-    that the workflow should be executed later.  A suspended module does
-    not execute the modules downstream but all other branches will be
-    executed. This is useful when executing external jobs where you do not
-    want to block vistrails while waiting for the execution to finish.
-
-    'queue' is a class instance that should provide a finished() method for
+    """Exception representing a VisTrails module being suspended.
+
+    Raising ModuleSuspended flags that the module is not ready to finish yet
+    and that the workflow should be executed later.
+    This is useful when executing external jobs where you do not want to block
+    vistrails while waiting for the execution to finish.
+
+    'monitor' is a class instance that should provide a finished() method for
     checking if the job has finished
 
     'children' is a list of ModuleSuspended instances that is used for nested
     modules
-    
     """
-    
-    def __init__(self, module, errormsg, queue=None, children=None):
-        self.queue = queue
-        self.children = children
+
+    def __init__(self, module, errormsg, handle=None, children=None,
+                 queue=None):
         ModuleError.__init__(self, module, errormsg)
+        self.handle = handle
+        if handle is None and queue is not None:
+            warnings.warn("Use of deprecated argument 'queue' replaced by "
+                          "'handle'",
+                          category=VistrailsDeprecation,
+                          stacklevel=2)
+            self.handle = queue
+        self.children = children
+        self.name = None
+
+    @property
+    def queue(self):
+        return self.handle
 
 class ModuleErrors(Exception):
     """Exception representing a list of VisTrails module runtime errors.
     This exception is recognized by the interpreter and allows meaningful
-    error reporting to the user and to the logging mechanism."""
+    error reporting to the user and to the logging mechanism.
+
+    """
     def __init__(self, module_errors):
         """ModuleErrors should be passed a list of ModuleError objects"""
         Exception.__init__(self, str(tuple(me.msg for me in module_errors)))
@@ -149,74 +181,50 @@ InvalidOutput = _InvalidOutput
 # DummyModuleLogging
 
 class DummyModuleLogging(object):
-    def end_update(self, *args, **kwargs): pass
-    def begin_update(self, *args, **kwargs): pass
-    def begin_compute(self, *args, **kwargs): pass
-    def update_cached(self, *args, **kwargs): pass
-    def signalSuccess(self, *args, **kwargs): pass
-    def annotate(self, *args, **kwargs): pass
+    def _dummy_method(self, *args, **kwargs): pass
 
-_dummy_logging = DummyModuleLogging()
-
-################################################################################
-# Serializable
+    def __getattr__(self, name):
+        return self._dummy_method
 
-class Serializable(object):
-    """
-    Serializable is a mixin class used to define methods to serialize and
-    deserialize modules. 
-    """
-    
-    def serialize(self):
-        """
-        Method used to serialize a module.
-        """
-        raise NotImplementedError('The serialize method is not defined for this module.')
-    
-    def deserialize(self):
-        """
-        Method used to deserialize a module.
-        """
-        raise NotImplementedError('The deserialize method is not defined for this module.')
+_dummy_logging = DummyModuleLogging()
 
 ################################################################################
 # Module
 
-class Module(Serializable):
-
+class Module(object):
     """Module is the base module from which all module functionality
-is derived from in VisTrails. It defines a set of basic interfaces to
-deal with data input/output (through ports, as will be explained
-later), as well as a basic mechanism for dataflow based updates.
+    is derived from in VisTrails. It defines a set of basic interfaces to
+    deal with data input/output (through ports, as will be explained
+    later), as well as a basic mechanism for dataflow based updates.
 
-Execution Model
+    *Execution Model*
 
-  VisTrails assumes fundamentally that a pipeline is a dataflow. This
-  means that pipeline cycles are disallowed, and that modules are
-  supposed to be free of side-effects. This is obviously not possible
-  in general, particularly for modules whose sole purpose is to
-  interact with operating system resources. In these cases, designing
-  a module is harder -- the side effects should ideally not be exposed
-  to the module interface.  VisTrails provides some support for making
-  this easier, as will be discussed later.
+    VisTrails assumes fundamentally that a pipeline is a dataflow. This
+    means that pipeline cycles are disallowed, and that modules are
+    supposed to be free of side-effects. This is obviously not possible
+    in general, particularly for modules whose sole purpose is to
+    interact with operating system resources. In these cases, designing
+    a module is harder -- the side effects should ideally not be exposed
+    to the module interface.  VisTrails provides some support for making
+    this easier, as will be discussed later.
 
-  VisTrails caches intermediate results to increase efficiency in
-  exploration. It does so by reusing pieces of pipelines in later
-  executions.
-  
-Terminology
+    VisTrails caches intermediate results to increase efficiency in
+    exploration. It does so by reusing pieces of pipelines in later
+    executions.
 
-  Module Interface: The module interface is the set of input and
-  output ports a module exposes.
+    *Terminology*
 
-Designing New Modules
+    Module Interface: The module interface is the set of input and
+    output ports a module exposes.
 
-  Designing new modules is essentially a matter of subclassing this
-  module class and overriding the compute() method. There is a
-  fully-documented example of this on the default package
-  'pythonCalc', available on the 'packages/pythonCalc' directory.
+    *Designing New Modules*
 
-  Caching
+    Designing new modules is essentially a matter of subclassing this
+    module class and overriding the compute() method. There is a
+    fully-documented example of this on the default package
+    'pythonCalc', available on the 'packages/pythonCalc' directory.
+
+    *Caching*
 
     Caching affects the design of a new module. Most importantly,
     users have to account for compute() being called more than
@@ -235,25 +243,23 @@ Designing New Modules
     subclass in the class hierarchy declarations). These modules (and
     anything that depends on their results) will then never be reused.
 
-
-  Intermediate Files
+    *Intermediate Files*
 
     Many modules communicate through intermediate files. VisTrails
     provides automatic filename and handle management to alleviate the
     burden of determining tricky things (e.g. longevity) of these
     files. Modules can request temporary file names through the file pool,
-    currently accessible through
-
-    self.interpreter.filePool
+    currently accessible through ``self.interpreter.filePool``.
 
     The FilePool class is available in core/modules/module_utils.py -
     consult its documentation for usage. Notably, using the file pool
     will make temporary files work correctly with caching, and will
     make sure the temporaries are correctly removed.
 
+    """
 
-
-"""
+    _settings = ModuleSettings(is_root=True, abstract=True)
+    _output_ports = [OPort("self", "Module", optional=True)]
 
     def __init__(self):
         self.inputPorts = {}
@@ -261,7 +267,8 @@ Designing New Modules
         self.upToDate = False
         self.had_error = False
         self.was_suspended = False
-        self.setResult("self", self) # every object can return itself
+        self.is_while = False
+        self.list_depth = 0
         self.logging = _dummy_logging
 
         # isMethod stores whether a certain input port is a method.
@@ -270,7 +277,16 @@ Designing New Modules
         # method order can work correctly
         self.is_method = Bidict()
         self._latest_method_order = 0
-        
+        self.control_params = {}
+        self.input_specs = {}
+        self.output_specs = {}
+        self.input_specs_order = []
+        self.output_specs_order = []
+        self.iterated_ports = []
+        self.streamed_ports = {}
+        self.in_pipeline = False
+        self.set_output("self", self) # every object can return itself
+
         # Pipeline info that a module should know about This is useful
         # for a spreadsheet cell to know where it is from. It will be
         # also used for talking back and forth between the spreadsheet
@@ -288,24 +304,30 @@ Designing New Modules
 
         self.is_breakpoint = False
 
-        # is_looping stores wether the module is a part of a loop
-        self.is_looping = False
-
-        # is_looping_module stores whether the module is a looping module
-        self.is_looping_module = False
-
         # computed stores wether the module was computed
         # used for the logging stuff
         self.computed = False
-        
-        self.suspended = False
 
         self.signature = None
-        
+
         # stores whether the output of the module should be annotated in the
         # execution log
         self.annotate_output = False
 
+    def transfer_attrs(self, module):
+        if module.cache != 1:
+            self.is_cacheable = lambda *args: False
+        self.list_depth = module.list_depth
+        self.is_breakpoint = module.is_breakpoint
+
+        for cp in module.control_parameters:
+            self.control_params[cp.name] = cp.value
+
+        self.input_specs = dict((p.name, p) for p in module.destinationPorts())
+        self.output_specs = dict((p.name, p) for p in module.sourcePorts())
+        self.input_specs_order = [p.name for p in module.destinationPorts()]
+        self.output_specs_order = [p.name for p in module.sourcePorts()]
+
     def __copy__(self):
         """Makes a copy of the input/output ports on shallow copy.
         """
@@ -318,11 +340,19 @@ Designing New Modules
         clone.inputPorts = copy.copy(self.inputPorts)
         clone.outputPorts = copy.copy(self.outputPorts)
         clone.outputPorts['self'] = clone
+        clone.control_params = self.control_params.copy()
+        clone.input_specs = self.input_specs
+        clone.output_specs = self.output_specs
+        clone.input_specs_order = self.input_specs_order
+        clone.output_specs_order = self.output_specs_order
+
         return clone
 
     def clear(self):
-        """clear(self) -> None. Removes all references, prepares for
-deletion."""
+        """clear(self) -> None.
+        Removes all references, prepares for deletion.
+
+        """
         for connector_list in self.inputPorts.itervalues():
             for connector in connector_list:
                 connector.clear()
@@ -333,48 +363,180 @@ deletion."""
         self._latest_method_order = 0
 
     def is_cacheable(self):
-        """is_cacheable() -> bool. A Module should return whether it
-can be reused across executions. It is safe for a Module to return
-different values in different occasions. In other words, it is
-possible for modules to be cacheable depending on their execution
-context."""
+        """is_cacheable() -> bool.
+        A Module should return whether it can be
+        reused across executions. It is safe for a Module to return
+        different values in different occasions. In other words, it is
+        possible for modules to be cacheable depending on their
+        execution context.
+
+        """
         return True
 
-    def updateUpstreamPort(self, port):
-        # update single port
-        if port in self.inputPorts:
-            for connector in self.inputPorts[port]:
-                connector.obj.update()
-                if hasattr(connector.obj, 'suspended') and \
-                   connector.obj.suspended:
-                    self.suspended = connector.obj.suspended
-            for connector in copy.copy(self.inputPorts[port]):
+    def update_upstream_port(self, port_name):
+        """Updates upstream of a single port instead of all ports."""
+
+        if port_name in self.inputPorts:
+            for connector in self.inputPorts[port_name]:
+                connector.obj.update() # Might raise
+            for connector in copy.copy(self.inputPorts[port_name]):
                 if connector.obj.get_output(connector.port) is InvalidOutput:
-                    self.removeInputConnector(port, connector)
+                    self.remove_input_connector(port_name, connector)
+
+
+    def useJobCache(self):
+        """ useJobCache() -> Module/None
+            Checks if this is a job cache
+        """
+        if not self.moduleInfo.get('pipeline', None):
+            return False
+        p_modules = self.moduleInfo['pipeline'].modules
+        p_module = p_modules[self.moduleInfo['moduleId']]
+        if p_module.has_control_parameter_with_name(
+                                            ModuleControlParam.JOB_CACHE_KEY):
+            jobCache = p_module.get_control_parameter_by_name(
+                                       ModuleControlParam.JOB_CACHE_KEY).value
+            if jobCache and jobCache.lower() == 'true':
+                return p_module
+        return False
 
-    def updateUpstream(self):
-        """ updateUpstream() -> None        
+    def setJobCache(self):
+        """ setJobCache() -> Boolean
+            Checks if this is a job cache and it exists
+        """
+        p_module = self.useJobCache()
+        if not p_module:
+            return False
+        jm = self.job_monitor()
+        specs = p_module.sourcePorts()
+        if jm.getCache(self.signature):
+            self.cache = jm.getCache(self.signature)
+            from vistrails.core.modules.basic_modules import Constant
+            for param, value in jm.getCache(self.signature).parameters.iteritems():
+                # get type for output param
+                spec = [s for s in specs if s.name == param][0]
+                module = spec.descriptors()[0].module
+                if not issubclass(module, Constant):
+                    raise ModuleError(self, "Trying to use a non-constant type a cache: %s" % spec.name)
+                self.set_output(param, module.translate_to_python(value))
+            self.upToDate = True
+            return True
+        return False
+
+    def addJobCache(self):
+        """ addJobCache() -> None
+            Add outputs from job cache
+        """
+        p_module = self.useJobCache()
+        if not p_module:
+            return False
+        jm = self.job_monitor()
+        specs = p_module.sourcePorts()
+        params = {}
+        if not jm.getCache(self.signature):
+            from vistrails.core.modules.basic_modules import Constant
+            for spec in specs:
+                if spec.name == 'self':
+                    continue
+                # get type for output param
+                module = spec.descriptors()[0].module
+                if not issubclass(module, Constant):
+                    raise ModuleError(self, "Trying to cache a non-constant type: %s" % spec.name)
+                params[spec.name] = module.translate_to_string(self.get_output(spec.name))
+                jm.setCache(self.signature, params, p_module.name)
+
+    def update_upstream(self):
+        """ update_upstream() -> None
         Go upstream from the current module, then update its upstream
         modules and check input connection based on upstream modules
         results
-        
+
         """
+        suspended = []
+        was_suspended = None
         for connectorList in self.inputPorts.itervalues():
             for connector in connectorList:
-                connector.obj.update()
-                if hasattr(connector.obj, 'suspended') and \
-                   connector.obj.suspended:
-                    self.suspended = connector.obj.suspended
+                try:
+                    connector.obj.update()
+                except ModuleWasSuspended, e:
+                    was_suspended = e
+                except ModuleSuspended, e:
+                    suspended.append(e)
+                # Here we keep going even if one of the module suspended, but
+                # we'll stop right after the loop
+        if len(suspended) == 1:
+            raise suspended[0]
+        elif suspended:
+            raise ModuleSuspended(
+                    self,
+                    "multiple suspended upstream modules",
+                    children=suspended)
+        elif was_suspended is not None:
+            raise was_suspended
         for iport, connectorList in copy.copy(self.inputPorts.items()):
             for connector in connectorList:
                 if connector.obj.get_output(connector.port) is InvalidOutput:
-                    self.removeInputConnector(iport, connector)
-                    
+                    self.remove_input_connector(iport, connector)
+
+    def set_iterated_ports(self):
+        """ set_iterated_ports() -> None
+        Calculates which inputs needs to be iterated over
+        """
+        iports = {}
+        from vistrails.core.modules.basic_modules import List, Variant
+        for port_name, connectorList in self.inputPorts.iteritems():
+            for connector in connectorList:
+
+                src_depth = connector.depth()
+                if not self.input_specs:
+                    # cannot do depth wrapping
+                    continue
+                # Give List an additional depth
+                dest_descs = self.input_specs[port_name].descriptors()
+                dest_depth = self.input_specs[port_name].depth
+                if len(dest_descs) == 1 and dest_descs[0].module == List:
+                    dest_depth += 1
+                if connector.spec:
+                    src_descs = connector.spec.descriptors()
+                    if len(src_descs) == 1 and src_descs[0].module == List and \
+                       len(dest_descs) == 1 and dest_descs[0].module == Variant:
+                        # special case - Treat Variant as list
+                        src_depth -= 1
+                    if len(src_descs) == 1 and src_descs[0].module == Variant and \
+                       len(dest_descs) == 1 and dest_descs[0].module == List:
+                        # special case - Treat Variant as list
+                        dest_depth -= 1
+
+                # store connector with greatest depth
+                # if value depth > port depth
+                depth = src_depth - dest_depth
+                if depth > 0 and (port_name not in iports or
+                                  iports[port_name][1] < depth):
+                    # keep largest
+                    # raw connector only use by streaming and then use only
+                    # one connector
+                    iports[port_name] = (port_name, depth, connector.get_raw())
+        self.iterated_ports = [iports[p] for p in self.input_specs_order
+                               if p in iports]
+
+    def set_streamed_ports(self):
+        """ set_streamed_ports() -> None
+        Calculates which inputs will be streamed
+
+        """
+        self.streamed_ports = {}
+        from vistrails.core.modules.basic_modules import Generator
+        for iport, connectorList in self.inputPorts.items():
+            for connector in connectorList:
+                value = connector.get_raw()
+                if isinstance(value, Generator):
+                    self.streamed_ports[iport] = value
+
     def update(self):
-        """ update() -> None        
+        """ update() -> None
         Check if the module is up-to-date then update the
         modules. Report to the logger if available
-        
+
         """
         if self.had_error:
             raise ModuleHadError(self)
@@ -383,10 +545,8 @@ context."""
         elif self.computed:
             return
         self.logging.begin_update(self)
-        self.updateUpstream()
-        if self.suspended:
-            self.had_error = True
-            return
+        if not self.setJobCache():
+            self.update_upstream()
         if self.upToDate:
             if not self.computed:
                 self.logging.update_cached(self)
@@ -397,32 +557,45 @@ context."""
         try:
             if self.is_breakpoint:
                 raise ModuleBreakpoint(self)
-            self.compute()
+            self.set_iterated_ports()
+            self.set_streamed_ports()
+            if self.streamed_ports:
+                self.build_stream()
+            elif self.list_depth > 0:
+                self.compute_all()
+            elif (self.in_pipeline and
+                  not self.is_while and
+                  (ModuleControlParam.WHILE_COND_KEY in self.control_params or
+                   ModuleControlParam.WHILE_MAX_KEY in self.control_params)):
+                self.is_while = True
+                self.compute_while()
+            else:
+                self.compute()
+                self.addJobCache()
             self.computed = True
         except ModuleSuspended, e:
-            self.suspended = e.msg
-            self._module_suspended = e
             self.had_error, self.was_suspended = False, True
-            self.logging.end_update(self, e, was_suspended=True)
-            self.logging.signalSuspended(self)
-            return
+            raise
         except ModuleError, me:
             if hasattr(me.module, 'interpreter'):
+                if me.errorTrace is None:
+                    me.errorTrace = traceback.format_exc()
                 raise
             else:
-                msg = "A dynamic module raised an exception: '%s'"
-                msg %= str(me)
-                raise ModuleError(self, msg)
+                msg = "A dynamic module raised an exception: '%s'" % me
+                raise ModuleError(self, msg, errorTrace=me.errorTrace)
         except ModuleErrors:
             raise
         except KeyboardInterrupt, e:
             raise ModuleError(self, 'Interrupted by user')
         except ModuleBreakpoint:
             raise
-        except Exception, e: 
-            import traceback
-            traceback.print_exc()
-            raise ModuleError(self, 'Uncaught exception: "%s"' % str(e))
+        except Exception, e:
+            debug.unexpected_exception(e)
+            raise ModuleError(
+                    self,
+                    "Uncaught exception: %s" % debug.format_exception(e),
+                    errorTrace=traceback.format_exc())
         if self.annotate_output:
             self.annotate_output_values()
         self.upToDate = True
@@ -430,50 +603,752 @@ context."""
         self.logging.end_update(self)
         self.logging.signalSuccess(self)
 
-    def checkInputPort(self, name):
-        """checkInputPort(name) -> None.
-Makes sure input port 'name' is filled."""
-        if not self.hasInputFromPort(name):
-            raise ModuleError(self, "'%s' is a mandatory port" % name)
+    def do_combine(self, combine_type, inputs, port_name_order):
+        values = []
+        port_names = []
+        for port_name in port_name_order:
+            # this is how the (brittle) recursion is accomplished
+            if not isinstance(port_name, basestring):
+                sub_combine_type = port_name[0]
+                sub_port_names = port_name[1:]
+                sub_values, sub_port_names = self.do_combine(sub_combine_type,
+                                                             inputs,
+                                                             sub_port_names)
+                values.append(sub_values)
+                port_names.extend(sub_port_names)
+            else:
+                values.append((e,) for e in inputs[port_name])
+                port_names.append(port_name)
+        if combine_type == "pairwise":
+            elements = [tuple(e for t in t_list for e in t)
+                        for t_list in izip(*values)]
+        elif combine_type == "cartesian":
+            elements = [tuple(e for t in t_list for e in t)
+                        for t_list in product(*values)]
+        else:
+            raise ValueError('Unknown combine type "%s"' % combine_type)
+        return elements, port_names
+
+    def get_combine_type(self, default="cartesian"):
+        if ModuleControlParam.LOOP_KEY in self.control_params:
+            return self.control_params[ModuleControlParam.LOOP_KEY]
+        return default
+
+    def compute_all(self):
+        """This method executes the module once for each input.
+           Similarly to controlflow's fold.
+
+        """
+        from vistrails.core.modules.sub_module import InputPort
+        if isinstance(self, InputPort):
+            return self.compute()
+        if self.list_depth < 1:
+            raise ModuleError(self, "List compute has wrong depth: %s" %
+                                    self.list_depth)
+        combine_type = self.get_combine_type('cartesian')
+        suspended = []
+
+        inputs = {} # dict of port_name: value
+        port_names = []
+        for port_name, depth, _ in self.iterated_ports:
+            # only iterate max depth and leave the others for the
+            # next iteration
+            if depth != self.list_depth:
+                continue
+            inputs[port_name] = self.get_input(port_name)
+            port_names.append(port_name)
+
+        if combine_type not in ['pairwise', 'cartesian']:
+            custom_order = json.loads(combine_type)
+            combine_type = custom_order[0]
+            port_names = custom_order[1:]
+
+        elements, port_names = self.do_combine(combine_type, inputs, port_names)
+        num_inputs = len(elements)
+        loop = self.logging.begin_loop_execution(self, num_inputs)
+        ## Update everything for each value inside the list
+        outputs = {}
+        for i in xrange(num_inputs):
+            self.logging.update_progress(self, float(i)/num_inputs)
+            module = copy.copy(self)
+            module.list_depth = self.list_depth - 1
+            module.had_error = False
+            module.was_suspended = False
+
+            if not self.upToDate: # pragma: no partial
+                ## Type checking if first iteration and last iteration level
+                if i == 0 and self.list_depth == 1:
+                    self.typeChecking(module, port_names, elements)
+
+                module.upToDate = False
+                module.computed = False
+                self.setInputValues(module, port_names, elements[i], i)
+
+            loop.begin_iteration(module, i)
+
+            try:
+                module.update()
+            except ModuleSuspended, e:
+                e.loop_iteration = i
+                module.logging.end_update(module, e, was_suspended=True)
+                suspended.append(e)
+                loop.end_iteration(module)
+                continue
+
+            loop.end_iteration(module)
+
+            ## Getting the result from the output port
+            for nameOutput in module.outputPorts:
+                if nameOutput not in outputs:
+                    outputs[nameOutput] = []
+                output = module.get_output(nameOutput)
+                outputs[nameOutput].append(output)
+
+            self.logging.update_progress(self, i * 1.0 / num_inputs)
+
+        if suspended:
+            raise ModuleSuspended(
+                    self,
+                    "function module suspended in %d/%d iterations" % (
+                            len(suspended), num_inputs),
+                    children=suspended)
+        # set final outputs
+        for nameOutput in outputs:
+            self.set_output(nameOutput, outputs[nameOutput])
+        loop.end_loop_execution()
+
+    def build_stream(self):
+        """Determines and builds correct generator type.
+
+        """
+        from vistrails.core.modules.basic_modules import PythonSource
+        if True in [g.accumulated for g in self.streamed_ports.values()]:
+            # the module can only compute once the streaming is finished
+            self.compute_after_streaming()
+        elif self.list_depth > 0:
+            # iterate the module for each value in the stream
+            self.compute_streaming()
+        elif isinstance(self, Streaming) or\
+             (isinstance(self, PythonSource) and
+              '%23%20pragma%3A%20streaming' in self.get_input('source')):
+            # Magic tag: "# pragma: streaming"
+
+            # the module creates its own generator object
+            self.compute()
+        else:
+            # the module cannot handle generator so we accumulate the stream
+            self.compute_accumulate()
+
+    def compute_streaming(self):
+        """This method creates a generator object and sets the outputs as
+        generators.
+
+        """
+        from vistrails.core.modules.basic_modules import Generator
+        type = self.control_params.get(ModuleControlParam.LOOP_KEY, 'pairwise')
+        if type == 'cartesian':
+            raise ModuleError(self,
+                              'Cannot use cartesian product while streaming!')
+        suspended = []
+
+        # only iterate the max depth and leave others for the next iteration
+        ports = [port for port, depth, value in self.iterated_ports
+                 if depth == self.list_depth]
+        num_inputs = self.iterated_ports[0][2].size
+        # the generator will read next from each iterated input port and
+        # compute the module again
+        module = copy.copy(self)
+        module.list_depth = self.list_depth - 1
+        if num_inputs:
+            milestones = [i*num_inputs//10 for i in xrange(1, 11)]
+        def generator(self):
+            self.logging.begin_compute(module)
+            i = 0
+            while 1:
+                iter_dict = dict([(port, (depth, value))
+                                  for port, depth, value in
+                                  self.iterated_ports])
+
+                elements = [iter_dict[port][1].next() for port in ports]
+                if None in elements:
+                    for name_output in module.outputPorts:
+                        module.set_output(name_output, None)
+                    if suspended:
+                        raise ModuleSuspended(
+                                self,
+                                ("function module suspended after streaming "
+                                 "%d/%d iterations") % (
+                                        len(suspended), num_inputs),
+                                children=suspended)
+                    self.logging.update_progress(module, 1.0)
+                    self.logging.end_update(module)
+                    yield None
+                if num_inputs:
+                    if i in milestones:
+                        self.logging.update_progress(module, float(i)/num_inputs)
+                else:
+                    self.logging.update_progress(module, 0.5)
+                module.had_error = False
+                ## Type checking
+                if i == 0:
+                    self.typeChecking(module, ports, [elements])
+
+                module.upToDate = False
+                module.computed = False
+
+                self.setInputValues(module, ports, elements, i)
+
+                try:
+                    module.compute()
+                except ModuleSuspended, e:
+                    e.loop_iteration = i
+                    suspended.append(e)
+                except Exception, e:
+                    raise ModuleError(module, str(e))
+                i += 1
+                yield True
+
+        _generator = generator(self)
+        # set streaming outputs
+        for name_output in self.outputPorts:
+            iterator = Generator(size=num_inputs,
+                                 module=module,
+                                 generator=_generator,
+                                 port=name_output)
+            self.set_output(name_output, iterator)
+
+    def compute_accumulate(self):
+        """This method creates a generator object that converts all
+        streaming inputs to list inputs for modules that does not explicitly
+        support streaming.
+
+        """
+        from vistrails.core.modules.basic_modules import Generator
+        suspended = []
+        # max depth should be one
+        ports = self.streamed_ports.keys()
+        num_inputs = self.streamed_ports[ports[0]].size
+        # the generator will read next from each iterated input port and
+        # compute the module again
+        module = copy.copy(self)
+        module.had_error = False
+        module.upToDate = False
+        module.computed = False
+
+        inputs = dict([(port, []) for port in ports])
+        def generator(self):
+            self.logging.begin_update(module)
+            i = 0
+            while 1:
+                elements = [self.streamed_ports[port].next() for port in ports]
+                if None in elements:
+                    self.logging.begin_compute(module)
+                    # assembled all inputs so do the actual computation
+                    elements = [inputs[port] for port in ports]
+                    ## Type checking
+                    self.typeChecking(module, ports, zip(*elements))
+                    self.setInputValues(module, ports, elements, i)
+                    try:
+                        module.compute()
+                    except Exception, e:
+                        raise ModuleError(module, str(e))
+                    if suspended:
+                        raise ModuleSuspended(
+                                self,
+                                ("function module suspended after streaming "
+                                 "%d/%d iterations") % (
+                                        len(suspended), num_inputs),
+                                children=suspended)
+                    self.logging.end_update(module)
+                    yield None
+
+                for port, value in zip(ports, elements):
+                    inputs[port].append(value)
+                for name_output in module.outputPorts:
+                    module.set_output(name_output, None)
+                i += 1
+                yield True
+
+        _generator = generator(self)
+        # set streaming outputs
+        for name_output in self.outputPorts:
+            iterator = Generator(size=num_inputs,
+                                 module=module,
+                                 generator=_generator,
+                                 port=name_output,
+                                 accumulated=True)
+            self.set_output(name_output, iterator)
+
+    def compute_after_streaming(self):
+        """This method creates a generator object that computes when the
+        streaming is finished.
+
+        """
+        from vistrails.core.modules.basic_modules import Generator
+        suspended = []
+
+        # max depth should be one
+        # max depth should be one
+        ports = self.streamed_ports.keys()
+        num_inputs = self.streamed_ports[ports[0]].size
+        # the generator will read next from each iterated input port and
+        # compute the module again
+        module = copy.copy(self)
+        module.had_error = False
+        module.upToDate = False
+        module.computed = False
+
+        def generator(self):
+            self.logging.begin_update(module)
+            i = 0
+            for name_output in module.outputPorts:
+                module.set_output(name_output, None)
+            while 1:
+                elements = [self.streamed_ports[port].next() for port in ports]
+                if None not in elements:
+                    self.logging.begin_compute(module)
+                    ## Type checking
+                    self.typeChecking(module, ports, [elements])
+                    self.setInputValues(module, ports, elements, i)
+                    try:
+                        module.compute()
+                    except Exception, e:
+                        raise ModuleError(module, str(e))
+                    if suspended:
+                        raise ModuleSuspended(
+                                self,
+                                ("function module suspended after streaming "
+                                 "%d/%d iterations") % (
+                                 len(suspended), num_inputs),
+                                children=suspended)
+                    self.logging.update_progress(self, 1.0)
+                    self.logging.end_update(module)
+                    yield None
+                i += 1
+                yield True
+
+        _generator = generator(self)
+        # set streaming outputs
+        for name_output in self.outputPorts:
+            iterator = Generator(size=num_inputs,
+                                 module=module,
+                                 generator=_generator,
+                                 port=name_output,
+                                 accumulated=True)
+            self.set_output(name_output, iterator)
+
+    def compute_while(self):
+        """This method executes the module once for each module.
+           Similarly to fold.
+
+        """
+        name_condition = self.control_params.get(
+            ModuleControlParam.WHILE_COND_KEY, None)
+        max_iterations = int(self.control_params.get(
+            ModuleControlParam.WHILE_MAX_KEY, 20))
+        delay = float(self.control_params.get(
+            ModuleControlParam.WHILE_DELAY_KEY, 0.0))
+        # todo only one state port supported right now
+        name_state_input = self.control_params.get(
+            ModuleControlParam.WHILE_INPUT_KEY, None)
+        name_state_input = [name_state_input] if name_state_input else None
+        name_state_output = self.control_params.get(
+            ModuleControlParam.WHILE_OUTPUT_KEY, None)
+        name_state_output = [name_state_output] if name_state_output else None
+
+        from vistrails.core.modules.basic_modules import create_constant
+
+        if name_state_input or name_state_output:
+            if not name_state_input or not name_state_output:
+                raise ModuleError(self,
+                                  "Passing state between iterations requires "
+                                  "BOTH StateInputPorts and StateOutputPorts "
+                                  "to be set")
+            if len(name_state_input) != len(name_state_output):
+                raise ModuleError(self,
+                                  "StateInputPorts and StateOutputPorts need "
+                                  "to have the same number of ports "
+                                  "(got %d and %d)" %(len(name_state_input),
+                                                      len(name_state_output)))
+
+        module = copy.copy(self)
+        module.had_error = False
+        module.is_while = True
+        state = None
+
+        loop = self.logging.begin_loop_execution(self, max_iterations)
+        for i in xrange(max_iterations):
+            if not self.upToDate:
+                module.upToDate = False
+                module.computed = False
+
+                # Set state on input ports
+                if i > 0 and name_state_input:
+                    for value, input_port, output_port \
+                     in izip(state, name_state_input, name_state_output):
+                        if input_port in module.inputPorts:
+                            del module.inputPorts[input_port]
+                        new_connector = ModuleConnector(
+                                create_constant(value), 'value',
+                                module.output_specs.get(output_port, None))
+                        module.set_input_port(input_port, new_connector)
+
+            loop.begin_iteration(module, i)
+
+            try:
+                module.update() # might raise ModuleError, ModuleSuspended,
+                                # ModuleHadError, ModuleWasSuspended
+            except ModuleSuspended, e:
+                e.loop_iteration = i
+                raise
+
+            loop.end_iteration(module)
+
+            if name_condition is not None:
+                if name_condition not in module.outputPorts:
+                    raise ModuleError(
+                            module,
+                            "Invalid output port: %s" % name_condition)
+                if not module.get_output(name_condition):
+                    break
+
+            if delay and i+1 != max_iterations:
+                time.sleep(delay)
+
+            # Get state on output ports
+            if name_state_output:
+                state = [module.get_output(port) for port in name_state_output]
+
+            self.logging.update_progress(self, i * 1.0 / max_iterations)
+
+        loop.end_loop_execution()
+
+        for name_output in self.outputPorts:
+            self.set_output(name_output, module.get_output(name_output))
+
+    def setInputValues(self, module, inputPorts, elementList, iteration):
+        """
+        Function used to set a value inside 'module', given the input port(s).
+        """
+        from vistrails.core.modules.basic_modules import create_constant
+        for element, inputPort in izip(elementList, inputPorts):
+            ## Cleaning the previous connector...
+            if inputPort in module.inputPorts:
+                del module.inputPorts[inputPort]
+            spec = None
+            if inputPort in self.input_specs:
+                spec = self.input_specs[inputPort].__copy__()
+                spec.depth += module.list_depth
+            new_connector = ModuleConnector(create_constant(element), 'value',
+                                            spec)
+            module.set_input_port(inputPort, new_connector)
+            # Affix a fake signature on the module
+            # Ultimately, we might want to give it the signature it would have
+            # with its current functions if it had a connection to the upstream
+            # of our InputList port through a Getter module?
+            # This structure with the Getter is unlikely to actually happen
+            # anywhere though...
+            # The fake signature is
+            # XOR(signature(loop module), iteration, hash(inputPort))
+            inputPort_hash = sha1_hash()
+            inputPort_hash.update(inputPort)
+            module.signature = b16encode(xor(
+                    b16decode(self.signature.upper()),
+                    long2bytes(iteration, 20),
+                    inputPort_hash.digest()))
+
+    Variant_desc = None
+    InputPort_desc = None
+
+    @staticmethod
+    def load_type_check_descs():
+        from vistrails.core.modules.module_registry import get_module_registry
+        reg = get_module_registry()
+        Module.Variant_desc = reg.get_descriptor_by_name(
+            'org.vistrails.vistrails.basic', 'Variant')
+        Module.InputPort_desc = reg.get_descriptor_by_name(
+            'org.vistrails.vistrails.basic', 'InputPort')
+
+    @staticmethod
+    def get_type_checks(source_spec):
+        if Module.Variant_desc is None:
+            Module.load_type_check_descs()
+        conf = get_vistrails_configuration()
+        error_on_others = getattr(conf, 'showConnectionErrors')
+        error_on_variant = (error_on_others or
+                            getattr(conf, 'showVariantErrors'))
+        errors = [error_on_others, error_on_variant]
+        return [errors[desc is Module.Variant_desc]
+                for desc in source_spec.descriptors()]
+
+    def typeChecking(self, module, inputPorts, inputList):
+        """
+        Function used to check if the types of the input list element and of the
+        inputPort of 'module' match.
+        """
+        from vistrails.core.modules.basic_modules import Generator
+        from vistrails.core.modules.basic_modules import get_module
+        if not module.input_specs:
+            return
+        for elementList in inputList:
+            if len(elementList) != len(inputPorts):
+                raise ModuleError(self,
+                                  'The number of input values and input ports '
+                                  'are not the same.')
+            for element, inputPort in izip(elementList, inputPorts):
+                if isinstance(element, Generator):
+                    raise ModuleError(self, "Generator is not allowed here")
+                port_spec = module.input_specs[inputPort]
+                # typecheck only if all params should be type-checked
+                if False in self.get_type_checks(port_spec):
+                    break
+                v_module = get_module(element, port_spec.signature)
+                if v_module is not None:
+                    if not self.compare(port_spec, v_module, inputPort):
+                        raise ModuleError(self,
+                                          'The type of a list element does '
+                                          'not match with the type of the '
+                                          'port %s.' % inputPort)
+                    del v_module
+                else:
+                    break
+
+    def createSignature(self, v_module):
+        """
+    `   Function used to create a signature, given v_module, for a port spec.
+        """
+        if isinstance(v_module, tuple):
+            v_module_class = []
+            for module_ in v_module:
+                v_module_class.append(self.createSignature(module_))
+            return v_module_class
+        else:
+            return v_module
+
+    def compare(self, port_spec, v_module, port):
+        """
+        Function used to compare two port specs.
+        """
+        port_spec1 = port_spec
+
+        from vistrails.core.modules.module_registry import get_module_registry
+        from vistrails.core.vistrail.port_spec import PortSpec
+        reg = get_module_registry()
+
+        v_module = self.createSignature(v_module)
+        port_spec2 = PortSpec(**{'signature': v_module})
+        matched = reg.are_specs_matched(port_spec2, port_spec1)
+
+        return matched
 
     def compute(self):
+        """This method should be overridden in order to perform the module's
+        computation.
+
+        """
         pass
 
-    def setResult(self, port, value):
-        self.outputPorts[port] = value
-        
+    def get_input(self, port_name, allow_default=True):
+        """Returns the value coming in on the input port named **port_name**.
+
+        :param port_name: the name of the input port being queried
+        :type port_name: str
+        :param allow_default: whether to return the default value if it exists
+        :type allow_default: bool
+        :returns: the value being passed in on the input port
+        :raises: ``ModuleError`` if there is no value on the port (and no default value if allow_default is True)
+
+        """
+        if port_name not in self.inputPorts:
+            if allow_default and self.registry:
+                defaultValue = self.get_default_value(port_name)
+                if defaultValue is not None:
+                    return defaultValue
+            raise ModuleError(self, "Missing value from port %s" % port_name)
+
+        # Cannot resolve circular reference here, need to be fixed later
+        from vistrails.core.modules.sub_module import InputPort
+        for conn in self.inputPorts[port_name]:
+            if isinstance(conn.obj, InputPort):
+                return conn()
+
+        # Check for generator
+        from vistrails.core.modules.basic_modules import Generator
+        raw = self.inputPorts[port_name][0].get_raw()
+        if isinstance(raw, Generator):
+            return raw
+
+        if self.input_specs:
+            # join connections for depth > 0 and List
+            list_desc = self.registry.get_descriptor_by_name(
+                    'org.vistrails.vistrails.basic', 'List')
+
+            if (self.input_specs[port_name].depth + self.list_depth > 0) or \
+                self.input_specs[port_name].descriptors() == [list_desc]:
+                return [j for i in self.get_input_list(port_name) for j in i]
+
+        # else return first connector item
+        value = self.inputPorts[port_name][0]()
+        return value
+
+    def get_input_list(self, port_name):
+        """Returns the value(s) coming in on the input port named
+        **port_name**.  When a port can accept more than one input,
+        this method obtains all the values being passed in.
+
+        :param port_name: the name of the input port being queried
+        :type port_name: str
+        :returns: a list of all the values being passed in on the input port
+        :raises: ``ModuleError`` if there is no value on the port
+        """
+
+        if port_name not in self.inputPorts:
+            raise ModuleError(self, "Missing value from port %s" % port_name)
+        # Cannot resolve circular reference here, need to be fixed later
+        from vistrails.core.modules.sub_module import InputPort
+        fromInputPortModule = [connector()
+                               for connector in self.inputPorts[port_name]
+                               if isinstance(connector.obj, InputPort)]
+        if len(fromInputPortModule)>0:
+            return fromInputPortModule
+        ports = []
+        for connector in self.inputPorts[port_name]:
+            from vistrails.core.modules.basic_modules import List, Variant
+            value = connector()
+            src_depth = connector.depth()
+            if not self.input_specs:
+                # cannot do depth wrapping
+                ports.append(value)
+                continue
+            # Give List an additional depth
+            dest_descs = self.input_specs[port_name].descriptors()
+            dest_depth = self.input_specs[port_name].depth + self.list_depth
+            if len(dest_descs) == 1 and dest_descs[0].module == List:
+                dest_depth += 1
+            if connector.spec:
+                src_descs = connector.spec.descriptors()
+                if len(src_descs) == 1 and src_descs[0].module == List and \
+                   len(dest_descs) == 1 and dest_descs[0].module == Variant:
+                    # special case - Treat Variant as list
+                    src_depth -= 1
+                if len(src_descs) == 1 and src_descs[0].module == Variant and \
+                   len(dest_descs) == 1 and dest_descs[0].module == List:
+                    # special case - Treat Variant as list
+                    dest_depth -= 1
+            # wrap depths that are too shallow
+            while (src_depth - dest_depth) < 0:
+                value = [value]
+                src_depth += 1
+            # type check list of lists
+            root = value
+            for i in xrange(1, src_depth):
+                try:
+                    # flatten
+                    root = [item for sublist in root for item in sublist]
+                except TypeError:
+                    raise ModuleError(self, "List on port %s has wrong"
+                                            " depth %s, expected %s." %
+                                            (port_name, i-1, src_depth))
+
+            if src_depth and root is not None:
+                self.typeChecking(self, [port_name],
+                                  [[r] for r in root] if src_depth else [[root]])
+            ports.append(value)
+        return ports
+
+    def set_output(self, port_name, value):
+        """This method is used to set a value on an output port.
+
+        :param port_name: the name of the output port to be set
+        :type port_name: str
+        :param value: the value to be assigned to the port
+
+        """
+        self.outputPorts[port_name] = value
+
+    def check_input(self, port_name):
+        """check_input(port_name) -> None.
+        Raises an exception if the input port named *port_name* is not set.
+
+        :param port_name: the name of the input port being checked
+        :type port_name: str
+        :raises: ``ModuleError`` if there is no value on the port
+        """
+        if not self.has_input(port_name):
+            raise ModuleError(self, "'%s' is a mandatory port" % port_name)
+
+    def has_input(self, port_name):
+        """Returns a boolean indicating whether there is a value coming in on
+        the input port named **port_name**.
+
+        :param port_name: the name of the input port being queried
+        :type port_name: str
+        :rtype: bool
+
+        """
+        return port_name in self.inputPorts
+
+    def force_get_input(self, port_name, default_value=None):
+        """Like :py:meth:`.get_input` except that if no value exists, it
+        returns a user-specified default_value or None.
+
+        :param port_name: the name of the input port being queried
+        :type port_name: str
+        :param default_value: the default value to be used if there is \
+        no value on the input port
+        :returns: the value being passed in on the input port or the default
+
+        """
+
+        if self.has_input(port_name):
+            return self.get_input(port_name)
+        else:
+            return default_value
+
+    def force_get_input_list(self, port_name):
+        """Like :py:meth:`.get_input_list` except that if no values
+        exist, it returns an empty list
+
+        :param port_name: the name of the input port being queried
+        :type port_name: str
+        :returns: a list of all the values being passed in on the input port
+
+        """
+        if port_name not in self.inputPorts:
+            return []
+        return self.get_input_list(port_name)
+
     def annotate_output_values(self):
         output_values = []
         for port in self.outputPorts:
             output_values.append((port, self.outputPorts[port]))
         self.logging.annotate(self, {'output': output_values})
 
-    def get_output(self, port):
-        # if self.outputPorts.has_key(port) or not self.outputPorts[port]: 
-        if port not in self.outputPorts:
-            raise ModuleError(self, "output port '%s' not found" % port)
-        return self.outputPorts[port]
+    def get_output(self, port_name):
+        if port_name not in self.outputPorts:
+            raise ModuleError(self, "output port '%s' not found" % port_name)
+        return self.outputPorts[port_name]
 
-    def getInputConnector(self, inputPort):
-        if not self.inputPorts.has_key(inputPort):
-            raise ModuleError(self, "Missing value from port %s" % inputPort)
-        return self.inputPorts[inputPort][0]
+    def get_input_connector(self, port_name):
+        if port_name not in self.inputPorts:
+            raise ModuleError(self, "Missing value from port %s" % port_name)
+        return self.inputPorts[port_name][0]
 
-    def getDefaultValue(self, inputPort):
+    def get_default_value(self, port_name):
         reg = self.registry
 
         d = None
         try:
             d = reg.get_descriptor(self.__class__)
-        except:
+        except Exception:
             pass
         if not d:
             return None
 
         ps = None
         try:
-            ps = reg.get_port_spec_from_descriptor(d, inputPort, 'input')
-        except:
+            ps = reg.get_port_spec_from_descriptor(d, port_name, 'input')
+        except Exception:
             pass
         if not ps:
             return None
@@ -498,86 +1373,58 @@ Makes sure input port 'name' is filled."""
 
         return None
 
-    def getInputFromPort(self, inputPort, allowDefault=True):
-        if inputPort not in self.inputPorts:
-            if allowDefault and self.registry:
-                defaultValue = self.getDefaultValue(inputPort)
-                if defaultValue is not None:
-                    return defaultValue
-            raise ModuleError(self, "Missing value from port %s" % inputPort)
-        # Cannot resolve circular reference here, need to be fixed later
-        from vistrails.core.modules.sub_module import InputPort
-        for conn in self.inputPorts[inputPort]:
-            if isinstance(conn.obj, InputPort):
-                return conn()
-        return self.inputPorts[inputPort][0]()
-
-    def hasInputFromPort(self, inputPort):
-        return self.inputPorts.has_key(inputPort)
-
     def __str__(self):
         return "<<%s>>" % str(self.__class__)
 
     def annotate(self, d):
-        self.logging.annotate(self, d)
 
-    def forceGetInputFromPort(self, inputPort, defaultValue=None):
-        if self.hasInputFromPort(inputPort):
-            return self.getInputFromPort(inputPort)
-        else:
-            return defaultValue
+        """Manually add provenance information to the module's execution
+        trace.  For example, a module that generates random numbers
+        might add the seed that was used to initialize the generator.
+
+        :param d: a dictionary where both the keys and values are strings
+        :type d: dict
 
-    def set_input_port(self, inputPort, conn, is_method=False):
-        if self.inputPorts.has_key(inputPort):
-            self.inputPorts[inputPort].append(conn)
+        """
+
+        self.logging.annotate(self, d)
+
+    def set_input_port(self, port_name, conn, is_method=False):
+        if port_name in self.inputPorts:
+            self.inputPorts[port_name].append(conn)
         else:
-            self.inputPorts[inputPort] = [conn]
+            self.inputPorts[port_name] = [conn]
         if is_method:
-            self.is_method[conn] = (self._latest_method_order, inputPort)
+            self.is_method[conn] = (self._latest_method_order, port_name)
             self._latest_method_order += 1
 
-    def getInputListFromPort(self, inputPort):
-        if not self.inputPorts.has_key(inputPort):
-            raise ModuleError(self, "Missing value from port %s" % inputPort)
-        # Cannot resolve circular reference here, need to be fixed later
-        from vistrails.core.modules.sub_module import InputPort
-        fromInputPortModule = [connector()
-                               for connector in self.inputPorts[inputPort]
-                               if isinstance(connector.obj, InputPort)]
-        if len(fromInputPortModule)>0:
-            return fromInputPortModule
-        return [connector() for connector in self.inputPorts[inputPort]]
+    def enable_output_port(self, port_name):
 
-    def forceGetInputListFromPort(self, inputPort):
-        if not self.inputPorts.has_key(inputPort):
-            return []
-        return self.getInputListFromPort(inputPort)
-
-    def enableOutputPort(self, outputPort):
-        """ enableOutputPort(outputPort: str) -> None
+        """ enable_output_port(port_name: str) -> None
         Set an output port to be active to store result of computation
-        
+
         """
         # Don't reset existing values, it screws up the caching.
-        if not self.outputPorts.has_key(outputPort):
-            self.setResult(outputPort, None)
-            
-    def removeInputConnector(self, inputPort, connector):
-        """ removeInputConnector(inputPort: str,
+        if port_name not in self.outputPorts:
+            self.set_output(port_name, None)
+
+    def remove_input_connector(self, port_name, connector):
+        """ remove_input_connector(port_name: str,
                                  connector: ModuleConnector) -> None
         Remove a connector from the connection list of an input port
-        
+
         """
-        if self.inputPorts.has_key(inputPort):
-            conList = self.inputPorts[inputPort]
+        if port_name in self.inputPorts:
+            conList = self.inputPorts[port_name]
             if connector in conList:
                 conList.remove(connector)
             if conList==[]:
-                del self.inputPorts[inputPort]
+                del self.inputPorts[port_name]
 
     def create_instance_of_type(self, ident, name, ns=''):
-        """ Create a vistrails module from the module registry.  This creates an instance of the module
-        for use in creating the object output by a Module.
+        """ Create a vistrails module from the module registry.  This creates
+        an instance of the module for use in creating the object output by a
+        Module.
         """
         from vistrails.core.modules.module_registry import get_module_registry
         try:
@@ -589,6 +1436,123 @@ Makes sure input port 'name' is filled."""
                   " with identifier " + str(ident) + " and namespace " + ns
             raise ModuleError(self, msg)
 
+    def set_streaming(self, UserGenerator):
+        """creates a generator object that computes when the next input is received.
+        """
+        # use the below tag if calling from a PythonSource
+        # pragma: streaming - This tag is magic, do not change.
+        from vistrails.core.modules.basic_modules import Generator
+
+        ports = self.streamed_ports.keys()
+        specs = []
+        num_inputs = self.streamed_ports[ports[0]].size
+        module = copy.copy(self)
+        module.list_depth = self.list_depth - 1
+        module.had_error = False
+        module.upToDate = False
+        module.computed = False
+
+        if num_inputs:
+            milestones = [i*num_inputs//10 for i in xrange(1, 11)]
+
+        def _Generator(self):
+            self.logging.begin_compute(module)
+            i = 0
+            # <initialize here>
+            #intsum = 0
+            userGenerator = UserGenerator(module)
+            while 1:
+                elements = [self.streamed_ports[port].next() for port in ports]
+                if None in elements:
+                    self.logging.update_progress(self, 1.0)
+                    self.logging.end_update(module)
+                    for name_output in module.outputPorts:
+                        module.set_output(name_output, None)
+                    yield None
+                ## Type checking
+                self.typeChecking(module, ports, [elements])
+                self.setInputValues(module, ports, elements, i)
+
+                userGenerator.next()
+                # <compute here>
+                #intsum += dict(zip(ports, elements))['integerStream']
+                #print "Sum so far:", intsum
+
+                # <set output here if any>
+                #module.set_output(name_output, intsum)
+                if num_inputs:
+                    if i in milestones:
+                        self.logging.update_progress(self, float(i)/num_inputs)
+                else:
+                    self.logging.update_progress(self, 0.5)
+                i += 1
+                yield True
+
+        generator = _Generator(self)
+        # sets streaming outputs for downstream modules
+        for name_output in self.outputPorts:
+            iterator = Generator(size=num_inputs,
+                                 module=module,
+                                 generator=generator,
+                                 port=name_output)
+
+            self.set_output(name_output, iterator)
+
+    def set_streaming_output(self, port, generator, size=0):
+        """This method is used to set a streaming output port.
+
+        :param port: the name of the output port to be set
+        :type port: str
+        :param generator: An iterator object supporting .next()
+        :param size: The number of values if known (default=0)
+        :type size: int
+        """
+        from vistrails.core.modules.basic_modules import Generator
+        module = copy.copy(self)
+
+        if size:
+            milestones = [i*size//10 for i in xrange(1, 11)]
+        def _Generator():
+            i = 0
+            while 1:
+                try:
+                    value = generator.next()
+                except StopIteration:
+                    module.set_output(port, None)
+                    self.logging.update_progress(self, 1.0)
+                    yield None
+                except Exception, e:
+                    me = ModuleError(self, "Error generating value: %s"% str(e),
+                                      errorTrace=str(e))
+                    raise me
+                if value is None:
+                    module.set_output(port, None)
+                    self.logging.update_progress(self, 1.0)
+                    yield None
+                module.set_output(port, value)
+                if size:
+                    if i in milestones:
+                        self.logging.update_progress(self, float(i)/size)
+                else:
+                    self.logging.update_progress(self, 0.5)
+                i += 1
+                yield True
+        _generator = _Generator()
+        self.set_output(port, Generator(size=size,
+                                        module=module,
+                                        generator=_generator,
+                                        port=port))
+
+    def job_monitor(self):
+        """ job_monitor() -> JobMonitor
+        Returns the JobMonitor for the associated controller if it exists
+        """
+        controller = self.moduleInfo['controller']
+        if controller is None:
+            raise ModuleError(self,
+                              "Cannot run job, no controller is specified!")
+        return controller.jobMonitor
+
     @classmethod
     def provide_input_port_documentation(cls, port_name):
         return None
@@ -597,6 +1561,63 @@ Makes sure input port 'name' is filled."""
     def provide_output_port_documentation(cls, port_name):
         return None
 
+    ####################################################################
+    # Deprecated methods
+
+    @deprecated("get_input")
+    def getInputFromPort(self, *args, **kwargs):
+        if 'allowDefault' in kwargs:
+            kwargs['allow_default'] = kwargs.pop('allowDefault')
+        return self.get_input(*args, **kwargs)
+
+    @deprecated("get_input_list")
+    def getInputListFromPort(self, *args, **kwargs):
+        return self.get_input_list(*args, **kwargs)
+
+    @deprecated("force_get_input")
+    def forceGetInputFromPort(self, *args, **kwargs):
+        return self.force_get_input(*args, **kwargs)
+
+    @deprecated("force_get_input_list")
+    def forceGetInputListFromPort(self, *args, **kwargs):
+        return self.force_get_input_list(*args, **kwargs)
+
+    @deprecated("has_input")
+    def hasInputFromPort(self, *args, **kwargs):
+        return self.has_input(*args, **kwargs)
+
+    @deprecated("check_input")
+    def checkInputPort(self, *args, **kwargs):
+        return self.check_input(*args, **kwargs)
+
+    @deprecated("set_output")
+    def setResult(self, *args, **kwargs):
+        return self.set_output(*args, **kwargs)
+
+    @deprecated("get_input_connector")
+    def getInputConnector(self, *args, **kwargs):
+        return self.get_input_connector(*args, **kwargs)
+
+    @deprecated("get_default_value")
+    def getDefaultValue(self, *args, **kwargs):
+        return self.get_default_value(*args, **kwargs)
+
+    @deprecated("enable_output_port")
+    def enableOutputPort(self, *args, **kwargs):
+        return self.enable_output_port(*args, **kwargs)
+
+    @deprecated("remove_input_connector")
+    def removeInputConnector(self, *args, **kwargs):
+        return self.remove_input_connector(*args, **kwargs)
+
+    @deprecated("update_upstream")
+    def updateUpstream(self, *args, **kwargs):
+        return self.update_upstream(*args, **kwargs)
+
+    @deprecated("update_upstream_port")
+    def updateUpstreamPort(self, *args, **kwargs):
+        return self.updateUpstreamPort(*args, **kwargs)
+
 ################################################################################
 
 class NotCacheable(object):
@@ -606,6 +1627,14 @@ class NotCacheable(object):
 
 ################################################################################
 
+class Streaming(object):
+    """ A mixin indicating support for streamable inputs
+
+    """
+    pass
+
+################################################################################
+
 class Converter(Module):
     """Base class for automatic conversion modules.
 
@@ -618,34 +1647,30 @@ class Converter(Module):
     Alternatively, you can override the classmethod can_convert() to provide
     a custom condition.
     """
+    _settings = ModuleSettings(abstract=True)
+    _input_ports = [IPort('in_value', 'Variant')]
+    _output_ports = [OPort('out_value', 'Variant')]
     @classmethod
     def can_convert(cls, sub_descs, super_descs):
         from vistrails.core.modules.module_registry import get_module_registry
         from vistrails.core.system import get_vistrails_basic_pkg_id
         reg = get_module_registry()
         basic_pkg = get_vistrails_basic_pkg_id()
-        variant_desc = reg.get_descriptor_by_name(basic_pkg, 'Variant')
         desc = reg.get_descriptor(cls)
 
-        def check_types(sub_descs, super_descs):
-            for (sub_desc, super_desc) in izip(sub_descs, super_descs):
-                if (sub_desc == variant_desc or super_desc == variant_desc):
-                    continue
-                if not reg.is_descriptor_subclass(sub_desc, super_desc):
-                    return False
-            return True
-
         in_port = reg.get_port_spec_from_descriptor(
                 desc,
                 'in_value', 'input')
         if (len(sub_descs) != len(in_port.descriptors()) or
-                not check_types(sub_descs, in_port.descriptors())):
+                not reg.is_descriptor_list_subclass(sub_descs,
+                                                    in_port.descriptors())):
             return False
         out_port = reg.get_port_spec_from_descriptor(
                 desc,
                 'out_value', 'output')
         if (len(out_port.descriptors()) != len(super_descs)
-                or not check_types(out_port.descriptors(), super_descs)):
+                or not reg.is_descriptor_list_subclass(out_port.descriptors(),
+                                                       super_descs)):
             return False
 
         return True
@@ -661,6 +1686,11 @@ class ModuleConnector(object):
         # typecheck
         self.obj = obj
         self.port = port
+        if spec is None:
+            # guess type
+            from vistrails.core.modules.basic_modules import get_module
+            from vistrails.core.vistrail.port_spec import PortSpec
+            spec = PortSpec(**{'signature': get_module(self.get_raw())})
         self.spec = spec
         self.typecheck = typecheck
 
@@ -669,8 +1699,48 @@ class ModuleConnector(object):
         self.obj = None
         self.port = None
 
+    def depth(self, fix_list=True):
+        """depth(result) -> int. Returns the list depth of the port value."""
+        from vistrails.core.modules.basic_modules import List
+        depth = self.obj.list_depth + self.spec.depth
+        descs = self.spec.descriptors()
+        if fix_list and len(descs) == 1 and descs[0].module == List:
+            # lists are Variants of depth 1
+            depth += 1
+        return depth
+
+    def get_raw(self):
+        """get_raw() -> Module. Returns the value or a Generator."""
+        return self.obj.get_output(self.port)
+
+
     def __call__(self):
         result = self.obj.get_output(self.port)
+        if isinstance(result, Module):
+            warnings.warn(
+                    "A Module instance was used as data: "
+                    "module=%s, port=%s, object=%r" % (type(self.obj).__name__,
+                                                       self.port, result),
+                    UserWarning)
+        from vistrails.core.modules.basic_modules import Generator
+        value = result
+        if isinstance(result, Generator):
+            return result
+        depth = self.depth(fix_list=False)
+        if depth > 0:
+            value = result
+            # flatten list
+            for i in xrange(1, depth):
+                try:
+                    value = [item for sublist in value for item in sublist]
+                except TypeError:
+                    raise ModuleError(self.obj, "List on port %s has wrong"
+                                      " depth %s, expected %s." %
+                                      (self.port, i, depth))
+            if depth:
+                # Only type-check first value
+                value = value[0] if value is not None and len(value) else None
+
         if self.spec is not None and self.typecheck is not None:
             descs = self.spec.descriptors()
             typecheck = self.typecheck
@@ -678,7 +1748,8 @@ class ModuleConnector(object):
                 if not typecheck[0]:
                     return result
                 mod = descs[0].module
-                if hasattr(mod, 'validate') and not mod.validate(result):
+                if value is not None and hasattr(mod, 'validate') \
+                   and not mod.validate(value):
                     raise ModuleError(self.obj, "Type passed on Variant port "
                                       "%s does not match destination type "
                                       "%s" % (self.port, descs[0].name))
@@ -688,10 +1759,10 @@ class ModuleConnector(object):
                         typecheck = [True] * len(descs)
                     else:
                         return result
-                if not isinstance(result, tuple):
+                if not isinstance(value, tuple):
                     raise ModuleError(self.obj, "Type passed on Variant port "
                                       "%s is not a tuple" % self.port)
-                elif len(result) != len(descs):
+                elif len(value) != len(descs):
                     raise ModuleError(self.obj, "Object passed on Variant "
                                       "port %s does not have the correct "
                                       "length (%d, expected %d)" % (
@@ -701,7 +1772,7 @@ class ModuleConnector(object):
                         continue
                     mod = desc.module
                     if hasattr(mod, 'validate'):
-                        if not mod.validate(result[i]):
+                        if not mod.validate(value[i]):
                             raise ModuleError(
                                     self.obj,
                                     "Element %d of tuple passed on Variant "
@@ -709,34 +1780,36 @@ class ModuleConnector(object):
                                     "type %s" % (i, self.port, desc.name))
         return result
 
-def new_module(baseModule, name, dict={}, docstring=None):
-    """new_module(baseModule or [baseModule list],
+
+def new_module(base_module, name, class_dict={}, docstring=None):
+    """new_module(base_module or [base_module list],
                   name,
-                  dict={},
+                  class_dict={},
                   docstring=None
 
     Creates a new VisTrails module dynamically. Exactly one of the
-    elements of the baseModule list (or baseModule itself, in the case
+    elements of the base_module list (or base_module itself, in the case
     it's a single class) should be a subclass of Module.
     """
-    if isinstance(baseModule, type):
-        assert issubclass(baseModule, Module)
-        superclasses = (baseModule, )
-    elif isinstance(baseModule, list):
-        assert len([x for x in baseModule
-                    if issubclass(x, Module)]) == 1
-        superclasses = tuple(baseModule)
-    d = copy.copy(dict)
+    if isinstance(base_module, type):
+        assert issubclass(base_module, Module)
+        superclasses = (base_module, )
+    elif isinstance(base_module, list):
+        assert sum(1 for x in base_module if issubclass(x, Module)) == 1
+        superclasses = tuple(base_module)
+    else:
+        raise TypeError
+    d = copy.copy(class_dict)
     if docstring:
         d['__doc__'] = docstring
     return type(name, superclasses, d)
-    
+
 # This is the gist of how type() works. The example is run from a python
 # toplevel
 
 # >>> class X(object):
 # ...     def f(self): return 3
-# ... 
+# ...
 # >>> a = X()
 # >>> a.f()
 # 3
@@ -750,3 +1823,39 @@ def new_module(baseModule, name, dict={}, docstring=None):
 # >>> c = Z()
 # >>> c.f()
 # 4
+
+import unittest
+
+class TestImplicitLooping(unittest.TestCase):
+    def run_vt(self, vt_basename):
+        from vistrails.core.system import vistrails_root_directory
+        from vistrails.core.db.locator import FileLocator
+        from vistrails.core.db.io import load_vistrail
+        from vistrails.core.console_mode import run
+        from vistrails.tests.utils import capture_stdout
+        import os
+        filename = os.path.join(vistrails_root_directory(), "tests",
+                                "resources", vt_basename)
+        try:
+            errs = []
+            locator = FileLocator(os.path.abspath(filename))
+            (v, _, _, _) = load_vistrail(locator)
+            w_list = []
+            for version, _ in v.get_tagMap().iteritems():
+                w_list.append((locator,version))
+            if len(w_list) > 0:
+                with capture_stdout() as c:
+                    errs = run(w_list, update_vistrail=False)
+                for err in errs:
+                    self.fail(str(err))
+        except Exception, e:
+            self.fail(debug.format_exception(e))
+
+    def test_implicit_while(self):
+        self.run_vt("test-implicit-while.vt")
+
+    def test_streaming(self):
+        self.run_vt("test-streaming.vt")
+
+    def test_list_custom(self):
+        self.run_vt("test-list-custom.vt")
diff --git a/vistrails/core/packagemanager.py b/vistrails/core/packagemanager.py
index 7a5d87b..663ad66 100644
--- a/vistrails/core/packagemanager.py
+++ b/vistrails/core/packagemanager.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 """The package manager takes care of everything that has got to do
 with handling packages, from setting paths to adding new packages
 to checking dependencies to initializing them."""
+from __future__ import division
+
 import copy
 import inspect
 import itertools
@@ -43,16 +46,18 @@ import os
 import sys
 import warnings
 
-from vistrails.core import debug, get_vistrails_application
-from vistrails.core.configuration import ConfigurationObject
+from vistrails.core import debug, get_vistrails_application, system
+from vistrails.core.configuration import ConfigurationObject, \
+    get_vistrails_configuration
 import vistrails.core.data_structures.graph
-import vistrails.core.db.io
-from vistrails.core.modules.module_registry import ModuleRegistry, \
-                                         MissingPackage, MissingPackageVersion
+from vistrails.core.modules.module_registry import MissingPackage, \
+    MissingPackageVersion
 from vistrails.core.modules.package import Package
-from vistrails.core.utils import VistrailsInternalError, InstanceObject, \
+from vistrails.core.requirements import MissingRequirement
+from vistrails.core.utils import VistrailsInternalError, \
     versions_increasing, VistrailsDeprecation
 import vistrails.packages
+
 ##############################################################################
 
 
@@ -97,7 +102,7 @@ class PackageManager(object):
         if self._packages is not None:
             return self._packages
         # Imports standard packages directory
-        conf = self._configuration
+        conf = self._startup.temp_configuration
         old_sys_path = copy.copy(sys.path)
         if conf.check('packageDirectory'):
             sys.path.insert(0, conf.packageDirectory)
@@ -119,23 +124,25 @@ class PackageManager(object):
         if self._userpackages is not None:
             return self._userpackages
         # Imports user packages directory
-        conf = self._configuration
         old_sys_path = copy.copy(sys.path)
-        if conf.check('userPackageDirectory'):
-            sys.path.insert(0, os.path.join(conf.userPackageDirectory,
-                                            os.path.pardir))
-        try:
-            import userpackages
-        except ImportError:
-            debug.critical('ImportError: "userpackages" sys.path: %s' % sys.path)
-            raise
-        finally:
-            sys.path = old_sys_path
-        os.environ['VISTRAILS_USERPACKAGES_DIR'] = conf.userPackageDirectory
-        self._userpackages = userpackages
-        return userpackages
+        userPackageDir = system.get_vistrails_directory('userPackageDir')
+        if userPackageDir is not None:
+            sys.path.insert(0, os.path.join(userPackageDir, os.path.pardir))
+            try:
+                import userpackages
+            except ImportError:
+                debug.critical('ImportError: "userpackages" sys.path: %s' % 
+                               sys.path)
+                raise
+            finally:
+                sys.path = old_sys_path
+            os.environ['VISTRAILS_USERPACKAGES_DIR'] = userPackageDir
+            self._userpackages = userpackages
+            return userpackages
+        # possible that we don't have userPackageDir set!
+        return None
 
-    def __init__(self, configuration):
+    def __init__(self, registry, startup):
         """__init__(configuration: ConfigurationObject) -> PackageManager
         configuration is the persistent configuration object of the application.
         
@@ -145,7 +152,9 @@ class PackageManager(object):
             m = "Package manager can only be constructed once."
             raise VistrailsInternalError(m)
         _package_manager = self
-        self._configuration = configuration
+
+        self._registry = registry
+        self._startup = startup
 
         # Contains packages that have not yet been enabled, but exist on the
         # filesystem
@@ -155,45 +164,42 @@ class PackageManager(object):
         self._package_versions = {} # identifier: str -> version -> Package
         self._old_identifier_map = {} # old_id: str -> new_id: str
         self._dependency_graph = vistrails.core.data_structures.graph.Graph()
+        self._default_prefix_dict = \
+                                {'basic_modules': 'vistrails.core.modules.',
+                                 'abstraction': 'vistrails.core.modules.'}
 
-        self._registry = None
         self._userpackages = None
         self._packages = None
         self._abstraction_pkg = None
         self._currently_importing_package = None
 
-    def init_registry(self, registry_filename=None):
-        if registry_filename is not None:
-            self._registry = vistrails.core.db.io.open_registry(registry_filename)
-            self._registry.set_global()
-        else:
-            self._registry = ModuleRegistry()
-            self._registry.set_global()
-
-            def setup_basic_package():
-                # setup basic package
-                basic_package = self.add_package('basic_modules')
-                # FIXME need to serialize old_identifiers
-                basic_package.old_identifiers = ['edu.utah.sci.vistrails.basic']
-                self._registry._default_package = basic_package
-                prefix_dictionary = {'basic_modules': 'vistrails.core.modules.'}
-                self.initialize_packages(prefix_dictionary)
-            setup_basic_package()
-
-            self._abstraction_pkg = self.add_package('abstraction', False)
-            # FIXME need to get this info from the package, but cannot
-            # do this since controller isn't imported yet
-            self._abstraction_pkg.identifier = 'local.abstractions'
-            self._abstraction_pkg.name = 'My SubWorkflows'
-            self._abstraction_pkg.version = '1.6'
-            self._registry.add_package(self._abstraction_pkg)
-
         # Setup a global __import__ hook that calls Package#import_override()
         # for all imports executed from that package
         import __builtin__
         self._orig_import = __builtin__.__import__
         __builtin__.__import__ = self._import_override
 
+        # Compute the list of available packages, _available_packages
+        self.build_available_package_names_list()
+
+        if get_vistrails_configuration().loadPackages:
+            for pkg in self._startup.enabled_packages.itervalues():
+                self.add_package(pkg.name, prefix=pkg.prefix)
+        else:
+            try:
+                basic_pkg = self._startup.enabled_packages['basic_modules']
+            except KeyError:
+                pass
+            else:
+                self.add_package(basic_pkg.name, prefix=basic_pkg.prefix)
+
+            try:
+                abs_pkg = self._startup.enabled_packages['abstraction']
+            except KeyError:
+                pass
+            else:
+                self.add_package(abs_pkg.name, prefix=abs_pkg.prefix)
+
     def _import_override(self,
                          name, globals={}, locals={}, fromlist=[], level=-1):
         # Get the caller module, using globals (like the original __import
@@ -256,8 +262,10 @@ class PackageManager(object):
         return self._orig_import(name, globals, locals, fromlist, level)
 
     def finalize_packages(self):
-        """Finalizes all installed packages. Call this only prior to
-exiting VisTrails."""
+        """Finalizes all installed packages. Call this only prior to exiting
+        VisTrails.
+
+        """
         for package in self._package_list.itervalues():
             package.finalize()
         self._package_list = {}
@@ -266,33 +274,31 @@ exiting VisTrails."""
         global _package_manager
         _package_manager = None
 
-    def get_available_package(self, codepath):
+    def get_available_package(self, codepath, prefix=None):
         try:
             pkg = self._available_packages[codepath]
         except KeyError:
-            pkg = self._registry.create_package(codepath)
+            pkg = self._registry.create_package(codepath, prefix=prefix)
             self._available_packages[codepath] = pkg
+        pkg.persistent_configuration = \
+                                self._startup.get_pkg_configuration(codepath)
         return pkg
 
-    def add_package(self, codepath, add_to_package_list=True):
-        """Adds a new package to the manager. This does not initialize it.
-To do so, call initialize_packages()"""
+    def add_package(self, codepath, add_to_package_list=True, prefix=None):
+        """Adds a new package to the manager. This does not initialize it.  To
+        do so, call initialize_packages()
+
+        """
         package = self.get_available_package(codepath)
         if add_to_package_list:
-            self.add_to_package_list(codepath, package)
+            self.add_to_package_list(codepath, package, prefix)
         return package
 
-    def add_to_package_list(self, codepath, package):
+    def add_to_package_list(self, codepath, package, prefix=None):
         self._available_packages[codepath] = package
         self._package_list[codepath] = package
-
-    def initialize_abstraction_pkg(self, prefix_dictionary):
-        if self._abstraction_pkg is None:
-            raise RuntimeError("Subworkflows packages is None")
-        self.add_to_package_list(self._abstraction_pkg.codepath,
-                                 self._abstraction_pkg)
-        self.late_enable_package(self._abstraction_pkg.codepath, 
-                                 prefix_dictionary, False)
+        if prefix is not None:
+            self._default_prefix_dict[codepath] = prefix
 
     def remove_old_identifiers(self, identifier):
         # remove refs in old_identifier_map
@@ -323,8 +329,10 @@ To do so, call initialize_packages()"""
         app.send_notification("package_removed", codepath)
 
     def has_package(self, identifier, version=None):
-        """has_package(identifer: string) -> Boolean.
-Returns true if given package identifier is present."""
+        """has_package(identifer: string) -> Boolean.  
+        Returns true if given package identifier is present.
+
+        """
 
         # check if it's an old identifier
         identifier = self._old_identifier_map.get(identifier, identifier)
@@ -479,10 +487,11 @@ Returns true if given package identifier is present."""
                 msg = 'duplicate package identifier: %s' % codepath
                 raise VistrailsInternalError(msg)
             self.add_package(codepath)
+        app = get_vistrails_application()
         pkg = self.get_package_by_codepath(codepath)
         try:
             pkg.load(prefix_dictionary.get(pkg.codepath, None))
-            pkg.create_startup_package_node()
+            # pkg.create_startup_package_node()
         except Exception, e:
             # invert self.add_package
             del self._package_list[codepath]
@@ -499,9 +508,9 @@ Returns true if given package identifier is present."""
             #pkg.check_requirements()
             self._registry.initialize_package(pkg)
             self._registry.signals.emit_new_package(pkg.identifier, True)
-            app = get_vistrails_application()
             app.send_notification("package_added", codepath)
             self.add_menu_items(pkg)
+            self._startup.set_package_to_enabled(codepath)
         except Exception, e:
             del self._package_versions[pkg.identifier][pkg.version]
             if len(self._package_versions[pkg.identifier]) == 0:
@@ -517,6 +526,7 @@ Returns true if given package identifier is present."""
             except MissingPackage:
                 pass
             raise e
+        self._startup.save_persisted_startup()
 
     def late_disable_package(self, codepath):
         """late_disable_package disables a package 'late', that is,
@@ -525,7 +535,9 @@ Returns true if given package identifier is present."""
         """
         pkg = self.get_package_by_codepath(codepath)
         self.remove_package(codepath)
-        pkg.remove_own_dom_element()
+        app = get_vistrails_application()
+        self._startup.set_package_to_disabled(codepath)
+        self._startup.save_persisted_startup()
 
     def reload_package_disable(self, codepath):
         # for all reverse dependencies, disable them
@@ -554,7 +566,8 @@ Returns true if given package identifier is present."""
         for dep_pkg in reversed(reverse_deps):
             self.late_enable_package(dep_pkg.codepath, prefix_dictionary)
 
-    def initialize_packages(self,prefix_dictionary={}):
+    def initialize_packages(self, prefix_dictionary={},
+                            report_missing_dependencies=True):
         """initialize_packages(prefix_dictionary={}): None
 
         Initializes all installed packages. If prefix_dictionary is
@@ -562,34 +575,41 @@ Returns true if given package identifier is present."""
         the prefix such that prefix + package_name is a valid python
         import."""
 
-        packages = self.import_packages_module()
-        userpackages = self.import_user_packages_module()
-
         failed = []
         # import the modules
+        app = get_vistrails_application()
         for package in self._package_list.itervalues():
             # print '+ initializing', package.codepath, id(package)
             if package.initialized():
                 # print '- already initialized'
                 continue
             try:
-                package.load(prefix_dictionary.get(package.codepath, None))
+                prefix = prefix_dictionary.get(package.codepath)
+                if prefix is None:
+                    prefix = self._default_prefix_dict.get(package.codepath)
+                package.load(prefix)
             except Package.LoadFailed, e:
                 debug.critical("Package %s failed to load and will be "
-                               "disabled" % package.name, str(e))
+                               "disabled" % package.name, e)
                 # We disable the package manually to skip over things
                 # we know will not be necessary - the only thing needed is
                 # the reference in the package list
-                package.remove_own_dom_element()
+                self._startup.set_package_to_disabled(package.codepath)
                 failed.append(package)
+            except MissingRequirement, e:
+                debug.critical("Package <codepath %s> is missing a "
+                               "requirement: %s" % (
+                                   package.codepath, e.requirement),
+                               e)
             except Package.InitializationFailed, e:
                 debug.critical("Initialization of package <codepath %s> "
-                               "failed and will be disabled" % \
-                                   package.codepath, str(e))
+                               "failed and will be disabled" %
+                               package.codepath,
+                               e)
                 # We disable the package manually to skip over things
                 # we know will not be necessary - the only thing needed is
                 # the reference in the package list
-                package.remove_own_dom_element()
+                self._startup.set_package_to_disabled(package.codepath)
                 failed.append(package)
             else:
                 if package.identifier not in self._package_versions:
@@ -619,15 +639,18 @@ Returns true if given package identifier is present."""
             try:
                 self.add_dependencies(package)
             except Package.MissingDependency, e:
-                debug.critical("Dependencies of package %s are missing "
-                               "so it will be disabled" % package.name, str(e))
+                if report_missing_dependencies:
+                    debug.critical("Dependencies of package %s are missing "
+                                   "so it will be disabled" % package.name,
+                                   e)
             except Exception, e:
-                debug.critical("Got an exception while getting dependencies "
-                               "of %s so it will be disabled" % package.name,
-                               str(e))
+                if report_missing_dependencies:
+                    debug.critical("Got an exception while getting dependencies "
+                                   "of %s so it will be disabled" % package.name,
+                                   e)
             else:
                 continue
-            package.remove_own_dom_element()
+            self._startup.set_package_to_disabled(package.codepath)
             self._dependency_graph.delete_vertex(package.identifier)
             del self._package_versions[package.identifier][package.version]
             if len(self._package_versions[package.identifier]) == 0:
@@ -653,21 +676,28 @@ Returns true if given package identifier is present."""
                 #pkg.check_requirements()
                 try:
                     self._registry.initialize_package(pkg)
+                except MissingRequirement, e:
+                    if report_missing_dependencies:
+                        debug.critical("Package <codepath %s> is missing a "
+                                       "requirement: %s" % (
+                                           pkg.codepath, e.requirement),
+                                       e)
+                    self.late_disable_package(pkg.codepath)
                 except Package.InitializationFailed, e:
                     debug.critical("Initialization of package <codepath %s> "
-                                   "failed and will be disabled" % \
-                                       pkg.codepath, str(e))
+                                   "failed and will be disabled" %
+                                   pkg.codepath,
+                                   e)
                     # We disable the package manually to skip over things
                     # we know will not be necessary - the only thing needed is
                     # the reference in the package list
                     self.late_disable_package(pkg.codepath)
-#                     pkg.remove_own_dom_element()
-#                     failed.append(package)
                 else:
                     self.add_menu_items(pkg)
                     app = get_vistrails_application()
                     app.send_notification("package_added", pkg.codepath)
 
+        self._startup.save_persisted_startup()
 
     def add_menu_items(self, pkg):
         """add_menu_items(pkg: Package) -> None
@@ -733,9 +763,8 @@ Returns true if given package identifier is present."""
                 if (hasattr(pkg._module, "can_handle_identifier") and
                         pkg._module.can_handle_identifier(identifier)):
                     return pkg
-            except pkg.LoadFailed:
-                pass
-            except pkg.InitializationFailed:
+            except (pkg.LoadFailed, pkg.InitializationFailed,
+                    MissingRequirement):
                 pass
             except Exception, e:
                 pass
@@ -748,31 +777,56 @@ Returns true if given package identifier is present."""
         The distinction between package names, identifiers and
         code-paths is described in doc/package_system.txt
         """
+        return self._available_packages.keys()
 
-        pkg_name_set = set()
-
+    def build_available_package_names_list(self):
         def is_vistrails_package(path):
-            return ((path.endswith('.py') and
-                     not path.endswith('__init__.py') and
-                     os.path.isfile(path)) or
-                    os.path.isdir(path) and \
-                        os.path.isfile(os.path.join(path, '__init__.py')))
-
-        def search(dirname):
+            if os.path.isfile(path):
+                return (path.endswith('.py') and
+                        not path.endswith('__init__.py'))
+            elif os.path.isdir(path):
+                return os.path.isfile(os.path.join(path, '__init__.py'))
+            return False
+
+        def search(dirname, prefix):
             for name in os.listdir(dirname):
                 if is_vistrails_package(os.path.join(dirname, name)):
                     if name.endswith('.py'):
                         name = name[:-3]
-                    pkg_name_set.add(name)
+                    self.get_available_package(name, prefix=prefix)
 
         # Finds standard packages
         packages = self.import_packages_module()
-        search(os.path.dirname(packages.__file__))
+        # This makes VisTrails not zip-safe
+        search(os.path.dirname(packages.__file__),
+               prefix='vistrails.packages.')
+
+        # Finds user packages
         userpackages = self.import_user_packages_module()
-        search(os.path.dirname(userpackages.__file__))
+        if userpackages is not None:
+            search(os.path.dirname(userpackages.__file__),
+                   prefix='userpackages.')
+
+        # Finds plugin packages
+        try:
+            from pkg_resources import iter_entry_points
+        except ImportError:
+            pass
+        else:
+            for entry_point in iter_entry_points('vistrails.packages'):
+                # Reads module name and turns it into prefix and codepath
+                name = entry_point.module_name.rsplit('.', 1)
+                if len(name) > 1:
+                    prefix, name = name
+                    prefix = '%s.' % prefix
+                else:
+                    prefix = ''
+                    name, = name
+
+                # Create the Package, with the right prefix
+                self.get_available_package(name, prefix=prefix)
 
-        pkg_name_set.update(self._package_list)
-        return list(pkg_name_set)
+        return self._available_packages.keys()
 
     def dependency_graph(self):
         """dependency_graph() -> Graph.  Returns a graph with package
@@ -821,7 +875,7 @@ Returns true if given package identifier is present."""
         except vistrails.core.data_structures.graph.Graph.GraphContainsCycles, e:
             raise self.DependencyCycle(e.back_edge[0],
                                        e.back_edge[1])
-        return sorted_packages
+        return list(reversed(sorted_packages))
         
     def get_all_dependencies(self, identifier, reverse=False, dep_graph=None):
         if dep_graph is None:
@@ -854,7 +908,6 @@ Returns true if given package identifier is present."""
         return self.get_all_dependencies(identifier, True, dep_graph)
 
 def get_package_manager():
-    global _package_manager
     if not _package_manager:
         raise VistrailsInternalError("package manager not constructed yet.")
     return _package_manager
@@ -866,67 +919,52 @@ import unittest
 
 class TestImports(unittest.TestCase):
     def test_package(self):
-        # Hacks PackageManager so that it temporarily uses our test package
-        # instead of userpackages
+        from vistrails.tests.utils import MockLogHandler
+
         pm = get_package_manager()
-        from vistrails.tests.resources import import_pkg
-        def fake_userpkg_mod():
-            pm._userpackages = import_pkg
-            return import_pkg
-        old_userpackages = pm._userpackages
-        old_import_userpackages = pm.import_user_packages_module
-        pm._userpackages = import_pkg
-        pm.import_user_packages_module = fake_userpkg_mod
-
-        old_fix_names = list(Package.FIX_PACKAGE_NAMES)
-        Package.FIX_PACKAGE_NAMES.append('tests.resources.import_targets')
+        pm.get_available_package(
+                'test_import_pkg',
+                prefix='vistrails.tests.resources.import_pkg.')
 
-        try:
-            # Check the package is in the list
-            available_pkg_names = pm.available_package_names_list()
-            self.assertIn('test_import_pkg', available_pkg_names)
+        # Check the package is in the list
+        available_pkg_names = pm.available_package_names_list()
+        self.assertIn('test_import_pkg', available_pkg_names)
 
-            # Import __init__ and check metadata
-            pkg = pm.look_at_available_package('test_import_pkg')
+        # Import __init__ and check metadata
+        pkg = pm.look_at_available_package('test_import_pkg')
+        with MockLogHandler(debug.DebugPrint.getInstance().logger) as log:
             pkg.load('vistrails.tests.resources.import_pkg.')
-            self.assertEqual(pkg.identifier,
-                             'org.vistrails.tests.test_import_pkg')
-            self.assertEqual(pkg.version,
-                             '0.42')
-            for n in ['vistrails.tests.resources.import_targets.test1',
-                      'vistrails.tests.resources.import_targets.test2']:
-                self.assertIn(n, sys.modules)
-
-            # Import init.py
-            pm.late_enable_package(
-                    'test_import_pkg',
-                    {'test_import_pkg':
-                     'vistrails.tests.resources.import_pkg.'})
-            pkg = pm.get_package_by_codepath('test_import_pkg')
-            for n in ['vistrails.tests.resources.import_targets.test3',
-                      'vistrails.tests.resources.import_targets.test4',
-                      'vistrails.tests.resources.import_targets.test5']:
-                self.assertIn(n, sys.modules)
-
-            # Check dependencies
-            deps = pkg.get_py_deps()
-            for dep in ['vistrails.tests.resources.import_pkg.test_import_pkg',
-                        'vistrails.tests.resources.import_pkg.test_import_pkg.init',
-                        'vistrails.tests.resources.import_pkg.test_import_pkg.module1',
-                        'vistrails.tests.resources.import_pkg.test_import_pkg.module2',
-                        'vistrails.tests.resources.import_targets',
-                        'vistrails.tests.resources.import_targets.test1',
-                        'vistrails.tests.resources.import_targets.test2',
-                        'vistrails.tests.resources.import_targets.test3',
-                        'vistrails.tests.resources.import_targets.test4',
-                        'vistrails.tests.resources.import_targets.test5',
-                        'vistrails.tests.resources.import_targets.test6']:
-                self.assertIn(dep, deps)
-        finally:
-            pm._userpackages = old_userpackages
-            pm.import_user_packages_module = old_import_userpackages
-            Package.FIX_PACKAGE_NAMES = old_fix_names
-            try:
-                pm.late_disable_package('test_import_pkg')
-            except MissingPackage:
-                pass
+        self.assertEqual(len(log.messages['warning']), 1)
+        self.assertEqual(pkg.identifier,
+                         'org.vistrails.tests.test_import_pkg')
+        self.assertEqual(pkg.version,
+                         '0.42')
+        for n in ['vistrails.tests.resources.import_targets.test1',
+                  'vistrails.tests.resources.import_targets.test2']:
+            self.assertIn(n, sys.modules, "%s not in sys.modules" % n)
+
+        # Import init.py
+        pm.late_enable_package(
+                'test_import_pkg',
+                {'test_import_pkg':
+                 'vistrails.tests.resources.import_pkg.'})
+        pkg = pm.get_package_by_codepath('test_import_pkg')
+        for n in ['vistrails.tests.resources.import_targets.test3',
+                  'vistrails.tests.resources.import_targets.test4',
+                  'vistrails.tests.resources.import_targets.test5']:
+            self.assertIn(n, sys.modules, "%s not in sys.modules" % n)
+
+        # Check dependencies
+        deps = pkg.get_py_deps()
+        for dep in ['vistrails.tests.resources.import_pkg.test_import_pkg',
+                    'vistrails.tests.resources.import_pkg.test_import_pkg.init',
+                    'vistrails.tests.resources.import_pkg.test_import_pkg.module1',
+                    'vistrails.tests.resources.import_pkg.test_import_pkg.module2',
+                    'vistrails.tests.resources.import_targets',
+                    'vistrails.tests.resources.import_targets.test1',
+                    'vistrails.tests.resources.import_targets.test2',
+                    'vistrails.tests.resources.import_targets.test3',
+                    'vistrails.tests.resources.import_targets.test4',
+                    'vistrails.tests.resources.import_targets.test5',
+                    'vistrails.tests.resources.import_targets.test6']:
+            self.assertIn(dep, deps)
diff --git a/vistrails/core/packagerepository.py b/vistrails/core/packagerepository.py
index 2a7a9b5..d110c37 100644
--- a/vistrails/core/packagerepository.py
+++ b/vistrails/core/packagerepository.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core import debug
 import os
 import vistrails.core.configuration
+from vistrails.core import system
 import shutil
 import urllib2
 import tempfile
@@ -50,11 +54,12 @@ import os.path
 class PackageRepository(object):
 
     def __init__(self):
-        conf = vistrails.core.configuration.get_vistrails_configuration()
-        if conf.check('userPackageDirectory'):
-            self._upd = conf.userPackageDirectory
+        upd = system.get_vistrails_directory('userPackageDir')
+        if upd is not None:
+            self._upd = upd
         else:
-            self._upd = conf.get('dotVistrails') + '/.userpackages/'
+            conf = vistrails.core.configuration.get_vistrails_configuration()
+            self._upd = os.path.join(conf.get('dotVistrails'), '.userpackages')
 
     def create_main_directory(self, codepath):
         debug.log("Makedir '%s'" % (os.path.join(self._upd, codepath)))
@@ -107,7 +112,7 @@ class LocalPackageRepository(PackageRepository):
         try:
             f = open(os.path.join(self._path, codepath, 'MANIFEST'))
         except IOError, e:
-            raise InvalidPackage("Package is missing manifest.")
+            raise PackageRepository.InvalidPackage("Package is missing manifest.")
         # create directory
         self.create_main_directory(codepath)
         for l in f:
@@ -144,7 +149,7 @@ class HTTPPackageRepository(PackageRepository):
         try:
             f = urllib2.urlopen(self._path + '/' + codepath + '/MANIFEST')
         except urllib2.HTTPError, e:
-            raise InvalidPackage("Package is missing manifest.")
+            raise PackageRepository.InvalidPackage("Package is missing manifest.")
         self.create_main_directory(codepath)
         for l in f:
             l = l[:-1]
diff --git a/vistrails/core/param_explore.py b/vistrails/core/param_explore.py
index 2bbba31..1c58fe3 100644
--- a/vistrails/core/param_explore.py
+++ b/vistrails/core/param_explore.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """
 This module handles Parameter Exploration in VisTrails
 """
+from __future__ import division
+
 from vistrails.core import debug
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.core.vistrail.module_param import ModuleParam
@@ -239,6 +242,27 @@ class ActionBasedParameterExploration(object):
         exploreDimension(currentPipeline, pre_actions, len(actions)-1)
         return (results, resultActions)
 
+def _pipelinePositions(sheetCount, rowCount, colCount,
+                       pipelines):
+    """ _pipelinePositions(sheetCount: int, rowCount: int,
+                           colCount: int, pipelines: list of Pipeline,
+                           controller: VistrailCintroller
+                           -> list of Positions
+    Apply the pipeline locations to a list of pipeline positions in a
+    parameter exploration given that pipelines has multiple chunk
+    of sheetCount x rowCount x colCount cells
+
+    """
+
+    pipelinePositions = []
+    for pId in xrange(len(pipelines)):
+        col = pId % colCount
+        row = (pId // colCount) % rowCount
+        sheet = (pId // (colCount*rowCount)) % sheetCount
+        pipelinePositions.append((row, col, sheet))
+    return pipelinePositions
+
+
 ################################################################################
         
 
diff --git a/vistrails/core/paramexplore/__init__.py b/vistrails/core/paramexplore/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/paramexplore/__init__.py
+++ b/vistrails/core/paramexplore/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/paramexplore/function.py b/vistrails/core/paramexplore/function.py
index e833463..bfd4d44 100644
--- a/vistrails/core/paramexplore/function.py
+++ b/vistrails/core/paramexplore/function.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 
     * PEFunction
 """
+from __future__ import division
+
 from vistrails.db.domain import DBPEFunction, DBPEParameter
 from vistrails.core.paramexplore.param import PEParam
 import copy
diff --git a/vistrails/core/paramexplore/param.py b/vistrails/core/paramexplore/param.py
index 6a79146..15ce7bf 100644
--- a/vistrails/core/paramexplore/param.py
+++ b/vistrails/core/paramexplore/param.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
     * PEParam
 
  """
+from __future__ import division
+
 from vistrails.db.domain import DBPEParameter
 
 import unittest
diff --git a/vistrails/core/paramexplore/paramexplore.py b/vistrails/core/paramexplore/paramexplore.py
index 8a1de5d..c541abb 100644
--- a/vistrails/core/paramexplore/paramexplore.py
+++ b/vistrails/core/paramexplore/paramexplore.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This file contains the definition of the class ParameterExploration """
 
+from __future__ import division
+
 from xml.sax.saxutils import unescape
 
 import vistrails.core.db.action
@@ -47,7 +50,7 @@ from vistrails.core.modules.paramexplore import IntegerLinearInterpolator, \
    FloatLinearInterpolator, RGBColorInterpolator, HSVColorInterpolator,\
    UserDefinedFunctionInterpolator
 
-
+from ast import literal_eval
 import unittest
 import copy
 
@@ -102,25 +105,25 @@ class ParameterExploration(DBParameterExploration):
     
     def get_dims(self):
         try:
-            return eval(self._dims)
-        except:
+            return literal_eval(self._dims)
+        except Exception:
             return []
     def set_dims(self, d):
         try:
             _dims = repr(d)
-        except:
+        except Exception:
             _dims = []
     dims = property(get_dims, set_dims)
 
     def get_layout(self):
         try:
-            return eval(self._layout)
-        except:
+            return literal_eval(self._layout)
+        except Exception:
             return {}
     def set_layout(self, l):
         try:
             _layout = repr(l)
-        except:
+        except Exception:
             _layout = '{}'
     layout = property(get_layout, set_layout)
 
@@ -139,6 +142,8 @@ class ParameterExploration(DBParameterExploration):
         added_functions = {}
         vistrail_vars = []
         function_actions = []
+        tmp_f_id = -1L
+        tmp_p_id = -1L
         for i in xrange(len(self.functions)):
             pe_function = self.functions[i]
             module = pipeline.db_get_object(Module.vtType, pe_function.module_id)
@@ -146,8 +151,6 @@ class ParameterExploration(DBParameterExploration):
             if module.is_vistrail_var():
                 vistrail_vars.append(module.get_vistrail_var())
             port_spec = reg.get_input_port_spec(module, pe_function.port_name)
-            tmp_f_id = -1L
-            tmp_p_id = -1L
             for param in pe_function.parameters:
                 port_spec_item = port_spec.port_spec_items[param.pos]
                 dim = param.dimension
@@ -160,25 +163,25 @@ class ParameterExploration(DBParameterExploration):
                 if param.interpolator == 'Linear Interpolation':
                     # need to figure out type
                     if port_spec_item.module == "Integer":
-                        i_range = eval(text)
+                        i_range = literal_eval(text)
                         p_min = int(i_range[0])
                         p_max =int(i_range[1])
                         values = IntegerLinearInterpolator(p_min, p_max,
                                                      count).get_values()
                     if port_spec_item.module == "Float":
-                        i_range = eval(text)
+                        i_range = literal_eval(text)
                         p_min = float(i_range[0])
                         p_max =float(i_range[1])
                         values = FloatLinearInterpolator(p_min, p_max,
                                                      count).get_values()
                 elif param.interpolator == 'RGB Interpolation':
-                    i_range = eval(text)
+                    i_range = literal_eval(text)
                     p_min = str(i_range[0])
                     p_max =str(i_range[1])
                     values = RGBColorInterpolator(p_min, p_max,
                                                      count).get_values()
                 elif param.interpolator == 'HSV Interpolation':
-                    i_range = eval(text)
+                    i_range = literal_eval(text)
                     p_min = str(i_range[0])
                     p_max =str(i_range[1])
                     values = HSVColorInterpolator(p_min, p_max,
@@ -186,7 +189,7 @@ class ParameterExploration(DBParameterExploration):
                 elif param.interpolator == 'List':
                     p_module = port_spec_item.descriptor.module
                     values = [p_module.translate_to_python(m)
-                              for m in eval(text)]
+                              for m in literal_eval(text)]
                 elif param.interpolator == 'User-defined Function':
                     p_module = port_spec_item.descriptor.module
                     values = UserDefinedFunctionInterpolator(p_module,
diff --git a/vistrails/core/publishing/__init__.py b/vistrails/core/publishing/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/publishing/__init__.py
+++ b/vistrails/core/publishing/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/publishing/parse_latex.py b/vistrails/core/publishing/parse_latex.py
index ae086f1..3af70a7 100644
--- a/vistrails/core/publishing/parse_latex.py
+++ b/vistrails/core/publishing/parse_latex.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from itertools import izip
 import re
 
diff --git a/vistrails/core/query/__init__.py b/vistrails/core/query/__init__.py
index 1a22cf3..73a0de4 100644
--- a/vistrails/core/query/__init__.py
+++ b/vistrails/core/query/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -138,6 +139,8 @@
 #             result = result.union(query.run(pipeline, module_ids))
 
 ################################################################################
+from __future__ import division
+
 import xml.sax.saxutils
 
 from vistrails.core.utils import memo_method
@@ -265,7 +268,7 @@ class Query1c(Query):
            vistrails.vistrails_name = %s and
            vistrails.vistrails_id = wf_exec.vistrails_id""", name)
         lst = list(c.fetchall())
-        versions = set([x[1] for x in lst])
+        versions = set(x[1] for x in lst)
         executions = set(lst)
         result = []
         for version in versions:
@@ -292,55 +295,6 @@ class Query1c(Query):
         return result
     
 
-class Query2(Query):
-
-    def run(self, vistrail, name):
-        import vistrails.gui.vis_application
-        c = vistrails.gui.vis_application.logger.db.cursor()
-        c.execute("""
-        select distinct module_id, wf_version from
-        wf_exec, exec, vistrails
-        where
-           wf_exec.wf_exec_id = exec.wf_exec_id and
-           vistrails.vistrails_name = %s and
-           vistrails.vistrails_id = wf_exec.vistrails_id""", name)
-        lst = list(c.fetchall())
-        versions = set([x[1] for x in lst])
-        executions = set(lst)
-        result = []
-        for version in versions:
-            p = vistrail.getPipeline(int(version))
-            inv_graph = p.graph.inverse()
-
-            # s = upstream(x) union x where x.name = filesink blablabla
-            s = set()
-            for module_id, module in p.modules.iteritems():
-                if (module_id, version) not in executions:
-                    continue
-                if module.name == 'FileSink':
-                    for f in module.functions:
-                        if (f.name == 'outputName' and
-                            len(f.params) == 1 and
-                            f.params[0].value() == 'atlas-x.gif'):
-                            s = s.union(set(self.upstream(inv_graph, module_id) + [module_id]))
-                            break
-
-            # s2 = upstream(y) where y.name = softmean
-            s2 = set()
-            for module_id, module in p.modules.iteritems():
-                if module.name == 'SoftMean':
-                    s2 = s2.union(set(self.upstream(inv_graph, module_id) + [module_id]))
-
-            qresult = s - s2
-            
-            for m in qresult:
-                result.append((int(version), m))
-        self.queryResult = result
-        self.tupleLength = 2
-        self.computeIndices()
-        return result
-
-
 class Query3(Query):
 
     def run(self, vistrail, name):
@@ -354,7 +308,7 @@ class Query3(Query):
            vistrails.vistrails_name = %s and
            vistrails.vistrails_id = wf_exec.vistrails_id""", name)
         lst = list(c.fetchall())
-        versions = set([x[1] for x in lst])
+        versions = set(x[1] for x in lst)
         executions = set(lst)
         result = []
         for version in versions:
diff --git a/vistrails/core/query/combined.py b/vistrails/core/query/combined.py
index 5096d23..f2fef91 100644
--- a/vistrails/core/query/combined.py
+++ b/vistrails/core/query/combined.py
@@ -1,48 +1,54 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from version import SearchCompiler
 from visual import VisualQuery
 
 class CombinedSearch(VisualQuery):
-    def __init__(self, search_str=None, pipeline=None, versions_to_check=None):
+    def __init__(self, search_str=None, pipeline=None, versions_to_check=None,
+                 use_regex=False):
         VisualQuery.__init__(self, pipeline, versions_to_check)
         self.search_str = search_str
+        self.use_regex = use_regex
 
     def run(self, vistrail, name):
         VisualQuery.run(self, vistrail, name)
-        self.search_stmt = SearchCompiler(self.search_str).searchStmt
+        compiler = SearchCompiler(self.search_str, self.use_regex)
+        self.search_stmt = compiler.searchStmt
 
     def match(self, vistrail, action):
         if self.queryPipeline is not None and \
diff --git a/vistrails/core/query/multiple.py b/vistrails/core/query/multiple.py
index 5a4afb2..027d632 100644
--- a/vistrails/core/query/multiple.py
+++ b/vistrails/core/query/multiple.py
@@ -1,46 +1,51 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.query import Query
 from combined import CombinedSearch
 
 class MultipleSearch(Query):
     # vistrails_to_check { Vistrail: set(version_ids) }
-    def __init__(self, search_str=None, pipeline=None, entities_to_check={}):
+    def __init__(self, search_str=None, pipeline=None, entities_to_check={},
+                 use_regex=False):
         self.entities_to_check = entities_to_check
         self.queryPipeline = pipeline
         self.search_str = search_str
+        self.use_regex = use_regex
         self.queries = {}
         self.queries_by_vistrail = {}
         self.cur_vistrail = None
@@ -51,7 +56,7 @@ class MultipleSearch(Query):
     def run(self):
         for entity, versions_to_check in self.entities_to_check.iteritems():
             query = CombinedSearch(self.search_str, self.queryPipeline, 
-                                   versions_to_check)
+                                   versions_to_check, self.use_regex)
             query.run(entity.vistrail, '')
             self.queries[entity] = query
             self.queries_by_vistrail[entity.vistrail] = query
diff --git a/vistrails/core/query/version.py b/vistrails/core/query/version.py
index 4a769e4..792085d 100644
--- a/vistrails/core/query/version.py
+++ b/vistrails/core/query/version.py
@@ -1,46 +1,49 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # We need to remove QtGui and QtCore refernce by storing all of our
 # notes in plain text, not html, should be fix later
-from vistrails.core.query import extract_text
-import vistrails.core.utils
+from __future__ import division
+
+import datetime
 import re
 import time
-
 import unittest
-import datetime
+
+from vistrails.core.query import extract_text
+from vistrails.core.system import time_strptime
 
 ################################################################################
 
@@ -49,10 +52,6 @@ class SearchParseError(Exception):
         Exception.__init__(self, *args, **kwargs)
 
 class SearchStmt(object):
-    def __init__(self, content):
-        self.text = content
-        self.content = re.compile('.*'+content+'.*', re.MULTILINE | re.IGNORECASE)
-
     def match(self, vistrail, action):
         return True
 
@@ -397,44 +396,57 @@ class BeforeSearchStmt(TimeSearchStmt):
     def match(self, vistrail, action):
         if not action.date:
             return False
-        t = time.mktime(time.strptime(action.date, "%d %b %Y %H:%M:%S"))
+        t = time.mktime(time_strptime(action.date, "%d %b %Y %H:%M:%S"))
         return t <= self.date
 
 class AfterSearchStmt(TimeSearchStmt):
     def match(self, vistrail, action):
         if not action.date:
             return False
-        t = time.mktime(time.strptime(action.date, "%d %b %Y %H:%M:%S"))
+        t = time.mktime(time_strptime(action.date, "%d %b %Y %H:%M:%S"))
         return t >= self.date
 
-class UserSearchStmt(SearchStmt):
+class RegexEnabledSearchStmt(SearchStmt):
+    def __init__(self, content, use_regex):
+        self.content = content
+        self.use_regex = use_regex
+        if self.use_regex:
+            self.regex = re.compile(content, re.MULTILINE | re.IGNORECASE)
+
+    def _content_matches(self, v):
+        if self.use_regex:
+            return self.regex.match(v)
+        else:
+            return v in self.content
+
+class UserSearchStmt(RegexEnabledSearchStmt):
     def match(self, vistrail, action):
         if not action.user:
             return False
-        return self.content.match(action.user)
+        return self._content_matches(action.user)
 
-class NotesSearchStmt(SearchStmt):
+class NotesSearchStmt(RegexEnabledSearchStmt):
     def match(self, vistrail, action):
         if vistrail.has_notes(action.id):
             plainNotes = extract_text(vistrail.get_notes(action.id))
-            return self.content.search(plainNotes)
+            return self._content_matches(plainNotes)
         return False
 
-class NameSearchStmt(SearchStmt):
+class NameSearchStmt(RegexEnabledSearchStmt):
     def match(self, vistrail, action):
         m = 0
         tm = vistrail.get_tagMap()
         if action.timestep in tm:
-            m = self.content.match(tm[action.timestep])
+            m = self._content_matches(tm[action.timestep])
         if bool(m) == False:
-            m = self.content.match(vistrail.get_description(action.timestep))
+            m = self._content_matches(vistrail.get_description(action.timestep))
         return bool(m)
 
-class ModuleSearchStmt(SearchStmt):
+class ModuleSearchStmt(RegexEnabledSearchStmt):
     def match(self, vistrail, action):
         pipeline = vistrail.getPipeline(action.timestep)
         for module in pipeline.modules.itervalues():
-            if self.content.match(module.name):
+            if self._content_matches(module.name):
                 return True
         return False
 
@@ -472,48 +484,48 @@ class TrueSearch(SearchStmt):
 
 class SearchCompiler(object):
     SEPARATOR = -1
-    def __init__(self, searchStr):
-        self.searchStmt = self.compile(searchStr)
-    def compile(self, searchStr):
+    def __init__(self, searchStr, use_regex=False):
+        self.searchStmt = self.compile(searchStr, use_regex)
+    def compile(self, searchStr, use_regex):
         lst = []
         t1 = searchStr.split(' ')
         while t1:
             tok = t1[0]
-            cmd = tok.split(':')
-            if not SearchCompiler.dispatch.has_key(cmd[0]):
-                fun = SearchCompiler.parseAny
-            else:
+            cmd = tok.split(':', 1)
+            if SearchCompiler.dispatch.has_key(cmd[0]):
                 fun = SearchCompiler.dispatch[cmd[0]]
-            if len(cmd) > 1:
-                [search, rest] = fun(self, cmd[1:] + t1[1:])
+                if len(cmd) > 1:
+                    t1 = [cmd[1]] + t1[1:]
+                search, rest = fun(self, t1, use_regex)
             else:
-                [search, rest] = fun(self, t1)
+                search, rest = self.parseAny(t1, use_regex)
             lst.append(search)
             t1 = rest
         return AndSearchStmt(lst)
-    def parseUser(self, tokStream):
+    def parseAny(self, tokStream, use_regex):
         if len(tokStream) == 0:
             raise SearchParseError('Expected token, got end of search')
-        return (UserSearchStmt(tokStream[0]), tokStream[1:])
-    def parseAny(self, tokStream):
+        tok = tokStream[0]
+        return (OrSearchStmt([UserSearchStmt(tok, use_regex),
+                              NotesSearchStmt(tok, use_regex),
+                              NameSearchStmt(tok, use_regex)]),
+                tokStream[1:])
+    def parseUser(self, tokStream, use_regex):
         if len(tokStream) == 0:
             raise SearchParseError('Expected token, got end of search')
-        tok = tokStream[0]
-        return (OrSearchStmt([UserSearchStmt(tok),
-                              NotesSearchStmt(tok),
-                              NameSearchStmt(tok)]), tokStream[1:])
-    def parseNotes(self, tokStream):
+        return (UserSearchStmt(tokStream[0], use_regex), tokStream[1:])
+    def parseNotes(self, tokStream, use_regex):
         if len(tokStream) == 0:
             raise SearchParseError('Expected token, got end of search')
         lst = []
         while len(tokStream):
             tok = tokStream[0]
             if ':' in tok:
-                return (AndSearchStmt(lst), tokStream)
-            lst.append(NotesSearchStmt(tok))
+                return (AndSearchStmt(lst, use_regex), tokStream)
+            lst.append(NotesSearchStmt(tok, use_regex))
             tokStream = tokStream[1:]
         return (AndSearchStmt(lst), [])
-    def parseName(self, tokStream):
+    def parseName(self, tokStream, use_regex):
         if len(tokStream) == 0:
             raise SearchParseError('Expected token, got end of search')
         lst = []
@@ -521,10 +533,10 @@ class SearchCompiler(object):
             tok = tokStream[0]
             if ':' in tok:
                 return (AndSearchStmt(lst), tokStream)
-            lst.append(NameSearchStmt(tok))
+            lst.append(NameSearchStmt(tok, use_regex))
             tokStream = tokStream[1:]
         return (AndSearchStmt(lst), [])
-    def parseModule(self, tokStream):
+    def parseModule(self, tokStream, use_regex):
         if len(tokStream) == 0:
             raise SearchParseError('Expected token, got end of search')
         lst = []
@@ -532,10 +544,10 @@ class SearchCompiler(object):
             tok = tokStream[0]
             if ':' in tok:
                 return (AndSearchStmt(lst), tokStream)
-            lst.append(ModuleSearchStmt(tok))
+            lst.append(ModuleSearchStmt(tok, use_regex))
             tokStream = tokStream[1:]
         return (AndSearchStmt(lst), [])
-    def parseBefore(self, tokStream):
+    def parseBefore(self, tokStream, use_regex):
         old_tokstream = tokStream
         try:
             if len(tokStream) == 0:
@@ -554,14 +566,14 @@ class SearchCompiler(object):
         except SearchParseError, e:
             if 'Expected a date' in e.args[0]:
                 try:
-                    return self.parseAny(old_tokstream)
+                    return self.parseAny(old_tokstream, use_regex)
                 except SearchParseError, e2:
                     print "Another exception...", e2.args[0]
                     raise e
             else:
                 raise
             
-    def parseAfter(self, tokStream):
+    def parseAfter(self, tokStream, use_regex):
         try:
             if len(tokStream) == 0:
                 raise SearchParseError('Expected token, got end of search')
@@ -579,7 +591,7 @@ class SearchCompiler(object):
         except SearchParseError, e:
             if 'Expected a date' in e.args[0]:
                 try:
-                    return self.parseAny(['after'] + tokStream)
+                    return self.parseAny(['after'] + tokStream, use_regex)
                 except SearchParseError, e2:
                     print "Another exception...", e2.args[0]
                     raise e
diff --git a/vistrails/core/query/visual.py b/vistrails/core/query/visual.py
index 9e87d14..91947ea 100644
--- a/vistrails/core/query/visual.py
+++ b/vistrails/core/query/visual.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core import query
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.utils import append_to_dict_of_lists
@@ -51,8 +54,8 @@ class VisualQuery(query.Query):
                                 target_ids, template_ids):
         resultIds = set()
         while 1:
-            templateNames = set([(i, template.modules[i].name)
-                                 for i in template_ids])
+            templateNames = set((i, template.modules[i].name)
+                                for i in template_ids)
             targetNames = {}
             for i in target_ids:
                 append_to_dict_of_lists(targetNames, target.modules[i].name, i)
diff --git a/vistrails/core/recent_vistrails.py b/vistrails/core/recent_vistrails.py
index 9f0297c..2503a02 100644
--- a/vistrails/core/recent_vistrails.py
+++ b/vistrails/core/recent_vistrails.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ RecentVistrailList is a Helper class to manage serialization and
 unserialization of a list of locators to XML """
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 from vistrails.core.db.locator import FileLocator, DBLocator
 
diff --git a/vistrails/core/repository/__init__.py b/vistrails/core/repository/__init__.py
index cdc9214..d1486d2 100644
--- a/vistrails/core/repository/__init__.py
+++ b/vistrails/core/repository/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # Nothing here on purpose
+from __future__ import division
+
 pass
diff --git a/vistrails/core/repository/poster/__init__.py b/vistrails/core/repository/poster/__init__.py
index bd04291..459141d 100644
--- a/vistrails/core/repository/poster/__init__.py
+++ b/vistrails/core/repository/poster/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -61,6 +62,8 @@ Support for streaming HTTP uploads, and multipart/form-data encoding
 New releases of poster will always have a version number that compares greater
 than an older version of poster.
 New in version 0.6."""
+from __future__ import division
+
 import vistrails.core.repository.poster.streaminghttp
 import vistrails.core.repository.poster.encode
 
diff --git a/vistrails/core/repository/poster/encode.py b/vistrails/core/repository/poster/encode.py
index 2905c47..8495486 100644
--- a/vistrails/core/repository/poster/encode.py
+++ b/vistrails/core/repository/poster/encode.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -60,6 +61,8 @@ as multipart/form-data suitable for a HTTP POST or PUT request.
 
 multipart/form-data is the standard way to upload files over HTTP"""
 
+from __future__ import division
+
 __all__ = ['gen_boundary', 'encode_and_quote', 'MultipartParam',
         'encode_string', 'encode_file_header', 'get_body_size', 'get_headers',
         'multipart_encode']
@@ -161,7 +164,7 @@ class MultipartParam(object):
                     fileobj.seek(0, 2)
                     self.filesize = fileobj.tell()
                     fileobj.seek(0)
-                except:
+                except IOError:
                     raise ValueError("Could not determine filesize")
 
     def __cmp__(self, other):
@@ -366,7 +369,7 @@ def get_headers(params, boundary):
     headers['Content-Length'] = str(get_body_size(params, boundary))
     return headers
 
-class multipart_yielder:
+class multipart_yielder(object):
     def __init__(self, params, boundary, cb):
         self.params = params
         self.boundary = boundary
diff --git a/vistrails/core/repository/poster/streaminghttp.py b/vistrails/core/repository/poster/streaminghttp.py
index 5f1cfd0..e0a1f5a 100644
--- a/vistrails/core/repository/poster/streaminghttp.py
+++ b/vistrails/core/repository/poster/streaminghttp.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -81,6 +82,8 @@ Example usage:
 ...                       {'Content-Length': str(len(s))})
 """
 
+from __future__ import division
+
 import httplib, urllib2, socket
 from httplib import NotConnected
 
@@ -90,7 +93,7 @@ __all__ = ['StreamingHTTPConnection', 'StreamingHTTPRedirectHandler',
 if hasattr(httplib, 'HTTPS'):
     __all__.extend(['StreamingHTTPSHandler', 'StreamingHTTPSConnection'])
 
-class _StreamingHTTPMixin:
+class _StreamingHTTPMixin(object):
     """Mixin class for HTTP and HTTPS connections that implements a streaming
     send method."""
     def send(self, value):
diff --git a/vistrails/core/requirements.py b/vistrails/core/requirements.py
index 01b76d5..5858695 100644
--- a/vistrails/core/requirements.py
+++ b/vistrails/core/requirements.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """module that allows online inspection of environment to test presence of
 runtime components such as binaries, libraries, other python modules, etc."""
+from __future__ import division
+
 import sys
 
 import vistrails.core.bundles.installbundle
@@ -45,13 +48,11 @@ import vistrails.core.system
 
 def python_module_exists(module_name):
     """python_module_exists(module_name): Boolean.
-Returns if python module of given name can be safely imported."""
-    
-    try:
-        sys.modules[module_name]
+    Returns if python module of given name can be safely imported.
+
+    """
+    if module_name in sys.modules:
         return True
-    except KeyError:
-        pass
     try:
         __import__(module_name)
         return True
@@ -61,11 +62,13 @@ Returns if python module of given name can be safely imported."""
 
 def executable_file_exists(filename):
     """executable_file_exists(filename): Boolean.
-Returns if certain file is in current path and is executable."""
+    Returns if certain file is in current path and is executable.
+    
+    """
     result = vistrails.core.system.executable_is_in_path(filename)
-    if result == "":
-        result = vistrails.core.system.executable_is_in_pythonpath(filename)
-    return result != ""
+    if not result:
+        result = vistrails.core.system.executable_is_in_path(filename)
+    return result
 
 # FIXME: Add documentation.
 
diff --git a/vistrails/core/resources/default_vistrails_startup b/vistrails/core/resources/default_vistrails_startup
deleted file mode 100644
index 0a6c394..0000000
--- a/vistrails/core/resources/default_vistrails_startup
+++ /dev/null
@@ -1,204 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-
-# Vistrails initialization file
-##############################################################################
-
-##############################################################################
-# Basic configuration
-
-# Comment this to use the logging mechanism (which is being 
-# overhauled, so right now it's also broken)
-configuration.nologger = True
-
-# Uncomment this to prevent VisTrails's splash screen from appearing
-# configuration.showSplash = False
-
-# Uncomment this to enable VisTrails's python shell by default
-# configuration.pythonPrompt = True
-
-# Uncomment this to switch to the non-caching execution model
-# configuration.useCache = False
-
-# Uncomment this to start VisTrails with maximized windows
-# configuration.maximizeWindows = True
-
-# Uncomment this if you run multiple monitors, to start VisTrails
-# with different windows in different monitors
-# configuration.multiHeads = True
-
-# Set verbosenessLevel to 1 or 2 to enable dumping of non-critical warnings
-# and information messages to stderr.
-# configuration.verbosenessLevel = 1 # 2
-
-##############################################################################
-# VisTrails packages.
-
-# VisTrails packages are collections of modules that provide user-specified
-# functionality to VisTrails. Use addPackage to let VisTrails know which 
-# packages you want enabled.
-
-# Interpackage dependencies must currently be handled manually by the user.
-
-# For example, the spreadsheet package depends on VTK for some functionality,
-# so if you want that functionality, you should add the vtk package before
-# the spreadsheet package.
-
-# the vtk package is the main visualization package for VisTrails
-# addPackage('vtk')
-
-# pythonCalc is an example package intended simply to demonstrate how to
-# create new packages
-# addPackage('pythonCalc')
-
-# ImageMagick uses the ImageMagick command-line suite to perform various
-# tasks on images (conversion, filtering, etc).
-#addPackage('ImageMagick')
-
-# The spreadsheet package enables the Visualization Spreadsheet
-# addPackage('spreadsheet')
-
-# The HTTP package provides an easy way to access files from http and use
-# them as regular files in VisTrails pipelines.
-# addPackage('HTTP')
-
-# The pylab (matplotlib) package for plotting and histograms
-# addPackage('pylab')
-
-
-################################################################################
-# Hooks
-
-# Currently, there is only one hook in VisTrails: the startup hook. By adding
-# arbitrary callables to the startup hook, it is possible to run user-defined
-# code after all packages have been initialized, but before VisTrails runs.
-
-# This is intended to show that it is possible to have user-defined code
-# in specific places in VisTrails. If you think you need a hook somewhere that
-# we haven't allowed yet, please let us know, and we'll include it in a future
-# release.
-
-def testHook():
-    """Prints the Module class hierarchy to stdout."""
-    def printTree(n, indent = 0):
-        def iprint(str):
-            print '%s%s' % (" " * indent, str)
-        iprint('Class: %s' % n.descriptor.name)
-        for c in n.children:
-            printTree(c, indent+4)
-            
-    import modules
-    import modules.module_registry
-    t = modules.module_registry.registry.classTree
-    printTree(t)
-
-# Uncomment this line to install the startup hook
-# addStartupHook(testHook)
-
-
-##############################################################################
-# If you have an appropriate Qt license, you can install signal inspectors,
-# which might make debugging a whole lot easier. To do that, uncomment the
-# following lines.
-
-
-# import qt
-# connections = {}
-# def connectHandler(*args):
-#     """This handler writes all signal connections to /tmp/signalslotnames.txt"""
-#     emitter = args[0].__class__.__name__
-#     signal = args[1]
-#     f = signal.find('(')
-#     if f == -1:
-#         signal = signal[1:]
-#     else:
-#         signal = signal[1:f]
-#     try:
-#         receiver = args[2].im_class.__name__
-#         slot = args[2].im_func.__name__
-#     except AttributeError:
-#         receiver = args[2].__self__.__class__.__name__
-#         slot = args[2].__class__.__name__
-#     entry = (emitter, signal, receiver, slot)
-#     print entry
-#     global connections
-#     try:
-#         connections[emitter].add((signal, receiver, slot))
-#     except:
-#         connections[emitter] = set(((signal, receiver, slot),))
-#     signals = {}
-#     slots = {}
-#     sig_count = 1
-#     slot_count = 1
-#     f = open('/tmp/connections.txt', 'w')
-#     f.write('digraph {\n')
-#     for (k, v) in connections.iteritems():
-#         print k, v
-#         recs = {}
-#         for (sig, rec, sl) in v:
-#             if not signals.has_key(sig):
-#                 signals[sig] = sig_count
-#                 sig_count += 1
-#             if not slots.has_key(sl):
-#                 slots[sl] = slot_count
-#                 slot_count += 1
-#             try:
-#                 recs[rec].append( str(signals[sig]) + ':' + str(slots[sl]))
-#             except:
-#                 recs[rec] = [str(signals[sig]) + ':' + str(slots[sl])]
-#         for rec, sigslotlist in recs.iteritems():
-#             f.write('%s -> %s [label = "%s"];\n' % (k, rec, ";".join(sigslotlist)))
-# #     if not entry in connections:
-# #         f = open('/tmp/connections.txt', 'a')
-# #         f.write("%s %s %s\n" % emi)
-# #         f.close()
-# #     connections.add(entry)
-#     f.write('}\n')
-#     f.close()
-#     f = open('/tmp/signalslotnames.txt', 'w')
-#     sigs = [(v, k) for (k, v) in signals.items()]
-#     sigs.sort()
-#     sls = [(v, k) for (k, v) in slots.items()]
-#     sls.sort()
-#     f.write('signals: \n')
-#     for (k,v) in sigs:
-#         f.write('%s: %s\n' % (k, v))
-#     f.write('slots: \n')
-#     for (k,v) in sls:
-#         f.write('%s: %s\n' % (k, v))
-
-
-# This line hooks connectHandler to Qt's signals. You can use user-defined
-# code here.
-# qt.enableSignalDebugging(connectCall = connectHandler)
diff --git a/vistrails/core/resources/default_vistrails_startup_xml b/vistrails/core/resources/default_vistrails_startup_xml
index f901b45..6b31123 100644
--- a/vistrails/core/resources/default_vistrails_startup_xml
+++ b/vistrails/core/resources/default_vistrails_startup_xml
@@ -1,6 +1,6 @@
 <startup version="0.1">
   <configuration>
-    <key name="nologger">
+    <key name="executionLog">
       <bool value="True"/>
     </key>
   </configuration>
@@ -9,28 +9,35 @@
     <package name="pythonCalc"/>
     <package name="spreadsheet"/>
     <package name="dialogs"/>
-    <package name="HTTP"/>
+    <package name="URL"/>
     <package name="controlflow"/>
     <package name="tabledata"/>
+    <package name="gmaps"/>
+    <package name="CLTools"/>
+    <package name="matplotlib"/>
+    <package name="persistent_archive"/>
+    <package name="sklearn"/>
+    <package name="sql"/>
+    <package name="tej"/>
   </packages>
   <disabledpackages/>
 </startup>
 
 <!--
-	This is what a "regular" startup file looks like.
+    This is what a "regular" startup file looks like.
 
 <startup version="0.1">
   <configuration>
-    <key name="nologger">
+    <key name="executionLog">
       <bool value="True"/>
     </key>
     <key name="shell">
       <configuration>
-        <key name="font_face">
-  	  <str value="Bitstream Vera mono"/>
+        <key name="fontFace">
+      <str value="Bitstream Vera mono"/>
         </key>
-        <key name="font_size">
-	  <int value="9"/>
+        <key name="fontSize">
+      <int value="9"/>
         </key>
       </configuration>
     </key>
@@ -40,7 +47,7 @@
     <package name="spreadsheet"/>
     <package name="pythonCalc"/>
     <package name="ImageMagick"/>
-    <package name="HTTP"/>
+    <package name="URL"/>
     <package name="teem"/>
     <package name="ectmc"/>
     <package name="macet"/>
@@ -48,9 +55,9 @@
     <package name="meshutils"/>
     <package name="afront">
       <configuration>
-	<key name="debug">
-	  <bool value="True"/>
-	</key>
+    <key name="debug">
+      <bool value="True"/>
+    </key>
       </configuration>
     </package>
     <package name="metro"/>
diff --git a/vistrails/core/resources/spawned_startup_xml b/vistrails/core/resources/spawned_startup_xml
index b65ed3a..56a306c 100644
--- a/vistrails/core/resources/spawned_startup_xml
+++ b/vistrails/core/resources/spawned_startup_xml
@@ -19,24 +19,11 @@
   </packages>
   <disabledpackages/>
   <configuration>
-    <key name="nologger">
-      <bool value="True"/>
-    </key>
     <key name="nologfile">
       <bool value="True"/>
     </key>
     <key name="spawned">
       <bool value="True"/>
     </key>
-    <key name="shell">
-      <configuration>
-        <key name="font_face">
-          <str value="Bitstream Vera mono"/>
-        </key>
-        <key name="font_size">
-          <int value="9"/>
-        </key>
-      </configuration>
-    </key>
   </configuration>
 </startup>
diff --git a/vistrails/core/startup.py b/vistrails/core/startup.py
index 3487722..fb69add 100644
--- a/vistrails/core/startup.py
+++ b/vistrails/core/startup.py
@@ -1,56 +1,106 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Describes the start-up process of VisTrails"""
+from __future__ import division
+
 from vistrails.core import debug
 from vistrails.core import system
-from vistrails.core.utils.uxml import named_elements, elements_filter, \
-     eval_xml_value, enter_named_element
+from vistrails.core.configuration import ConfigurationObject
+from vistrails.db.domain import DBStartup, DBStartupPackage, \
+    DBEnabledPackages, DBDisabledPackages
+import vistrails.db.services.io
+import vistrails.core.db.io
+from vistrails.core.system import get_elementtree_library, \
+    get_vistrails_directory, systemType
+from vistrails.core.utils import version_string_to_list
+
+import atexit
 import copy
-import vistrails.core.packagemanager
-import vistrails.core.utils
 import os.path
+import re
 import shutil
+import string
 import sys
 import tempfile
 import vistrails.core.configuration
-import xml.dom.minidom
+
+ElementTree = get_elementtree_library()
 
 ################################################################################
 
-class VistrailsStartup(object):
+class StartupPackage(DBStartupPackage):
+    def __init__(self, *args, **kwargs):
+        if 'prefix' in kwargs:
+            self.prefix = kwargs['prefix']
+            del kwargs['prefix']
+        else:
+            self.prefix = None
+        DBStartupPackage.__init__(self, *args, **kwargs)
+
+    @staticmethod
+    def convert(_pkg):
+        _pkg.__class__ = StartupPackage
+        if _pkg.configuration is not None:
+            ConfigurationObject.convert(_pkg.configuration)
+        _pkg.prefix = None
+
+    def __copy__(self):
+        """ __copy__() -> StartupPackage - Returns a clone of itself """ 
+        return StartupPackage.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBStartupPackage.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = StartupPackage
+        cp.prefix = self.prefix
+        return cp
+
+    configuration = DBStartupPackage.db_configuration
+    name = DBStartupPackage.db_name
+
+    def __eq__(self, other):
+        if type(self) != type(other):
+            return False
+        return (self.name == other.name and
+                self.configuration == other.configuration)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+class VistrailsStartup(DBStartup):
     """
     VistrailsStartup is the class that initializes VisTrails based on
     a configuration. Both application mode (interactive and
@@ -61,538 +111,552 @@ class VistrailsStartup(object):
     
     """
 
-    def __init__(self, config=None, tempconfig=None):
-        """ VistrailsStartup(config, tempconfig: ConfigurationObject,
-                             optionsDict: dict) -> None
-        Setup the configuration. config is the persistent configuration and 
-        tempconfig is the current configuration.
-        
-        """
-        assert (config is None or
-                isinstance(config, vistrails.core.configuration.ConfigurationObject))
-        assert (tempconfig is None or
-                isinstance(tempconfig, vistrails.core.configuration.ConfigurationObject))
-        if config:
-            self.configuration = config
-        else:
-            self.configuration = vistrails.core.configuration.default()
-        if tempconfig:
-            self.temp_configuration = tempconfig
-        else:
-            self.temp_configuration = copy.copy(self.configuration)
-        
-        self.startupHooks = []
-        
-        # This needs to be here because we want to log all initialization
-        # steps
-        self.setupLogFile()
-        self._python_environment = self.runDotVistrails()
-        self.load_configuration()
-        
-        #the problem is that maybe the logFile now points to a different place
-        self.setupLogFile()
-        
-        self.setupDefaultFolders()
-        #package_manager needs the persistent configuration    
-        self._package_manager = vistrails.core.packagemanager.PackageManager(
-            self.configuration)
-            
-        self._do_load_packages = True
-        self._package_dictionary = {}
-        # stores all packages that must be enabled on startup
-        self._needed_packages = []
-        
-    def init(self):
-        """ init() -> None        
-        Initialize VisTrails with optionsDict. optionsDict can be
-        another VisTrails Configuration object, e.g. ConfigurationObject
-        
-        """
-        if self._do_load_packages:
-            self.load_packages()
-        if self._do_load_packages:
-            # don't call this anymore since we do an add_package for it now
-            # self.setupBaseModules()
-            self.installPackages()
-        self.runStartupHooks()
-
-    def set_needed_packages(self, package_list):
-        self._needed_packages = package_list
-
-    ##########################################################################
-    # startup.xml related
-
-    def startup_dom(self):
-        filename = os.path.join(self.temp_configuration.dotVistrails,'startup.xml')
-        return xml.dom.minidom.parse(filename)
-
-    def write_startup_dom(self, dom):
-        filename = os.path.join(self.temp_configuration.dotVistrails,'startup.xml')
-        f = open(filename, 'w')
-        f.write(dom.toxml())
-                
-    def load_configuration(self):
-        """load_configuration() -> None
-        Loads the appropriate configuration from .vistrails/startup.xml.
-        This will overwrite both configuration and temp_configuration
-        
-        """
-        dom = self.startup_dom()
-        conf = enter_named_element(dom.documentElement, 'configuration')
-        self.configuration.set_from_dom_node(conf)
-        self.temp_configuration.set_from_dom_node(conf)
-        
-    def load_packages(self):
-        """load_packages() -> None
+    # !!! IMPORTANT: keep logDirectory first!
+    DIRECTORIES = [('logDir', 'logs', False),
+                   ('userPackageDir', 'userpackages', True),
+                   ('subworkflowsDir', 'subworkflows', False),
+                   ('thumbs.cacheDir', 'thumbs', False)]
+    DOT_VISTRAILS_PREFIX = "$DOT_VISTRAILS"
+    DOT_VISTRAILS_PREFIX_RE = re.compile("%s([%s/\\\\]|$)" % 
+                                         (re.escape(DOT_VISTRAILS_PREFIX),
+                                          os.path.sep))
+
+    first_run = False
+
+    def __init__(self, options_config, command_line_config, 
+                 use_dot_vistrails=True):
+        """VistrailsStartup(dot_vistrails: str) -> None
+
+        Setup VisTrails configuration and options. dot_vistrals
+        indicates the file we will use to load and save configuration
+        options; if it is None, options will not be loaded or saved
+        for the session.
 
-        Loads the appropriate packages from .vistrails/startup.xml.
         """
-        
-        for package_name in self._needed_packages:
-            self._package_manager.add_package(package_name)
-
-        def parse_package(node):
-            is_value = (lambda node: node.nodeName in
-                        set(['bool', 'str', 'int', 'float']))
-            package_name = str(node.attributes['name'].value)
-            # FIXME use more robust checks here!
-            if package_name != 'basic_modules' and \
-                    package_name != 'abstraction':
-                self._package_manager.add_package(package_name)
-        dom = self.startup_dom()
-        doc = dom.documentElement
-        packages_node = enter_named_element(doc, 'packages')
-        for package_node in named_elements(packages_node, 'package'):
-            parse_package(package_node)
-
-    ##########################################################################
-
-    def get_python_environment(self):
-        """get_python_environment(): returns the python environment generated
-by startup.py. This should only be called after init()."""
-        return self._python_environment
-
-    def create_default_directory(self):
-        if os.path.lexists(self.temp_configuration.dotVistrails):
-            return
 
-        debug.log('Will try to create default directory')
+        DBStartup.__init__(self)
+        self.db_enabled_packages = DBEnabledPackages()
+        self.db_disabled_packages = DBDisabledPackages()
+
+        self._dot_vistrails = None
+
+        # self._enabled_packages = {}
+        # self._disabled_packages = {}
+
+        self.configuration = vistrails.core.configuration.default()
+
+        if ((command_line_config is not None and
+                 command_line_config.check('spawned')) or 
+                (options_config is not None and 
+                 options_config.check('spawned'))):
+            # Here we are in 'spawned' mode, i.e. we are running
+            # non-interactively as a slave
+            # We are going to create a .vistrails directory as a temporary
+            # directory and copy a specific configuration file
+            # We don't want to load packages that the user might enabled in
+            # this machine's configuration file as it would slow down the
+            # startup time, but we'll load any needed package without
+            # confirmation
+            tmpdir = tempfile.mkdtemp(prefix='vt_spawned_')
+            @atexit.register
+            def clean_dotvistrails():
+                shutil.rmtree(tmpdir, ignore_errors=True)
+            command_line_config.dotVistrails = tmpdir
+            shutil.copyfile(os.path.join(system.vistrails_root_directory(),
+                                         'core', 'resources',
+                                         'spawned_startup_xml'),
+                            os.path.join(tmpdir, 'startup.xml'))
+            command_line_config.enablePackagesSilently = True
+            command_line_config.errorLog = False
+            command_line_config.singleInstance = False
+
+        if use_dot_vistrails:
+            if command_line_config is not None and \
+               command_line_config.check('dotVistrails'):
+                self._dot_vistrails = command_line_config.get('dotVistrails')
+            elif options_config is not None and \
+                 options_config.check('dotVistrails'):
+                self._dot_vistrails = options_config.get('dotVistrails')
+            else:
+                self._dot_vistrails = self.configuration.get('dotVistrails')
+            self.setup_base_dot_vistrails()
+
+        self.load_and_update_configurations(options_config, 
+                                            command_line_config)
+        self.update_packages()
+        self.setup_dot_vistrails()
+
+    @staticmethod
+    def convert(_startup):
+        _startup.__class__ = VistrailsStartup
+        ConfigurationObject.convert(_startup.configuration)
+        for _pkg in _startup.db_enabled_packages.db_packages:
+            StartupPackage.convert(_pkg)
+        for _pkg in _startup.db_disabled_packages.db_packages:
+            StartupPackage.convert(_pkg)
+
+    ########################################################################
+    # Properties
+
+    configuration = DBStartup.db_configuration
+    def _get_enabled_packages(self):
+        return self.db_enabled_packages.db_packages_name_index
+    enabled_packages = property(_get_enabled_packages)
+    def _get_disabled_packages(self):
+        return self.db_disabled_packages.db_packages_name_index
+    disabled_packages = property(_get_disabled_packages)
+    version = DBStartup.db_version
+
+    def __eq__(self, other):
+        if type(self) != type(other):
+            return False
+        def check_packages(self_pkgs, other_pkgs):
+            if len(self_pkgs.db_packages) != len(other_pkgs.db_packages):
+                return False
+            for (p_name, pkg1) in \
+                    self_pkgs.db_packages_name_index.iteritems():
+                if p_name not in other_pkgs.db_packages_name_index:
+                    return False
+                else:
+                    pkg2 = other_pkgs.db_packages_name_index[p_name]
+                    if pkg1 != pkg2:
+                        return False
+            return True
+        return (self.configuration == other.configuration and
+                check_packages(self.db_enabled_packages, 
+                               other.db_enabled_packages) and
+                check_packages(self.db_disabled_packages,
+                               other.db_disabled_packages))
+
+    def get_startup_xml_fname(self):
+        return os.path.join(self._dot_vistrails, 'startup.xml')
+
+    def setup_base_dot_vistrails(self):
+        self.create_dot_vistrails_if_necessary()
+        self.create_startupxml_if_needed()
+
+    def load_and_update_configurations(self, options_config, 
+                                       command_line_config):
+        # load options from startup.xml
+        self.load_persisted_startup()
+
+        # set up temporary configuration with options and command-line
+        self.temp_configuration = copy.copy(self.configuration)
+
+        if options_config is not None:
+            self.temp_configuration.update(options_config)
+        if command_line_config is not None:
+            self.temp_configuration.update(command_line_config)
+
+    def setup_init_file(self, dir_name):
+        name = os.path.join(dir_name, '__init__.py')
         try:
-            os.mkdir(self.temp_configuration.dotVistrails)
-            debug.log('Succeeded!')
+            f = open(name, 'w')
+            f.write('pass\n')
+            f.close()
         except:
-            debug.critical("""Failed to create initialization directory.
-                    This could be an indication of a permissions problem.
-                    Make sure parent directory of '%s' is writable."""
-                    % self.temp_configuration.dotVistrails)
+            msg = ("""Failed to create file '%s'. This could indicate a
+            rare combination of a race condition and a permissions problem.
+            Please make sure it is writable.""" % name)
+            debug.critical(msg)
             sys.exit(1)
-                
-    def runDotVistrails(self):
-        """ runDotVistrails() -> None
-        Setup to run user .vistrails file
-
-        """        
-        def addStartupHook(hook):
-            """ addStartupHook(hook: function) -> None
-            Add a hook for start-up after initialization
-            
-            """
-            self.startupHooks.append(hook)
 
-        def addPackage(packageName, *args, **keywords):
-            """ addPackage(packageName: str, *args) -> None
-            """
-            self._package_manager.add_package(packageName)
+    def expand_vt_path(self, dir_name):
+        m = self.DOT_VISTRAILS_PREFIX_RE.match(dir_name)
+        if m:
+            if self._dot_vistrails is None:
+                return None
+            else:
+                # could be "$DOT_VISTRAILS" or "$DOT_VISTRAILS/userpackages"
+                prefix_len = len(self.DOT_VISTRAILS_PREFIX) + len(m.groups()[0])
+                if prefix_len < len(dir_name):
+                    return os.path.join(self._dot_vistrails, 
+                                        dir_name[prefix_len:])
+                else:
+                    return self._dot_vistrails
+        return dir_name
 
-        def create_user_packages_init(userpackagesname):
+    def create_directory(self, dir_name):
+        if not os.path.isdir(dir_name):
+            debug.warning('Will try to create directory "%s"' % dir_name)
             try:
-                name = os.path.join(userpackagesname, '__init__.py')
-                f = open(name, 'w')
-                f.write('pass\n')
-                f.close()
-            except:
-                msg = ("""Failed to create file '%s'. This could indicate a
-                rare combination of a race condition and a permissions problem.
-                Please make sure it is writable.""" % name)
+                os.mkdir(dir_name)
+                return True
+            except Exception, e:
+                msg = ("Failed to create directory: '%s'."
+                       "This could be an indication of a permissions problem."
+                       "Make sure directory '%s' in writable." %
+                       (str(e), dir_name))
                 debug.critical(msg)
                 sys.exit(1)
+        return False
 
-        def create_user_packages_dir(userpackagesname=None):
-            debug.warning('Will try to create userpackages directory')
-            if userpackagesname is None:
-                userpackagesname = os.path.join(self.temp_configuration.dotVistrails,
-                                            'userpackages')
-            if not os.path.isdir(userpackagesname):
-                try:
-                    os.mkdir(userpackagesname)
-                    self.configuration.userPackageDirectory = userpackagesname
-                    self.temp_configuration.userPackageDirectory = \
-                        userpackagesname
-                except:
-                    msg = ("""Failed to create userpackages directory: '%s'.
-                    This could be an indication of a permissions problem.
-                    Make sure directory '%s' in writable.""" %
-                           (userpackagesname,
-                            self.configuration.dotVistrails))
-                    debug.critical(msg)
-                    sys.exit(1)
-            create_user_packages_init(userpackagesname)
-                
-        def create_thumbnails_dir(thumbnails_dir=None):
-            debug.log('Will try to create thumbnails directory')
-            if thumbnails_dir is None:
-                thumbnails_dir = os.path.join(self.temp_configuration.dotVistrails,
-                                            'thumbs')
-
-            if not os.path.isdir(thumbnails_dir):
-                try:
-                    os.mkdir(thumbnails_dir)
-                    self.configuration.thumbs.cacheDirectory = thumbnails_dir
-                    self.temp_configuration.thumbs.cacheDirectory = \
-                        thumbnails_dir
-                except:
-                    msg = ("Failed to create thumbnails cache directory: '%s'.  "
-                           "This could be an indication of a permissions "
-                           "problem.  Make sure directory '%s' is writable." % \
-                               (thumbnails_dir, 
-                                self.configuration.dotVistrails))
-                    debug.critical(msg)
-                    sys.exit(1)   
-                                
-        def create_abstractions_dir(abstractions_dir=None):
-            debug.log('Will try to create subworkflows directory')
-            abstractions_dir = os.path.join(self.temp_configuration.dotVistrails,
-                                            'subworkflows')
-
-            if not os.path.isdir(abstractions_dir):
-                try:
-                    os.mkdir(abstractions_dir)
-                    self.configuration.abstractionsDirectory = abstractions_dir
-                    self.temp_configuration.abstractionsDirectory = \
-                        abstractions_dir
-                except:
-                    msg = ("Failed to create subworkflows directory: '%s'.  "
-                           "This could be an indication of a permissions "
-                           "problem.  Make sure directory '%s' is writable." % \
-                               (abstractions_dir, 
-                                self.configuration.dotVistrails))
-                    debug.critical(msg)
-                    sys.exit(1)
-#             try:
-#                 root_dir = core.system.vistrails_root_directory()
-#                 default_file = os.path.join(root_dir,'core','resources',
-#                                             'abstractions_init')
-#                 user_file = os.path.join(abstractions_dir, '__init__.py')
-#                 print 'copying', default_file, '->', abstractions_dir
-#                 shutil.copyfile(default_file, user_file)
-#                 debug.log('Succeeded!')
-#             except Exception, e:
-#                 print e
-#                 debug.critical("Failed to copy default file to abstractions "
-#                                "package.  This could be an indication of a "
-#                                "permissions problem. Make sure directory "
-#                                "'%s' is writable" % abstractions_dir)
-#                 sys.exit(1)
-
-        def install_default_startup():
-            debug.log('Will try to create default startup script')
-            try:
-                root_dir = vistrails.core.system.vistrails_root_directory()
-                default_file = os.path.join(root_dir,'core','resources',
-                                            'default_vistrails_startup')
-                user_file = os.path.join(self.temp_configuration.dotVistrails,
-                                         'startup.py')
-                shutil.copyfile(default_file,user_file)
-                debug.log('Succeeded!')
-            except:
-                debug.critical("""Failed to copy default file %s.
-                This could be an indication of a permissions problem.
-                Make sure directory '%s' is writable"""
-                % (user_file,self.temp_configuration.dotVistrails))
-                sys.exit(1)
+    def setup_directory(self, config_key, default_dir, setup_init_file=False):
+        abs_dir_name = get_vistrails_directory(config_key, 
+                                               self.temp_configuration)        
+        if abs_dir_name is not None:
+            self.create_directory(abs_dir_name)
+        if abs_dir_name is not None and setup_init_file:
+            self.setup_init_file(abs_dir_name)
+        return abs_dir_name
 
-        def install_default_startupxml_if_needed():
-            fname = os.path.join(self.temp_configuration.dotVistrails,
-                                 'startup.xml')
-            root_dir = vistrails.core.system.vistrails_root_directory() 
-            origin = os.path.join(root_dir, 'core','resources',
-                                  'default_vistrails_startup_xml')
-            def skip():
-                if os.path.isfile(fname):
-                    try:
-                        d = self.startup_dom()
-                        v = str(d.getElementsByTagName('startup')[0].attributes['version'].value)
-                        r = vistrails.core.utils.version_string_to_list(v)
-                        return r >= [0, 1]
-                    except:
-                        return False
-                else:
-                    return False
-            if skip():
-                return
-            try:
-                shutil.copyfile(origin, fname)
-                debug.log('Succeeded!')
-            except:
-                debug.critical("""Failed to copy default configuration
-                file to %s. This could be an indication of a
-                permissions problem. Please make sure '%s' is writable."""
-                               % (fname,
-                                  self.temp_configuration.dotVistrails))
+    def setup_log_file(self, abs_dir_name):
+        import vistrails.core.system
+        version = vistrails.core.system.vistrails_version()
+        version = version.replace(".", "_")
 
-        def execDotVistrails(tried_once=False):
-            """ execDotVistrails() -> None
-            Actually execute the Vistrail initialization
-            
-            """
-            # if it is file, then must move old-style .vistrails to
-            # directory.
-            if os.path.isfile(self.temp_configuration.dotVistrails):
-                debug.warning("Old-style initialization hooks. Will try to set things correctly.")
-                (fd, name) = tempfile.mkstemp()
-                os.close(fd)
-                try:
-                    shutil.copyfile(self.temp_configuration.dotVistrails, name)
-                    try:
-                        os.unlink(self.temp_configuration.dotVistrails)
-                    except:
-                        debug.critical("""Failed to remove old initialization file.
-                        This could be an indication of a permissions problem.
-                        Make sure file '%s' is writable."""
-                        % self.temp_configuration.dotVistrails)
-                        sys.exit(1)
-                    self.create_default_directory()
-                    try:
-                        destiny = os.path.join(self.temp_configuration.dotVistrails,
-                                               'startup.py')
-                        shutil.copyfile(name, destiny)
-                    except:
-                        debug.critical("""Failed to copy old initialization file to
-                        newly-created initialization directory. This must have been
-                        a race condition. Please remove '%s' and
-                        restart VisTrails."""
-                        % self.temp_configuration.dotVistrails)
-                        sys.exit(1)
-                    debug.critical("Successful move!")
-                finally:
-                    try:
-                        os.unlink(name)
-                    except:
-                        debug.warning("Failed to erase temporary file.")
-
-            if os.path.isdir(self.temp_configuration.dotVistrails):
-                if self.temp_configuration.check('userPackageDirectory'):
-                    userpackages = self.temp_configuration.userPackageDirectory
-                else:
-                    userpackages = os.path.join(self.temp_configuration.dotVistrails,
-                                            'userpackages')
-                startup = os.path.join(self.temp_configuration.dotVistrails,
-                                       'startup.py')
-                if self.temp_configuration.check('abstractionsDirectory'):
-                    abstractions = self.temp_configuration.abstractionsDirectory
-                else:
-                    abstractions = os.path.join(self.temp_configuration.dotVistrails,
-                                            'subworkflows')
-                if (self.temp_configuration.has('thumbs') and
-                    self.temp_configuration.thumbs.check('cacheDirectory')):
-                    thumbnails = self.temp_configuration.thumbs.cacheDirectory
-                else:
-                    thumbnails = os.path.join(self.temp_configuration.dotVistrails,
-                                          'thumbs')
-                if not os.path.isdir(userpackages):
-                    create_user_packages_dir(userpackages)
-                if not os.path.isfile(os.path.join(userpackages, 
-                                                   '__init__.py')):
-                    create_user_packages_init(userpackages)
-                if not os.path.isdir(abstractions):
-                    create_abstractions_dir(abstractions)
-                if not os.path.isdir(thumbnails):
-                    create_thumbnails_dir(thumbnails)
-                try:
-                    
-                    dotVistrails = open(startup)
-                    g = {}
-                    localsDir = {'configuration': self.temp_configuration,
-                                 'addStartupHook': addStartupHook,
-                                 'addPackage': addPackage}
-                    old_path = copy.copy(sys.path)
-                    sys.path.append(self.temp_configuration.dotVistrails)
-                    exec dotVistrails in localsDir
-                    sys.path = old_path
-                    del localsDir['addPackage']
-                    del localsDir['addStartupHook']
-                    return localsDir
-                except IOError:
-                    if tried_once:
-                        debug.critical("""Still cannot find default file.
-                        Something has gone wrong. Please make sure ~/.vistrails
-                        exists, is writable, and ~/.vistrails/startup.py does
-                        not exist.""")
-                        sys.exit(1)
-                    debug.critical('%s not found' % startup)
-                    debug.critical('Will try to install default '
-                                              'startup file')
-                    install_default_startup()
-                    install_default_startupxml_if_needed()
-                    return execDotVistrails(True)
-            elif not os.path.lexists(self.temp_configuration.dotVistrails):
-                debug.log('%s not found' % self.temp_configuration.dotVistrails)
-                self.create_default_directory()
-                create_user_packages_dir()
-                create_abstractions_dir()
-                create_thumbnails_dir()
-                install_default_startup()
-                install_default_startupxml_if_needed()
-                return execDotVistrails(True)
-
-        #install_default_startupxml_if_needed()
-        # Now execute the dot vistrails
-        return execDotVistrails()
-
-    def setupDefaultFolders(self):
-        """ setupDefaultFolders() -> None        
-        Give default values to folders when there are no values specified
-        
-        """
-        if self.temp_configuration.has('rootDirectory'):
-            system.set_vistrails_root_directory(self.temp_configuration.rootDirectory)
-        if self.temp_configuration.has('dataDirectory'):
-            system.set_vistrails_data_directory( \
-                self.temp_configuration.dataDirectory)
-        if self.temp_configuration.has('fileDirectory'):
-            system.set_vistrails_file_directory( \
-                self.temp_configuration.fileDirectory)
-        if (self.temp_configuration.has('verbosenessLevel') and
-            self.temp_configuration.verbosenessLevel != -1):
-            verbose = self.temp_configuration.verbosenessLevel
+        if self.temp_configuration.errorLog:
+            log_fname = os.path.join(abs_dir_name, 'vistrails_%s.log' % version)
+            if log_fname is not None:
+                debug.DebugPrint.getInstance().set_logfile(log_fname)
+
+    def setup_debug(self):
+        if (self.temp_configuration.has('debugLevel') and
+            self.temp_configuration.debugLevel != -1):
+            verbose = self.temp_configuration.debugLevel
             if verbose < 0:
                 msg = ("""Don't know how to set verboseness level to %s - "
                        "setting to the lowest one I know of: 0""" % verbose)
                 debug.critical(msg)
-                verbose = 0
+                verbose = self.temp_configuration.debugLevel = 0
             if verbose > 2:
                 msg = ("""Don't know how to set verboseness level to %s - "
                        "setting to the highest one I know of: 2""" % verbose)
                 debug.critical(msg)
-                verbose = 2
+                verbose = self.temp_configuration.debugLevel = 2
             dbg = debug.DebugPrint.getInstance()
             levels = [dbg.WARNING, dbg.INFO, dbg.DEBUG]
             dbg.set_message_level(levels[verbose])
             debug.log("Set verboseness level to %s" % verbose)
-        
-        #these checks may need to update the persistent configuration, so
-        # we have to change both objects
-        #userpackages directory
-        if not self.temp_configuration.check('userPackageDirectory'):
-            s = os.path.join(self.temp_configuration.dotVistrails,
-                             'userpackages')
-            self.temp_configuration.userPackageDirectory = s
-        if not self.configuration.check('userPackageDirectory'):
-            s = os.path.join(self.configuration.dotVistrails,
-                             'userpackages')
-            self.configuration.userPackageDirectory = s
-        #abstractions directory    
-        if not self.temp_configuration.check('abstractionsDirectory') or \
-                self.temp_configuration.abstractionsDirectory == \
-                os.path.join(self.temp_configuration.userPackageDirectory, 
-                             'abstractions'):
-            s = os.path.join(self.temp_configuration.dotVistrails,
-                             'subworkflows')
-            self.temp_configuration.abstractionsDirectory = s
-        if not self.configuration.check('abstractionsDirectory') or \
-                self.configuration.abstractionsDirectory == \
-                os.path.join(self.configuration.userPackageDirectory, 
-                             'abstractions'):
-            s = os.path.join(self.configuration.dotVistrails,
-                             'subworkflows')
-            self.configuration.abstractionsDirectory = s
-        #thumbnails directory    
-        if self.temp_configuration.has('thumbs'):
-            if not self.temp_configuration.thumbs.check('cacheDirectory'):
-                s = os.path.join(self.temp_configuration.dotVistrails,'thumbs')
-                self.temp_configuration.thumbs.cacheDirectory = s
-        if self.configuration.has('thumbs'):
-            if not self.configuration.thumbs.check('cacheDirectory'):
-                s = os.path.join(self.configuration.dotVistrails, 'thumbs')
-                self.configuration.thumbs.cacheDirectory = s
-        
-    def setupLogFile(self):
-        def get_version():
-            import vistrails.core.system
-            version = vistrails.core.system.vistrails_version()
-            return version.replace(".","_")
-        #To make sure we always save a log file name according to the
-        #current version, we will only consider the directory stored in
-        # logFile and append a name with the correct version encoded. 
-        if not self.temp_configuration.check('logFile'):
-            s = os.path.join(self.temp_configuration.dotVistrails,
-                             'vistrails_%s.log'%(get_version()))
-            self.temp_configuration.logFile = s
-        else:
-            dirname = os.path.dirname(self.temp_configuration.logFile)
-            self.temp_configuration.logFile = os.path.join(dirname,
-                                        'vistrails_%s.log'%(get_version()))
-        if not self.configuration.check('logFile'):
-            # if this was not set before, it should point to the
-            # value in temp_configuration
-            s = os.path.join(self.temp_configuration.dotVistrails,
-                             'vistrails_%s.log'%(get_version()))
-            self.configuration.logFile = s
+
+
+    def setup_dot_vistrails(self):
+        for i, args in enumerate(self.DIRECTORIES):
+            abs_dir_name = self.setup_directory(*args)
+            # Brittle, know that log directory is first
+            if i == 0:
+                self.setup_log_file(abs_dir_name)
+        self.setup_debug()
+
+    def create_dot_vistrails_if_necessary(self):
+        if os.path.exists(self._dot_vistrails):
+            if not os.path.isdir(self._dot_vistrails):
+                raise ValueError('The .vistrails directory cannot be used or '
+                                 'created because the specified path "%s" is '
+                                 'a file not a directory.' % 
+                                 self._dot_vistrails)
+            else:
+                return
+
+        debug.log('Will try to create default directory')
+        try:
+            os.mkdir(self._dot_vistrails)
+            debug.log('Succeeded!')
+        except:
+            debug.critical("""Failed to create initialization directory.
+                    This could be an indication of a permissions problem.
+                    Make sure parent directory of '%s' is writable."""
+                    % self._dot_vistrails)
+            raise
+
+    def update_packages(self):
+        # make sure basic_modules and abstraction are enabled
+        self.set_package_to_enabled('basic_modules')
+        self.set_package_to_enabled('abstraction')
+        self.enabled_packages['basic_modules'].prefix = \
+                                            "vistrails.core.modules."
+        self.enabled_packages['abstraction'].prefix = \
+                                            "vistrails.core.modules."
+
+    def load_persisted_startup(self):
+        if self._dot_vistrails is not None:
+            fname = self.get_startup_xml_fname()
+            other = vistrails.core.db.io.load_startup(fname)
+            self.configuration.update(other.configuration)
+            self.db_enabled_packages = copy.copy(other.db_enabled_packages)
+            self.db_disabled_packages = copy.copy(other.db_disabled_packages)
+
+    def save_persisted_startup(self):
+        if self._dot_vistrails is not None:
+            fname = self.get_startup_xml_fname()
+            vistrails.core.db.io.save_startup(self, fname)
+
+    def get_pkg_startup_info(self, codepath):
+        if codepath in self.enabled_packages:
+            return self.enabled_packages[codepath]
+        elif codepath in self.disabled_packages:
+            return self.disabled_packages[codepath]
+        return None
+
+    def get_pkg_configuration(self, codepath):
+        startup_info = self.get_pkg_startup_info(codepath)
+        if startup_info is not None:
+            return startup_info.configuration
+        return None
+
+    def persist_pkg_configuration(self, codepath, config):
+        startup_info = self.get_pkg_startup_info(codepath)
+        if startup_info is not None:
+            startup_info.configuration = config
         else:
-            dirname = os.path.dirname(self.configuration.logFile)
-            self.configuration.logFile = os.path.join(dirname,
-                                        'vistrails_%s.log'%(get_version()))
-        if not os.path.lexists(self.temp_configuration.dotVistrails):
-            self.create_default_directory()
-        if self.configuration.check('nologfile'):
-            debug.DebugPrint.getInstance().set_logfile(None)
+            startup_info = StartupPackage(name=codepath,
+                                          configuration=config)
+            self.db_disabled_packages.db_add_package(startup_info)
+        self.save_persisted_startup()
+
+    def set_package_enabled(self, codepath, enabled=True):
+        package = None
+        was_enabled = False
+        was_disabled = False
+        if codepath in self.enabled_packages:
+            package = self.enabled_packages[codepath]
+            was_enabled = True
+        if codepath in self.disabled_packages:
+            if package is None:
+                package = self.disabled_packages[codepath]
+            was_disabled = True
+        if package is None:
+            package = StartupPackage(name=codepath)
+
+        def update_package_list(update_obj):
+            # this is a kludge since the db code doesn't support non-keyed
+            # deletion and name isn't a key right now
+            # FIXME may cause issues with relational storage
+            old_packages = update_obj.db_packages
+            update_obj.db_packages = []
+            update_obj.db_packages_name_index = {}
+            for p in old_packages:
+                if p.name != codepath:
+                    update_obj.db_add_package(p)
+            
+        if was_enabled:
+            update_package_list(self.db_enabled_packages)
+        if was_disabled:
+            update_package_list(self.db_disabled_packages)
+
+        if enabled:
+            self.db_enabled_packages.db_add_package(package)
         else:
-            debug.DebugPrint.getInstance().set_logfile(self.temp_configuration.logFile)
-        
-    def setupBaseModules(self):
-        """ setupBaseModules() -> None        
-        Import basic modules for self-registration. The import here is
-        on purpose, not a typo against the coding rule
+            self.db_disabled_packages.db_add_package(package)
+
+    def set_package_to_enabled(self, codepath):
+        self.set_package_enabled(codepath, True)
+
+    def set_package_to_disabled(self, codepath):
+        self.set_package_enabled(codepath, False)
+
+    def create_startupxml_if_needed(self):
+        needs_create = True
+        fname = self.get_startup_xml_fname()
+        if os.path.isfile(fname):
+            try:
+                tree = ElementTree.parse(fname)
+                startup_version = \
+                    vistrails.db.services.io.get_version_for_xml(tree.getroot())
+                version_list = version_string_to_list(startup_version)
+                if version_list >= [0,1]:
+                    needs_create = False
+            except:
+                debug.warning("Unable to read startup.xml file, "
+                              "creating a new one")
+
+        if needs_create:
+            root_dir = system.vistrails_root_directory()
+            origin = os.path.join(root_dir, 'core','resources',
+                                  'default_vistrails_startup_xml')
+            try:
+                shutil.copyfile(origin, fname)
+                debug.log('Succeeded!')
+                self.first_run = True
+            except:
+                debug.critical("""Failed to copy default configuration
+                file to %s. This could be an indication of a
+                permissions problem. Please make sure '%s' is writable."""
+                               % (fname, self._dot_vistrails))
+                raise
+
+import unittest
+import stat
+
+class TestStartup(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # Mock DebugPrint#set_logfile()
+        def set_logfile(self, filename):
+            cls._log_filename = filename
+        cls._old_debugprint_set_logfile = debug.DebugPrint.set_logfile
+        debug.DebugPrint.set_logfile = set_logfile
+
+    @classmethod
+    def tearDownClass(cls):
+        # Un-mock DebugPrint#set_logfile()
+        debug.DebugPrint.set_logfile = cls._old_debugprint_set_logfile
+
+    def check_structure(self, dir_name):
+        self.assertTrue(os.path.isdir(dir_name))
+        self.assertTrue(os.path.isfile(os.path.join(dir_name, 
+                                                    'startup.xml')))
+        for t in VistrailsStartup.DIRECTORIES:
+            a_dir = os.path.join(dir_name, t[1])
+            self.assertTrue(os.path.isdir(a_dir),
+                            'Directory "%s" does not exist' % a_dir)
+            if t[2]:
+                self.assertTrue(os.path.isfile(os.path.join(a_dir, 
+                                                            '__init__.py')))
+
+        import vistrails.core.system
+        version = vistrails.core.system.vistrails_version()
+        version = version.replace(".", "_")
+        self.assertEqual(
+                self._log_filename,
+                os.path.join(dir_name, 'logs', 'vistrails_%s.log' % version))
+
+    def test_simple_create(self):
+        dir_name = tempfile.mkdtemp()
+        options_config = ConfigurationObject(dotVistrails=dir_name)
+        try:
+            startup = VistrailsStartup(options_config, None)
+            self.check_structure(dir_name)
+        finally:
+            shutil.rmtree(dir_name)
+
+    def test_create_dir_create(self):
+        outer_dir_name = tempfile.mkdtemp()
+        dir_name = os.path.join(outer_dir_name, '.vistrails')
+        cl_config = ConfigurationObject(dotVistrails=dir_name)
+        try:
+            startup = VistrailsStartup(None, cl_config)
+            self.check_structure(dir_name)
+        finally:
+            shutil.rmtree(outer_dir_name)
         
-        """
-        import vistrails.core.modules.vistrails_module
-        import vistrails.core.modules.basic_modules
-        import vistrails.core.modules.sub_module
+    def test_config_override(self):
+        dir_name = tempfile.mkdtemp()
+        user_pkg_dir = tempfile.mkdtemp()
+        abstractions_dir = tempfile.mkdtemp()
+        thumbs_dir = tempfile.mkdtemp()
+        log_dir = tempfile.mkdtemp()
+        config = vistrails.core.configuration.default()
+        config.dotVistrails = dir_name
+        config.userPackageDir = user_pkg_dir
+        config.subworkflowsDir= abstractions_dir
+        config.thumbs.cacheDir = thumbs_dir
+        config.logDir = log_dir
+        try:
+            startup = VistrailsStartup(config, None)
+            self.assertTrue(os.path.isfile(os.path.join(dir_name, 
+                                                        'startup.xml')))
+            for t in VistrailsStartup.DIRECTORIES:
+                a_dir = os.path.join(dir_name, t[1])
+                self.assertFalse(os.path.isdir(a_dir),
+                                'Directory "%s" exists' % a_dir)
+        finally:
+            shutil.rmtree(dir_name)
+            shutil.rmtree(user_pkg_dir)
+            shutil.rmtree(abstractions_dir)
+            shutil.rmtree(thumbs_dir)
+            shutil.rmtree(log_dir)
 
-    def installPackages(self):
-        """ installPackages() -> None
-        Scheme through packages directory and initialize them all
-        """
-        # Imports standard packages directory
-        self._package_manager.initialize_packages(self._package_dictionary)
-
-        # Enable abstractions
-        import vistrails.core.modules.abstraction
-        abstraction_pkg = "abstraction"
-        abstraction_dict = {abstraction_pkg: 'vistrails.core.modules.'}
-        self._package_manager.initialize_abstraction_pkg(abstraction_dict)
-
-    def runStartupHooks(self):
-        """ runStartupHooks() -> None
-        After initialization, need to run all start up hooks registered
+    def test_config_override_create(self):
+        dir_name = tempfile.mkdtemp()
+        outer_user_pkg_dir = tempfile.mkdtemp()
+        user_pkg_dir = os.path.join(outer_user_pkg_dir, 'userpackages')
+        outer_abstractions_dir = tempfile.mkdtemp()
+        abstractions_dir = os.path.join(outer_abstractions_dir, 'subworkflows')
+        outer_thumbs_dir = tempfile.mkdtemp()
+        thumbs_dir = os.path.join(outer_thumbs_dir, 'thumbs')
+        outer_log_dir = tempfile.mkdtemp()
+        log_dir = os.path.join(outer_log_dir, 'logs')
+        config = vistrails.core.configuration.default()
+        config.dotVistrails = dir_name
+        config.userPackageDir = user_pkg_dir
+        config.subworkflowsDir = abstractions_dir
+        config.thumbs.cacheDir = thumbs_dir
+        config.logDir = log_dir
+        try:
+            startup = VistrailsStartup(config, None)
+            self.assertTrue(os.path.isfile(os.path.join(dir_name, 
+                                                        'startup.xml')))
+            for t in VistrailsStartup.DIRECTORIES:
+                a_dir = os.path.join(dir_name, t[1])
+                self.assertFalse(os.path.isdir(a_dir),
+                                'Directory "%s" exists' % a_dir)
+            self.assertTrue(os.path.isdir(user_pkg_dir))
+            self.assertTrue(os.path.isdir(abstractions_dir))
+            self.assertTrue(os.path.isdir(thumbs_dir))
+            self.assertTrue(os.path.isdir(log_dir))
+        finally:
+            shutil.rmtree(dir_name)
+            shutil.rmtree(outer_user_pkg_dir)
+            shutil.rmtree(outer_abstractions_dir)
+            shutil.rmtree(outer_thumbs_dir)
+            shutil.rmtree(outer_log_dir)
+    
+    def test_default_startup_xml(self):
+        dir_name = tempfile.mkdtemp()
+        config = ConfigurationObject(dotVistrails=dir_name)
+        try:
+            startup = VistrailsStartup(config, None)
+            self.assertTrue(startup.configuration.executionLog)
+            self.assertTrue(startup.configuration.autoSave)
+            self.assertTrue(startup.temp_configuration.autoSave)
+        finally:
+            shutil.rmtree(dir_name)
+
+    def test_cannot_create(self):
+        (fd, fname) = tempfile.mkstemp()
+        os.close(fd)
+        config = ConfigurationObject(dotVistrails=fname)
+        try:
+            with self.assertRaises(ValueError):
+                startup = VistrailsStartup(config, None)
+        finally:
+            os.unlink(fname)
         
-        """
-        for hook in self.startupHooks:
-            try:
-                hook()
-            except Exception, e:
-                debug.critical("Exception raised during hook: %s - %s" %
-                             (e.__class__, e))
+    def test_permissions(self):
+        if systemType in ['Windows', 'Microsoft']:
+            self.skipTest("chmod on Windows is limited")
+        dir_name = tempfile.mkdtemp()
+        config = ConfigurationObject(dotVistrails=dir_name)
+        try:
+            os.chmod(dir_name, stat.S_IRUSR)
+            with self.assertRaises(IOError):
+                startup = VistrailsStartup(config, None)
+        finally:
+            os.chmod(dir_name, stat.S_IRWXU)
+            shutil.rmtree(dir_name)
 
-    def destroy(self):
-        """ destroy() -> None
-        Finalize all packages to, such as, get rid of temp files
+    def test_load_old_startup_xml(self):
+        # has old nested shell settings that don't match current naming
+        startup_tmpl = os.path.join(system.vistrails_root_directory(),
+                                    'tests', 'resources',
+                                    'startup-0.1.xml.tmpl')
+        f = open(startup_tmpl, 'r')
+        template = string.Template(f.read())
         
-        """
-        self._package_manager.finalize_packages()
+        startup_dir = tempfile.mkdtemp(prefix="vt_startup")
+        old_startup_fname = os.path.join(startup_dir, "startup.xml")
+        with open(old_startup_fname, 'w') as f:
+            f.write(template.substitute({'startup_dir': startup_dir}))
 
-    def set_registry(self, registry_filename=None):
-        if registry_filename is not None:
-            self._do_load_packages = False
-        self._package_manager.init_registry(registry_filename)
-            
+        startup1 = vistrails.core.db.io.load_startup(old_startup_fname)
+
+        (h, fname) = tempfile.mkstemp(suffix=".xml")
+        os.close(h)
+        try:
+            vistrails.core.db.io.save_startup(startup1, fname)
+            startup2 = vistrails.core.db.io.load_startup(fname)
+            self.assertEqual(startup1, startup2)
+        finally:
+            os.remove(fname)
+            shutil.rmtree(startup_dir)
+
+    # def test_load_packages(self):
+    #     from vistrails.core.system import default_dot_vistrails
+    #     dir_name = default_dot_vistrails()
+    #     config = ConfigurationObject(dotVistrails=dir_name)
+    #     startup = VistrailsStartup(config, None)
+        
+        
+if __name__ == '__main__':
+    unittest.main()
diff --git a/vistrails/core/system/__init__.py b/vistrails/core/system/__init__.py
index 7099165..7283f42 100644
--- a/vistrails/core/system/__init__.py
+++ b/vistrails/core/system/__init__.py
@@ -1,105 +1,116 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from __future__ import with_statement
+from __future__ import division, with_statement
 
 import datetime
-import getpass
+import functools
+import locale
 import os
-import os.path
-import subprocess
-import sys
 import platform
-import socket
+import sys
+import time
 import urllib2
+import warnings
+
 from vistrails.core import debug
-from vistrails.core.utils import unimplemented, VistrailsInternalError, Chdir
+from vistrails.core.utils import unimplemented, VistrailsDeprecation, Chdir
 
-import unittest
+
+###############################################################################
+
+from common import *
+
+def with_c_locale(func):
+    @functools.wraps(func)
+    def newfunc(*args, **kwargs):
+        previous_locale = locale.setlocale(locale.LC_TIME)
+        locale.setlocale(locale.LC_TIME, 'C')
+        try:
+            return func(*args, **kwargs)
+        finally:
+            locale.setlocale(locale.LC_TIME, previous_locale)
+    return newfunc
+
+ at with_c_locale
+def strptime(*args, **kwargs):
+    """Version of datetime.strptime that always uses the C locale.
+
+    This is because date strings are used internally in the database, and
+    should not be localized.
+    """
+    return datetime.datetime.strptime(*args, **kwargs)
+
+ at with_c_locale
+def time_strptime(*args, **kwargs):
+    """Version of time.strptime that always uses the C locale.
+
+    This is because date strings are used internally in the database, and
+    should not be localized.
+    """
+    return time.strptime(*args, **kwargs)
+
+ at with_c_locale
+def strftime(dt, *args, **kwargs):
+    """Version of datetime.strftime that always uses the C locale.
+
+    This is because date strings are used internally in the database, and
+    should not be localized.
+    """
+    if hasattr(dt, 'strftime'):
+        return dt.strftime(*args, **kwargs)
+    else:
+        return time.strftime(dt, *args, **kwargs)
 
 ##############################################################################
 
 systemType = platform.system()
 
 if systemType in ['Windows', 'Microsoft']:
-    from vistrails.core.system.windows import guess_total_memory, temporary_directory, \
-        list2cmdline, \
-        home_directory, remote_copy_program, remote_shell_program, \
-        graph_viz_dot_command_line, remove_graph_viz_temporaries, \
-        link_or_copy,executable_is_in_path, executable_is_in_pythonpath, \
-        execute_cmdline, get_executable_path, execute_piped_cmdlines, TestWindows
+    from vistrails.core.system.windows import *
 
 elif systemType in ['Linux']:
-    from vistrails.core.system.linux import guess_total_memory, temporary_directory, \
-        list2cmdline, \
-        home_directory, remote_copy_program, remote_shell_program, \
-        graph_viz_dot_command_line, remove_graph_viz_temporaries, \
-        link_or_copy, XDestroyWindow, executable_is_in_path, \
-        executable_is_in_pythonpath, execute_cmdline, get_executable_path, \
-        execute_piped_cmdlines, TestLinux
+    from vistrails.core.system.linux import *
 
 elif systemType in ['Darwin']:
-    from vistrails.core.system.osx import guess_total_memory, temporary_directory, \
-        list2cmdline, \
-        home_directory, remote_copy_program, remote_shell_program, \
-        graph_viz_dot_command_line, remove_graph_viz_temporaries, \
-        link_or_copy, executable_is_in_path, executable_is_in_pythonpath, \
-        execute_cmdline, get_executable_path, execute_piped_cmdlines, TestMacOSX
+    from vistrails.core.system.osx import *
 else:
     debug.critical("VisTrails could not detect your operating system.")
     sys.exit(1)
 
-def touch(file_name):
-    """touch(file_name) -> None Equivalent to 'touch' in a shell. If
-    file exists, updates modified time to current time. If not,
-    creates a new 0-length file.
-    
-    """
-    if os.path.isfile(file_name):
-        os.utime(file_name, None)
-    else:
-        open(file_name, 'w')
-
-def mkdir(dir_name):
-    """mkdir(dir_name) -> None Equivalent to 'mkdir' in a shell except
-    that if the directory exists, it will not be overwritten.
-
-    """
-    if not os.path.isdir(dir_name):
-        os.mkdir(dir_name)
-
-##############################################################################
+###############################################################################
 
 # Makes sure root directory is sensible.
 if __name__ == '__main__':
@@ -125,16 +136,35 @@ __examplesDir = __fileDir
 
 __defaultFileType = '.vt'
 
-__defaultPkgPrefix = 'org.vistrails.vistrails'
+_defaultPkgPrefix = 'org.vistrails.vistrails'
 
 def get_vistrails_default_pkg_prefix():
-    return __defaultPkgPrefix
+    """Gets the namespace under which identifiers of builtin packages live.
+
+    You should *not* use this, it is only useful intended to expand short names
+    of builtin packages in parse_descriptor_string.
+    """
+    warnings.warn("get_vistrails_default_pkg_prefix() is deprecated",
+                  category=VistrailsDeprecation)
+    return _defaultPkgPrefix
 
 def get_vistrails_basic_pkg_id():
-    return "%s.basic" % get_vistrails_default_pkg_prefix()
+    return "%s.basic" % _defaultPkgPrefix
+
+def get_vistrails_directory(config_key, conf=None):
+    if conf is None:
+        from vistrails.core.configuration import get_vistrails_configuration
+        conf = get_vistrails_configuration()
+    if conf.has_deep_value(config_key):
+        d = conf.get_deep_value(config_key)
+        if os.path.isabs(d):
+            return d
+        else:
+            return os.path.join(current_dot_vistrails(conf), d)
+    return None
 
 def set_vistrails_data_directory(d):
-    """ set_vistrails_data_directory(d:str) -> None 
+    """ set_vistrails_data_directory(d:str) -> None
     Sets vistrails data directory taking into account environment variables
 
     """
@@ -149,7 +179,7 @@ def set_vistrails_data_directory(d):
 def set_vistrails_file_directory(d):
     """ set_vistrails_file_directory(d: str) -> None
     Sets vistrails file directory taking into accoun environment variables
-    
+
     """
     global __fileDir
     new_d = os.path.expanduser(d)
@@ -160,7 +190,7 @@ def set_vistrails_file_directory(d):
     __fileDir = os.path.realpath(d)
 
 def set_vistrails_root_directory(d):
-    """ set_vistrails_root_directory(d:str) -> None 
+    """ set_vistrails_root_directory(d:str) -> None
     Sets vistrails root directory taking into account environment variables
 
     """
@@ -183,7 +213,7 @@ def set_vistrails_default_file_type(t):
         __defaultFileType = t
     else:
         __defaultFileType = '.vt'
-        
+
 def vistrails_root_directory():
     """ vistrails_root_directory() -> str
     Returns vistrails root directory
@@ -206,7 +236,7 @@ def vistrails_examples_directory():
     return __examplesDir
 
 def vistrails_data_directory():
-    """ vistrails_data_directory() -> str 
+    """ vistrails_data_directory() -> str
     Returns vistrails data directory
 
     """
@@ -220,7 +250,7 @@ def vistrails_default_file_type():
     return __defaultFileType
 
 def packages_directory():
-    """ packages_directory() -> str 
+    """ packages_directory() -> str
     Returns vistrails packages directory
 
     """
@@ -230,7 +260,7 @@ def blank_vistrail_file():
     unimplemented()
 
 def resource_directory():
-    """ resource_directory() -> str 
+    """ resource_directory() -> str
     Returns vistrails gui resource directory
 
     """
@@ -238,26 +268,28 @@ def resource_directory():
                         'gui', 'resources')
 
 def default_options_file():
-    """ default_options_file() -> str 
+    """ default_options_file() -> str
     Returns vistrails default options file
 
     """
     return os.path.join(home_directory(), ".vistrailsrc")
 
 def default_dot_vistrails():
-    """ default_dot_vistrails() -> str 
+    """ default_dot_vistrails() -> str
     Returns the default VisTrails per-user directory.
 
     """
     return os.path.join(home_directory(), '.vistrails')
 
-def current_dot_vistrails():
+def current_dot_vistrails(conf=None):
     """ current_dot_vistrails() -> str
     Returns the VisTrails per-user directory.
 
     """
-    from vistrails.core.configuration import get_vistrails_configuration
-    return get_vistrails_configuration().dotVistrails
+    if conf is None:
+        from vistrails.core.configuration import get_vistrails_configuration
+        conf = get_vistrails_configuration()
+    return conf.dotVistrails
 
 def default_connections_file():
     """ default_connections_file() -> str
@@ -266,11 +298,7 @@ def default_connections_file():
     """
     return os.path.join(current_dot_vistrails(), 'connections.xml')
 
-def python_version():
-    """python_version() -> (major, minor, micro, release, serial)
-    Returns python version info."""
-    return sys.version_info
-
+VERSION = '2.2'
 def vistrails_version():
     """vistrails_version() -> string - Returns the current VisTrails version."""
     # 0.1 was the Vis2005 version
@@ -278,7 +306,7 @@ def vistrails_version():
     # 0.3 was the plugin/vtk version
     # 0.4 is cleaned up version with new GUI
     # 1.0 is version with new schema
-    return '2.1.4'
+    return VERSION
 
 def get_latest_vistrails_version():
     """get_latest_vistrails_version() -> string - Returns latest vistrails
@@ -317,76 +345,44 @@ def new_vistrails_release_exists():
     return (False, None)
 
 def vistrails_revision():
-    """vistrails_revision() -> str 
+    """vistrails_revision() -> str
     When run on a working copy, shows the current svn revision else
     shows the latest release revision
 
     """
     git_dir = os.path.join(vistrails_root_directory(), '..')
     with Chdir(git_dir):
-        release = "269e4808eca3"
+        release = vistrails_version()
         import vistrails.core.requirements
         if vistrails.core.requirements.executable_file_exists('git'):
             lines = []
-            result = execute_cmdline(['git', 'describe', '--always', '--abbrev=12'],
-                                     lines)
+            result = execute_cmdline(
+                ['git', 'describe', '--always'],
+                lines)
             if len(lines) == 1:
                 if result == 0:
                     release = lines[0].strip(" \n")
     return release
 
-def current_user():
-    return getpass.getuser()
 
-def current_ip():
-    """ current_ip() -> str
-    Gets current IP address trying to avoid the IPv6 interface """
-    try:
-        info = socket.getaddrinfo(socket.gethostname(), None)
-        # Try to find an IPv4
-        for i in info:
-            if i[0] == socket.AF_INET:
-                return i[4][0]
-        # Return any address
-        for i in info:
-            if i[0] in (socket.AF_INET, socket.AF_INET6):
-                return i[4][0]
-    except:
-        return ''
-
-def current_time():
-    """current_time() -> datetime.datetime
-    Returns the current time
-
-    """
-    # FIXME should use DB if available...
-    return datetime.datetime.now()
-
-def current_machine():
-    return socket.getfqdn()
-
-def current_architecture():
-    bit_string = platform.architecture()[0]
-    if bit_string.endswith('bit'):
-        return int(bit_string[:-3])
-    else:
-        return 32 # default value
-
-def current_processor():
-    proc = platform.processor()
-    if not proc:
-        proc = 'n/a'
-    return proc
+_registry = None
+def get_module_registry():
+    global _registry
+    if _registry is None:
+        from vistrails.core.modules.module_registry import get_module_registry
+        _registry = get_module_registry()
+    return _registry
 
 def short_about_string():
-    return """VisTrails version %s.%s -- contact at vistrails.org""" % \
+    return """VisTrails version %s (%s) -- contact at vistrails.org""" % \
             (vistrails_version(), vistrails_revision())
 
 def about_string():
     """about_string() -> string - Returns the about string for VisTrails."""
-    return """VisTrails version %s.%s -- contact at vistrails.org
+    return """VisTrails version %s (%s) -- contact at vistrails.org
 
-Copyright (C) 2011-2014 NYU-Poly. Copyright (C) 2006-2011 University of Utah. 
+Copyright (C) 2014-2015 New York University. Copyright (C) 2011-2014 NYU-Poly.
+Copyright (C) 2006-2011 University of Utah.
 All rights reserved.
 http://www.vistrails.org
 
@@ -397,34 +393,25 @@ modification, are permitted provided that the following conditions are met:
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
-    * Neither the name of the University of Utah nor the
+    * Neither the name of the New York University nor the
       names of its contributors may be used to endorse or promote products
       derived from this software without specific prior written permission.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" \
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \
-ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, \
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING \
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.""" % (vistrails_version(), 
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.""" % (vistrails_version(),
                                                          vistrails_revision())
 
-def get_elementtree_library():
-    try:
-        import cElementTree as ElementTree
-    except ImportError:
-        # try python 2.5-style
-        import xml.etree.cElementTree as ElementTree
-    return ElementTree
-    
-def execute_cmdline2(cmd_list):
-    return execute_piped_cmdlines([cmd_list])
-
-################################################################################
+###############################################################################
 
+import unittest
 
 if __name__ == '__main__':
     unittest.main()
@@ -440,14 +427,12 @@ class TestSystem(unittest.TestCase):
                     self.assertEquals(v1, vistrails_revision())
             except AssertionError:
                 raise
-            except:
+            except Exception:
                 pass
             try:
                 with Chdir(os.path.join(r, '..', '..')):
                     self.assertEquals(v1, vistrails_revision())
             except AssertionError:
                 raise
-            except:
+            except Exception:
                 pass
-            
-            
diff --git a/vistrails/core/system/common.py b/vistrails/core/system/common.py
new file mode 100644
index 0000000..c3e3f02
--- /dev/null
+++ b/vistrails/core/system/common.py
@@ -0,0 +1,139 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+import os
+import sys
+import getpass
+import socket
+import datetime
+import platform
+import tempfile
+import warnings
+
+from vistrails.core import debug
+from vistrails.core.utils import VistrailsDeprecation
+
+
+__all__ = ['touch', 'mkdir', 'python_version',
+           'current_user', 'current_ip', 'current_time',
+           'current_machine', 'current_architecture', 'current_processor',
+           'get_elementtree_library', 'temporary_directory']
+
+###############################################################################
+
+def touch(file_name):
+    """touch(file_name) -> None Equivalent to 'touch' in a shell. If
+    file exists, updates modified time to current time. If not,
+    creates a new 0-length file.
+
+    """
+    if os.path.isfile(file_name):
+        os.utime(file_name, None)
+    else:
+        open(file_name, 'w')
+
+def mkdir(dir_name):
+    """mkdir(dir_name) -> None Equivalent to 'mkdir' in a shell except
+    that if the directory exists, it will not be overwritten.
+
+    """
+    if not os.path.isdir(dir_name):
+        os.mkdir(dir_name)
+
+def python_version():
+    """python_version() -> (major, minor, micro, release, serial)
+    Returns python version info."""
+    return sys.version_info
+
+def current_user():
+    return getpass.getuser()
+
+def current_ip():
+    """ current_ip() -> str
+    Gets current IP address trying to avoid the IPv6 interface """
+    try:
+        info = socket.getaddrinfo(socket.gethostname(), None)
+        # Try to find an IPv4
+        for i in info:
+            if i[0] == socket.AF_INET:
+                return i[4][0]
+        # Return any address
+        for i in info:
+            if i[0] in (socket.AF_INET, socket.AF_INET6):
+                return i[4][0]
+    except Exception, e:
+        debug.unexpected_exception(e)
+        return ''
+
+def current_time():
+    """current_time() -> datetime.datetime
+    Returns the current time
+
+    """
+    # FIXME should use DB if available...
+    return datetime.datetime.now()
+
+def current_machine():
+    return socket.getfqdn()
+
+def current_architecture():
+    bit_string = platform.architecture()[0]
+    if bit_string.endswith('bit'):
+        return int(bit_string[:-3])
+    else:
+        return 32 # default value
+
+def current_processor():
+    proc = platform.processor()
+    if not proc:
+        proc = 'n/a'
+    return proc
+
+def get_elementtree_library():
+    try:
+        import cElementTree as ElementTree
+    except ImportError:
+        # try python 2.5-style
+        import xml.etree.cElementTree as ElementTree
+    return ElementTree
+
+def temporary_directory():
+    warnings.warn(
+            "temporary_directory() is deprecated; use the tempfile module "
+            "instead",
+            category=VistrailsDeprecation)
+    return tempfile.gettempdir()
diff --git a/vistrails/core/system/linux.py b/vistrails/core/system/linux.py
index cbdf7a5..cc44110 100644
--- a/vistrails/core/system/linux.py
+++ b/vistrails/core/system/linux.py
@@ -1,46 +1,61 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import os
 import re
 import shutil
-from ctypes import CDLL, c_void_p
+import tempfile
+
+from vistrails.core.utils import VistrailsInternalError
+
 from vistrails.core.system.unix import executable_is_in_path,\
-     executable_is_in_pythonpath, list2cmdline, execute_cmdline, \
+     list2cmdline, execute_cmdline, execute_cmdline2, \
      get_executable_path, execute_piped_cmdlines
 
-import unittest
+
+__all__ = ['executable_is_in_path', 'list2cmdline', 'execute_cmdline',
+           'execute_cmdline2', 'get_executable_path', 'execute_piped_cmdlines',
+
+           'guess_total_memory',
+           'home_directory', 'remote_copy_program', 'remote_shell_program',
+           'graph_viz_dot_command_line', 'remove_graph_viz_temporaries',
+           'link_or_copy', 'XDestroyWindow',
+           'shell_font_face', 'shell_font_size',
+           'TestLinux']
 
 ################################################################################
 
@@ -66,23 +81,16 @@ def parse_meminfo():
     return info
 
 def guess_total_memory():
-    """ guess_total_memory() -> int 
-    Return system memory in bytes. 
-    
-    """
-    return parse_meminfo()['MemTotal']
+    """ guess_total_memory() -> int
+    Return system memory in bytes.
 
-def temporary_directory():
-    """ temporary_directory() -> str 
-    Returns the path to the system's temporary directory 
-    
     """
-    return "/tmp/"
+    return parse_meminfo()['MemTotal']
 
 def home_directory():
-    """ home_directory() -> str 
+    """ home_directory() -> str
     Returns user's home directory using environment variable $HOME
-    
+
     """
     return os.getenv('HOME')
 
@@ -96,18 +104,18 @@ def graph_viz_dot_command_line():
     return 'dot -Tplain -o '
 
 def remove_graph_viz_temporaries():
-    """ remove_graph_viz_temporaries() -> None 
-    Removes temporary files generated by dot 
-    
+    """ remove_graph_viz_temporaries() -> None
+    Removes temporary files generated by dot
+
     """
-    os.unlink(temporary_directory() + "dot_output_vistrails.txt")
-    os.unlink(temporary_directory() + "dot_tmp_vistrails.txt")
+    os.unlink(tempfile.gettempdir() + "dot_output_vistrails.txt")
+    os.unlink(tempfile.gettempdir() + "dot_tmp_vistrails.txt")
 
 def link_or_copy(src, dst):
-    """link_or_copy(src:str, dst:str) -> None 
+    """link_or_copy(src:str, dst:str) -> None
     Tries to create a hard link to a file. If it is not possible, it will
-    copy file src to dst 
-    
+    copy file src to dst
+
     """
     # Links if possible, but we're across devices, we need to copy.
     try:
@@ -120,11 +128,11 @@ def link_or_copy(src, dst):
             raise e
 
 def get_libX11():
-    """ get_libX11() -> CDLL    
+    """ get_libX11() -> CDLL
     Return the X11 library loaded with ctypes. Only available on
     Linux.  We also need a way to find the correct X11 library name on
     different machines. Right now, libX11.so.6 is used.
-    
+
     """
     from vistrails.core.bundles import py_import
     ctypes = py_import('ctypes', {
@@ -139,14 +147,14 @@ def get_libX11():
 def XDestroyWindow(displayId, windowId):
     """ XDestroyWindow(displayId: void_p_str, windowId: void_p_str) -> None
     Destroy the X window specified by two strings displayId and
-    windowId containing void pointer string of (Display*) and (Window)    
+    windowId containing void pointer string of (Display*) and (Window)
     type.
     This is specific for VTKCell to remove the top shell window. Since
     VTK does not expose X11-related functions to Python, we have to
     use ctypes to hi-jack X11 library and call XDestroyWindow to kill
     the top-shell widget after reparent the OpenGL canvas to another
     Qt widget
-    
+
     """
     from vistrails.core.bundles import py_import
     ctypes = py_import('ctypes', {
@@ -160,49 +168,49 @@ def XDestroyWindow(displayId, windowId):
     libx = get_libX11()
     libx.XDestroyWindow(displayPtr, windowPtr)
 
+def shell_font_face():
+    return 'Fixed'
+
+def shell_font_size():
+    return 12
+
 ################################################################################
 
+import unittest
 
 class TestLinux(unittest.TestCase):
-     """ Class to test Linux specific functions """
-     
-     def test1(self):
-         """ Test if guess_total_memory() is returning an int >= 0"""
-         result = guess_total_memory()
-         assert isinstance(result, (int, long))
-         assert result >= 0
-
-     def test2(self):
-         """ Test if home_directory is not empty """
-         result = home_directory()
-         assert result != ""
-
-     def test3(self):
-         """ Test if temporary_directory is not empty """
-         result = temporary_directory()
-         assert result != ""
-
-     def test4(self):
-         """ Test if origin of link_or_copy'ed file is deleteable. """
-         import tempfile
-         import os
-         (fd1, name1) = tempfile.mkstemp()
-         os.close(fd1)
-         (fd2, name2) = tempfile.mkstemp()
-         os.close(fd2)
-         os.unlink(name2)
-         link_or_copy(name1, name2)
-         try:
-             os.unlink(name1)
-         except:
-             self.fail("Should not throw")
-         os.unlink(name2)
-
-     def test_executable_file_in_path(self):
-         # Should exist in any POSIX shell, which is what we have in OSX
-         result = executable_is_in_path('ls')
-         assert os.access(result, os.X_OK)
+    """ Class to test Linux specific functions """
+
+    def test1(self):
+        """ Test if guess_total_memory() is returning an int >= 0"""
+        result = guess_total_memory()
+        assert isinstance(result, (int, long))
+        assert result >= 0
+
+    def test2(self):
+        """ Test if home_directory is not empty """
+        result = home_directory()
+        assert result != ""
+
+    def test3(self):
+        """ Test if origin of link_or_copy'ed file is deleteable. """
+        import tempfile
+        import os
+        (fd1, name1) = tempfile.mkstemp()
+        os.close(fd1)
+        (fd2, name2) = tempfile.mkstemp()
+        os.close(fd2)
+        os.unlink(name2)
+        link_or_copy(name1, name2)
+        try:
+            os.unlink(name1)
+        except OSError:
+            self.fail("Should not throw")
+        os.unlink(name2)
+
+    def test_executable_file_in_path(self):
+        # Should exist in any POSIX shell
+        self.assertTrue(executable_is_in_path('ls'))
 
 if __name__ == '__main__':
     unittest.main()
-             
diff --git a/vistrails/core/system/mac_site.py b/vistrails/core/system/mac_site.py
index 3cdac45..91c8277 100644
--- a/vistrails/core/system/mac_site.py
+++ b/vistrails/core/system/mac_site.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ contains parts from site.py for python2.7 needed when using py2app
 """
 
+from __future__ import division
+
 import sys
 
 # for distutils.commands.install
diff --git a/vistrails/core/system/osx.py b/vistrails/core/system/osx.py
index 9547375..81352c5 100644
--- a/vistrails/core/system/osx.py
+++ b/vistrails/core/system/osx.py
@@ -1,52 +1,67 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ Mac OS X specific file """
-      
+
 # from xml import dom
 # from xml.dom.xmlbuilder import DOMInputSource, DOMBuilder
+from __future__ import division
+
 import xml.etree.cElementTree as ElementTree
 import datetime
 import os
 import shutil
 import subprocess
-import time
+import tempfile
+
+from vistrails.core.system import time_strptime
 from vistrails.core.system.unix import executable_is_in_path, list2cmdline, \
-     executable_is_in_pythonpath, execute_cmdline, execute_piped_cmdlines
+     execute_cmdline, execute_piped_cmdlines, execute_cmdline2
+from vistrails.core import debug
 import vistrails.core.utils
 
-import unittest
+
+__all__ = ['executable_is_in_path', 'list2cmdline',
+           'execute_cmdline', 'execute_piped_cmdlines', 'execute_cmdline2',
+
+           'guess_total_memory',
+           'home_directory', 'remote_copy_program', 'remote_shell_program',
+           'graph_viz_dot_command_line', 'remove_graph_viz_temporaries',
+           'link_or_copy', 'get_executable_path',
+           'shell_font_face', 'shell_font_size',
+           'TestMacOSX']
 
 ###############################################################################
 # Extract system detailed information of a Mac system
@@ -61,20 +76,20 @@ import unittest
 # This recipe uses the system_profiler application to retrieve detailed
 # information about a Mac OS X system. There are two useful ways to use it:
 # the first is to ask for a complete Python datastructure containing
-# information about the system (see OSXSystemProfiler.all()) and the 
+# information about the system (see OSXSystemProfiler.all()) and the
 # other is two ask for particular keys in the system information database.
 
 def group(lst, n):
     """group([0,3,4,10,2,3], 2) => [(0,3), (4,10), (2,3)]
-    
+
     Group a list into consecutive n-tuples. Incomplete tuples are
     discarded e.g.
-    
+
     >>> group(range(10), 3)
     [(0, 1, 2), (3, 4, 5), (6, 7, 8)]
-    
+
     """
-    return zip(*[lst[i::n] for i in xrange(n)]) 
+    return zip(*[lst[i::n] for i in xrange(n)])
 
 class OSXSystemProfiler(object):
     "Provide information from the Mac OS X System Profiler"
@@ -89,8 +104,19 @@ class OSXSystemProfiler(object):
             command.append(str(category))
         if detail is not None:
             command.extend(['-detailLevel', '%d' % detail])
-        p = subprocess.Popen(command, stdout=subprocess.PIPE)
-        self.document = ElementTree.parse(p.stdout)
+        p = subprocess.Popen(command, stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        stdout, stderr = p.communicate()
+        stderr = stderr.strip()
+        if stderr:
+            lines = stderr.splitlines()
+            if len(lines) > 1 or len(lines[0]) > 44:
+                line = "%s..." % lines[0][:41]
+            else:
+                line = lines[0]
+            debug.warning("Error output from system_profiler: %s" % line,
+                          stderr)
+        self.document = ElementTree.XML(stdout)
 
     def _content(self, node):
         "Get the text node content of an element or an empty string"
@@ -107,7 +133,7 @@ class OSXSystemProfiler(object):
             return float(self._content(node))
         elif node.tag == 'date': #  <date>2004-07-05T13:29:29Z</date>
             return datetime.datetime(
-                *time.strptime(self._content(node), '%Y-%m-%dT%H:%M:%SZ')[:5])
+                *time_strptime(self._content(node), '%Y-%m-%dT%H:%M:%SZ')[:5])
         elif node.tag == 'array':
             return [self._convert_value_node(n) for n in node.getchildren()]
         elif node.tag == 'dict':
@@ -115,7 +141,7 @@ class OSXSystemProfiler(object):
                 for n, m in group(node.getchildren(), 2)])
         else:
             raise ValueError(node.tag)
-    
+
     def __getitem__(self, key):
         nodes = self.document.getiterator('dict')
         results = []
@@ -129,37 +155,6 @@ class OSXSystemProfiler(object):
                     else:
                         results.append(v)
         return results
-    
-#     def all(self):
-#         """Return the complete information from the system profiler
-#         as a Python data structure"""
-        
-#         return self._convert_value_node(
-#             self.document.documentElement.firstChild)
-
-###############################################################################
-
-def example():
-    from optparse import OptionParser
-    from pprint import pprint
-
-    info = OSXSystemProfiler("SPHardwareDataType")
-    parser = OptionParser()
-    parser.add_option("-f", "--field", action="store", dest="field",
-                      help="display the value of the specified field")
-    
-    (options, args) = parser.parse_args()
-    if len(args) != 0:
-        parser.error("no arguments are allowed")
-    
-    if options.field is not None:
-        pprint(info[options.field])
-    else:
-        # just print some comment keys known to exist in only one important
-        # dictionary
-        for k in ['cpu_type', 'current_processor_speed', 'l2_cache_size',
-                  'physical_memory', 'user_name', 'os_version', 'ip_address']:
-            print '%s: %s' % (k, info[k][0])
 
 ###############################################################################
 
@@ -167,12 +162,12 @@ def parse_meminfo():
     """ parse_meminfo() -> int
     Uses the system_profiler application to retrieve detailed information
     about a Mac OS X system. Returns memory size in Megabytes.
-    
+
     Just use the "SPHardwareDataType" category to limit the amount of
     information gathered.
 
     """
-        
+
     result = -1
     info = OSXSystemProfiler("SPHardwareDataType")
     mem = info['physical_memory'][0]
@@ -185,23 +180,16 @@ def parse_meminfo():
     return result
 
 def guess_total_memory():
-    """ guess_total_memory() -> int 
-    Return system memory in bytes. If PyXML is not installed it returns -1 
-    
-    """
-    return parse_meminfo()
+    """ guess_total_memory() -> int
+    Return system memory in bytes. If PyXML is not installed it returns -1
 
-def temporary_directory():
-    """ temporary_directory() -> str 
-    Returns the path to the system's temporary directory 
-    
     """
-    return "/tmp/"
+    return parse_meminfo()
 
 def home_directory():
-    """ home_directory() -> str 
+    """ home_directory() -> str
     Returns user's home directory using environment variable $HOME
-    
+
     """
     return os.getenv('HOME')
 
@@ -219,18 +207,18 @@ def graph_viz_dot_command_line():
     return 'dot -Tplain -o '
 
 def remove_graph_viz_temporaries():
-    """ remove_graph_viz_temporaries() -> None 
-    Removes temporary files generated by dot 
-    
+    """ remove_graph_viz_temporaries() -> None
+    Removes temporary files generated by dot
+
     """
-    os.unlink(temporary_directory() + "dot_output_vistrails.txt")
-    os.unlink(temporary_directory() + "dot_tmp_vistrails.txt")
+    os.unlink(tempfile.gettempdir() + "dot_output_vistrails.txt")
+    os.unlink(tempfile.gettempdir() + "dot_tmp_vistrails.txt")
 
 def link_or_copy(src, dst):
-    """link_or_copy(src:str, dst:str) -> None 
+    """link_or_copy(src:str, dst:str) -> None
     Tries to create a hard link to a file. If it is not possible, it will
-    copy file src to dst 
-    
+    copy file src to dst
+
     """
     # Links if possible, but we're across devices, we need to copy.
     try:
@@ -243,48 +231,46 @@ def link_or_copy(src, dst):
             raise e
 
 def get_executable_path(executable_name):
+    """get_executable_path(executable_name: str) -> str
+    Get the absolute filename of an executable, searching in the PATH.
+    """
+    pathlist = os.environ['PATH'].split(os.pathsep)
     vt_path = os.getenv("EXECUTABLEPATH")
-    if vt_path is not None:
-        vt_path = vt_path.strip()
-        executable_path = \
-            os.path.join(os.path.dirname(vt_path), executable_name)
-        if os.path.exists(executable_path):
-            return executable_path
-    paths = os.environ['PATH']
-    paths = paths.split(os.pathsep)
-    for prefix in paths:
-        path = os.path.join(prefix, executable_name)
-        if os.path.exists(path):
-            return path
-    return None
+    if vt_path:
+        pathlist.insert(0, vt_path.strip())
+    for path in pathlist:
+        fullpath = os.path.join(path, executable_name)
+        if os.path.isfile(fullpath):
+            return os.path.abspath(fullpath)
+
+def shell_font_face():
+    return 'Monaco'
+
+def shell_font_size():
+    return 12
 
 ################################################################################
 
+import unittest
 
 class TestMacOSX(unittest.TestCase):
-     """ Class to test Mac OS X specific functions """
-     
-     def test1(self):
-         """ Test if guess_total_memory() is returning an int >= 0"""
-         result = guess_total_memory()
-         assert isinstance(result, (int, long))
-         assert result >= 0
-
-     def test2(self):
-         """ Test if home_directory is not empty """
-         result = home_directory()
-         assert result != ""
-
-     def test3(self):
-         """ Test if temporary_directory is not empty """
-         result = temporary_directory()
-         assert result != ""
-
-     def test_executable_file_in_path(self):
-         # Should exist in any POSIX shell, which is what we have in OSX
-         result = executable_is_in_path('ls')
-         assert result == "/bin/ls" # Any UNIX should respect this.
+    """ Class to test Mac OS X specific functions """
+
+    def test1(self):
+        """ Test if guess_total_memory() is returning an int >= 0"""
+        result = guess_total_memory()
+        assert isinstance(result, (int, long))
+        assert result >= 0
+
+    def test2(self):
+        """ Test if home_directory is not empty """
+        result = home_directory()
+        assert result != ""
+
+    def test_executable_file_in_path(self):
+        # Should exist in any POSIX shell, which is what we have in OSX
+        self.assertTrue(executable_is_in_path('ls'))
 
 if __name__ == '__main__':
     unittest.main()
-             
+
diff --git a/vistrails/core/system/unix.py b/vistrails/core/system/unix.py
index 0cede13..1ef6ab7 100644
--- a/vistrails/core/system/unix.py
+++ b/vistrails/core/system/unix.py
@@ -1,80 +1,61 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Routines common to Linux and OSX."""
+from __future__ import division
+
 import os
-import os.path
-import stat
 import subprocess
-import sys
-import vistrails.core.utils
-import re
 
-def executable_is_in_path(filename):
-    """executable_is_in_path(filename): string
-    Tests if filename corresponds to an executable file on the path. Returns
-the filename if true, or an empty string if false."""
-    cmdline = ['which','%s' % filename]
-    output = []
-    result = execute_cmdline(cmdline, output)
-    if result == 1:
-        return ""
-    if result != 0:
-        msg = ("'%s' failed. Return code %s. Output: %s" %
-               (cmdline, result, output))
-        raise vistrails.core.utils.VistrailsInternalError(msg)
-    else:
-        output = output[0][:-1]
-        return output
 
-def executable_is_in_pythonpath(filename):
-    """executable_is_in_pythonpath(filename: str)
-    Check if exename can be reached in the PYTHONPATH environment. Return
-    the filename if true, or an empty string if false.
-    
+__all__ = ['executable_is_in_path', 'list2cmdline', 'execute_cmdline',
+           'get_executable_path', 'execute_piped_cmdlines', 'execute_cmdline2']
+
+###############################################################################
+
+def executable_is_in_path(filename):
+    """ executable_is_in_path(filename: str) -> string
+    Check if exename can be reached in the PATH environment.
     """
-    pathlist = sys.path
-    for dir in pathlist:
-        fullpath = os.path.join(dir, filename)
-        try:
-            st = os.stat(fullpath)
-        except os.error:
-            continue        
-        if stat.S_ISREG(st[stat.ST_MODE]):
-            return filename
-    return ""
+    pathlist = os.environ['PATH'].split(os.pathsep) + ["."]
+    for path in pathlist:
+        fullpath = os.path.join(path, filename)
+        if os.path.isfile(fullpath):
+            return True
+    return False
 
 def list2cmdline(lst):
     for el in lst:
@@ -94,21 +75,19 @@ def execute_cmdline(lst, output):
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT,
                                close_fds=True)
-    # cscheid: Should this be busy-waiting? What's going on here?
-    result = None
-    while result == None:
-        result = process.poll()
+    result = process.wait()
     output.extend(process.stdout.readlines())
     return result
 
 def get_executable_path(executable_name):
-    paths = os.environ['PATH']
-    paths = paths.split(os.pathsep)
-    for prefix in paths:
-        path = os.path.join(prefix, executable_name)
-        if os.path.exists(path):
-            return path
-    return None
+    """get_executable_path(executable_name: str) -> str
+    Get the absolute filename of an executable, searching in the PATH.
+    """
+    pathlist = os.environ['PATH'].split(os.pathsep)
+    for path in pathlist:
+        fullpath = os.path.join(path, executable_name)
+        if os.path.isfile(fullpath):
+            return os.path.abspath(fullpath)
 
 def execute_piped_cmdlines(cmd_list_list):
     stdin = subprocess.PIPE
@@ -123,3 +102,6 @@ def execute_piped_cmdlines(cmd_list_list):
     (output, errs) = process.communicate()
     result = process.returncode
     return (result, output, errs)
+
+def execute_cmdline2(cmd_list):
+    return execute_piped_cmdlines([cmd_list])
diff --git a/vistrails/core/system/windows.py b/vistrails/core/system/windows.py
index 88e085c..87a8647 100644
--- a/vistrails/core/system/windows.py
+++ b/vistrails/core/system/windows.py
@@ -1,54 +1,52 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import os
 import shutil
-import sys
-import stat
 import subprocess
-import vistrails.core.system
-
-import unittest
 
 try:
     from ctypes import windll, Structure, c_ulong, c_ulonglong, byref, sizeof
     importSuccess = True
-    
+
     class WIN32MEMORYSTATUSEX(Structure):
-        """ Structure that represents memory information returned by 
+        """ Structure that represents memory information returned by
         Windows API
-        
+
         """
         _fields_ = [
             ('dwLength', c_ulong),
@@ -64,53 +62,50 @@ try:
 
 except ImportError:
     importSuccess = False
-    
+
+
+__all__ = ['guess_total_memory', 'home_directory',
+           'list2cmdline', 'remote_copy_program', 'remote_shell_program',
+           'graph_viz_dot_command_line', 'remove_graph_viz_temporaries',
+           'link_or_copy', 'executable_is_in_path', 'execute_cmdline',
+           'get_executable_path', 'execute_piped_cmdlines', 'execute_cmdline2',
+           'shell_font_face', 'shell_font_size',
+           'TestWindows']
+
+
 ##############################################################################
 def parse_meminfo():
-    """ 
+    """
     parse_meminfo() -> long
-    Calls Windows 32 API GlobalMemoryStatus(Ex) to get memory information 
+    Calls Windows 32 API GlobalMemoryStatus(Ex) to get memory information
     It requires ctypes module
-    
-    """ 
+
+    """
     try:
         kernel32 = windll.kernel32
 
         result = WIN32MEMORYSTATUSEX()
         result.dwLength = sizeof(WIN32MEMORYSTATUSEX)
         kernel32.GlobalMemoryStatusEx(byref(result))
-    except:
+    except Exception:
         return -1
-    return long(result.dwTotalPhys / 1024)
+    return result.dwTotalPhys // 1024
 
 def guess_total_memory():
-    """ guess_total_memory() -> int 
-    Return system memory in megabytes. If ctypes is not installed it returns -1 
-    
+    """ guess_total_memory() -> int
+    Return system memory in megabytes. If ctypes is not installed it returns -1
+
     """
     if importSuccess:
         return parse_meminfo()
     else:
         return -1
 
-def temporary_directory():
-    """ temporary_directory() -> str 
-    Returns the path to the system's temporary directory. Tries to use the $TMP 
-    environment variable, if it is present. Else, tries $TEMP, else uses 'c:/' 
-    
-    """
-    if os.environ.has_key('TMP'):
-        return os.environ['TMP'] + '\\'
-    elif os.environ.has_key('TEMP'):
-        return os.environ['TEMP'] + '\\'
-    else:
-        return 'c:/'
-
 def home_directory():
-    """ home_directory() -> str 
+    """ home_directory() -> str
     Returns user's home directory using windows environment variables
     $HOMEDRIVE and $HOMEPATH
-    
+
     """
     if len(os.environ['HOMEPATH']) == 0:
         return '\\'
@@ -134,53 +129,24 @@ def remove_graph_viz_temporaries():
     pass
 
 def link_or_copy(src, dst):
-    """link_or_copy(src:str, dst:str) -> None 
-    Copies file src to dst 
-    
+    """link_or_copy(src:str, dst:str) -> None
+    Copies file src to dst
+
     """
     shutil.copyfile(src, dst)
 
 def executable_is_in_path(filename):
-    """ executable_is_in_path(filename: str) -> string    
-    Check if exename can be reached in the PATH environment. Return
-    the filename if true, or an empty string if false.
-    
-    """
-    pathlist = (os.environ['PATH'].split(os.pathsep) +
-                [vistrails.core.system.vistrails_root_directory(),
-                 "."])
-    for dir in pathlist:
-        fullpath = os.path.join(dir, filename)
-        try:
-            st = os.stat(fullpath)
-        except os.error:
-            try:
-                st = os.stat(fullpath+'.exe')
-            except:
-                continue        
-        if stat.S_ISREG(st[stat.ST_MODE]):
-            return filename
-    return ""
-
-def executable_is_in_pythonpath(filename):
-    """ executable_is_in_pythonpath(filename: str) -> string    
-    Check if exename can be reached in the PYTHONPATH environment. Return
-    the filename if true, or an empty string if false.
-    
+    """ executable_is_in_path(filename: str) -> bool
+    Check if exename can be reached in the PATH environment.
     """
-    pathlist = sys.path
-    for dir in pathlist:
-        fullpath = os.path.join(dir, filename)
-        try:
-            st = os.stat(fullpath)
-        except os.error:
-            try:
-                st = os.stat(fullpath+'.exe')
-            except:
-                continue        
-        if stat.S_ISREG(st[stat.ST_MODE]):
-            return filename
-    return ""
+    pathlist = os.environ['PATH'].split(os.pathsep) + ["."]
+    exts = os.environ['PATHEXT'].split(os.pathsep)
+    for path in pathlist:
+        for ext in exts:
+            fullpath = os.path.join(path, filename) + ext
+            if os.path.isfile(fullpath):
+                return True
+    return False
 
 def list2cmdline(lst):
     for el in lst:
@@ -194,7 +160,7 @@ def execute_cmdline(lst, output):
     will always return 0
 
     """
-    proc = subprocess.Popen(lst, shell=True, stdin=subprocess.PIPE, 
+    proc = subprocess.Popen(lst, shell=True, stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     proc.wait()
     if proc.stdout:
@@ -202,10 +168,28 @@ def execute_cmdline(lst, output):
     return proc.returncode
 
 def get_executable_path(executable_name):
-    filename = os.path.abspath(os.path.join(os.path.dirname(__file__),'../../../',executable_name))
-    if os.path.exists(filename) or os.path.exists(filename+'.exe'):
-        return filename
-    return None
+    """get_executable_path(executable_name: str) -> str
+    Get the absolute filename of an executable, searching in VisTrails's top
+    directory then the PATH.
+    """
+    exts = os.environ['PATHEXT'].split(os.pathsep)
+
+    # Search in top directory
+    filename = os.path.abspath(os.path.join(
+            os.path.dirname(__file__),
+            '../../..',
+            executable_name))
+    for ext in exts:
+        if os.path.isfile(filename + ext):
+            return filename
+
+    # Search in path
+    pathlist = os.environ['PATH'].split(os.pathsep) + ["."]
+    for path in pathlist:
+        for ext in exts:
+            fullpath = os.path.join(path, executable_name) + ext
+            if os.path.isfile(fullpath):
+                return os.path.abspath(fullpath)
 
 def execute_piped_cmdlines(cmd_list_list):
     stdin = subprocess.PIPE
@@ -220,31 +204,35 @@ def execute_piped_cmdlines(cmd_list_list):
     result = process.returncode
     return (result, output, errs)
 
+def execute_cmdline2(cmd_list):
+    return execute_piped_cmdlines([cmd_list])
+
+def shell_font_face():
+    return 'Courier New'
+
+def shell_font_size():
+    return 8
+
 ################################################################################
 
+import unittest
 
 class TestWindows(unittest.TestCase):
-     """ Class to test Windows specific functions """
-     
-     def test1(self):
-         """ Test if guess_total_memory() is returning an int >= 0"""
-         result = guess_total_memory()
-         assert isinstance(result, (int, long))
-         assert result >= 0
-
-     def test2(self):
-         """ Test if home_directory is not empty """
-         result = home_directory()
-         assert result != ""
-
-     def test3(self):
-         """ Test if temporary_directory is not empty """
-         result = temporary_directory()
-         assert result != ""
-
-     def test_executable_file_in_path(self):
-         result = executable_is_in_path('cmd')
-         assert result != ""
+    """ Class to test Windows specific functions """
+
+    def test1(self):
+        """ Test if guess_total_memory() is returning an int >= 0"""
+        result = guess_total_memory()
+        assert isinstance(result, (int, long))
+        assert result >= 0
+
+    def test2(self):
+        """ Test if home_directory is not empty """
+        result = home_directory()
+        assert result != ""
+
+    def test_executable_file_in_path(self):
+        self.assertTrue(executable_is_in_path('cmd'))
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/vistrails/core/theme.py b/vistrails/core/theme.py
index 176aa56..b314afc 100644
--- a/vistrails/core/theme.py
+++ b/vistrails/core/theme.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,6 +38,8 @@ This module describes a core theme structure for VisTrails GUI. It
 specifies measurements
 """
 
+from __future__ import division
+
 from vistrails.core.utils.color import ColorByName
 import vistrails.core.system
 ################################################################################
@@ -63,6 +66,9 @@ class DefaultCoreTheme(object):
         # Padded space of Module shape into its label
         self.MODULE_LABEL_MARGIN = (20, 20, 20, 15)
 
+        # Padded space of Module shape into its edit widget
+        self.MODULE_EDIT_MARGIN = (8, 4, 8, 4)
+
         # Margin of Module shape into its ports
         self.MODULE_PORT_MARGIN = (4, 4, 4, 4)
 
diff --git a/vistrails/core/thumbnails.py b/vistrails/core/thumbnails.py
index 838905d..dbf01d0 100644
--- a/vistrails/core/thumbnails.py
+++ b/vistrails/core/thumbnails.py
@@ -1,49 +1,54 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+import itertools
 
 """ Utilities for dealing with the thumbnails """
 import os
 import os.path
 import shutil
+import tempfile
 import time
 import uuid
 import mimetypes
 # mimetypes are broken by default on windows so use the builtins
 # Remove line below when it is fixed here: http://bugs.python.org/issue15207
 mimetypes.init(files=[])
-from vistrails.core import debug
+from vistrails.core import debug, system
 from vistrails.core.configuration import get_vistrails_configuration, \
       get_vistrails_persistent_configuration
 from vistrails.core.utils import VistrailsInternalError
@@ -60,16 +65,20 @@ class ThumbnailCache(object):
     _instance = None
     IMAGE_MAX_WIDTH = 200 
     SUPPORTED_TYPES = ['image/png','image/jpeg','image/bmp','image/gif']
-    class ThumbnailCacheSingleton(object):
-        def __call__(self, *args, **kw):
-            if ThumbnailCache._instance is None:
-                obj = ThumbnailCache(*args, **kw)
-                ThumbnailCache._instance = obj
-            return ThumbnailCache._instance
-        
-    getInstance = ThumbnailCacheSingleton()
-    
+    @staticmethod
+    def getInstance(*args, **kwargs):
+        if ThumbnailCache._instance is None:
+            obj = ThumbnailCache(*args, **kwargs)
+            ThumbnailCache._instance = obj
+        return ThumbnailCache._instance
+
+    @staticmethod
+    def clearInstance():
+        if ThumbnailCache._instance is not None:
+            ThumbnailCache._instance.destroy()
+
     def __init__(self):
+        self._temp_directory = None
         self.elements = {}
         self.vtelements = {}
         self.conf = None
@@ -77,17 +86,24 @@ class ThumbnailCache(object):
         if conf.has('thumbs'):
             self.conf = conf.thumbs
         self.init_cache()
+
+    def destroy(self):
+        if self._temp_directory is not None:
+            print "removing thumbnail directory"
+            shutil.rmtree(self._temp_directory)
         
     def get_directory(self):
-        if self.conf.check('cacheDirectory'):
-            thumbnail_dir = self.conf.cacheDirectory
+        thumbnail_dir = system.get_vistrails_directory('thumbs.cacheDir')
+        if thumbnail_dir is not None:
             if not os.path.exists(thumbnail_dir):
                 raise VistrailsInternalError("Cannot find %s" % thumbnail_dir)
             return thumbnail_dir
         
-        raise VistrailsInternalError("'thumbs.cacheDirectory' not"
-                                     " specified in configuration")
-        return None
+        # raise VistrailsInternalError("'thumbs.cacheDir' not"
+        #                              " specified in configuration")
+        if self._temp_directory is None:
+            self._temp_directory = tempfile.mkdtemp(prefix='vt_thumbs_')
+        return self._temp_directory
     
     def init_cache(self):
         for root,dirs, files in os.walk(self.get_directory()):
@@ -133,8 +149,9 @@ class ThumbnailCache(object):
                     entry.abs_name = dstname
                         
                 except shutil.Error, e:
-                    debug.warning("Could not move thumbnail from %s to %s: %s" \
-                                  % (sourcedir, destdir, str(e)))
+                    debug.warning("Could not move thumbnail from %s to %s" % (
+                                  sourcedir, destdir),
+                                  e)
                     
     def remove_lru(self,n=1):
         elements = self.elements.values()
@@ -143,13 +160,13 @@ class ThumbnailCache(object):
         debug.debug("Will remove %s elements from cache..."%num)
         debug.debug("Cache has %s elements and %s bytes"%(len(elements),
                                                              self.size()))
-        for i in range(num):
+        for elem in itertools.islice(elements, num):
             try:
-                del self.elements[elements[i].name]    
-                os.unlink(elements[i].abs_name)
+                del self.elements[elem.name]
+                os.unlink(elem.abs_name)
             except os.error, e:
-                debug.warning("Could not remove file %s: %s" % \
-                                 (elements[i].abs_name, str(e)))
+                debug.warning("Could not remove file %s" % elem.abs_name, e)
+
     def remove(self,key):
         if key in self.elements.keys():
             entry = self.elements[key]
@@ -178,7 +195,7 @@ class ThumbnailCache(object):
         if len(thumbnail_fnames) > 0:
             image = self._merge_thumbnails(thumbnail_fnames)
         fname = None
-        if image != None and image.width() > 0 and image.height() > 0:
+        if image is not None and image.width() > 0 and image.height() > 0:
             fname = "%s.png" % str(uuid.uuid1())
             abs_fname = self._save_thumbnail(image, fname) 
             statinfo = os.stat(abs_fname)
@@ -214,13 +231,15 @@ class ThumbnailCache(object):
         Deletes all files inside dirname
     
         """
+        if dirname is None:
+            return
         try:
             for root, dirs, files in os.walk(dirname):
                 for fname in files:
                     os.unlink(os.path.join(root,fname))
                     
         except OSError, e:
-            debug.warning("Error when removing thumbnails: %s"%str(e))
+            debug.warning("Error when removing thumbnails", e)
     
     @staticmethod
     def _get_thumbnail_fnames(folder):
diff --git a/vistrails/core/upgradeworkflow.py b/vistrails/core/upgradeworkflow.py
index 9db165a..5af737e 100644
--- a/vistrails/core/upgradeworkflow.py
+++ b/vistrails/core/upgradeworkflow.py
@@ -1,53 +1,57 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """This file contains code to handle InvalidPipeline exceptions that contain
 upgrade requests."""
+from __future__ import division
+
 from vistrails.core import debug
 import vistrails.core.db.action
 from vistrails.core.modules.module_registry import get_module_registry, \
-     ModuleDescriptor, MissingModule, MissingPort
+     ModuleDescriptor, MissingModule, MissingPort, MissingPackage
 from vistrails.core.modules.utils import parse_descriptor_string, \
-    create_descriptor_string, parse_port_spec_string, \
-    create_port_spec_string, expand_port_spec_string
+    create_descriptor_string, parse_port_spec_string, create_port_spec_string
 from vistrails.core.packagemanager import get_package_manager
 from vistrails.core.system import get_vistrails_basic_pkg_id
 from vistrails.core.vistrail.annotation import Annotation
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.connection import Connection
 from vistrails.core.vistrail.port import Port
 from vistrails.core.vistrail.port_spec import PortSpec
+from vistrails.core.vistrail.port_spec_item import PortSpecItem
 from vistrails.core.utils import versions_increasing
 import copy
 
@@ -65,11 +69,174 @@ class UpgradeWorkflowError(Exception):
     def __str__(self):
         return "Upgrading workflow failed.\n" + self._msg
 
+class UpgradeModuleRemap(object):
+    def __init__(self, start_version, end_version, 
+                 output_version, new_module=None,
+                 dst_port_remap=None, src_port_remap=None,
+                 function_remap=None, annotation_remap=None,
+                 control_param_remap=None, module_name=None):
+        self.module_name = module_name
+        self.start_version = start_version
+        self.end_version = end_version
+        self.output_version = output_version
+        self.new_module = new_module
+
+        if dst_port_remap is None:
+            self._dst_port_remap = {}
+        else:
+            self._dst_port_remap = dst_port_remap
+        if src_port_remap is None:
+            self._src_port_remap = {}
+        else:
+            self._src_port_remap = src_port_remap
+        if function_remap is None:
+            self._function_remap = {}
+        else:
+            self._function_remap = function_remap
+        if annotation_remap is None:
+            self._annotation_remap = {}
+        else:
+            self._annotation_remap = annotation_remap
+        if control_param_remap is None:
+            self._control_param_remap = {}
+        else:
+            self._control_param_remap = control_param_remap
+
+    @classmethod
+    def __copy__(cls, obj):
+        newobj = cls()
+        for k, v in obj.__dict__.iteritems():
+            if k.startswith('_') and k.endswith('_remap'):
+                v = copy.copy(v)
+            newobj.__dict__[k] = v
+        return newobj
+
+    @classmethod
+    def from_tuple(cls, module_name, t):
+        if len(t) == 3:
+            obj = cls(t[0], t[1], None, t[2], module_name=module_name)
+            remap = None
+        elif len(t) == 4:
+            obj = cls(t[0], t[1], None, t[2], module_name=module_name)
+            remap = t[3]
+        elif len(t) == 5:
+            obj = cls(t[0], t[1], t[2], t[3], module_name=module_name)
+            remap = t[4]
+        else:
+            raise TypeError("UpgradeModuleRemap.from_tuple() got a tuple of "
+                            "length %d" % len(t))
+        if remap is not None:
+            for remap_type, remap_dict in remap.iteritems():
+                for remap_name, remap_change in remap_dict.iteritems():
+                    obj.add_remap(remap_type, remap_name, remap_change)
+        return obj
+
+    def _get_dst_port_remap(self):
+        return self._dst_port_remap
+    dst_port_remap = property(_get_dst_port_remap)
+
+    def _get_src_port_remap(self):
+        return self._src_port_remap
+    src_port_remap = property(_get_src_port_remap)
+    
+    def _get_function_remap(self):
+        # !!! we're going to let dst_port_remap serve as a
+        # base for function_remap but the developer is
+        # responsible for knowing that anything beyond name
+        # remaps requires different functions
+        d = copy.copy(self._dst_port_remap)
+        d.update(self._function_remap)
+        return d
+    function_remap = property(_get_function_remap)
+    
+    def _get_annotation_remap(self):
+        return self._annotation_remap
+    annotation_remap = property(_get_annotation_remap)    
+
+    def _get_control_param_remap(self):
+        return self._control_param_remap
+    control_param_remap = property(_get_control_param_remap)    
+
+    def add_remap(self, remap_type, remap_name, remap_change):
+        if not hasattr(self, '_%s' % remap_type):
+            raise ValueError('remap_type "%s" not allowed' % remap_type)
+        d = getattr(self, '_%s' % remap_type)
+        d[remap_name] = remap_change
+            
+        # if remap_type not in self.allowed_remaps:
+        #     raise ValueError("remap_type must be one of %s" % allowed_remaps)
+        # self.remap[remap_type][remap_name] = remap_change
+        
+    def get_remap(self, remap_type):
+        if not hasattr(self, '_%s' % remap_type):
+            raise ValueError('remap_type "%s" not allowed' % remap_type)
+        d = getattr(self, '_%s' % remap_type)
+        return d
+
+        # if remap_type not in self.allowed_remaps:
+        #     raise ValueError("remap_type must be one of %s" % allowed_remaps)
+        # return self.remap[remap_type]
+
+    def get_output_version(self):
+        return self.output_version
+
+class UpgradePackageRemap(object):
+    def __init__(self):
+        self.remaps = {}  # name (str): remap (UpgradeModuleRemap)
+
+    @classmethod
+    def __copy__(cls, obj):
+        newobj = cls()
+        newobj.remaps = dict((modname, copy.copy(modremap))
+                             for modname, modremap in obj.remaps.iteritems())
+        return newobj
+
+    @classmethod
+    def from_dict(cls, d):
+        pkg_remap = cls()
+        for module_name, remap_list in d.iteritems():
+            for remap in remap_list:
+                pkg_remap.add_module_remap(remap, module_name)
+        return pkg_remap
+
+    def add_module_remap(self, module_remap, module_name=None):
+        if isinstance(module_remap, tuple):
+            if module_name is None:
+                raise ValueError("module_name must be specified if "
+                                 "module_remap is a tuple")
+            module_remap = UpgradeModuleRemap.from_tuple(module_name, 
+                                                         module_remap)
+        else:
+            if module_name is not None:
+                # assume user wants to override name
+                module_remap.module_name = module_name
+        if module_remap.module_name not in self.remaps:
+            self.remaps[module_remap.module_name] = []
+        self.remaps[module_remap.module_name].append(module_remap)
+
+    def get_module_remaps(self, module_name):
+        if module_name in self.remaps:
+            return self.remaps[module_name]
+        return []
+
+    def has_module_remaps(self, module_name):
+        return module_name in self.remaps
+
+    def get_module_upgrade(self, module_name, old_version):
+        for module_remap in self.get_module_remaps(module_name):
+            if ((module_remap.start_version is None or 
+                 not versions_increasing(old_version, 
+                                         module_remap.start_version)) and
+                (module_remap.end_version is None or
+                 versions_increasing(old_version, 
+                                     module_remap.end_version))):
+                return module_remap
+        return None
+
 class UpgradeWorkflowHandler(object):
 
     @staticmethod
     def dispatch_request(controller, module_id, current_pipeline):
-        reg = get_module_registry()
         pm = get_package_manager()
         if module_id not in current_pipeline.modules:
             # It is possible that some other upgrade request has
@@ -82,6 +249,10 @@ class UpgradeWorkflowHandler(object):
         if hasattr(pkg.module, 'handle_module_upgrade_request'):
             f = pkg.module.handle_module_upgrade_request
             return f(controller, module_id, current_pipeline)
+        elif hasattr(pkg.module, '_upgrades'):
+            return UpgradeWorkflowHandler.remap_module(controller, module_id, 
+                                                       current_pipeline,
+                                                       pkg.module._upgrades)
         else:
             debug.log('Package "%s" cannot handle upgrade request. '
                       'VisTrails will attempt automatic upgrade.' % \
@@ -92,7 +263,7 @@ class UpgradeWorkflowHandler(object):
     @staticmethod
     def check_port_spec(module, port_name, port_type, descriptor=None, 
                         sigstring=None):
-        from vistrails.core.modules.basic_modules import identifier as basic_pkg
+        basic_pkg = get_vistrails_basic_pkg_id()
 
         reg = get_module_registry()
         found = False
@@ -128,8 +299,6 @@ class UpgradeWorkflowHandler(object):
 
     @staticmethod
     def find_descriptor(controller, pipeline, module_id, desired_version=''):
-        from vistrails.core.modules.abstraction \
-            import identifier as local_abstraction_pkg
         reg = get_module_registry()
 
         get_descriptor = reg.get_descriptor_by_name
@@ -165,8 +334,14 @@ class UpgradeWorkflowHandler(object):
         return d
 
     @staticmethod
-    def check_upgrade(pipeline, module_id, d, function_remap={},
-                      src_port_remap={}, dst_port_remap={}):
+    def check_upgrade(pipeline, module_id, d, function_remap=None,
+                      src_port_remap=None, dst_port_remap=None):
+        if function_remap is None:
+            function_remap = {}
+        if src_port_remap is None:
+            src_port_remap = {}
+        if dst_port_remap is None:
+            dst_port_remap = {}
         invalid_module = pipeline.modules[module_id]
         def check_connection_port(port):
             port_type = PortSpec.port_type_map.inverse[port.type]
@@ -195,8 +370,9 @@ class UpgradeWorkflowHandler(object):
 
     @staticmethod
     def attempt_automatic_upgrade(controller, pipeline, module_id,
-                                  function_remap={}, src_port_remap={}, 
-                                  dst_port_remap={}, annotation_remap={}):
+                                  function_remap=None, src_port_remap=None, 
+                                  dst_port_remap=None, annotation_remap=None,
+                                  control_param_remap=None):
         """attempt_automatic_upgrade(module_id, pipeline): [Action]
 
         Attempts to automatically upgrade module by simply adding a
@@ -222,7 +398,7 @@ class UpgradeWorkflowHandler(object):
             else:
                 nss = mname
             msg = ("Could not upgrade module %s from package %s.\n" %
-                    (mname, mpkg))
+                    (nss, mpkg))
             raise UpgradeWorkflowError(msg)
 
         UpgradeWorkflowHandler.check_upgrade(pipeline, module_id, d, 
@@ -239,7 +415,8 @@ class UpgradeWorkflowHandler(object):
                                                      function_remap,
                                                      src_port_remap, 
                                                      dst_port_remap,
-                                                     annotation_remap)
+                                                     annotation_remap,
+                                                     control_param_remap)
 
     @staticmethod
     def create_new_connection(controller, src_module, src_port, 
@@ -283,8 +460,22 @@ class UpgradeWorkflowHandler(object):
 
     @staticmethod
     def replace_generic(controller, pipeline, old_module, new_module,
-                        function_remap={}, src_port_remap={}, 
-                        dst_port_remap={}, annotation_remap={}):
+                        function_remap=None, src_port_remap=None, 
+                        dst_port_remap=None, annotation_remap=None,
+                        control_param_remap=None, use_registry=True):
+        if function_remap is None:
+            function_remap = {}
+        if src_port_remap is None:
+            src_port_remap = {}
+        if dst_port_remap is None:
+            dst_port_remap = {}
+        if annotation_remap is None:
+            annotation_remap = {}
+        if control_param_remap is None:
+            control_param_remap = {}
+
+        basic_pkg = get_vistrails_basic_pkg_id()
+
         ops = []
         ops.extend(controller.delete_module_list_ops(pipeline, [old_module.id]))
         
@@ -308,6 +499,27 @@ class UpgradeWorkflowHandler(object):
                            value=annotation.value)
             new_module.add_annotation(new_annotation)
 
+        for control_param in old_module.control_parameters:
+            if control_param.name not in control_param_remap:
+                control_param_name = control_param.name
+            else:
+                remap = control_param_remap[control_param.name]
+                if remap is None:
+                    # don't add the control param back in
+                    continue
+                elif not isinstance(remap, basestring):
+                    ops.extend(remap(control_param))
+                    continue
+                else:
+                    control_param_name = remap
+
+            new_control_param = \
+                ModuleControlParam(id=controller.id_scope.getNewId(
+                                                   ModuleControlParam.vtType),
+                                   name=control_param_name,
+                                   value=control_param.value)
+            new_module.add_control_parameter(new_control_param)
+
         if not old_module.is_group() and not old_module.is_abstraction():
             for port_spec in old_module.port_spec_list:
                 if port_spec.type == 'input':
@@ -359,12 +571,28 @@ class UpgradeWorkflowHandler(object):
             else:
                 new_param_vals = []
                 aliases = []
+            if use_registry:
+                function_port_spec = function_name
+            else:
+                def mk_psi(pos):
+                    psi = PortSpecItem(module="Module", package=basic_pkg,
+                                       namespace="", pos=pos)
+                    return psi
+                n_items = len(new_param_vals)
+                function_port_spec = PortSpec(name=function_name,
+                                              items=[mk_psi(i) 
+                                                     for i in xrange(n_items)])
             new_function = controller.create_function(new_module, 
-                                                      function_name,
+                                                      function_port_spec,
                                                       new_param_vals,
                                                       aliases)
             new_module.add_function(new_function)
 
+        if None in function_remap:
+            # used to add new functions
+            remap = function_remap[None]
+            function_ops.extend(remap(None, new_module))
+
         # add the new module
         ops.append(('add', new_module))
         ops.extend(function_ops)
@@ -387,10 +615,17 @@ class UpgradeWorkflowHandler(object):
                     source_name = remap
                     
             old_dst_module = pipeline.modules[old_conn.destination.moduleId]
+            if use_registry:
+                source_port = source_name
+            else:
+                source_port = Port(name=source_name,
+                                   type='source',
+                                   signature=create_port_spec_string(
+                                       [(basic_pkg, 'Variant', '')]))
 
             new_conn = create_new_connection(controller,
                                              new_module,
-                                             source_name,
+                                             source_port,
                                              old_dst_module,
                                              old_conn.destination)
             ops.append(('add', new_conn))
@@ -411,19 +646,27 @@ class UpgradeWorkflowHandler(object):
                     destination_name = remap
                     
             old_src_module = pipeline.modules[old_conn.source.moduleId]
+            if use_registry:
+                destination_port = destination_name
+            else:
+                destination_port = Port(name=destination_name,
+                                        type='destination',
+                                        signature=create_port_spec_string(
+                                            [(basic_pkg, 'Variant', '')]))
+
             new_conn = create_new_connection(controller,
                                              old_src_module,
                                              old_conn.source,
                                              new_module,
-                                             destination_name)
+                                             destination_port)
             ops.append(('add', new_conn))
         
         return [vistrails.core.db.action.create_action(ops)]
 
     @staticmethod
     def replace_group(controller, pipeline, module_id, new_subpipeline):
-        old_group = pipeline.modules[module_id]
         basic_pkg = get_vistrails_basic_pkg_id()
+        old_group = pipeline.modules[module_id]
         new_group = controller.create_module(basic_pkg, 'Group', '', 
                                              old_group.location.x, 
                                              old_group.location.y)
@@ -433,8 +676,9 @@ class UpgradeWorkflowHandler(object):
 
     @staticmethod
     def replace_module(controller, pipeline, module_id, new_descriptor,
-                       function_remap={}, src_port_remap={}, dst_port_remap={},
-                       annotation_remap={}):
+                       function_remap=None, src_port_remap=None,
+                       dst_port_remap=None, annotation_remap=None,
+                       control_param_remap=None, use_registry=True):
         old_module = pipeline.modules[module_id]
         internal_version = -1
         # try to determine whether new module is an abstraction
@@ -446,17 +690,20 @@ class UpgradeWorkflowHandler(object):
             controller.create_module_from_descriptor(new_descriptor,
                                                      old_module.location.x,
                                                      old_module.location.y,
-                                                     internal_version)
+                                                     internal_version,
+                                                     not use_registry)
 
         return UpgradeWorkflowHandler.replace_generic(controller, pipeline, 
                                                       old_module, new_module,
                                                       function_remap, 
                                                       src_port_remap, 
                                                       dst_port_remap,
-                                                      annotation_remap)
+                                                      annotation_remap,
+                                                      control_param_remap,
+                                                      use_registry)
 
     @staticmethod
-    def remap_module(controller, module_id, pipeline, module_remap):
+    def remap_module(controller, module_id, pipeline, pkg_remap):
 
         """remap_module offers a method to shortcut the
         specification of upgrades.  It is useful when just changing
@@ -466,7 +713,7 @@ class UpgradeWorkflowHandler(object):
         first three arguments are passed from the arguments to that
         method.
 
-        module_remap specifies all of the changes and is of the format
+        pkg_remap specifies all of the changes and is of the format
         {<old_module_name>: [(<start_version>, <end_version>, 
                              <new_module_klass> | <new_module_id> | None, 
                              <remap_dictionary>)]}
@@ -487,7 +734,7 @@ class UpgradeWorkflowHandler(object):
             ops = []
             ...
             return ops
-        module_remap = {'FileSink': [(None, '1.5.1', FileSink,
+        pkg_remap = {'FileSink': [(None, '1.5.1', FileSink,
                                      {'dst_port_remap':
                                           {'overrideFile': 'overwrite',
                                            'outputName': outputName_remap},
@@ -500,75 +747,87 @@ class UpgradeWorkflowHandler(object):
         reg = get_module_registry()
 
         old_module = pipeline.modules[module_id]
+        old_version = old_module.version
         old_desc_str = create_descriptor_string(old_module.package,
                                                 old_module.name,
                                                 old_module.namespace,
                                                 False)
         # print 'running module_upgrade_request', old_module.name
-        if old_desc_str in module_remap:
-            for upgrade_tuple in module_remap[old_desc_str]:
-                (start_version, end_version, new_module_type, remap) = \
-                    upgrade_tuple
-                old_version = old_module.version
-                if ((start_version is None or 
-                     not versions_increasing(old_version, start_version)) and
-                    (end_version is None or
-                     versions_increasing(old_version, end_version))):
-                    # do upgrade
-                    
-                    if new_module_type is None:
-                        try:
-                            new_module_desc = \
-                                reg.get_descriptor_by_name(old_module.package, 
-                                                           old_module.name, 
-                                                           old_module.namespace)
-                        except MissingModule, e:
-                            # if the replacement is an abstraction,
-                            # and it has been upgraded, we use that
-                            if reg.has_abs_upgrade(old_module.package,
-                                                   old_module.name,
-                                                   old_module.namespace):
-                                new_module_desc = \
-                                    reg.get_abs_upgrade(old_module.package,
-                                                        old_module.name,
-                                                        old_module.namespace)
-                            else:
-                                raise e
-                    elif isinstance(new_module_type, basestring):
-                        d_tuple = parse_descriptor_string(new_module_type,
-                                                          old_module.package)
-                        try:
-                            new_module_desc = \
-                                reg.get_descriptor_by_name(*d_tuple)
-                        except MissingModule, e:
-                            # if the replacement is an abstraction,
-                            # and it has been upgraded, we use that
-                            if reg.has_abs_upgrade(*d_tuple):
-                                new_module_desc = reg.get_abs_upgrade(*d_tuple)
-                            else:
-                                raise e
-                    else: # we have a klass for get_descriptor
-                        new_module_desc = reg.get_descriptor(new_module_type)
-                   
-                    src_port_remap = remap.get('src_port_remap', {})
-                    dst_port_remap = remap.get('dst_port_remap', {})
-                    # !!! we're going to let dst_port_remap serve as a
-                    # base for function_remap but the developer is
-                    # responsible for knowing that anything beyond name
-                    # remaps requires different functions
-                    function_remap = copy.copy(dst_port_remap)
-                    function_remap.update(remap.get('function_remap', {}))
-                    annotation_remap = remap.get('annotation_remap', {})
-                    action_list = \
-                        UpgradeWorkflowHandler.replace_module(controller, 
-                                                              pipeline,
-                                                              module_id, 
-                                                              new_module_desc,
-                                                              function_remap,
-                                                              src_port_remap,
-                                                              dst_port_remap,
-                                                              annotation_remap)
-                    return action_list
+        if not isinstance(pkg_remap, UpgradePackageRemap):
+            pkg_remap = UpgradePackageRemap.from_dict(pkg_remap)
+        
+
+        action_list = []
+
+        old_module_t = \
+            (old_module.package, old_module.name, old_module.namespace)
+        module_remap = pkg_remap.get_module_upgrade(old_desc_str, old_version)
+        tmp_pipeline = copy.copy(pipeline)
+        while module_remap is not None:
+            new_module_type = module_remap.new_module
+            if new_module_type is None:
+                new_module_t = old_module_t
+            elif isinstance(new_module_type, basestring):
+                new_module_t = parse_descriptor_string(new_module_type,
+                                                       old_module_t[0])
+            else:
+                new_module_desc = reg.get_descriptor(new_module_type)
+                new_module_t = new_module_desc.spec_tuple
+
+            new_pkg_version = module_remap.output_version
+            if (new_pkg_version is None or
+                  reg.get_package_by_name(new_module_t[0]).version == new_pkg_version):
+                # upgrading to the current version
+                try:
+                    new_module_desc = reg.get_descriptor_by_name(*new_module_t)
+                except MissingModule, e:
+                    # if the replacement is an abstraction,
+                    # and it has been upgraded, we use that
+                    if reg.has_abs_upgrade(*new_module_t):
+                        new_module_desc = reg.get_abs_upgrade(*new_module_t)
+                    else:
+                        raise e
+                use_registry = True
+                next_module_remap = None
+            else:
+                new_module_desc = ModuleDescriptor(package=new_module_t[0],
+                                                   name=new_module_t[1],
+                                                   namespace=new_module_t[2],
+                                                   package_version=new_pkg_version)
+                use_registry = False
+
+                # need to try more upgrades since this one isn't current
+                old_desc_str = create_descriptor_string(new_module_t[0],
+                                                        new_module_t[1],
+                                                        new_module_t[2],
+                                                        False)
+                old_version = new_pkg_version
+                next_module_remap = pkg_remap.get_module_upgrade(old_desc_str,
+                                                                 old_version)
+                old_module_t = new_module_t
+            replace_module = UpgradeWorkflowHandler.replace_module
+            actions = replace_module(controller, 
+                                     tmp_pipeline,
+                                     module_id, 
+                                     new_module_desc,
+                                     module_remap.function_remap,
+                                     module_remap.src_port_remap,
+                                     module_remap.dst_port_remap,
+                                     module_remap.annotation_remap,
+                                     module_remap.control_param_remap,
+                                     use_registry)
+
+            for a in actions:
+                for op in a.operations:
+                    # Update the id of the module being updated
+                    if op.vtType == 'add' and op.what == 'module':
+                        module_id = op.objectId
+                tmp_pipeline.perform_action(a)
+
+            action_list.extend(actions)
+            module_remap = next_module_remap
+        if len(action_list) > 0:
+            return action_list
 
         # otherwise, just try to automatic upgrade
         # attempt_automatic_upgrade
@@ -576,3 +835,176 @@ class UpgradeWorkflowHandler(object):
                                                                 pipeline,
                                                                 module_id)
     
+import unittest
+
+class TestUpgradePackageRemap(unittest.TestCase):
+    def test_from_dict(self):
+        def outputName_remap(old_conn, new_module):
+            ops = []
+            return ops
+        pkg_remap_d = {'FileSink': [(None, '1.5.1', None,
+                                     {'dst_port_remap':
+                                      {'overrideFile': 'overwrite',
+                                       'outputName': outputName_remap},
+                                      'function_remap':
+                                      {'overrideFile': 'overwrite',
+                                       'outputName': 'outputPath'}})]}
+        pkg_remap = UpgradePackageRemap.from_dict(pkg_remap_d)
+
+    def create_workflow(self, c):
+        upgrade_test_pkg = 'org.vistrails.vistrails.tests.upgrade'
+
+        d1 = ModuleDescriptor(package=upgrade_test_pkg,
+                              name='TestUpgradeA',
+                              namespace='',
+                              package_version='0.8')
+        m1 = c.create_module_from_descriptor(d1, use_desc_pkg_version=True)
+        m1.is_valid = False
+        c.add_module_action(m1)
+
+        d2 = ModuleDescriptor(package=upgrade_test_pkg,
+                              name='TestUpgradeB',
+                              namespace='',
+                              package_version = '0.8')
+        m2 = c.create_module_from_descriptor(d2, use_desc_pkg_version=True)
+        m2.is_valid = False
+        c.add_module_action(m2)
+
+        basic_pkg = get_vistrails_basic_pkg_id()
+        psi = PortSpecItem(module="Float", package=basic_pkg,
+                           namespace="", pos=0)
+        function_port_spec = PortSpec(name="a", type="input", items=[psi])
+        f = c.create_function(m1, function_port_spec, [12])
+        c.add_function_action(m1, f)
+
+        conn_out_psi = PortSpecItem(module="Integer", package=basic_pkg,
+                                    namespace="", pos=0)
+        conn_out_spec = PortSpec(name="z", type="output",
+                                 items=[conn_out_psi])
+        conn_in_psi = PortSpecItem(module="Integer", package=basic_pkg,
+                                   namespace="", pos=0)
+        conn_in_spec = PortSpec(name="b", type="input",
+                                items=[conn_in_psi])
+        conn = c.create_connection(m1, conn_out_spec, m2, conn_in_spec)
+        c.add_connection_action(conn)
+        return c.current_version
+
+    def run_multi_upgrade_test(self, pkg_remap):
+        from vistrails.core.application import get_vistrails_application
+
+        app = get_vistrails_application()
+        created_vistrail = False
+        pm = get_package_manager()
+        try:
+            pm.late_enable_package('upgrades',
+                                   {'upgrades':
+                                    'vistrails.tests.resources.'})
+            app.new_vistrail()
+            created_vistrail = True
+            c = app.get_controller()
+            self.create_workflow(c)
+        
+            p = c.current_pipeline
+            actions = UpgradeWorkflowHandler.remap_module(c, 0, p, pkg_remap)
+        finally:
+            if created_vistrail:
+                app.close_vistrail()
+            try:
+                pm.late_disable_package('upgrades')
+            except MissingPackage:
+                pass
+
+    def test_multi_upgrade_obj(self):
+        module_remap_1 = UpgradeModuleRemap('0.8', '0.9', '0.9', None,
+                                            module_name="TestUpgradeA")
+        module_remap_1.add_remap('function_remap', 'a', 'aa')
+        module_remap_1.add_remap('src_port_remap', 'z', 'zz')
+        module_remap_2 = UpgradeModuleRemap('0.9', '1.0', '1.0', None,
+                                            module_name="TestUpgradeA")
+        module_remap_2.add_remap('function_remap', 'aa', 'aaa')
+        module_remap_2.add_remap('src_port_remap', 'zz', 'zzz')
+        pkg_remap = UpgradePackageRemap()
+        pkg_remap.add_module_remap(module_remap_1)
+        pkg_remap.add_module_remap(module_remap_2)
+        self.run_multi_upgrade_test(pkg_remap)
+
+    def test_multi_upgrade_dict(self):
+        pkg_remap = {"TestUpgradeA": 
+                     [UpgradeModuleRemap('0.8', '0.9', '0.9', None,
+                                         function_remap={'a': 'aa'},
+                                         src_port_remap={'z': 'zz'}),
+                      UpgradeModuleRemap('0.9', '1.0', '1.0', None,
+                                         function_remap={'aa': 'aaa'},
+                                         src_port_remap={'zz': 'zzz'})]}
+        self.run_multi_upgrade_test(pkg_remap)
+
+    def test_multi_upgrade_legacy(self):
+        # note that remap specifies the 0.8 -> 1.0 upgrade directly as
+        # must be the case for legacy upgrades
+        pkg_remap = {"TestUpgradeA": [('0.8', '1.0', None,
+                                       {"function_remap": {'a': 'aaa'},
+                                        "src_port_remap": {'z': 'zzz'}}),
+                                      ('0.9', '1.0', None,
+                                       {"function_remap": {'aa': 'aaa'},
+                                        "src_port_remap": {'zz': 'zzz'}})]}
+        self.run_multi_upgrade_test(pkg_remap)
+
+    def test_multi_upgrade_rename(self):
+        pkg_remap = {"TestUpgradeA": 
+                     [UpgradeModuleRemap('0.8', '0.9', '0.9', "TestUpgradeB",
+                                         dst_port_remap={'a': 'b'},
+                                         src_port_remap={'z': 'zz'})],
+                     "TestUpgradeB":
+                     [UpgradeModuleRemap('0.9', '1.0', '1.0', None,
+                                         src_port_remap={'zz': None})]}
+        self.run_multi_upgrade_test(pkg_remap)
+
+    def test_external_upgrade(self):
+        from vistrails.core.application import get_vistrails_application
+
+        app = get_vistrails_application()
+        default_upgrades = app.temp_configuration.upgrades
+        default_upgrade_delay = app.temp_configuration.upgradeDelay
+        app.temp_configuration.upgrades = True
+        app.temp_configuration.upgradeDelay = False
+
+        created_vistrail = False
+        pm = get_package_manager()
+        try:
+            pm.late_enable_package('upgrades',
+                                   {'upgrades':
+                                    'vistrails.tests.resources.'})
+            app.new_vistrail()
+            created_vistrail = True
+            c = app.get_controller()
+            current_version = self.create_workflow(c)
+            for m in c.current_pipeline.modules.itervalues():
+                self.assertEqual(m.version, '0.8')
+
+            c.change_selected_version(current_version, from_root=True)
+            
+            self.assertEqual(len(c.current_pipeline.modules), 2)
+            for m in c.current_pipeline.modules.itervalues():
+                self.assertEqual(m.version, '1.0')
+                if m.name == "TestUpgradeA":
+                    self.assertEqual(m.functions[0].name, 'aaa')
+            self.assertEqual(len(c.current_pipeline.connections), 1)
+            conn = c.current_pipeline.connections.values()[0]
+            self.assertEqual(conn.source.name, 'zzz')
+            self.assertEqual(conn.destination.name, 'b')
+                
+        finally:
+            if created_vistrail:
+                app.close_vistrail()
+            try:
+                pm.late_disable_package('upgrades')
+            except MissingPackage:
+                pass
+            app.temp_configuration.upgrades = default_upgrades
+            app.temp_configuration.upgradeDelay = default_upgrade_delay
+
+if __name__ == '__main__':
+    import vistrails.core.application
+
+    vistrails.core.application.init()
+    unittest.main()
diff --git a/vistrails/core/utils/__init__.py b/vistrails/core/utils/__init__.py
index 1b09d76..ff7220e 100644
--- a/vistrails/core/utils/__init__.py
+++ b/vistrails/core/utils/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,20 +37,21 @@
 This module defines common functions and exception class definitions
 used all over VisTrails.
 """
-from __future__ import with_statement
+from __future__ import division, with_statement
 
-import vistrails.core.debug
 from vistrails.core.utils.enum import enum
 from vistrails.core.utils.timemethod import time_method, time_call
 from vistrails.core.utils.tracemethod import trace_method, bump_trace, report_stack, \
      trace_method_options, trace_method_args
 from vistrails.core.utils.color import ColorByName
-from vistrails.core.utils.lockmethod import lock_method
 import copy
+from distutils.version import LooseVersion
 import errno
+import functools
 import itertools
 import os
 import sys
+import warnings
 import weakref
 
 
@@ -59,10 +61,13 @@ import tempfile
 ################################################################################
 
 def invert(d):
-    """invert(dict) -> dict. Returns an inverted dictionary by
-    switching key-value pairs. If you use this repeatedly,
-    consider switching the underlying data structure to a
-    core.data_structures.bijectivedict.Bidict instead."""
+    """invert(dict) -> dict. 
+
+    Returns an inverted dictionary by switching key-value pairs. If
+    you use this repeatedly, consider switching the underlying data
+    structure to a core.data_structures.bijectivedict.Bidict instead.
+
+    """
     return dict([[v,k] for k,v in d.items()])
 
 ################################################################################
@@ -81,38 +86,69 @@ class VistrailsWarning(Warning):
 class VistrailsDeprecation(VistrailsWarning):
     pass
 
+def deprecated(*args):
+    new_name = None
+    def _deprecated(func):
+        @functools.wraps(func)
+        def new_func(*args, **kwargs):
+            if new_name is not None:
+                warnings.warn("Call to deprecated function %s "
+                              "replaced by %s" % (
+                                  func.__name__, new_name),
+                              category=VistrailsDeprecation,
+                              stacklevel=2)
+            else:
+                warnings.warn("Call to deprecated function %s" % func.__name__,
+                              category=VistrailsDeprecation,
+                              stacklevel=2)
+            return func(*args, **kwargs)
+        return new_func
+    if len(args) == 1 and callable(args[0]):
+        return _deprecated(args[0])
+    else:
+        new_name = args[0]
+        return _deprecated
+
 ################################################################################
 
 class NoMakeConnection(Exception):
-    """NoMakeConnection is raised when a VisConnection doesn't know
-    how to create a live version of itself. This is an internal error
-    that should never be seen by a user. Please report a bug if you
-    see this."""
+    """NoMakeConnection is raised when a VisConnection doesn't know how to
+    create a live version of itself. This is an internal error that
+    should never be seen by a user. Please report a bug if you see
+    this.
+
+    """
     def __init__(self, conn):
         self.conn = conn
     def __str__(self):
         return "Connection %s has no makeConnection method" % self.conn
 
 class NoSummon(Exception):
-    """NoSummon is raised when a VisObject doesn't know how to create
-    a live version of itself. This is an internal error that should
-    never be seen by a user. Please report a bug if you see this."""
+    """NoSummon is raised when a VisObject doesn't know how to create a
+    live version of itself. This is an internal error that should
+    never be seen by a user. Please report a bug if you see this.
+
+    """
     def __init__(self, obj):
         self.obj = obj
     def __str__(self):
         return "Module %s has no summon method" % self.obj
 
 class UnimplementedException(Exception):
-    """UnimplementedException is raised when some interface hasn't
-    been implemented yet. This is an internal error that should never
-    be seen by a user. Please report a bug if you see this."""
+    """UnimplementedException is raised when some interface hasn't been
+    implemented yet. This is an internal error that should never be
+    seen by a user. Please report a bug if you see this.
+
+    """
     def __str__(self):
         return "Object is Unimplemented"
 
 class AbstractException(Exception):
     """AbstractException is raised when an abstract method is called.
     This is an internal error that should never be seen by a
-    user. Please report a bug if you see this."""
+    user. Please report a bug if you see this.
+
+    """
     def __str__(self):
         return "Abstract Method was called"
 
@@ -120,15 +156,17 @@ class VistrailsInternalError(Exception):
     """VistrailsInternalError is raised when an unexpected internal
     inconsistency happens. This is (clearly) an internal error that
     should never be seen by a user. Please report a bug if you see
-    this."""
-    def __init__(self, msg):
-        self.emsg = msg
+    this.
+
+    """
     def __str__(self):
-        return "Vistrails Internal Error: " + str(self.emsg)
+        return "Vistrails Internal Error: " + str(self.message)
 
 class VersionTooLow(Exception):
-    """VersionTooLow is raised when you're running an outdated version
-    of some necessary software or package."""
+    """VersionTooLow is raised when you're running an outdated version of
+    some necessary software or package.
+
+    """
     def __init__(self, sw, required_version):
         self.sw = sw
         self.required_version = required_version
@@ -140,8 +178,10 @@ class VersionTooLow(Exception):
                 " or later")
 
 class InvalidModuleClass(Exception):
-    """InvalidModuleClass is raised when there's something wrong with
-a class that's being registered as a module within VisTrails."""
+    """InvalidModuleClass is raised when there's something wrong with a
+    class that's being registered as a module within VisTrails.
+
+    """
 
     def __init__(self, klass):
         self.klass = klass
@@ -205,7 +245,7 @@ class InvalidPipeline(Exception):
         # it is invalid. So if it throws an Exception, we will just ignore
         try:
             self._pipeline = copy.copy(pipeline)
-        except:
+        except Exception:
             self._pipeline = None
         self._version = version
 
@@ -289,9 +329,7 @@ def save_profile_to_disk(callable_, filename):
     callable_.profiler_object.dump_stats(filename)
 
 def save_all_profiles():
-    # This is internal because core.system imports core.utils... :/
-    import vistrails.core.system
-    td = vistrails.core.system.temporary_directory()
+    td = tempfile.gettempdir()
     for (name, method) in get_profiled_methods():
         fout = td + name + '.pyp'
         #print fout
@@ -414,38 +452,13 @@ def version_string_to_list(version):
     numbers and strings:
 
     version_string('0.1') -> [0, 1]
-    version_string('0.9.9alpha') -> [0, 9, '9alpha']
+    version_string('0.9.9alpha1') -> [0, 9, 9, alpha', 1]
 
     """
-    def convert(value):
-        try:
-            return int(value)
-        except ValueError:
-            return value
-    return [convert(value) for value in version.split('.')]
+    return LooseVersion(version).version
 
 def versions_increasing(v1, v2):
-    v1_list = v1.split('.')
-    v1_list.reverse()
-    v2_list = v2.split('.')
-    v2_list.reverse()
-    try:
-        while len(v1_list) > 0 and len(v2_list) > 0:
-            v1_num = int(v1_list.pop())
-            v2_num = int(v2_list.pop())
-            if v1_num < v2_num:
-                return True
-            elif v1_num > v2_num:
-                return False
-        if len(v1_list) < len(v2_list):
-            return True
-        elif len(v1_list) > len(v2_list):
-            return False
-    except ValueError:
-        vistrails.core.debug.critical("Cannot compare versions whose components " +
-                       "are not integers")
-    return False
-                
+    return LooseVersion(v1) < LooseVersion(v2)
 
 ##############################################################################
 # DummyView & DummyScene
@@ -469,6 +482,7 @@ class DummyView(object):
     def set_module_not_executed(self, *args, **kwargs): pass
     def set_module_progress(self, *args, **kwargs): pass
     def set_module_persistent(self, *args, **kwargs): pass
+    def set_execution_progress(self, *args, **kwargs): pass
     def flushMoveActions(self, *args, **kwargs): pass
     def scene(self): 
         return self._scene
@@ -524,7 +538,44 @@ class Ref(object):
             import new
             instance_method = new.instancemethod
         return instance_method(self._func, self._obj(), self._clas)
-    
+
+###############################################################################
+
+def xor(first, *others):
+    """XORs bytestrings.
+
+    Example: xor('abcd', '\x20\x01\x57\x56') = 'Ac42'
+    """
+    l = len(first)
+    first = [ord(c) for c in first]
+    for oth in others:
+        if len(oth) != l:
+            raise ValueError("All bytestrings should have the same length: "
+                             "%d != %d" % (l, len(oth)))
+        first = [c ^ ord(o) for (c, o) in itertools.izip(first, oth)]
+    return ''.join(chr(c) for c in first)
+
+def long2bytes(nb, length=None):
+    """Turns a single integer into a little-endian bytestring.
+
+    Uses as many bytes as necessary or optionally pads to length bytes.
+    Might return a result longer than length.
+
+    Example: long2bytes(54321, 4) = b'\x31\xD4\x00\x00'
+    """
+    if nb < 0:
+        raise ValueError
+    elif nb == 0:
+        result = b'\x00'
+    else:
+        result = b''
+        while nb > 0:
+            result += chr(nb & 0xFF)
+            nb = nb >> 8
+    if length is not None and len(result) < length:
+        result += '\x00' * (length - len(result))
+    return result
+
 ################################################################################
 
 class Chdir(object):
@@ -609,7 +660,8 @@ class TestCommon(unittest.TestCase):
     def test_version_string_to_list(self):
         self.assertEquals(version_string_to_list("0.1"), [0, 1])
         self.assertEquals(version_string_to_list("1.0.2"), [1, 0, 2])
-        self.assertEquals(version_string_to_list("1.0.2beta"), [1, 0, '2beta'])
+        self.assertEquals(version_string_to_list("1.0.2beta"),
+                          [1, 0, 2, 'beta'])
     
     def test_ref(self):
         class C(object):
@@ -639,6 +691,61 @@ class TestCommon(unittest.TestCase):
         
         self.assertRaises(Exception, raise_exception)
         self.assertEquals(os.getcwd(), currentpath)
-        
+
+    def test_deprecated(self):
+        import re
+        def canon_path(path):
+            path = os.path.realpath(path)
+            p, f = os.path.dirname(path), os.path.basename(path)
+            f = re.split(r'[$.]', f)[0]
+            return os.path.join(p, f)
+        def check_warning(msg, f):
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                f(1, 2)
+            self.assertEqual(len(w), 1)
+            w, = w
+            self.assertEqual(w.message.message, msg)
+            self.assertEqual(w.category, VistrailsDeprecation)
+            self.assertTrue(canon_path(w.filename),
+                            canon_path(__file__))
+
+        @deprecated('repl1')
+        def func1(a, b):
+            self.assertEqual((a, b), (1, 2))
+        @deprecated
+        def func2(a, b):
+            self.assertEqual((a, b), (1, 2))
+        check_warning('Call to deprecated function func1 replaced by repl1',
+                      func1)
+        check_warning('Call to deprecated function func2', func2)
+
+        foo = None
+        class Foo(object):
+            @deprecated('repl1')
+            def meth1(s, a, b):
+                self.assertEqual((s, a, b), (foo, 1, 2))
+            @deprecated
+            def meth2(s, a, b):
+                self.assertEqual((s, a, b), (foo, 1, 2))
+            @staticmethod
+            @deprecated('repl3')
+            def meth3(a, b):
+                self.assertEqual((a, b), (1, 2))
+            @staticmethod
+            @deprecated
+            def meth4(a, b):
+                self.assertEqual((a, b), (1, 2))
+        foo = Foo()
+        check_warning('Call to deprecated function meth1 replaced by repl1',
+                      foo.meth1)
+        check_warning('Call to deprecated function meth2',
+                      foo.meth2)
+        check_warning('Call to deprecated function meth3 replaced by repl3',
+                      foo.meth3)
+        check_warning('Call to deprecated function meth4',
+                      foo.meth4)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/vistrails/core/utils/color.py b/vistrails/core/utils/color.py
index 0b20b30..d0e2dcd 100644
--- a/vistrails/core/utils/color.py
+++ b/vistrails/core/utils/color.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,6 +40,8 @@ color defines
 
 ################################################################################
 
+from __future__ import division
+
 class ColorByName(object):
     """
     Provides a list of colors that can be queried by name
@@ -415,9 +418,9 @@ class TestColorByName(unittest.TestCase):
         self.assertEquals(ColorByName.get_no_alpha('red'),
                           [1.0, 0.0, 0.0])
         self.assertEquals(ColorByName.get('not exist'),
-                          [0.0, 0.0, 0.0, 1.0]),        
+                          [0.0, 0.0, 0.0, 1.0])
         self.assertEquals(ColorByName.get_no_alpha('another not exist'),
-                          [0.0, 0.0, 0.0]),
+                          [0.0, 0.0, 0.0])
 
 
 class TestColorConversion(unittest.TestCase):
diff --git a/vistrails/core/utils/enum.py b/vistrails/core/utils/enum.py
index 3ab79b0..183e4b4 100644
--- a/vistrails/core/utils/enum.py
+++ b/vistrails/core/utils/enum.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """enum helps create enumeration classes.
 
 """
+from __future__ import division
+
 from itertools import izip
 
 def enum(className, enumValues, doc = None):
diff --git a/vistrails/core/utils/expression.py b/vistrails/core/utils/expression.py
index 98b9bb4..47e1e97 100644
--- a/vistrails/core/utils/expression.py
+++ b/vistrails/core/utils/expression.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ Helper functions for parsing and evaluating expressions """
 
+from __future__ import division
+
 ################################################################################
 
 def evaluate_expressions(expressions):
@@ -45,9 +48,9 @@ def evaluate_expressions(expressions):
     # FIXME: eval should pretty much never be used
     (base, exps) = parse_expression(str(expressions))
     for e in exps:
-        try:                        
-            base = base[:e[0]] + unicode(eval(e[1],None,None)) + base[e[0]:]
-        except:
+        try:
+            base = base[:e[0]] + unicode(eval(e[1], None, None)) + base[e[0]:]
+        except Exception:
             base = base[:e[0]] + '$' + e[1] + '$' + base[e[0]:]
     return base
 
diff --git a/vistrails/core/utils/gcutils.py b/vistrails/core/utils/gcutils.py
index 172130c..6d9badd 100644
--- a/vistrails/core/utils/gcutils.py
+++ b/vistrails/core/utils/gcutils.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Utilities for debugging garbage collection, leaked memory, etc."""
 
+from __future__ import division
+
 import gc
 
 def get_objects_by_typename():
diff --git a/vistrails/core/utils/lockmethod.py b/vistrails/core/utils/lockmethod.py
deleted file mode 100644
index 9006415..0000000
--- a/vistrails/core/utils/lockmethod.py
+++ /dev/null
@@ -1,99 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-def lock_method(lock):
-    
-    def decorator(method):
-        def decorated(self, *args, **kwargs):
-            try:
-                lock.acquire()
-                result = method(self, *args, **kwargs)
-            finally:
-                lock.release()
-            return result
-        decorated.func_doc = method.__doc__
-        return decorated
-
-    return decorator
-
-##############################################################################
-
-import unittest
-import threading
-
-class TestLockMethod(unittest.TestCase):
-
-    lock = threading.Lock()
-    @lock_method(lock)
-    def foo(self):
-        self.assertEquals(self.lock.locked(), True)
-
-    @lock_method(lock)
-    def foo_throws(self):
-        raise Exception()
-
-    @lock_method(lock)
-    def foo_finally(self):
-        try:
-            raise Exception
-            return False
-        finally:
-            return True
-
-    @lock_method(lock)
-    def foo_docstring(self):
-        """FOO"""
-        pass
-
-    def test_common(self):
-        self.assertEquals(self.lock.locked(), False)
-        self.foo()
-        self.assertEquals(self.lock.locked(), False)
-
-    def test_throws(self):
-        self.assertEquals(self.lock.locked(), False)
-        self.assertRaises(Exception, self.foo_throws)
-        self.assertEquals(self.lock.locked(), False)
-
-    def test_finally(self):
-        self.assertEquals(self.lock.locked(), False)
-        self.assertEquals(self.foo_finally(), True)
-        self.assertEquals(self.lock.locked(), False)
-
-    def test_docstring(self):
-        self.assertEquals(self.foo_docstring.__doc__, "FOO")
-        
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/vistrails/core/utils/timemethod.py b/vistrails/core/utils/timemethod.py
index f43b8d4..7bbe5d3 100644
--- a/vistrails/core/utils/timemethod.py
+++ b/vistrails/core/utils/timemethod.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """Defines a time decorator that times function calls."""
 
+from __future__ import division
+
 import time
 
 def time_method(method):
diff --git a/vistrails/core/utils/tracemethod.py b/vistrails/core/utils/tracemethod.py
index 6054dbd..85a8702 100644
--- a/vistrails/core/utils/tracemethod.py
+++ b/vistrails/core/utils/tracemethod.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,6 +38,8 @@ thread-safe. It won't crash, but the bump() printouts might not be correct.
 
 Also defines report_stack, a decorator that dumps the traceback whenever
 a method gets called."""
+from __future__ import division
+
 import sys
 import traceback
 from vistrails.core.data_structures.stack import Stack
@@ -103,11 +106,11 @@ def report_stack(method):
         print "-" * 78
         try:
             print "Method: " + method.im_class.__name__ + '.' + method.__name__
-        except:
+        except AttributeError:
             pass
         try:
             print "Function: " + method.func_name
-        except:
+        except AttributeError:
             pass
         traceback.print_stack()
         print "-" * 78
diff --git a/vistrails/core/utils/uxml.py b/vistrails/core/utils/uxml.py
index 3d93a38..1f7902a 100644
--- a/vistrails/core/utils/uxml.py
+++ b/vistrails/core/utils/uxml.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.dom import minidom
 import xml.parsers.expat
 import __builtin__
diff --git a/vistrails/core/vistrail/__init__.py b/vistrails/core/vistrail/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/core/vistrail/__init__.py
+++ b/vistrails/core/vistrail/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/core/vistrail/abstraction.py b/vistrails/core/vistrail/abstraction.py
index d0faf55..718a5ae 100644
--- a/vistrails/core/vistrail/abstraction.py
+++ b/vistrails/core/vistrail/abstraction.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 
 from vistrails.core.modules.module_registry import get_module_registry
@@ -40,6 +43,7 @@ from vistrails.core.utils import VistrailsInternalError
 from vistrails.core.vistrail.annotation import Annotation
 from vistrails.core.vistrail.location import Location
 from vistrails.core.vistrail.module import Module
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.db.domain import DBAbstraction
 
@@ -98,6 +102,8 @@ class Abstraction(DBAbstraction, Module):
             ModuleFunction.convert(_function)
         for _annotation in _abstraction.db_get_annotations():
             Annotation.convert(_annotation)
+        for _control_parameter in _abstraction.db_get_controlParameters():
+            ModuleControlParam.convert(_control_parameter)
         _abstraction.set_defaults()
 
     ##########################################################################
@@ -107,6 +113,7 @@ class Abstraction(DBAbstraction, Module):
     id = DBAbstraction.db_id
     cache = DBAbstraction.db_cache
     annotations = DBAbstraction.db_annotations
+    control_parameters = DBAbstraction.db_controlParameters
     location = DBAbstraction.db_location
     center = DBAbstraction.db_location
     name = DBAbstraction.db_name
@@ -124,7 +131,7 @@ class Abstraction(DBAbstraction, Module):
         try:
             desc = reg.get_descriptor_by_name(self.package, self.name, 
                                               self.namespace)
-        except:
+        except Exception:
             # Should only get here if the abstraction's descriptor was
             # removed from the registry which only happens when the
             # abstraction should be destroyed.
diff --git a/vistrails/core/vistrail/action.py b/vistrails/core/vistrail/action.py
index 565e2bb..44f94c0 100644
--- a/vistrails/core/vistrail/action.py
+++ b/vistrails/core/vistrail/action.py
@@ -1,47 +1,49 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from datetime import date, datetime
-from time import strptime
 
-from vistrails.core.vistrail.annotation import Annotation
-from vistrails.core.vistrail.operation import AddOp, ChangeOp, DeleteOp
-from vistrails.db.domain import DBAction
-from itertools import izip
+from __future__ import division
 
+from datetime import datetime
+from itertools import izip
 import unittest
-import vistrails.core
+
+from vistrails.db.domain import DBAction
+from vistrails.core.system import strftime, time_strptime
+from vistrails.core.vistrail.annotation import Annotation
+from vistrails.core.vistrail.operation import AddOp, ChangeOp, DeleteOp
 
 class Action(DBAction):
 
@@ -88,14 +90,14 @@ class Action(DBAction):
 
     def _get_date(self):
         if self.db_date is not None:
-            return self.db_date.strftime('%d %b %Y %H:%M:%S')
-        return datetime(1900,1,1).strftime('%d %b %Y %H:%M:%S')
+            return strftime(self.db_date, '%d %b %Y %H:%M:%S')
+        return strftime(datetime(1900,1,1), '%d %b %Y %H:%M:%S')
 
     def _set_date(self, date):
         if isinstance(date, datetime):
             self.db_date = date
         elif isinstance(date, basestring) and date.strip() != '':
-            newDate = datetime(*strptime(date, '%d %b %Y %H:%M:%S')[0:6])
+            newDate = datetime(*time_strptime(date, '%d %b %Y %H:%M:%S')[0:6])
             self.db_date = newDate
     date = property(_get_date, _set_date)
 
@@ -197,9 +199,7 @@ class TestAction(unittest.TestCase):
         from vistrails.core.vistrail.module import Module
         from vistrails.core.vistrail.module_function import ModuleFunction
         from vistrails.core.vistrail.module_param import ModuleParam
-        from vistrails.core.vistrail.operation import AddOp
         from vistrails.db.domain import IdScope
-        from datetime import datetime
         
         if id_scope is None:
             id_scope = IdScope()
@@ -247,7 +247,7 @@ class TestAction(unittest.TestCase):
 
     def test1(self):
         """Exercises aliasing on modules"""
-        import vistrails.core.vistrail
+        import vistrails.core.system
         from vistrails.core.db.locator import XMLFileLocator
         v = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
                            '/tests/resources/dummy.xml').load()
@@ -260,7 +260,6 @@ class TestAction(unittest.TestCase):
 
     def test2(self):
         """Exercises aliasing on points"""
-        import vistrails.core.vistrail
         from vistrails.core.db.locator import XMLFileLocator
         import vistrails.core.system
         v = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
diff --git a/vistrails/core/vistrail/action_annotation.py b/vistrails/core/vistrail/action_annotation.py
index 782c51e..81b55b7 100644
--- a/vistrails/core/vistrail/action_annotation.py
+++ b/vistrails/core/vistrail/action_annotation.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBActionAnnotation
 
 import unittest
diff --git a/vistrails/core/vistrail/annotation.py b/vistrails/core/vistrail/annotation.py
index 6b38855..fb48fad 100644
--- a/vistrails/core/vistrail/annotation.py
+++ b/vistrails/core/vistrail/annotation.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBAnnotation
 
 import unittest
diff --git a/vistrails/core/vistrail/connection.py b/vistrails/core/vistrail/connection.py
index 8d93bf2..a70e4c9 100644
--- a/vistrails/core/vistrail/connection.py
+++ b/vistrails/core/vistrail/connection.py
@@ -1,44 +1,45 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.configuration import get_vistrails_configuration
 """ This python module defines Connection class.
 """
 import copy
 from vistrails.db.domain import DBConnection
-from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.modules.vistrails_module import ModuleConnector
 from vistrails.core.vistrail.port import PortEndPoint, Port
 
 import unittest
@@ -46,43 +47,6 @@ from vistrails.db.domain import IdScope
 
 ################################################################################
 
-Variant_desc = None
-InputPort_desc = None
-
-def moduleConnection(conn):
-    """moduleConnection(conn)-> function
-    Returns a function to build a module connection
-
-    """
-    def theFunction(src, dst):
-        global Variant_desc, InputPort_desc
-        if Variant_desc is None:
-            reg = get_module_registry()
-            Variant_desc = reg.get_descriptor_by_name(
-                    'org.vistrails.vistrails.basic', 'Variant')
-            InputPort_desc = reg.get_descriptor_by_name(
-                    'org.vistrails.vistrails.basic', 'InputPort')
-
-        iport = conn.destination.name
-        oport = conn.source.name
-        src.enableOutputPort(oport)
-        conf = get_vistrails_configuration()
-        error_on_others = getattr(conf, 'errorOnConnectionTypeerror')
-        error_on_variant = (error_on_others or
-                            getattr(conf, 'errorOnVariantTypeerror'))
-        errors = [error_on_others, error_on_variant]
-        if isinstance(src, InputPort_desc.module):
-            typecheck = [False]
-        else:
-            typecheck = [errors[desc is Variant_desc]
-                         for desc in conn.source.spec.descriptors()]
-        dst.set_input_port(
-                iport,
-                ModuleConnector(src, oport, conn.destination.spec, typecheck))
-    return theFunction
-
-################################################################################
-
 class Connection(DBConnection):
     """ A Connection is a connection between two modules.
     Right now there's only Module connections.
@@ -127,9 +91,6 @@ class Connection(DBConnection):
         if not len(self.ports) > 0:
             self.source = Port(type='source')
             self.destination = Port(type='destination')
-#             self.source.endPoint = PortEndPoint.Source
-#             self.destination.endPoint = PortEndPoint.Destination
-        self.makeConnection = moduleConnection(self)
 
     def __copy__(self):
         """__copy__() -> Connection -  Returns a clone of self.
@@ -140,7 +101,6 @@ class Connection(DBConnection):
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
         cp = DBConnection.do_copy(self, new_ids, id_scope, id_remap)
         cp.__class__ = Connection
-        cp.makeConnection = moduleConnection(cp)
         for port in cp.ports:
             Port.convert(port)
         return cp
@@ -157,46 +117,6 @@ class Connection(DBConnection):
         for port in _connection.ports:
             Port.convert(port)
 
-#         _connection.sourceInfo = \
-#             (_connection.source.moduleName, _connection.source.sig)
-#         _connection.destinationInfo = \
-#             (_connection.destination.moduleName, _connection.destination.sig)
-# #        print _connection.sourceInfo
-# #        print _connection.destinationInfo
-#         portFromRepresentation = registry.portFromRepresentation
-#         newSource = \
-#             portFromRepresentation(_connection.source.moduleName, 
-#                                    _connection.source.sig,
-#                                    PortEndPoint.Source, None, True)
-#         newDestination = \
-#             portFromRepresentation(_connection.destination.moduleName,
-#                                    _connection.destination.sig,
-#                                    PortEndPoint.Destination, None, True)
-#         newSource.moduleId = _connection.source.moduleId
-#         newDestination.moduleId = _connection.destination.moduleId
-#         _connection.source = newSource
-#         _connection.destination = newDestination
-        _connection.makeConnection = moduleConnection(_connection)
-
-
-    ##########################################################################
-    # Debugging
-
-    def show_comparison(self, other):
-        if type(other) != type(self):
-            print "Type mismatch"
-            return
-        if self.__source != other.__source:
-            print "Source mismatch"
-            self.__source.show_comparison(other.__source)
-            return
-        if self.__dest != other.__dest:
-            print "Dest mismatch"
-            self.__dest.show_comparison(other.__dest)
-            return
-        print "no difference found"
-        assert self == other
-
     ##########################################################################
     # Properties
 
@@ -216,8 +136,8 @@ class Connection(DBConnection):
 
     def _set_sourceId(self, id):
         """ _set_sourceId(id : int) -> None 
-        Sets this connection source id. It updates both self.__source.moduleId
-        and self.__source.id. Do not use this function, use sourceId 
+        Sets this connection source id. It updates both self.source.moduleId
+        and self.source.id. Do not use this function, use sourceId
         property: c.sourceId = id
 
         """
@@ -235,7 +155,7 @@ class Connection(DBConnection):
 
     def _set_destinationId(self, id):
         """ _set_destinationId(id : int) -> None 
-        Sets this connection destination id. It updates self.__dest.moduleId. 
+        Sets this connection destination id. It updates self.dest.moduleId.
         Do not use this function, use destinationId property: 
         c.destinationId = id
 
@@ -243,25 +163,6 @@ class Connection(DBConnection):
         self.destination.moduleId = id
     destinationId = property(_get_destinationId, _set_destinationId)
 
-    def _get_type(self):
-        """_get_type() -> VistrailModuleType - Returns this connection type.
-        Do not use this function, use type property: c.type = t 
-
-        """
-        return self.source.type
-
-    def _set_type(self, t):
-        """ _set_type(t: VistrailModuleType) -> None 
-        Sets this connection type and updates self.__source.type and 
-        self.__dest.type. It also updates the correct makeConnection function.
-        Do not use this function, use type property: c.type = t
-
-        """
-        self.source.type = t
-        self.destination.type = t
-        self.updateMakeConnection()
-    type = property(_get_type, _set_type)
-
     def _get_source(self):
         """_get_source() -> Port
         Returns source port. Do not use this function, use source property: 
@@ -276,9 +177,8 @@ class Connection(DBConnection):
 
     def _set_source(self, source):
         """_set_source(source: Port) -> None 
-        Sets this connection source port. It also updates this connection 
-        makeConnection function. Do not use this function, use source 
-        property instead: c.source = source
+        Sets this connection source port. Do not use this function,
+        use source property instead: c.source = source
 
         """
         try:
@@ -304,10 +204,9 @@ class Connection(DBConnection):
         return None
 
     def _set_destination(self, dest):
-        """_set_destination(dest: Port) -> None 
-        Sets this connection destination port. It also updates this connection 
-        makeConnection function. Do not use this function, use destination 
-        property instead: c.destination = dest
+        """_set_destination(dest: Port) -> None
+         Sets this connection destination port. Do not use this
+        function, use destination property instead: c.destination = dest
 
         """
         try:
@@ -391,13 +290,6 @@ class TestConnection(unittest.TestCase):
         self.assertEquals(c1, c2)
         self.assertEquals(c1.id, c2.id)
 
-    def testModuleConnection(self):
-        a = Connection.fromID(0)
-        c = moduleConnection(a)
-        def bogus(asd):
-            return 3
-        assert type(c) == type(bogus)
-
     def testEmptyConnection(self):
         """Tests sane initialization of empty connection"""
         c = Connection()
diff --git a/vistrails/core/vistrail/controller.py b/vistrails/core/vistrail/controller.py
index 47a3852..e87efca 100644
--- a/vistrails/core/vistrail/controller.py
+++ b/vistrails/core/vistrail/controller.py
@@ -1,81 +1,87 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from itertools import izip
 import os
 import uuid
+import re
 import shutil
 import tempfile
 
-from vistrails.core.configuration import get_vistrails_configuration, \
-                                         get_vistrails_persistent_configuration
+from vistrails.core.configuration import get_vistrails_configuration
 import vistrails.core.db.action
 import vistrails.core.db.io
 import vistrails.core.db.locator
 from vistrails.core import debug
 from vistrails.core.data_structures.graph import Graph
 from vistrails.core.interpreter.default import get_default_interpreter
+from vistrails.core.vistrail.job import JobMonitor
 from vistrails.core.layout.workflow_layout import WorkflowLayout, \
     Pipeline as LayoutPipeline, Defaults as LayoutDefaults
-from vistrails.core.log.controller import LogControllerFactory, DummyLogController
+from vistrails.core.log.controller import LogController, DummyLogController
 from vistrails.core.log.log import Log
 from vistrails.core.modules.abstraction import identifier as abstraction_pkg, \
     version as abstraction_ver
 from vistrails.core.modules.basic_modules import identifier as basic_pkg
+from vistrails.core.modules.module_descriptor import ModuleDescriptor
 import vistrails.core.modules.module_registry
 from vistrails.core.modules.module_registry import ModuleRegistryException, \
     MissingModuleVersion, MissingModule, MissingPackageVersion, MissingPort, \
     MissingPackage, PortsIncompatible
 from vistrails.core.modules.package import Package
 from vistrails.core.modules.sub_module import new_abstraction, read_vistrail, \
-    get_all_abs_namespaces, get_cur_abs_namespace, get_cur_abs_annotation_key, \
-    get_next_abs_annotation_key, save_abstraction, parse_abstraction_name
-from vistrails.core.packagemanager import PackageManager, get_package_manager
+    get_all_abs_namespaces, get_cur_abs_namespace, get_next_abs_annotation_key, save_abstraction, parse_abstraction_name
+from vistrails.core.packagemanager import get_package_manager
 import vistrails.core.packagerepository
 from vistrails.core.thumbnails import ThumbnailCache
 from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler, UpgradeWorkflowError
 from vistrails.core.utils import VistrailsInternalError, PortAlreadyExists, DummyView, \
     InvalidPipeline
-from vistrails.core.system import vistrails_default_file_type
+from vistrails.core.system import vistrails_default_file_type, \
+    get_vistrails_directory
 from vistrails.core.vistrail.abstraction import Abstraction
 from vistrails.core.vistrail.action import Action
 from vistrails.core.vistrail.annotation import Annotation
 from vistrails.core.vistrail.connection import Connection
 from vistrails.core.vistrail.group import Group
 from vistrails.core.vistrail.location import Location
-from vistrails.core.vistrail.module import Module, ModuleFunction, ModuleParam
+from vistrails.core.vistrail.module import Module
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.core.vistrail.module_param import ModuleParam
 from vistrails.core.vistrail.pipeline import Pipeline
@@ -91,6 +97,7 @@ from vistrails.db.services.io import SaveBundle, open_vt_log_from_db
 from vistrails.db.services.vistrail import getSharedRoot
 from vistrails.core.utils import any
 
+
 def vt_action(description_or_f=None):
     def get_f(f, description=None):
         def new_f(self, *args, **kwargs):
@@ -122,6 +129,19 @@ class CompareThumbnailsError(Exception):
         return "Comparing thumbnails failed.\n%s\n%s\n%s" % \
             (self._msg, self._first, self._second)
 
+def dot_escape(s):
+    return '"%s"' % s.replace('\\', '\\\\').replace('"', '\\"')
+
+custom_color_key = '__color__'
+
+custom_color_fmt = re.compile(r'^([0-9]+) *, *([0-9]+) *, *([0-9]+)$')
+
+def parse_custom_color(color):
+    m = custom_color_fmt.match(color)
+    if not m:
+        raise ValueError("Color annotation doesn't match format")
+    return tuple(int(m.group(i)) for i in xrange(1, 4))
+
 class VistrailController(object):
     def __init__(self, vistrail=None, locator=None, abstractions=None, 
                  thumbnails=None, mashups=None, id_scope=None, 
@@ -133,6 +153,7 @@ class VistrailController(object):
         self.file_name = ''
         self.is_abstraction = False
         self.changed = False
+        self._upgrade_rev_map = None
 
         # if _cache_pipelines is True, cache pipelines to speed up
         # version switching
@@ -140,6 +161,7 @@ class VistrailController(object):
         self.flush_pipeline_cache()
         self._current_full_graph = None
         self._current_terse_graph = None
+        self.show_upgrades = False
         self.num_versions_always_shown = 1
 
         # if self.search is True, vistrail is currently being searched
@@ -170,7 +192,7 @@ class VistrailController(object):
         # theme used to estimate module size for layout
         self.layoutTheme = DefaultCoreTheme()
         
-        self.set_vistrail(vistrail, locator, 
+        self.set_vistrail(vistrail, locator,
                           abstractions=abstractions, 
                           thumbnails=thumbnails,
                           mashups=mashups,
@@ -184,6 +206,14 @@ class VistrailController(object):
         self._current_version = version
     current_version = property(_get_current_version, _set_current_version)
 
+    def _get_current_base_version(self):
+        version = self.current_version
+        if self._upgrade_rev_map:
+            return self._upgrade_rev_map.get(version, version)
+        else:
+            return version
+    current_base_version = property(_get_current_base_version)
+
     def _get_current_pipeline(self):
         return self._current_pipeline
     def _set_current_pipeline(self, pipeline):
@@ -194,13 +224,13 @@ class VistrailController(object):
         self._pipelines = {0: Pipeline()}
 
     def logging_on(self):
-        return not get_vistrails_configuration().check('nologger')
+        return get_vistrails_configuration().check('executionLog')
             
     def get_logger(self):
         if self.logging_on():
-            return LogControllerFactory.getInstance().create_logger(self.log)
+            return LogController(self.log)
         else:
-            return DummyLogController()
+            return DummyLogController
         
     def get_locator(self):
         return self.locator
@@ -224,6 +254,11 @@ class VistrailController(object):
                 ThumbnailCache.getInstance().add_entries_from_files(thumbnails)
             if mashups is not None:
                 self._mashups = mashups
+            job_annotation = vistrail.get_annotation('__jobs__')
+            self.jobMonitor = JobMonitor(job_annotation and job_annotation.value)
+        else:
+            self.jobMonitor = JobMonitor()
+
         self.current_version = -1
         self.current_pipeline = Pipeline()
         if self.locator != locator and self.locator is not None:
@@ -237,7 +272,7 @@ class VistrailController(object):
             self.set_changed(True)
         if self.vistrail is not None:
             self.recompute_terse_graph()
-        
+
     def close_vistrail(self, locator):
         if not self.vistrail.is_abstraction:
             self.unload_abstractions()
@@ -264,7 +299,7 @@ class VistrailController(object):
         Change the controller file name
         
         """
-        if file_name == None:
+        if file_name is None:
             file_name = ''
         if self.file_name!=file_name:
             self.file_name = file_name
@@ -506,7 +541,7 @@ class VistrailController(object):
         added_upgrade = False
         should_migrate_tags = get_vistrails_configuration().check("migrateTags")
         for action in self._delayed_actions:
-            self.vistrail.add_action(action, start_version, 
+            self.vistrail.add_action(action, start_version,
                                      self.current_session)
             # HACK to populate upgrade information
             if (action.has_annotation_with_key(desc_key) and
@@ -539,15 +574,20 @@ class VistrailController(object):
             self.recompute_terse_graph()
             self.invalidate_version_tree(False)
 
-    def perform_action(self, action):
+    def perform_action(self, action, do_validate=True, raise_exception=False):
         """ performAction(action: Action) -> timestep
-        
+
         Performs given action on current pipeline.
-        
+
+        By default, the resulting pipeline will get validated, but no exception
+        will be raised if it is invalid. However you will get these on your
+        next call to change_selected_version().
         """
         if action is not None:
             self.current_pipeline.perform_action(action)
             self.current_version = action.db_id
+            if do_validate:
+                self.validate(self.current_pipeline, raise_exception)
             return action.db_id
         return None
 
@@ -579,9 +619,14 @@ class VistrailController(object):
     @staticmethod
     def create_module_from_descriptor_static(id_scope, descriptor, 
                                              x=0.0, y=0.0, 
-                                             internal_version=-1):
+                                             internal_version=-1,
+                                             use_desc_pkg_version=False):
         reg = vistrails.core.modules.module_registry.get_module_registry()
-        package = reg.get_package_by_name(descriptor.identifier)
+        if not use_desc_pkg_version:
+            package = reg.get_package_by_name(descriptor.identifier)
+            pkg_version = package.version
+        else:
+            pkg_version = descriptor.package_version
         loc_id = id_scope.getNewId(Location.vtType)
         location = Location(id=loc_id,
                             x=x, 
@@ -589,7 +634,7 @@ class VistrailController(object):
                             )
         if internal_version > -1:
             # only get the current namespace if this is a local subworkflow
-            if package == abstraction_pkg:
+            if descriptor.identifier == abstraction_pkg:
                 namespace = get_cur_abs_namespace(descriptor.module.vistrail)
             else:
                 namespace = descriptor.namespace
@@ -598,7 +643,7 @@ class VistrailController(object):
                                  name=descriptor.name,
                                  package=descriptor.identifier,
                                  namespace=namespace,
-                                 version=package.version,
+                                 version=pkg_version,
                                  location=location,
                                  internal_version=internal_version,
                                  )
@@ -609,7 +654,7 @@ class VistrailController(object):
                            name=descriptor.name,
                            package=descriptor.identifier,
                            namespace=descriptor.namespace,
-                           version=package.version,
+                           version=pkg_version,
                            location=location,
                            )
         else:
@@ -618,7 +663,7 @@ class VistrailController(object):
                             name=descriptor.name,
                             package=descriptor.identifier,
                             namespace=descriptor.namespace,
-                            version=package.version,
+                            version=pkg_version,
                             location=location,
                             )
         module.is_valid = True
@@ -635,6 +680,20 @@ class VistrailController(object):
         static_call = VistrailController.create_module_from_descriptor_static
         return static_call(id_scope, d, x, y, internal_version)
 
+    def create_old_module(self, *args, **kwargs):
+        return self.create_old_module_static(self.id_scope, *args, **kwargs)
+
+    @staticmethod
+    def create_old_module_static(id_scope, identifier, name, namespace='', 
+                                 version='', x=0.0, y=0.0, internal_version=-1):
+        dummy_d = ModuleDescriptor(name=name, 
+                                   package=identifier, 
+                                   namespace=namespace, 
+                                   package_version=version, 
+                                   internal_version=internal_version)
+        return VistrailController.create_module_from_descriptor_static(
+            id_scope, dummy_d, x, y, internal_version, True)
+
     def create_connection_from_ids(self, output_id, output_port_spec,
                                        input_id, input_port_spec):
         output_module = self.current_pipeline.modules[output_id]
@@ -736,9 +795,10 @@ class VistrailController(object):
         return self.create_function_static(self.id_scope, *args, **kwargs)
 
     @staticmethod
-    def create_function_static(id_scope, module, function_name, 
+    def create_function_static(id_scope, module, port_spec,
                                param_values=[], aliases=[], query_methods=[]):
-        port_spec = module.get_port_spec(function_name, 'input')
+        if isinstance(port_spec, basestring):
+            port_spec = module.get_port_spec(port_spec, 'input')
         if (len(param_values) <= 0 and port_spec.defaults is not None and
             any(d is not None for d in port_spec.defaults)):
             param_values = port_spec.defaults
@@ -746,7 +806,7 @@ class VistrailController(object):
         f_id = id_scope.getNewId(ModuleFunction.vtType)
         new_function = ModuleFunction(id=f_id,
                                       pos=module.getNumFunctions(),
-                                      name=function_name,
+                                      name=port_spec.name,
                                       )
         new_function.is_valid = True
         new_params = \
@@ -767,24 +827,23 @@ class VistrailController(object):
             -> [ModuleFunction]
         
         """
-        new_functions = []
         static_call = VistrailController.create_function_static
-        for f in functions:
-            new_functions.append(static_call(id_scope, module, *f))
-        return new_functions
+        return [static_call(id_scope, module, *f) for f in functions]
 
     def create_port_spec(self, *args, **kwargs):
         return self.create_port_spec_static(self.id_scope, *args, **kwargs)
     
     @staticmethod
     def create_port_spec_static(id_scope, module, port_type, port_name, 
-                                port_sigstring, port_sort_key=-1):
+                                port_sigstring, port_sort_key=-1,
+                                port_depth=0):
         p_id = id_scope.getNewId(PortSpec.vtType)
         port_spec = PortSpec(id=p_id,
                              type=port_type,
                              name=port_name,
                              sigstring=port_sigstring,
                              sort_key=port_sort_key,
+                             depth=port_depth
                              )
         # don't know how many port spec items are created until after...
         for psi in port_spec.port_spec_items:
@@ -1203,6 +1262,48 @@ class VistrailController(object):
                                                         module.id)])
         return action
 
+    @vt_action
+    def delete_control_parameter(self, name, module_id):
+        """ delete_control_parameter(name: str, module_id: long) -> version_id
+        Deletes an control_parameter from a module
+
+        """
+        module = self.current_pipeline.get_module_by_id(module_id)
+        control_parameter = module.get_control_parameter_by_name(name)
+        action = vistrails.core.db.action.create_action([('delete', control_parameter,
+                                                module.vtType, module.id)])
+        return action
+
+    @vt_action
+    def add_control_parameter(self, pair, module_id):
+        """ add_control_parameter(pair: (str, str), moduleId: int)
+        Add/Update a name/value pair control_parameter into the module of
+        moduleId
+
+        """
+        assert isinstance(pair[0], basestring)
+        assert isinstance(pair[1], basestring)
+        if pair[0].strip()=='':
+            return
+
+        module = self.current_pipeline.get_module_by_id(module_id)
+        a_id = self.vistrail.idScope.getNewId(ModuleControlParam.vtType)
+        control_parameter = ModuleControlParam(id=a_id,
+                                name=pair[0],
+                                value=pair[1],
+                                )
+        if module.has_control_parameter_with_name(pair[0]):
+            old_control_parameter = module.get_control_parameter_by_name(pair[0])
+            action = \
+                vistrails.core.db.action.create_action([('change', old_control_parameter,
+                                                   control_parameter,
+                                                   module.vtType, module.id)])
+        else:
+            action = vistrails.core.db.action.create_action([('add', control_parameter,
+                                                        module.vtType,
+                                                        module.id)])
+        return action
+
     def update_functions_ops_from_ids(self, module_id, functions):
         module = self.current_pipeline.modules[module_id]
         return self.update_functions_ops(module, functions)
@@ -1311,6 +1412,8 @@ class VistrailController(object):
         op_list.append(('add', group))
         op_list.extend(('add', c) for c in connections)
         action = vistrails.core.db.action.create_action(op_list)
+        self.set_action_annotation(action, Action.ANNOTATION_DESCRIPTION,
+                                   "Grouped modules")
         self.add_new_action(action)
 #         for op in action.operations:
 #             print op.vtType, op.what, op.old_obj_id, op.new_obj_id
@@ -1334,31 +1437,6 @@ class VistrailController(object):
         result = self.perform_action(action)
         return abstraction
 
-    def create_abstractions_from_groups(self, group_ids):
-        for group_id in group_ids:
-            self.create_abstraction_from_group(group_id)
-
-    def create_abstraction_from_group(self, group_id, name=""):
-        self.flush_delayed_actions()
-        name = self.get_abstraction_name(name)
-        
-        (abstraction, connections) = \
-            self.build_abstraction_from_group(self.current_pipeline, 
-                                              group_id, name)
-
-        op_list = []
-        getter = self.get_connections_to_and_from
-        op_list.extend(('delete', c)
-                       for c in getter(self.current_pipeline, [group_id]))
-        op_list.append(('delete', self.current_pipeline.modules[group_id]))
-        op_list.append(('add', abstraction))
-        op_list.extend(('add', c) for c in connections)
-        action = vistrails.core.db.action.create_action(op_list)
-        self.add_new_action(action)
-        result = self.perform_action(action)
-        return abstraction
-
-
     def ungroup_set(self, module_ids):
         self.flush_delayed_actions()
         for m_id in module_ids:
@@ -1377,6 +1455,8 @@ class VistrailController(object):
         op_list.extend(('add', m) for m in modules)
         op_list.extend(('add', c) for c in connections)
         action = vistrails.core.db.action.create_action(op_list)
+        self.set_action_annotation(action, Action.ANNOTATION_DESCRIPTION,
+                                   "Ungrouped modules")
         self.add_new_action(action)
         res = self.perform_action(action)
         self.validate(self.current_pipeline, False)
@@ -1492,10 +1572,11 @@ class VistrailController(object):
                     names = in_names
                     cur_names = in_cur_names
                     process_list = in_process_list
-                elif m.name == 'OutputPort':
+                else:  # m.name == 'OutputPort'
                     neighbors = self.get_upstream_neighbors(pipeline, m)
                     names = out_names
                     cur_names = out_cur_names
+                    process_list = out_process_list
                     
                 if len(neighbors) < 1:
                     # print "not adding, no neighbors"
@@ -1593,7 +1674,7 @@ class VistrailController(object):
                 if m.name == 'InputPort':
                     neighbors = self.get_downstream_neighbors(full_pipeline, m)
                     names = in_names
-                elif m.name == 'OutputPort':
+                else:  # m.name == 'OutputPort'
                     neighbors = self.get_upstream_neighbors(full_pipeline, m)
                     names = out_names
                 if len(neighbors) < 1:
@@ -1808,16 +1889,13 @@ class VistrailController(object):
         
     def get_abstraction_dir(self):
         conf = get_vistrails_configuration()
-        if conf.check('abstractionsDirectory'):
-            abstraction_dir = conf.abstractionsDirectory
-            if not os.path.exists(abstraction_dir):
-                raise VistrailsInternalError("Cannot find %s" % \
-                                                 abstraction_dir)
-            return abstraction_dir
-        else:
-            raise VistrailsInternalError("'abstractionsDirectory' not"
+        abstraction_dir = get_vistrails_directory("subworkflowsDir")
+        if abstraction_dir is None:
+            raise VistrailsInternalError("'subworkflowsDir' not"
                                          " specified in configuration")
-        return None
+        elif not os.path.exists(abstraction_dir):
+            raise VistrailsInternalError("Cannot find %s" % abstraction_dir)
+        return abstraction_dir
 
     def get_abstraction_desc(self, package, name, namespace, module_version=None):
         reg = vistrails.core.modules.module_registry.get_module_registry()
@@ -1976,13 +2054,6 @@ class VistrailController(object):
                                                     abs_name, None, 
                                                     module_version, 
                                                     is_global, avail_fnames)
-            #if desc.version != module_version:
-                #print "upgraded version", module_version, "of", abs_name, "(namespace: %s)"%abstraction_uuid, "to version", desc.version, "and namespace", desc.namespace
-#        else:
-#            if upgrade_version is not None:
-#                print "version", old_version, "of", abs_name, "(namespace: %s)"%abstraction_uuid, "already in registry as upgraded version", module_version
-#            else:
-#                print "version", module_version, "of", abs_name, "(namespace: %s)"%abstraction_uuid, "already in registry"
         return desc
     
     def unload_abstractions(self):
@@ -1994,56 +2065,10 @@ class VistrailController(object):
             for namespace in get_all_abs_namespaces(abs_vistrail):
                 try:
                     reg.delete_module(abstraction_pkg, abs_name, namespace)
-                except:
+                except Exception:
                     pass
         self._loaded_abstractions.clear()
 
-        # for abs_fname, abs_vistrail in self._loaded_abstractions.iteritems():
-        #     abs_desc_info = abs_vistrail.get_annotation('__abstraction_descriptor_info__')
-        #     if abs_desc_info is not None:
-        #         abs_desc_info = eval(abs_desc_info.value)
-        #         # Don't unload package abstractions that have been
-        #         # upgraded by this controller (during a manual version
-        #         # upgrade) because that would also unload the version
-        #         # in the module palette
-        #         if abs_desc_info[2] == abs_vistrail.get_annotation('__abstraction_uuid__').value:
-        #             continue
-        #     abs_name = parse_abstraction_name(abs_fname)
-        #     abs_namespace = abs_vistrail.get_annotation('__abstraction_uuid__').value
-        #     try:
-        #         descriptor = self.get_abstraction_descriptor(abs_name, abs_namespace)
-        #         print "removing all versions of", abs_name, "from registry (namespace: %s)"%abs_namespace
-        #         while descriptor is not None:
-        #             reg = core.modules.module_registry.get_module_registry()
-        #             reg.delete_module(abstraction_pkg, abs_name, abs_namespace)
-        #             descriptor = self.get_abstraction_descriptor(abs_name, abs_namespace)
-        #     except:
-        #         # No versions of the abstraction exist in the registry now
-        #         pass
-        # self._loaded_abstractions.clear()
-
-#    def update_abstraction(self, abstraction, new_actions):
-#        module_version = abstraction.internal_version
-#        if isinstance(module_version, basestring):
-#            module_version = int(module_version)
-#        abstraction_uuid = \
-#            abstraction.vistrail.get_annotation('__abstraction_uuid__').value
-#        upgrade_action = self.create_upgrade_action(new_actions) 
-#        
-#        a = (abstraction.vistrail, 
-#             module_version)
-#        
-#        desc = self.get_abstraction_desc(abstraction.name, abstraction_uuid,
-#                                         new_version)
-#        if desc is None:
-#            # desc = self.add_abstraction_to_registry(abstraction.vistrail,
-#            # abstraction.
-#            pass
-#        # FIXME finish this!
-                                         
-                                         
-        
-
     def manage_package_names(self, vistrail, package):
         vistrail = copy.copy(vistrail)
         dependencies = []
@@ -2361,12 +2386,11 @@ class VistrailController(object):
                                           descriptor_tuple[1],
                                           descriptor_tuple[4],
                                           [v for k, v in lookup.iteritems()
-                                           if k[1] != None])
+                                           if k[1] is not None])
                 descriptor_tuple = (new_desc.package, new_desc.name, 
                                     new_desc.namespace, new_desc.package_version,
                                     str(new_desc.version))
             return self.check_abstraction(descriptor_tuple, lookup)
-        return None
         
     def ensure_abstractions_loaded(self, vistrail, abs_fnames):
         lookup = {}
@@ -2390,11 +2414,10 @@ class VistrailController(object):
                 for abstraction in abstraction_list:
                     abstraction.module_descriptor = descriptor
             except InvalidPipeline, e:
-                debug.critical("Error loading abstraction '%s'" % \
-                               descriptor_info[1], str(e))
-            
-    def build_ungroup(self, full_pipeline, module_id):
+                debug.critical("Error loading abstraction '%s'" %
+                               descriptor_info[1], e)
 
+    def build_ungroup(self, full_pipeline, module_id):
         group = full_pipeline.modules[module_id]
         if group.vtType == Group.vtType:
             pipeline = group.pipeline
@@ -2403,57 +2426,55 @@ class VistrailController(object):
         else:
             print 'not a group or abstraction?'
             return
-      
+
         pipeline.ensure_connection_specs()
 
+        # First, we copy all the modules from inside the group pipeline to the
+        # outer pipeline.
+        # We skip the InputPort and OutputPort modules, which we add to
+        # port_modules instead.
+        port_modules = set()
         modules = []
         connections = []
         id_remap = {}
         for module in pipeline.module_list:
-            # FIXME have better checks for this
-            if module.package != basic_pkg or (module.name != 'InputPort' and
-                                               module.name != 'OutputPort'):
+            if module.package == basic_pkg and (module.name == 'InputPort' or
+                                                module.name == 'OutputPort'):
+                if module.name == 'InputPort':
+                    port_modules.add((module, 'input'))
+                else:
+                    port_modules.add((module, 'output'))
+            else:
                 modules.append(module.do_copy(True, self.id_scope, id_remap))
-        self.translate_modules(modules, -group.location.x, -group.location.y)
         module_index = dict([(m.id, m) for m in modules])
 
+        # If the connection was to/from an OutputPort/InputPort module, we
+        # store the association in open_ports so we can reconnect these to the
+        # outside later.
+        # We also add them to the unconnected_port_modules dictionary.
         open_ports = {}
-        for connection in pipeline.connection_list:
-            all_inside = True
-            all_outside = True
-            for port in connection.ports:
-                if (Module.vtType, port.moduleId) not in id_remap:
-                    all_inside = False
-                else:
-                    all_outside = False
-            
-            if all_inside:
-                connections.append(connection.do_copy(True, self.id_scope, 
-                                                      id_remap))
-            else:
-                if (Module.vtType, connection.source.moduleId) not in id_remap:
-                    port_module = \
-                        pipeline.modules[connection.source.moduleId]
-                    port_type = 'input'
-                elif (Module.vtType, connection.destination.moduleId) \
-                        not in id_remap:
-                    port_module = \
-                        pipeline.modules[connection.destination.moduleId]
-                    port_type = 'output'
-                else:
-                    continue
-
-                (port_name, _, _, neighbors) = \
-                    group.get_port_spec_info(port_module)
-                new_neighbors = \
-                    [(module_index[id_remap[(Module.vtType, m.id)]], n)
-                     for (m, n) in neighbors
-                     if (Module.vtType, m.id) in id_remap]
-                open_ports[(port_name, port_type)] = new_neighbors        
-
+        unconnected_port_modules = {}
+        for port_module, port_type in port_modules:
+            (port_name, _, _, _, neighbors) = \
+                group.get_port_spec_info(port_module)
+            new_neighbors = \
+                [(module_index[id_remap[(Module.vtType, m.id)]], n)
+                 for (m, n) in neighbors
+                 if (Module.vtType, m.id) in id_remap]
+            open_ports[(port_name, port_type)] = new_neighbors
+            unconnected_port_modules[(port_name, port_type)] = port_module
+
+        # Now iterate over the outer connections
+        # If the connection was between the outside and the group module, we
+        # connect to the actual destination instead, using the open_ports dict.
+        # We also remove the corresponding port from unconnected_port_modules.
         for connection in full_pipeline.connection_list:
             if connection.source.moduleId == group.id:
                 key = (connection.source.name, 'output')
+                try:
+                    del unconnected_port_modules[key]
+                except KeyError:
+                    pass
                 if key not in open_ports:
                     continue
                 neighbors = open_ports[key]
@@ -2467,6 +2488,10 @@ class VistrailController(object):
                                                               input_port))
             elif connection.destination.moduleId == group.id:
                 key = (connection.destination.name, 'input')
+                try:
+                    del unconnected_port_modules[key]
+                except KeyError:
+                    pass
                 if key not in open_ports:
                     continue
                 neighbors = open_ports[key]
@@ -2478,7 +2503,26 @@ class VistrailController(object):
                                                               output_port,
                                                               input_module, 
                                                               input_port))
-        # end for
+
+        # We are now left with unconnected_port_modules, a dictionary of
+        # InputPort and OutputPort modules for ports that are not connected
+        # to anything.
+        # We copy these modules over so that re-grouping will keep these ports.
+        for key, port_module in unconnected_port_modules.iteritems():
+            modules.append(port_module.do_copy(True, self.id_scope, id_remap))
+
+        # Center the group's modules on the old group's location
+        self.translate_modules(modules, -group.location.x, -group.location.y)
+
+        # Now copy the inner connections
+        # If the connection is between two modules that come from the group
+        # (all_inside is True), we copy it.
+        for connection in pipeline.connection_list:
+            all_inside = all((Module.vtType, port.moduleId) in id_remap
+                             for port in connection.ports)
+            if all_inside:
+                connections.append(connection.do_copy(True, self.id_scope,
+                                                      id_remap))
 
         return (modules, connections)
 
@@ -2572,10 +2616,10 @@ class VistrailController(object):
                     extra_info = {}
                 extra_info['pathDumpCells'] = create_temp_folder(prefix='vt_thumb')
                 temp_folder_used = True
-#           
+
             kwargs = {'locator': locator,
                       'current_version': version,
-                      'view': view,
+                      'view': view if view is not None else DummyView(),
                       'logger': self.get_logger(),
                       'controller': self,
                       'aliases': aliases,
@@ -2673,25 +2717,226 @@ class VistrailController(object):
                 locator.clean_temporaries()
                 if self._auto_save:
                     locator.save_temporary(self.vistrail)
-            view = DummyView()
-            return self.execute_workflow_list([(self.locator,
-                                                self.current_version,
-                                                self.current_pipeline,
-                                                view,
-                                                custom_aliases,
-                                                custom_params,
-                                                reason,
-                                                sinks,
-                                                extra_info)])
-
-    def recompute_terse_graph(self):
+            try:
+                return self.execute_workflow_list([(self.locator,
+                                                    self.current_version,
+                                                    self.current_pipeline,
+                                                    None,
+                                                    custom_aliases,
+                                                    custom_params,
+                                                    reason,
+                                                    sinks,
+                                                    extra_info)])
+            except Exception, e:
+                debug.unexpected_exception(e)
+                raise
+
+    def prune_versions(self, versions):
+        """ prune_versions(versions: list of version numbers) -> None
+        Prune all versions in 'versions' out of the view
+
+        """
+        # We need to go up-stream to the highest invisible node
+        current = self._current_terse_graph
+        if not current:
+            self.recompute_terse_graph()
+            current, full = self._current_terse_graph, self._current_full_graph
+        else:
+            full = self._current_full_graph
+        changed = False
+        new_current_version = None
+        for v in versions:
+            if v!=0: # not root
+                highest = v
+                while True:
+                    p = full.parent(highest)
+                    if p==-1:
+                        break
+                    if p in current.vertices:
+                        break
+                    highest = p
+                if highest!=0:
+                    changed = True
+                    if highest == self.current_version:
+                        new_current_version = full.parent(highest)
+                self.vistrail.pruneVersion(highest)
+        if changed:
+            self.set_changed(True)
+        if new_current_version is not None:
+            self.change_selected_version(new_current_version)
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False)
+
+    def hide_versions_below(self, v=None):
+        """ hide_versions_below(v: int) -> None
+        Hide all versions including and below v
+
+        """
+        if v is None:
+            v = self.current_base_version
+        full = self.vistrail.getVersionGraph()
+        x = [v]
+
+        am = self.vistrail.actionMap
+
+        changed = False
+
+        while 1:
+            try:
+                current=x.pop()
+            except IndexError:
+                break
+
+            children = [to for (to, _) in full.adjacency_list[current]
+                        if (to in am) and \
+                            not self.vistrail.is_pruned(to)]
+            self.vistrail.hideVersion(current)
+            changed = True
+
+            for child in children:
+                x.append(child)
+
+        if changed:
+            self.set_changed(True)
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False, False)
+
+    def show_all_versions(self):
+        """ show_all_versions() -> None
+        Unprune (graft?) all pruned versions
+
+        """
+        am = self.vistrail.actionMap
+        for a in am.iterkeys():
+            self.vistrail.showVersion(a)
+        self.set_changed(True)
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False, False)
+
+    def expand_versions(self, v1, v2):
+        """ expand_versions(v1: int, v2: int) -> None
+        Expand all versions between v1 and v2
+
+        """
+        full = self.vistrail.getVersionGraph()
+        p = full.parent(v2)
+        while p > v1:
+            self.vistrail.expandVersion(p)
+            p = full.parent(p)
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False, True)
+
+    def collapse_versions(self, v):
+        """ collapse_versions(v: int) -> None
+        Collapse all versions including and under version v until the next tag or branch
+
+        """
+        full = self.vistrail.getVersionGraph()
+        x = [v]
+
+        am = self.vistrail.actionMap
+        tm = self.vistrail.get_tagMap()
+
+        upgrades = set()
+        for ann in self.vistrail.action_annotations:
+            if ann.key != Vistrail.UPGRADE_ANNOTATION:
+                continue
+            # The target is an upgrade
+            upgrades.add(int(ann.value))
+
+        while x:
+            current = x.pop()
+
+            all_children = [to for to, _ in full.adjacency_list[current]
+                            if to in am]
+            children = []
+            while all_children:
+                child = all_children.pop()
+                # Pruned: drop it
+                if self.vistrail.is_pruned(child):
+                    pass
+                # An upgrade: get its children directly
+                # (unless it is tagged, and that tag couldn't be moved)
+                elif (not self.show_upgrades and child in upgrades and
+                        child not in tm):
+                    all_children.extend(
+                        to for to, _ in full.adjacency_list[child]
+                        if to in am)
+                else:
+                    children.append(child)
+            if len(children) > 1:
+                break
+            self.vistrail.collapseVersion(current)
+
+            for child in children:
+                if (not child in tm and  # has no Tag
+                    child != self.current_base_version): # not selected
+                    x.append(child)
+
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False, True)
+
+    def expand_or_collapse_all_versions_below(self, v=None, expand=True):
+        """ expand_or_collapse_all_versions_below(v: int) -> None
+        Expand/Collapse all versions including and under version v
+
+        """
+        if v is None:
+            v = self.current_base_version
+
+        full = self.vistrail.getVersionGraph()
+        x = [v]
+
+        am = self.vistrail.actionMap
+
+        while 1:
+            try:
+                current=x.pop()
+            except IndexError:
+                break
+
+            children = [to for (to, _) in full.adjacency_list[current]
+                        if (to in am) and not self.vistrail.is_pruned(to)]
+            if expand:
+                self.vistrail.expandVersion(current)
+            else:
+                self.vistrail.collapseVersion(current)
+
+            for child in children:
+                x.append(child)
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False, True)
+
+    def expand_all_versions_below(self, v=None):
+        self.expand_or_collapse_all_versions_below(v, True)
+
+    def collapse_all_versions_below(self, v=None):
+        self.expand_or_collapse_all_versions_below(v, False)
+
+    def collapse_all_versions(self):
+        """ collapse_all_versions() -> None
+        Collapse all expanded versions
+
+        """
+        am = self.vistrail.actionMap
+        for a in am.iterkeys():
+            self.vistrail.collapseVersion(a)
+        self.recompute_terse_graph()
+        self.invalidate_version_tree(False, True)
+
+    def recompute_terse_graph(self, show_upgrades=None):
+        if show_upgrades is None:
+            show_upgrades = not getattr(get_vistrails_configuration(),
+                                        'hideUpgrades', True)
+        self.show_upgrades = show_upgrades
+
         # get full version tree (including pruned nodes) this tree is
         # kept updated all the time. This data is read only and should
         # not be updated!
         fullVersionTree = self.vistrail.tree.getVersionTree()
 
         # create tersed tree
-        x = [(0,None)]
+        open_list = [(0, None, False, False)]  # Elements to be handled
         tersedVersionTree = Graph()
 
         # cache actionMap and tagMap because they're properties, sort
@@ -2700,71 +2945,168 @@ class VistrailController(object):
         tm = self.vistrail.get_tagMap()
         last_n = self.vistrail.getLastActions(self.num_versions_always_shown)
 
-        while 1:
-            try:
-                (current,parent)=x.pop()
-            except IndexError:
-                break
+        upgrades = set()
+        upgrade_rev_map = {}
+        current_version = self.current_version
+        def rev_map(v):
+            return upgrade_rev_map.get(v, v)
 
-            # mount childs list
-            if current in am and self.vistrail.is_pruned(current):
-                children = []
-            else:
-                children = \
-                    [to for (to, _) in fullVersionTree.adjacency_list[current]
-                     if (to in am) and (not self.vistrail.is_pruned(to) or \
-                                            to == self.current_version)]
-
-            if (self.full_tree or
-                (current == 0) or  # is root
-                (current in tm) or # hasTag:
-                (len(children) <> 1) or # not oneChild:
-                (current == self.current_version) or # isCurrentVersion
-                (am[current].expand) or  # forced expansion
-                (current in last_n)): # show latest
+        if not self.show_upgrades:
+            # process upgrade annotations
+            for ann in self.vistrail.action_annotations:
+                if ann.key != Vistrail.UPGRADE_ANNOTATION:
+                    continue
+                # The target is an upgrade
+                upgrades.add(int(ann.value))
+                # Map from upgraded version to original
+                upgrade_rev_map[int(ann.value)] = ann.action_id
+
+            # Map current version
+            current_version = rev_map(current_version)
+
+            # Map tags
+            tm, orig_tm = {}, tm
+            for version, name in sorted(orig_tm.iteritems(),
+                                        key=lambda p: p[0]):
+                v = version
+                while v in upgrade_rev_map:
+                    v = upgrade_rev_map[v]
+                    if v in orig_tm:
+                        # Found another tag in upgrade chain, don't move tag
+                        v = version
+                        break
+                tm[v] = name
+            del orig_tm
+
+            # Transitively flatten upgrade_rev_map
+            for k, v in upgrade_rev_map.iteritems():
+                while v in upgrade_rev_map:
+                    v = upgrade_rev_map[v]
+                upgrade_rev_map[k] = v
+
+        while open_list:
+            current, parent, expandable, collapsible = open_list.pop()
+
+            # mount children list
+            all_children = [
+                to for to, _ in fullVersionTree.adjacency_list[current]
+                if to in am]
+            children = []
+            while all_children:
+                child = all_children.pop()
+                # Pruned: drop it
+                if self.vistrail.is_pruned(child):
+                    pass
+                # An upgrade: get its children directly
+                # (unless it is tagged, and that tag couldn't be moved)
+                elif (not self.show_upgrades and child in upgrades and
+                        child not in tm):
+                    all_children.extend(
+                        to for to, _ in fullVersionTree.adjacency_list[child]
+                        if to in am)
+                else:
+                    children.append(child)
+
+            display = (self.full_tree or
+                       current == 0 or                 # is root
+                       current in tm or                # hasTag:
+                       current in last_n or            # show latest
+                       current == current_version or   # isCurrentVersion
+                       len(children) != 1)             # leaf or branch
+
+            if (display or am[current].expand):        # forced expansion
 
                 # yes it will!  this needs to be here because if we
                 # are refining version view receives the graph without
                 # the non matching elements
-                if( (not self.refine) or
-                    (self.refine and not self.search) or
-                    (current == 0) or
-                    (self.refine and self.search and
-                     self.search.match(self.vistrail,am[current]) or
-                     current == self.current_version)):
+                if (not self.refine or
+                        (self.refine and not self.search) or
+                        current == 0 or
+                        (self.refine and self.search and
+                         self.search.match(self.vistrail, am[current])) or
+                        current == current_version):
                     # add vertex...
-                    tersedVersionTree.add_vertex(current)
+                    tersedVersionTree.add_vertex(current, tm.get(current))
 
                     # ...and the parent
                     if parent is not None:
-                        tersedVersionTree.add_edge(parent,current,0)
+                        collapse_here = not collapsible and not display
+                        tersedVersionTree.add_edge(parent, current,
+                                                   (expandable, collapse_here))
+                        collapsible = collapsible or collapse_here
 
                     # update the parent info that will be used by the
-                    # childs of this node
+                    # children of this node
                     parentToChildren = current
+                    expandable = False
                 else:
                     parentToChildren = parent
+                    expandable = True
             else:
                 parentToChildren = parent
+                expandable = True
 
-            for child in reversed(children):
-                x.append((child, parentToChildren))
+            if collapsible and len(children) > 1:
+                collapsible = False
+            for child in children:
+                open_list.append((child, parentToChildren,
+                                  expandable, collapsible))
 
         self._current_terse_graph = tersedVersionTree
         self._current_full_graph = self.vistrail.tree.getVersionTree()
-        
-    # def refine_graph(self, step=1.0):
-    #     """ refine_graph(step: float in [0,1]) -> (Graph, Graph)
-    #     Refine the graph of the current vistrail based the search
-    #     status of the controller. It also return the full graph as a
-    #     reference
-                     
-    #     """
-        
-    #     if self._current_full_graph is None:
-    #         self.recompute_terse_graph()
-    #     return (self._current_terse_graph, self._current_full_graph,
-    #             self._current_graph_layout)
+        self._upgrade_rev_map = upgrade_rev_map
+
+    def save_version_graph(self, filename, tersed=True, highlight=None):
+        if tersed:
+            graph = copy.copy(self._current_terse_graph)
+        else:
+            graph = copy.copy(self._current_full_graph)
+        tm = self.vistrail.get_tagMap()
+        vs = graph.vertices.keys()
+        vs.sort()
+        al = [(vfrom, vto, edgeid)
+              for vfrom, lto in graph.adjacency_list.iteritems()
+              for vto, edgeid in lto]
+        al.sort()
+
+        configuration = get_vistrails_configuration()
+        use_custom_colors = configuration.check('enableCustomVersionColors')
+
+        if isinstance(filename, basestring):
+            fp = open(filename, 'wb')
+            cleanup = lambda: fp.close()
+        else:
+            fp = filename
+            cleanup = lambda: None
+        try:
+            fp.write('digraph G {\n')
+            for v in vs:
+                descr = tm.get(v, None) or self.vistrail.get_description(v)
+                if use_custom_colors:
+                    color = self.vistrail.get_action_annotation(
+                            v,
+                            custom_color_key)
+                else:
+                    color = None
+                if color:
+                    color = '#%s%s%s' % tuple(
+                            '%02x' % c
+                            for c in parse_custom_color(color.value))
+                    fp.write('    %s [label=%s, '
+                             'style=filled, fillcolor="%s", color="%s"];\n' % (
+                             v, dot_escape(descr), color,
+                             'red' if v == highlight else 'black'))
+                else:
+                    fp.write('    %s [label=%s, color="%s"];\n' % (
+                             v, dot_escape(descr),
+                             'red' if v == highlight else 'black'))
+            fp.write('\n')
+            for s in al:
+                vfrom, vto, vdata = s
+                fp.write('    %s -> %s;\n' % (vfrom, vto))
+            fp.write('}\n')
+        finally:
+            cleanup()
 
     def get_latest_version_in_graph(self):
         if not self._current_terse_graph:
@@ -2790,7 +3132,7 @@ class VistrailController(object):
         """callback for try_to_enable_package"""
         return True
        
-    def try_to_enable_package(self, identifier, dep_graph, confirmed=False):
+    def try_to_enable_package(self, identifier, confirmed=False):
         """try_to_enable_package(identifier: str,
                                  dep_graph: Graph,
                                  confirmed: boolean)
@@ -2803,15 +3145,29 @@ class VistrailController(object):
 
         pm = get_package_manager()
         pkg = pm.identifier_is_available(identifier)
-        if pkg and not pm.has_package(pkg.identifier):
-            deps = pm.all_dependencies(identifier, dep_graph)[:-1]
-            if pkg.identifier in self._asked_packages:
-                return False
-            if not confirmed and \
-                    not self.enable_missing_package(pkg.identifier, deps):
-                self._asked_packages.add(pkg.identifier)
+        if pkg is None or pm.has_package(pkg.identifier):
+            return False
+
+        dep_graph = pm.build_dependency_graph([identifier])
+        deps = pm.get_ordered_dependencies(dep_graph)
+        other_deps = filter(lambda i: i != identifier, deps)
+        if pkg.identifier in self._asked_packages:
+            return False
+        if not confirmed and \
+                not self.enable_missing_package(pkg.identifier, other_deps):
+            self._asked_packages.add(pkg.identifier)
+            return False
+        # Ok, user wants to late-enable it. Let's give it a shot
+        for pkg_id in deps:
+            if not self.do_enable_package(pkg_id):
                 return False
-            # Ok, user wants to late-enable it. Let's give it a shot
+
+        return True
+
+    def do_enable_package(self, identifier):
+        pm = get_package_manager()
+        pkg = pm.identifier_is_available(identifier)
+        if pkg and not pm.has_package(pkg.identifier):
             try:
                 pm.late_enable_package(pkg.codepath)
                 pkg = pm.get_package_by_codepath(pkg.codepath)
@@ -2824,10 +3180,7 @@ class VistrailController(object):
             except pkg.MissingDependency, e:
                 for dependency in e.dependencies:
                     print 'MISSING DEPENDENCY:', dependency
-                    if not self.try_to_enable_package(dependency[0], dep_graph,
-                                                      True):
-                        return False
-                return self.try_to_enable_package(pkg.identifier, dep_graph, True)
+                return False
             except pkg.InitializationFailed:
                 self._asked_packages.add(pkg.identifier)
                 raise
@@ -2849,7 +3202,7 @@ class VistrailController(object):
             codepath = rep.find_package(identifier)
             if codepath and self.install_missing_package(identifier):
                 rep.install_package(codepath)
-                return self.try_to_enable_package(identifier, dep_graph, True)
+                return self.try_to_enable_package(identifier, True)
         self._asked_packages.add(identifier)
         return False
 
@@ -2958,15 +3311,28 @@ class VistrailController(object):
 
         process_missing_packages(root_exceptions)
         new_exceptions = []
-        
+
+        # Full dependency graph from all the packages detected as missing
         dep_graph = pm.build_dependency_graph(missing_packages.keys())
+        deps = pm.get_ordered_dependencies(dep_graph)
+        missing = set(missing_packages.iterkeys())
+        # This orders the list of packages detected as missing according to
+        # the order in which they'll be enabled
+        # This is so that if pkgA is a dependency of pkgB and both are in
+        # missing_packages.keys(), we enable pkgB before (since that will
+        # enable pkgA)
+        # This is to minimize the number of user prompts
+        enable_pkgs = reversed([pkg_id
+                                for pkg_id in deps
+                                if pkg_id in missing])
+
         # for identifier, err_list in missing_packages.iteritems():
-        for identifier in pm.get_ordered_dependencies(dep_graph):
+        for identifier in enable_pkgs:
             # print 'testing identifier', identifier
             if not pm.has_package(identifier):
                 try:
                     # print 'trying to enable package'
-                    if not self.try_to_enable_package(identifier, dep_graph):
+                    if not self.try_to_enable_package(identifier):
                         pass
                         # print 'failed to enable package'
                         # if not report_all_errors:
@@ -3072,7 +3438,8 @@ class VistrailController(object):
                 except MissingPackage:
                     # cannot get the package we need
                     continue
-                details = '\n'.join(str(e) for e in err_list)
+                details = '\n'.join(debug.format_exception(e)
+                                    for e in err_list)
                 debug.log('Processing upgrades in package "%s"' %
                           identifier, details)
                 if pkg.can_handle_all_errors():
@@ -3151,7 +3518,7 @@ class VistrailController(object):
                                     return new_actions
             return new_actions
 
-        if get_vistrails_configuration().check('upgradeOn'):
+        if get_vistrails_configuration().check('upgrades'):
             cur_pipeline = copy.copy(e._pipeline)
             # note that cur_pipeline is modified to be the result of
             # applying the actions in new_actions
@@ -3193,17 +3560,17 @@ class VistrailController(object):
                     #mashup.id = uuid.uuid1()
                     # we move it to the new version so that references still work
                     self._mashups.remove(mashup)
-                    
+
                     for action in mashup.actions:
                         for alias in action.mashup.aliases:
                             c = alias.component
-                            if (Module.vtType, c.vtmid) in mfp_remap:
+                            while (Module.vtType, c.vtmid) in mfp_remap:
                                 c.vtmid = mfp_remap[(Module.vtType, c.vtmid)]
-                            if (ModuleFunction.vtType,
+                            while (ModuleFunction.vtType,
                                 c.vtparent_id) in mfp_remap:
                                 c.vtparent_id=mfp_remap[(ModuleFunction.vtType,
                                                          c.vtparent_id)]
-                            if (ModuleParam.vtType, c.vtid) in mfp_remap:
+                            while (ModuleParam.vtType, c.vtid) in mfp_remap:
                                 c.vtid = mfp_remap[(ModuleParam.vtType,
                                                      c.vtid)]
                     mashup.currentVersion = mashup.getLatestVersion()
@@ -3218,7 +3585,7 @@ class VistrailController(object):
                 self._delayed_paramexps.extend(new_param_exps)
                 self._delayed_mashups.extend(new_mashups)
             else:
-                vistrail.add_action(upgrade_action, new_version, 
+                vistrail.add_action(upgrade_action, new_version,
                                     self.current_session)
                 vistrail.set_upgrade(new_version, str(upgrade_action.id))
                 if get_vistrails_configuration().check("migrateTags"):
@@ -3253,11 +3620,10 @@ class VistrailController(object):
 
         left_exceptions = check_exceptions(root_exceptions)
         if len(left_exceptions) > 0 or len(new_exceptions) > 0:
-            details = '\n'.join(set(str(e) for e in left_exceptions + \
-                                    new_exceptions))
-            # debug.critical("Some exceptions could not be handled", details)
-            raise InvalidPipeline(left_exceptions + new_exceptions, 
-                                  cur_pipeline, new_version)
+            e = InvalidPipeline(left_exceptions + new_exceptions,
+                                cur_pipeline, new_version)
+            debug.format_exception(e)
+            raise e
         return (new_version, cur_pipeline)
 
     def validate(self, pipeline, raise_exception=True):
@@ -3317,9 +3683,12 @@ class VistrailController(object):
             if from_root:
                 result = self.vistrail.getPipeline(version)
             elif version == self.current_version:
-                # we don't even need to check connection specs or
-                # registry
-                return self.current_pipeline
+                # Changing to current pipeline
+                # We only need to run validation if it was previously invalid
+                # (or didn't get validated)
+                result = self.current_pipeline
+                if self.current_pipeline.is_valid:
+                    return result
             # Fast check: if target is cached, copy it and we're done.
             elif version in self._pipelines:
                 result = copy.copy(self._pipelines[version])
@@ -3435,8 +3804,6 @@ class VistrailController(object):
                     self.current_version = new_version
                 except InvalidPipeline, e:
                     # display invalid pipeline?
-                    # import traceback
-                    # traceback.print_exc()
                     new_error = e
                     
                     # just do the version switch, anyway, but alert the
@@ -3485,8 +3852,7 @@ class VistrailController(object):
             elif len(e._exception_set) > 0:
                 process_err(e._exception_set.__iter__().next())
         except Exception, e:
-            import traceback
-            debug.critical(str(e), traceback.format_exc())
+            debug.critical("Unhandled exception", debug.format_exc())
 
     def write_temporary(self):
         if self.vistrail and self.changed:
@@ -3565,6 +3931,12 @@ class VistrailController(object):
         export=True means you should not update the current controller"""
         result = False 
         if self.vistrail and (self.changed or self.locator != locator):
+            # Save jobs as annotation
+            if self.jobMonitor.workflows:
+                self.vistrail.set_annotation('__jobs__',
+                                             self.jobMonitor.serialize())
+            else:
+                self.vistrail.set_annotation('__jobs__', '')
             # FIXME create this on-demand?
             abs_save_dir = tempfile.mkdtemp(prefix='vt_abs')
             is_abstraction = self.vistrail.is_abstraction
@@ -3633,20 +4005,12 @@ class VistrailController(object):
                     # Load all abstractions from new namespaces
                     self.ensure_abstractions_loaded(new_vistrail, 
                                                     save_bundle.abstractions) 
-                    conf = get_vistrails_configuration()
-                    if conf.has('runningJobsList') and conf.runningJobsList:
-                        conf_jobs = conf.runningJobsList.split(';')
-                        conf_jobs = [job.replace(old_locator.to_url(),
-                                       locator.to_url()) for job in conf_jobs]
-                        conf.runningJobsList = ';'.join(conf_jobs)
-                        get_vistrails_persistent_configuration(
-                                      ).runningJobsList = conf.runningJobsList
                     self.set_file_name(locator.name)
                     if old_locator and not export:
                         old_locator.clean_temporaries()
                         old_locator.close()
                     self.flush_pipeline_cache()
-                    self.change_selected_version(new_vistrail.db_currentVersion,
+                    self.change_selected_version(new_vistrail.db_currentVersion, 
                                                  from_root=True)
             else:
                 save_bundle = self.locator.save(save_bundle)
@@ -3691,12 +4055,13 @@ class VistrailController(object):
                             os.remove(os.path.join(root, name))
                     os.rmdir(abs_save_dir)
                 except OSError, e:
-                    raise VistrailsDBException("Can't remove %s: %s" % \
-                                                   (abs_save_dir, str(e)))
+                    raise VistrailsDBException("Can't remove %s: %s" % (
+                                               abs_save_dir,
+                                               debug.format_exception(e)))
             return result
 
 
-    def write_workflow(self, locator):
+    def write_workflow(self, locator, version=None):
         if self.current_pipeline:
             pipeline = Pipeline()
             # pipeline.set_abstraction_map(self.vistrail.abstractionMap)
@@ -3709,7 +4074,7 @@ class VistrailController(object):
             for connection in self.current_pipeline.connections.itervalues():
                 pipeline.add_connection(connection)
             save_bundle = SaveBundle(pipeline.vtType,workflow=pipeline)
-            locator.save_as(save_bundle)
+            locator.save_as(save_bundle, version)
 
     def write_log(self, locator):
         if self.log:
@@ -3918,5 +4283,139 @@ class VistrailController(object):
                 
         #return module move operations
         return self.move_modules_ops(moves)
-        
-            
+
+
+import unittest
+
+class TestTerseGraph(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        pm = vistrails.core.packagemanager.get_package_manager()
+        if pm.has_package('org.vistrails.test.upgrades_layout'):
+            return
+
+        d = {'test_upgrades_layout': 'vistrails.tests.resources.'}
+        pm.late_enable_package('test_upgrades_layout', d)
+        cls.maxDiff = None
+
+    @classmethod
+    def tearDownClass(cls):
+        manager = vistrails.core.packagemanager.get_package_manager()
+        if manager.has_package('org.vistrails.test.upgrades_layout'):
+            manager.late_disable_package('test_upgrades_layout')
+
+    def get_workflow(self, name):
+        from vistrails.core.db.locator import XMLFileLocator
+        from vistrails.core.system import vistrails_root_directory
+
+        locator = XMLFileLocator(vistrails_root_directory() +
+                                 '/tests/resources/' + name)
+        vistrail = locator.load()
+        return VistrailController(vistrail, locator)
+
+    def test_workflow1_upgrades(self):
+        """Computes the tersed version tree, with upgrades"""
+        controller = self.get_workflow('upgrades1.xml')
+        controller.recompute_terse_graph(True)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(1L, (False, False)), (5L, (False, False)), (16L, (True, False))],
+            1L: [(3L, (True, False))],
+            3L: [(4L, (False, False))],
+            5L: [(8L, (True, False)), (10L, (True, False))],
+            10L: [(11L, (False, False)), (13L, (True, False))],
+            4L: [], 8L: [], 11L: [], 13L: [], 16L: [],
+        })
+        controller.expand_all_versions_below(0)
+        controller.recompute_terse_graph(True)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(1L, (False, False)), (5L, (False, False)), (14L, (False, True))],
+            1L: [(2L, (False, True))],
+            2L: [(3L, (False, False))],
+            3L: [(4L, (False, False))],
+            5L: [(6L, (False, True)), (9L, (False, True))],
+            6L: [(7L, (False, False))],
+            7L: [(8L, (False, False))],
+            9L: [(10L, (False, False))],
+            10L: [(11L, (False, False)), (12L, (False, True))],
+            12L: [(13L, (False, False))],
+            14L: [(15L, (False, False))],
+            15L: [(16L, (False, False))],
+            4L: [], 8L: [], 11L: [], 13L: [], 16L: [],
+        })
+
+    def test_workflow1_no_upgrades(self):
+        """Computes the tersed version tree, without upgrades"""
+        controller = self.get_workflow('upgrades1.xml')
+        controller.recompute_terse_graph(False)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(1L, (False, False)), (5L, (False, False)), (14L, (False, False))],
+            1L: [(3L, (False, False))],
+            3L: [(4L, (False, False))],
+            5L: [(8L, (False, False)), (9L, (False, False))],
+            9L: [(11L, (False, False)), (13L, (False, False))],
+            4L: [], 8L: [], 11L: [], 13L: [], 14L: [],
+        })
+        controller.expand_all_versions_below(0)
+        controller.recompute_terse_graph(False)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(1L, (False, False)), (5L, (False, False)), (14L, (False, False))],
+            1L: [(3L, (False, False))],
+            3L: [(4L, (False, False))],
+            5L: [(8L, (False, False)), (9L, (False, False))],
+            9L: [(11L, (False, False)), (13L, (False, False))],
+            4L: [], 8L: [], 11L: [], 13L: [], 14L: [],
+        })
+
+    def test_workflow2_upgrades(self):
+        """Computes the tersed version tree, with upgrades"""
+        controller = self.get_workflow('upgrades2.xml')
+        controller.recompute_terse_graph(True)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(3L, (True, False)), (9L, (True, False)), (12L, (False, False))],
+            3L: [(7L, (True, False)), (6L, (True, False))],
+            9L: [(10L, (False, False)), (11L, (False, False))],
+            12L: [(13L, (False, False)), (15L, (False, False))],
+            13L: [(14L, (False, False)), (17L, (True, False))],
+            7L: [], 6L: [], 10L: [], 11L: [], 14L: [], 15L: [], 17L: [],
+        })
+        controller.expand_all_versions_below(0)
+        controller.recompute_terse_graph(True)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(1L, (False, True)), (8L, (False, True)), (12L, ((False, False)))],
+            1L: [(2L, (False, False))],
+            2L: [(3L, (False, False))],
+            3L: [(4L, (False, True)), (5L, (False, True))],
+            4L: [(7L, (False, False))],
+            5L: [(6L, (False, False))],
+            8L: [(9L, (False, False))],
+            9L: [(10L, (False, False)), (11L, (False, False))],
+            12L: [(13L, (False, False)), (15L, (False, False))],
+            13L: [(14L, (False, False)), (16L, (False, True))],
+            16L: [(17L, (False, False))],
+            7L: [], 6L: [], 10L: [], 11L: [], 14L: [], 15L: [], 17L: [],
+        })
+
+    def test_workflow2_no_upgrades(self):
+        """Computes the tersed version tree, without upgrades"""
+        controller = self.get_workflow('upgrades2.xml')
+        controller.recompute_terse_graph(False)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(2L, (True, False)), (9L, (True, False)), (13L, (True, False))],
+            2L: [(4L, (False, False)), (6L, (True, False))],
+            9L: [(10L, (False, False))],
+            13L: [(14L, (False, False)), (17L, (False, False))],
+            4L: [], 6L: [], 10L: [], 14L: [], 17L: [],
+        })
+        controller.expand_all_versions_below(0)
+        controller.recompute_terse_graph(False)
+        self.assertEqual(controller._current_terse_graph.adjacency_list, {
+            0: [(1L, (False, True)), (8L, (False, True)), (12L, ((False, True)))],
+            1L: [(2L, (False, False))],
+            2L: [(4L, (False, False)), (5L, (False, True))],
+            5L: [(6L, (False, False))],
+            8L: [(9L, (False, False))],
+            9L: [(10L, (False, False))],
+            12L: [(13L, (False, False))],
+            13L: [(14L, (False, False)), (17L, (False, False))],
+            4L: [], 6L: [], 10L: [], 14L: [], 17L: [],
+        })
diff --git a/vistrails/core/vistrail/group.py b/vistrails/core/vistrail/group.py
index 7a74879..8c9f30a 100644
--- a/vistrails/core/vistrail/group.py
+++ b/vistrails/core/vistrail/group.py
@@ -1,43 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from itertools import izip
 
 from vistrails.core.vistrail.annotation import Annotation
 from vistrails.core.vistrail.location import Location
 from vistrails.core.vistrail.module import Module
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.core.vistrail.port_spec import PortSpec, PortEndPoint
 from vistrails.db.domain import DBGroup
@@ -108,6 +112,8 @@ class Group(DBGroup, Module):
             ModuleFunction.convert(_function)
         for _annotation in _group.db_get_annotations():
             Annotation.convert(_annotation)
+        for _control_parameter in _group.db_get_controlParameters():
+            ModuleControlParam.convert(_control_parameter)
         _group.set_defaults()
 
     ##########################################################################
@@ -117,6 +123,7 @@ class Group(DBGroup, Module):
     id = DBGroup.db_id
     cache = DBGroup.db_cache
     annotations = DBGroup.db_annotations
+    control_parameters = DBGroup.db_controlParameters
     location = DBGroup.db_location
     center = DBGroup.db_location
     # version = DBGroup.db_version
@@ -132,22 +139,6 @@ class Group(DBGroup, Module):
     version = basic_pkg_version
     internal_version = ''
 
-    def summon(self):
-        result = self.module_descriptor.module()
-        result.pipeline = self.pipeline
-        if self._port_specs is None:
-            self.make_port_specs()
-        result.input_remap = self._input_remap
-        result.output_remap = self._output_remap
-        if self.cache != 1:
-            result.is_cacheable = lambda *args: False
-        if hasattr(result, 'input_ports_order'):
-            result.input_ports_order = [p.name for p in self.destinationPorts()]
-        if hasattr(result, 'output_ports_order'):
-            result.output_ports_order = [p.name for p in self.sourcePorts()]
-        result.registry = get_module_registry()
-        return result
-
     def is_group(self):
         return True
 
@@ -235,20 +226,20 @@ class Group(DBGroup, Module):
         registry = get_module_registry()
         for module in self.pipeline.module_list:
             if module.name == 'OutputPort' and module.package == basic_pkg:
-                (port_name, sigstring, optional, _) = \
+                (port_name, sigstring, optional, depth, _) = \
                     self.get_port_spec_info(module)
                 port_spec = registry.create_port_spec(port_name, 'output',
                                                       None, sigstring,
-                                                      optional)
+                                                      optional, depth=depth)
                 self._port_specs[(port_name, 'output')] = port_spec
                 self._output_port_specs.append(port_spec)
                 self._output_remap[port_name] = module
             elif module.name == 'InputPort' and module.package == basic_pkg:
-                (port_name, sigstring, optional, _) = \
+                (port_name, sigstring, optional, depth, _) = \
                     self.get_port_spec_info(module)
                 port_spec = registry.create_port_spec(port_name, 'input',
                                                       None, sigstring,
-                                                      optional)
+                                                      optional, depth=depth)
                 self._port_specs[(port_name, 'input')] = port_spec
                 self._input_port_specs.append(port_spec)
                 self._input_remap[port_name] = module
diff --git a/vistrails/core/vistrail/job.py b/vistrails/core/vistrail/job.py
new file mode 100644
index 0000000..8954def
--- /dev/null
+++ b/vistrails/core/vistrail/job.py
@@ -0,0 +1,679 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+""" Contains classes for persisting running executions to disk
+
+"""
+
+from __future__ import division
+
+from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core import debug
+from vistrails.core.modules.vistrails_module import NotCacheable, \
+    ModuleError, ModuleSuspended
+
+from uuid import uuid1
+
+import datetime
+import getpass
+import json
+import time
+import unittest
+import weakref
+
+
+class JobMixin(NotCacheable):
+    """ Mixin for suspendable modules.
+
+    This provides the base behavior for modules that submit jobs by handling
+    the serialization & JobMonitor interaction for you.
+
+    The module developer needs only implement the following methods:
+        job_read_inputs()
+        job_set_results()
+        job_start()
+        job_get_handle()
+        job_finish()
+    """
+
+    def compute(self):
+        """ Base behavior for job-submitting modules.
+
+        This provides the base code and calls the methods that the module
+        developer should provide.
+        """
+        debug.log("%s compute() starting\n"
+                  "signature = %r" % (self.__class__.__name__,
+                                      self.signature))
+
+        jm = self.job_monitor()
+
+        cache = jm.getCache(self.signature)
+        if cache is not None:
+            # Result is available from cache
+            jm.setCache(self.signature, cache.parameters)
+            debug.log("Cached results found; calling job_set_results()")
+            self.job_set_results(cache.parameters)
+            return
+        else:
+            debug.log("Cache miss")
+
+        job = jm.getJob(self.signature)
+        if job is None:
+            debug.log("Job doesn't exist")
+            params = self.job_read_inputs()
+            params = self.job_start(params)
+        else:
+            debug.log("Got job from JobMonitor")
+            params = job.parameters
+        jm.addJob(self.signature, params, self.job_name())
+
+        # Might raise ModuleSuspended
+        debug.log("Calling checkJob()")
+        try:
+            jm.checkJob(self, self.signature, self.job_get_handle(params))
+        except ModuleSuspended, e:
+            debug.log("checkJob() raised ModuleSuspended, job handle is %r" %
+                      e.handle)
+            raise
+
+        # Didn't raise: job is finished
+        debug.log("Calling job_finish()")
+        params = self.job_finish(params)
+        debug.log("Filling cache")
+        jm.setCache(self.signature, params)
+        debug.log("Calling job_set_results()")
+        self.job_set_results(params)
+
+    def update_upstream(self):
+        """ Decides whether or not to run the upstream.
+
+        If a job has already been submitted and the local JobMonitor knows of
+        it, we don't need to run upstream modules to check the status.
+
+        If status check indicates that the job no longer exists, then we should
+        run upstream then submit again.
+        """
+        if not hasattr(self, 'signature'):
+            raise ModuleError(self, "Module has no signature")
+        jm = self.job_monitor()
+        if not (jm.getCache(self.signature) or jm.getJob(self.signature)):
+            # We need to submit a new job
+            # Update upstream, compute() will need it
+            super(JobMixin, self).update_upstream()
+
+    def job_read_inputs(self):
+        """ Implemented by modules to read job parameters from input ports.
+
+        Returns the `params` dictionary used by subsequent methods.
+        """
+        raise NotImplementedError
+
+    def job_start(self, params):
+        """ Implemented by modules to submit the job.
+
+        Gets the `params` dictionary and returns a new dictionary, for example
+        with additional info necessary to check the status later.
+        """
+        raise NotImplementedError
+
+    def job_finish(self, params):
+        """ Implemented by modules to get info from the finished job.
+
+        This is called once the job is finished to get the results. These can
+        be added to the `params` dictionary that this method returns.
+
+        This is the right place to clean up the job from the server if they are
+        not supposed to persist.
+        """
+        raise NotImplementedError
+
+    def job_set_results(self, params):
+        """ Implemented by modules to set the output ports.
+
+        This is called after job_finished() or after getting the cached results
+        to set the output ports on this module, from the `params` dictionary.
+        """
+        raise NotImplementedError
+
+    def job_get_handle(self, params):
+        """ Implemented by modules to return the JobHandle object.
+
+        This returns an object following the JobHandle interface. The
+        JobMonitor will use it to check the status of the job and call back
+        this module once the job is done.
+
+        JobHandle needs the following method:
+          * finished(): returns True if the job is finished
+        """
+        return None
+
+    def job_name(self):
+        """ Readable name for the job.
+
+        Modules needn't override this, in which case a default will be
+        provided.
+        """
+        # use module description if it exists
+        if 'pipeline' in self.moduleInfo and self.moduleInfo['pipeline']:
+            p_modules = self.moduleInfo['pipeline'].modules
+            p_module = p_modules[self.moduleInfo['moduleId']]
+            if p_module.has_annotation_with_key('__desc__'):
+                return p_module.get_annotation_by_key('__desc__').value
+        return self.__class__.__name__
+
+
+class Workflow(object):
+    """ Represents a workflow that has jobs.
+
+    It can have one or several suspended modules.
+    It can be serialized to disk.
+    """
+    def __init__(self, version, name='untitled', id=None, user=None,
+                 start=None, jobs=None):
+        """ __init__(version: str/int, name: str, id: str,
+            user: str, start: str, jobs: list) -> None
+
+            version - workflow version
+            name - a human readable name for the job
+            id - persistent identifier
+            user - who started the job
+            start - start time
+            jobs - a dict with jobs
+        """
+        self.version = version
+        self.name = name
+        self.id = id if id else str(uuid1())
+        self.user = getpass.getuser()
+        self.start = start if start else datetime.datetime.now().isoformat()
+        self.jobs = jobs if jobs else {}
+        # parent modules are stored as temporary exceptions
+        self.parents = {}
+
+    def to_dict(self):
+        wf = dict()
+        wf['version'] = self.version
+        wf['id'] = self.id
+        wf['name'] = self.name
+        wf['user'] = self.user
+        wf['start'] = self.start
+        wf['jobs'] = self.jobs.keys()
+        return wf
+
+    @staticmethod
+    def from_dict(wf):
+        return Workflow(wf['version'], wf['name'], wf['id'],
+                        wf['user'], wf['start'], wf['jobs'])
+
+    def __eq__(self, other):
+        if self.version != other.version:
+            return False
+        if self.name != other.name:
+            return False
+        if self.id != other.id:
+            return False
+        if self.user != other.user:
+            return False
+        if self.start != other.start:
+            return False
+        if len(self.jobs) != len(other.jobs):
+            return False
+        if set(self.jobs) != set(other.jobs):
+            return False
+        return True
+
+    def reset(self):
+        for job in self.jobs.itervalues():
+            job.reset()
+        self.parents = {}
+
+    def completed(self):
+        """ Returns true if there are no suspended jobs
+        """
+        for job in self.jobs.itervalues():
+            if not job.finished:
+                return False
+        return True
+
+
+class Job(object):
+    """A suspended module.
+    """
+    def __init__(self, id, parameters, name='', start=None, finished=False):
+        """ __init__(id: str, parameters: dict, name: str, start: str,
+                     finished: bool)
+
+            id - persistent identifier
+            parameters - either output values or job parameters
+            start - start time
+            finished - is it finished or running?
+        """
+        self.id = id
+        self.parameters = parameters
+        self.name = name
+        self.start = start if start else datetime.datetime.now().isoformat()
+        self.finished = finished
+        self.updated = True
+
+    def reset(self):
+        self.updated = False
+
+    def mark(self):
+        self.updated = True
+
+    def finish(self, params=None):
+        self.parameters = params if params else {}
+        self.finished = True
+
+    def description(self):
+        return self.parameters.get('__desc__', '')
+
+    def to_dict(self):
+        m = dict()
+        m['id'] = self.id
+        m['parameters'] = self.parameters
+        m['name'] = self.name
+        m['start'] = self.start
+        m['finished'] = self.finished
+        return m
+
+    @staticmethod
+    def from_dict(m):
+        return Job(m['id'],
+                   m['parameters'],
+                   m['name'],
+                   m['start'],
+                   m['finished'])
+
+    def __eq__(self, other):
+        if self.id != other.id:
+            return False
+        if self.parameters != other.parameters:
+            return False
+        if self.start != other.start:
+            return False
+        if self.finished != other.finished:
+            return False
+        return True
+
+
+class JobMonitor(object):
+    """ Keeps a list of running jobs and the current job for a vistrail.
+
+    Jobs are added by the interpreter are saved with the vistrail.
+    A callback mechanism is used to interact with the associated GUI component.
+    """
+
+    def __init__(self, json_string=None):
+        self._current_workflow = None
+        self.workflows = {}
+        self.jobs = {}
+        self.callback = None
+        if json_string is not None:
+            self.unserialize(json_string)
+
+    def setCallback(self, callback=None):
+        """ setCallback(callback: class) -> None
+            Sets a callback when receiving commands
+
+        """
+        self.callback = weakref.ref(callback)
+
+    ###########################################################################
+    # Running Workflows
+
+    def serialize(self):
+        """ serialize() -> None
+            serializes the running jobs to json
+
+        """
+        _dict = {}
+
+        jobs = dict()
+        for id, job in self.jobs.items():
+            jobs[id] = job.to_dict()
+        _dict['jobs'] = jobs
+
+        workflows = dict()
+        for id, workflow in self.workflows.items():
+            workflows[id] = workflow.to_dict()
+        _dict['workflows'] = workflows
+
+        return json.dumps(_dict)
+
+    def unserialize(self, s):
+        """ unserialize(s: str) -> None
+            unserializes the running jobs from json
+
+        """
+
+        _dict = json.loads(s)
+
+        jobs = _dict.get('jobs', {})
+        self.jobs = {}
+        for id, job in jobs.iteritems():
+            self.jobs[id] = Job.from_dict(job)
+
+        workflows = _dict.get('workflows', {})
+        self.workflows = {}
+        for id, workflow in workflows.iteritems():
+            workflow['jobs'] = dict([(i, self.jobs[i])
+                                     for i in workflow['jobs']
+                                     if i in self.jobs])
+            wf = Workflow.from_dict(workflow)
+            self.workflows[id] = wf
+        return self.workflows
+
+    def addWorkflow(self, workflow):
+        """ addWorkflow(workflow: Workflow) -> None
+
+        """
+        self.workflows[workflow.id] = workflow
+        for id, job in workflow.jobs.iteritems():
+            self.jobs[id] = job
+
+    def getWorkflow(self, id):
+        """ getWorkflow(id: str) -> Workflow
+
+            Checks if a workflow exists using its id and returns it
+
+        """
+        return self.workflows.get(id, None)
+
+    def deleteWorkflow(self, id):
+        """ deleteWorkflow(id: str) -> None
+            deletes a workflow
+
+        """
+        workflow = self.workflows[id]
+        del self.workflows[id]
+        # delete jobs that only occur in this workflow
+        for job_id in workflow.jobs:
+            delete = True
+            for wf in self.workflows.values():
+                if job_id in wf.jobs:
+                    delete = False
+            if delete:
+                del self.jobs[job_id]
+        if self.callback is not None and self.callback() is not None:
+            self.callback().deleteWorkflow(id)
+
+    def deleteJob(self, id):
+        """ deleteJob(id: str, parent_id: str) -> None
+            deletes a job from all workflows
+        """
+        del self.jobs[id]
+        for wf in self.workflows.itervalues():
+            if id in wf.jobs:
+                del wf.jobs[id]
+        if self.callback is not None and self.callback() is not None:
+            self.callback().deleteJob(id)
+
+    ###########################################################################
+    # _current_workflow methods
+
+    def currentWorkflow(self):
+        """ currentWorkflow() -> Workflow
+
+        """
+        return self._current_workflow
+
+    def startWorkflow(self, workflow):
+        """ startWorkflow(workflow: Workflow) -> None
+
+        """
+        if self._current_workflow:
+            raise Exception("A workflow is still running: %s!" %
+                            self._current_workflow)
+        workflow.reset()
+        self._current_workflow = workflow
+        if self.callback is not None and self.callback() is not None:
+            self.callback().startWorkflow(workflow)
+
+    def addJobRec(self, obj, parent_id=None):
+        workflow = self.currentWorkflow()
+        id = obj.module.signature
+        if obj.children:
+            for child in obj.children:
+                self.addJobRec(child, id)
+            return
+        if id in workflow.jobs:
+            # this is an already existing new-style job
+            # mark that it has been used
+            workflow.jobs[id].mark()
+            return
+        if id in workflow.jobs:
+            # this is an already existing new-style job
+            # mark that it has been used
+            workflow.jobs[id].mark()
+            return
+        # this is a new old-style job that we need to add
+        self.addJob(id, {'__message__': obj.msg}, obj.name)
+
+    def finishWorkflow(self):
+        """ finish_job() -> None
+
+            Finishes the running workflow
+
+        """
+        workflow = self._current_workflow
+        # untangle parents
+        # only keep the top item
+        c = set()
+        for exception in workflow.parents.itervalues():
+            if exception.children:
+                c.update([id(child) for child in exception.children])
+        for child in c:
+            if child in workflow.parents:
+                del workflow.parents[child]
+        for parent in workflow.parents.itervalues():
+            self.addJobRec(parent)
+
+        # Assume all unfinished jobs that were not updated are now finished
+        for job in workflow.jobs.values():
+            if not job.finished and not job.updated:
+                job.finish()
+        if self.callback is not None and self.callback() is not None:
+            self.callback().finishWorkflow(workflow)
+        self._current_workflow = None
+
+    def addJob(self, id, params=None, name='', finished=False):
+        """ addJob(id: str, params: dict, name: str, finished: bool) -> uuid
+
+            Adds a job to the currently running workflow
+
+        """
+
+        params = params if params is not None else {}
+
+        if self.hasJob(id):
+            # update job attributes
+            job = self.getJob(id)
+            job.parameters = params
+            if name:
+                job.name = name
+            job.finished = finished
+            # we want to keep the start date
+        else:
+            job = Job(id, params, name, finished=finished)
+            self.jobs[id] = job
+
+        workflow = self.currentWorkflow()
+        if workflow:
+            workflow.jobs[id] = job
+            # we add workflows permanently if they have at least one job
+            self.workflows[workflow.id] = workflow
+        if self.callback is not None and self.callback() is not None:
+            self.callback().addJob(self.getJob(id))
+
+    def addParent(self, error):
+        """ addParent(id: str, name: str, finished: bool) -> None
+
+            Adds an exception to be used later
+
+        """
+        workflow = self.currentWorkflow()
+        if not workflow:
+            return  # ignore non-monitored jobs
+        workflow.parents[id(error)] = error
+
+    def setCache(self, id, params, name=''):
+        self.addJob(id, params, name, True)
+
+    def checkJob(self, module, id, handle):
+        """ checkJob(module: VistrailsModule, id: str, handle: object) -> None
+            Starts monitoring the job for the current running workflow
+            module - the module to suspend
+            id - the job identifier
+            handle - an object following the JobHandle interface, i.e. with a
+                finished method for checking if the job has completed
+
+        """
+        if not self.currentWorkflow():
+            if not handle or not self.isDone(handle):
+                raise ModuleSuspended(module, 'Job is running',
+                                      handle=handle)
+        job = self.getJob(id)
+        if self.callback is not None and self.callback() is not None:
+            self.callback().checkJob(module, id, handle)
+            return
+
+        conf = get_vistrails_configuration()
+        interval = conf.jobCheckInterval
+        if interval and not conf.jobAutorun:
+            if handle:
+                # wait for module to complete
+                try:
+                    while not self.isDone(handle):
+                        time.sleep(interval)
+                        print ("Waiting for job: %s,"
+                               "press Ctrl+C to suspend") % job.name
+                except KeyboardInterrupt:
+                    raise ModuleSuspended(module, 'Interrupted by user, job'
+                                          ' is still running', handle=handle)
+        else:
+            if not handle or not self.isDone(handle):
+                raise ModuleSuspended(module, 'Job is running',
+                                      handle=handle)
+
+    def getJob(self, id):
+        """ getJob(id: str) -> Job
+
+        """
+        return self.jobs.get(id, None)
+
+    def getCache(self, id):
+        """ getCache(id: str) -> Job
+            Checks if a completed module exists using its id and returns it
+        """
+        job = self.jobs.get(id, None)
+        return job if job and job.finished else None
+
+    def hasJob(self, id):
+        """ hasJob(id: str) -> bool
+
+            Checks if a job exists
+
+        """
+        return id in self.jobs
+
+    def updateUrl(self, new, old):
+        for workflow in self.workflows.values():
+            if workflow.vistrail == old:
+                workflow.vistrail = new
+
+    def isDone(self, handle):
+        """ isDone(self, monitor) -> bool
+
+            A job is done when it reaches finished or failed state
+            val() is used by stable batchq branch
+        """
+        finished = handle.finished()
+        if hasattr(finished, 'val'):
+            finished = finished.val()
+        if finished:
+            return True
+
+        # FIXME : deprecate this, remove from RemoteQ
+        # finished should just return True here too
+        if hasattr(handle, 'failed'):
+            failed = handle.failed()
+            if hasattr(failed, 'val'):
+                failed = failed.val()
+            if failed:
+                return True
+        return False
+
+
+###############################################################################
+# Testing
+
+class TestJob(unittest.TestCase):
+    def test_job(self):
+        jm = JobMonitor()
+        job1 = Job('`13/5', {'a': 3, 'b': '7'})
+        job2 = Job('3', {'a': 6}, 'my_name', 'a_string_date', True)
+        # test module to/from dict
+        job3 = Job.from_dict(job2.to_dict())
+        self.assertEqual(job2, job3)
+
+        workflow1 = Workflow(26)
+        workflow2 = Workflow('tagname', 'myjob', 'myid', 'tommy',
+                             '2013-10-07 13:06',
+                             {job1.id: job1, job2.id: job2})
+        # test workflow to/from dict
+        workflow3 = Workflow.from_dict(workflow2.to_dict())
+        self.assertEqual(workflow2, workflow3)
+
+        # test start/finish job
+        jm.startWorkflow(workflow2)
+        self.assertEqual(workflow2, jm._current_workflow)
+        jm.finishWorkflow()
+        self.assertEqual(None, jm._current_workflow)
+
+        # test add job
+        jm.startWorkflow(workflow2)
+        jm.addJob('my_uuid_id', {'myparam': 0})
+        self.assertIn('my_uuid_id', workflow2.jobs)
+        jm.finishWorkflow()
+
+        # test serialization
+        jm.addWorkflow(workflow1)
+        jm.addWorkflow(workflow2)
+        jm.unserialize(jm.serialize())
+        self.assertIn(workflow1.id, jm.workflows)
+        self.assertIn(workflow2.id, jm.workflows)
+        self.assertEqual(workflow1, jm.workflows[workflow1.id])
+        self.assertEqual(workflow2, jm.workflows[workflow2.id])
diff --git a/vistrails/core/vistrail/location.py b/vistrails/core/vistrail/location.py
index de71bd1..8339418 100644
--- a/vistrails/core/vistrail/location.py
+++ b/vistrails/core/vistrail/location.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.data_structures.point import Point
 from vistrails.db.domain import DBLocation
 
@@ -194,6 +197,6 @@ class TestLocation(unittest.TestCase):
         a = Location(x=0, y=1)
         b = Location(x=0, y=1)
         assert a == b
-        assert a != None
+        assert a is not None
         b = Location(x=0, y=0.1)
         assert a != b
diff --git a/vistrails/core/vistrail/module.py b/vistrails/core/vistrail/module.py
index 3360e14..d437d38 100644
--- a/vistrails/core/vistrail/module.py
+++ b/vistrails/core/vistrail/module.py
@@ -1,58 +1,58 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # Check for testing
 """ This module defines the class Module 
 """
+from __future__ import division
+
 import copy
 from itertools import izip
 import weakref
 
 from vistrails.db.domain import DBModule
-from vistrails.core.data_structures.point import Point
 from vistrails.core.vistrail.annotation import Annotation
 from vistrails.core.vistrail.location import Location
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.core.vistrail.module_param import ModuleParam
-from vistrails.core.vistrail.port import Port, PortEndPoint
 from vistrails.core.vistrail.port_spec import PortSpec
-from vistrails.core.utils import NoSummon, VistrailsInternalError, report_stack
-from vistrails.core.modules.module_descriptor import OverloadedPort
-from vistrails.core.modules.module_registry import get_module_registry, ModuleRegistry
+from vistrails.core.utils import NoSummon
+from vistrails.core.modules.module_registry import get_module_registry
 
 import unittest
-import vistrails.core
 
 ################################################################################
 
@@ -93,6 +93,8 @@ class Module(DBModule):
             self.is_watched = False
             self._descriptor_info = None
             self._module_descriptor = None
+            self.list_depth = 0
+            self.iterated_ports = []
         else:
             self.portVisible = copy.copy(other.portVisible)
             self.visible_input_ports = copy.copy(other.visible_input_ports)
@@ -104,6 +106,8 @@ class Module(DBModule):
             self.is_breakpoint = other.is_breakpoint
             self.is_watched = other.is_watched
             self._descriptor_info = None
+            self.list_depth = other.list_depth
+            self.iterated_ports = other.iterated_ports
             self._module_descriptor = other._module_descriptor
         if not self.namespace:
             self.namespace = None
@@ -142,18 +146,22 @@ class Module(DBModule):
             ModuleFunction.convert(_function)
         for _annotation in _module.db_get_annotations():
             Annotation.convert(_annotation)
+        for _control_parameter in _module.db_get_controlParameters():
+            ModuleControlParam.convert(_control_parameter)
         _module.set_defaults()
 
     ##########################################################################
     # CONSTANTS
         
     VISTRAIL_VAR_ANNOTATION = '__vistrail_var__'
+    INLINE_WIDGET_ANNOTATION = '__inline_widgets__'
 
     ##########################################################################
 
     id = DBModule.db_id
     cache = DBModule.db_cache
     annotations = DBModule.db_annotations
+    control_parameters = DBModule.db_controlParameters
     location = DBModule.db_location
     center = DBModule.db_location
     name = DBModule.db_name
@@ -187,6 +195,14 @@ class Module(DBModule):
         return self.db_has_annotation_with_key(key)
     def get_annotation_by_key(self, key):
         return self.db_get_annotation_by_key(key)        
+    def add_control_parameter(self, controlParameter):
+        self.db_add_controlParameter(controlParameter)
+    def delete_control_parameter(self, controlParameter):
+        self.db_delete_controlParameter(controlParameter)
+    def has_control_parameter_with_name(self, name):
+        return self.db_has_controlParameter_with_name(name)
+    def get_control_parameter_by_name(self, name):
+        return self.db_get_controlParameter_by_name(name)
     def toggle_breakpoint(self):
         self.is_breakpoint = not self.is_breakpoint
     def toggle_watched(self):
@@ -227,7 +243,7 @@ class Module(DBModule):
     input_port_specs = property(_get_input_port_specs)
     def _get_output_port_specs(self):
         return sorted(self._output_port_specs, 
-                      key=lambda x: (x.sort_key, x.id), reverse=True)
+                      key=lambda x: (x.sort_key, x.id))
     output_port_specs = property(_get_output_port_specs)
 
     def _get_descriptor_info(self):
@@ -250,6 +266,18 @@ class Module(DBModule):
     module_descriptor = property(_get_module_descriptor, 
                                  _set_module_descriptor)
 
+    def _get_editable_input_ports(self):
+        if self.has_annotation_with_key(Module.INLINE_WIDGET_ANNOTATION):
+            values = self.get_annotation_by_key(
+                             Module.INLINE_WIDGET_ANNOTATION).value.split(',')
+            return set() if values == [''] else set(values)
+        elif get_module_registry(
+                   ).is_constant_module(self.module_descriptor.module):
+            # Show value by default on constant modules
+            return set(['value'])
+        return set()
+    editable_input_ports = property(_get_editable_input_ports)
+
     def get_port_spec(self, port_name, port_type):
         """get_port_spec(port_name: str, port_type: str: ['input' | 'output'])
              -> PortSpec
@@ -270,14 +298,8 @@ class Module(DBModule):
 
     def summon(self):
         result = self.module_descriptor.module()
-        if self.cache != 1:
-            result.is_cacheable = lambda *args: False
-        if hasattr(result, 'input_ports_order'):
-            result.input_ports_order = [p.name for p in self.input_port_specs]
-        if hasattr(result, 'output_ports_order'):
-            result.output_ports_order = [p.name for p in self.output_port_specs]
-            # output_ports are reversed for display purposes...
-            result.output_ports_order.reverse()
+        result.transfer_attrs(self)
+
         # FIXME this may not be quite right because we don't have self.registry
         # anymore.  That said, I'm not sure how self.registry would have
         # worked for hybrids...
@@ -356,13 +378,14 @@ class Module(DBModule):
             if self.namespace:
                 return self.namespace + '|' + self.name
             return self.name
-        return ("(Module '%s:%s' id=%s functions:%s port_specs:%s annotations:%s)@%X" %
+        return ("(Module '%s:%s' id=%s functions:%s port_specs:%s annotations:%s control_parameters:%s)@%X" %
                 (self.package,
                  get_name(),
                  self.id,
                  [str(f) for f in self.functions],
                  [str(port_spec) for port_spec in self.db_portSpecs],
                  [str(a) for a in self.annotations],
+                 [str(c) for c in self.control_parameters],
                  id(self)))
 
     def __eq__(self, other):
@@ -387,12 +410,17 @@ class Module(DBModule):
             return False
         if len(self.annotations) != len(other.annotations):
             return False
+        if len(self.control_parameters) != len(other.control_parameters):
+            return False
         for f, g in izip(self.functions, other.functions):
             if f != g:
                 return False
         for f, g in izip(self.annotations, other.annotations):
             if f != g:
                 return False
+        for f, g in izip(self.control_parameters, other.control_parameters):
+            if f != g:
+                return False
         return True
 
     def __ne__(self, other):
@@ -420,10 +448,14 @@ class TestModule(unittest.TestCase):
         functions = [ModuleFunction(id=id_scope.getNewId(ModuleFunction.vtType),
                                     name='value',
                                     parameters=params)]
+        control_parameters = [ModuleControlParam(id=id_scope.getNewId(ModuleControlParam.vtType),
+                                  name='combiner',
+                                  value='pairwise')]
         module = Module(id=id_scope.getNewId(Module.vtType),
                         name='Float',
                         package=basic_pkg,
-                        functions=functions)
+                        functions=functions,
+                        controlParameters=control_parameters)
         return module
 
     def test_copy(self):
diff --git a/vistrails/core/vistrail/module_control_param.py b/vistrails/core/vistrail/module_control_param.py
new file mode 100644
index 0000000..2eae2aa
--- /dev/null
+++ b/vistrails/core/vistrail/module_control_param.py
@@ -0,0 +1,148 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from vistrails.db.domain import DBControlParameter
+
+import unittest
+import copy
+
+class ModuleControlParam(DBControlParameter):
+
+    # Valid control parameters should be put here
+    LOOP_KEY = 'loop_type' # How input lists are combined
+    WHILE_COND_KEY = 'while_cond' # Run module in a while loop
+    WHILE_INPUT_KEY = 'while_input' # input port for forwarded value
+    WHILE_OUTPUT_KEY = 'while_output' # output port for forwarded value
+    WHILE_MAX_KEY = 'while_max' # Max iterations
+    WHILE_DELAY_KEY = 'while_delay' # delay between iterations
+    CACHE_KEY = 'cache' # Turn caching on/off for this module (not implemented)
+    JOB_CACHE_KEY = 'job_cache' # Always persist output values to disk
+
+    ##########################################################################
+    # Constructors and copy
+
+    def __init__(self, *args, **kwargs):
+        DBControlParameter.__init__(self, *args, **kwargs)
+        if self.id is None:
+            self.id = -1
+        
+    def __copy__(self):
+        return ModuleControlParam.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBControlParameter.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = ModuleControlParam
+        return cp
+
+    @staticmethod
+    def convert(_control_parameter):
+        _control_parameter.__class__ = ModuleControlParam
+
+    ##########################################################################
+    # Properties
+
+    id = DBControlParameter.db_id
+    name = DBControlParameter.db_name
+    value = DBControlParameter.db_value
+
+    ##########################################################################
+    # Operators
+    
+    def __str__(self):
+        """__str__() -> str - Returns a string representation of an ModuleControlParam
+        object. 
+
+        """
+        rep = "<controlParameter id=%s name=%s value=%s</controlParameter>"
+        return  rep % (str(self.id), str(self.name), str(self.value))
+
+    def __eq__(self, other):
+        """ __eq__(other: ModuleControlParam) -> boolean
+        Returns True if self and other have the same attributes. Used by == 
+        operator. 
+        
+        """
+        if type(self) != type(other):
+            return False
+        if self.name != other.name:
+            return False
+        if self.value != other.value:
+            return False
+        return True
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+################################################################################
+# Unit tests
+
+
+class TestModuleControlParam(unittest.TestCase):
+
+    def create_control_parameter(self, id_scope=None):
+        from vistrails.db.domain import IdScope
+
+        if id_scope is None:
+            id_scope = IdScope()
+        control_parameter = ModuleControlParam(id=id_scope.getNewId(ModuleControlParam.vtType),
+                                name='name %s',
+                                value='some value %s')
+        return control_parameter
+
+    def test_copy(self):
+        from vistrails.db.domain import IdScope
+        id_scope = IdScope()
+
+        a1 = self.create_control_parameter(id_scope)
+        a2 = copy.copy(a1)
+        self.assertEquals(a1, a2)
+        self.assertEquals(a1.id, a2.id)
+        a3 = a1.do_copy(True, id_scope, {})
+        self.assertEquals(a1, a3)
+        self.assertNotEquals(a1.id, a3.id)
+
+    def test_serialization(self):
+        import vistrails.core.db.io
+        a1 = self.create_control_parameter()
+        xml_str = vistrails.core.db.io.serialize(a1)
+        a2 = vistrails.core.db.io.unserialize(xml_str, ModuleControlParam)
+        self.assertEquals(a1, a2)
+        self.assertEquals(a1.id, a2.id)
+
+    def test_str(self):
+        a1 = self.create_control_parameter()
+        str(a1)
diff --git a/vistrails/core/vistrail/module_function.py b/vistrails/core/vistrail/module_function.py
index b3f819a..75118bf 100644
--- a/vistrails/core/vistrail/module_function.py
+++ b/vistrails/core/vistrail/module_function.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 
     * ModuleFunction
 """
+from __future__ import division
+
 from vistrails.db.domain import DBFunction
 from vistrails.core.modules.utils import create_port_spec_string
 from vistrails.core.utils import enum, VistrailsInternalError, all, eprint
@@ -52,11 +55,6 @@ import vistrails.core
 
 ################################################################################
 
-PipelineElementType = enum('PipelineElementType',
-                           ['Module', 'Connection', 'Function', 'Parameter'])
-
-################################################################################
-
 class ModuleFunction(DBFunction):
     __fields__ = ['name', 'returnType', 'params']
     """ Stores a function from a vistrail module """
@@ -145,7 +143,7 @@ class ModuleFunction(DBFunction):
         child.setAttribute('name',self.name)
         child.setAttribute('returnType',self.type)
         for p in self.params:
-                p.serialize(doc,child)
+            p.serialize(doc,child)
         element.appendChild(child)
 
     def get_spec(self, port_type):
diff --git a/vistrails/core/vistrail/module_param.py b/vistrails/core/vistrail/module_param.py
index 0c8bc90..e56277f 100644
--- a/vistrails/core/vistrail/module_param.py
+++ b/vistrails/core/vistrail/module_param.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
     * ModuleParam
 
  """
+from __future__ import division
+
 from vistrails.db.domain import DBParameter
 from vistrails.core.modules.utils import parse_port_spec_item_string, \
     create_port_spec_item_string
diff --git a/vistrails/core/vistrail/operation.py b/vistrails/core/vistrail/operation.py
index bcb4f78..58aa008 100644
--- a/vistrails/core/vistrail/operation.py
+++ b/vistrails/core/vistrail/operation.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBAdd, DBChange, DBDelete
 from vistrails.db.domain import DBAnnotation, DBAbstraction, DBConnection, DBGroup, \
     DBLocation, DBModule, DBFunction, DBPluginData, DBParameter, DBPort, \
-    DBPortSpec
+    DBPortSpec, DBControlParameter
 
 from vistrails.core.vistrail.annotation import Annotation
 from vistrails.core.vistrail.abstraction import Abstraction
@@ -43,6 +46,7 @@ from vistrails.core.vistrail.connection import Connection
 from vistrails.core.vistrail.group import Group
 from vistrails.core.vistrail.location import Location
 from vistrails.core.vistrail.module import Module
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.core.vistrail.module_param import ModuleParam
 from vistrails.core.vistrail.plugin_data import PluginData
@@ -67,6 +71,7 @@ def convert_data(_data):
         DBPluginData.vtType: PluginData,
         DBPort.vtType: Port,
         DBPortSpec.vtType: PortSpec,
+        DBControlParameter.vtType: ModuleControlParam,
         }
     try:
         map[_data.vtType].convert(_data)
@@ -387,6 +392,13 @@ class TestOperation(unittest.TestCase):
                                what=Annotation.vtType,
                                objectId=m.id,
                                data=annotation)
+        cparam = ModuleControlParam(id=id_scope.getNewId(ModuleControlParam.vtType),
+                                name='foo',
+                                value='bar')
+        add_cparam = AddOp(id=id_scope.getNewId(AddOp.vtType),
+                               what=ModuleControlParam.vtType,
+                               objectId=m.id,
+                               data=cparam)
         
         return [add_op, change_op, delete_op, add_annotation]
 
diff --git a/vistrails/core/vistrail/pipeline.py b/vistrails/core/vistrail/pipeline.py
index fba8463..900b0c6 100644
--- a/vistrails/core/vistrail/pipeline.py
+++ b/vistrails/core/vistrail/pipeline.py
@@ -1,66 +1,59 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ##TODO Tests
 """ This module defines the class Pipeline """
+from __future__ import division
+
 from vistrails.core.cache.hasher import Hasher
 from vistrails.core.configuration import get_vistrails_configuration
 from vistrails.core.data_structures.bijectivedict import Bidict
 from vistrails.core.data_structures.graph import Graph
 from vistrails.core import debug
-from vistrails.core.modules.module_descriptor import ModuleDescriptor
 from vistrails.core.modules.module_registry import get_module_registry, \
     ModuleRegistryException, MissingModuleVersion, MissingPackage, PortMismatch
-from vistrails.core.system import get_vistrails_default_pkg_prefix, \
-    get_vistrails_basic_pkg_id
+from vistrails.core.system import get_vistrails_basic_pkg_id
 from vistrails.core.utils import VistrailsInternalError
-from vistrails.core.utils import expression, append_to_dict_of_lists
-from vistrails.core.utils.uxml import named_elements
-from vistrails.core.vistrail.abstraction import Abstraction
-from vistrails.core.vistrail.connection import Connection
 from vistrails.core.vistrail.group import Group
-from vistrails.core.vistrail.module import Module
-from vistrails.core.vistrail.module_function import ModuleFunction
-from vistrails.core.vistrail.module_param import ModuleParam
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
 from vistrails.core.vistrail.plugin_data import PluginData
-from vistrails.core.vistrail.port import Port, PortEndPoint
 from vistrails.core.vistrail.port_spec import PortSpec
 from vistrails.db.domain import DBWorkflow
 import vistrails.core.vistrail.action
-from vistrails.core.utils import profile, InvalidPipeline, versions_increasing
+from vistrails.core.utils import InvalidPipeline
 
-from xml.dom.minidom import getDOMImplementation, parseString
 import copy
 
 import unittest
@@ -284,45 +277,6 @@ class Pipeline(DBWorkflow):
     def fresh_connection_id(self):
         return self.get_tmp_id(Connection.vtType)
 
-    def check_connection(self, c):
-        """check_connection(c: Connection) -> boolean 
-        Checks semantics of connection
-          
-        """
-        if c.source.endPoint != Port.SourceEndPoint:
-            return False
-        if c.destination.endPoint != Port.DestinationEndPoint:
-            return False
-        if not self.has_module_with_id(c.sourceId):
-            return False
-        if not self.has_module_with_id(c.destinationId):
-            return False
-        if c.source.type != c.destination.type:
-            return False
-        return True
-    
-    def connects_at_port(self, p):
-        """ connects_at_port(p: Port) -> list of Connection 
-        Returns a list of Connections that connect at port p
-        
-        """
-        result = []
-        if p.endPoint == Port.DestinationEndPoint:
-            el = self.graph.edges_to(p.moduleId)
-            for (edgeto, edgeid) in el:
-                dest = self.connection[edgeid].destination
-                if VTKRTTI().intrinsicPortEqual(dest, p):
-                    result.append(self.connection[edgeid])
-        elif p.endPoint == Port.SourceEndPoint:
-            el = self.graph.edges_from(p.moduleId)
-            for (edgeto, edgeid) in el:
-                source = self.connection[edgeid].source
-                if VTKRTTI().intrinsicPortEqual(source, p):
-                    result.append(self.connection[edgeid])
-        else:
-            raise VistrailsInternalError("port with bogus information")
-        return result
-
     def connections_to_module(self, moduleId):
         """ connections_to_module(int moduleId) -> list of module ids
         returns a list of module ids that are inputs to the given moduleId
@@ -484,7 +438,7 @@ class Pipeline(DBWorkflow):
                                    old_conn.id)
             if self.graph.out_degree(old_conn.sourceId) < 1:
                 self.modules[old_conn.sourceId].connected_output_ports.discard(
-                    conn.source.name)
+                    old_conn.source.name)
             if self.graph.in_degree(old_conn.destinationId) < 1:
                 connected_input_ports = \
                     self.modules[old_conn.destinationId].connected_input_ports
@@ -886,26 +840,6 @@ class Pipeline(DBWorkflow):
         for c in self.connections.iterkeys():
             self.connection_signature(c)
 
-    def get_subpipeline(self, module_set):
-        """get_subpipeline([module_id] or subgraph) -> Pipeline
-
-        Returns a subset of the current pipeline with the modules passed
-        in as module_ids and the internal connections between them."""
-        if isinstance(module_set, list):
-            subgraph = self.graph.subgraph(module_set)
-        elif isinstance(module_set, Graph):
-            subgraph = module_set
-        else:
-            raise TypeError("Expected list of ints or graph")
-        result = Pipeline()
-        for module_id in subgraph.iter_vertices():
-            result.add_module(copy.copy(self.modules[module_id]))
-        for (conn_from, conn_to, conn_id) in subgraph.iter_all_edges():
-            result.add_connection(copy.copy(self.connections[conn_id]))
-                # TODO : I haven't finished this yet. -cscheid
-        raise NotImplementedError
-        return result
-
     ##########################################################################
     # Registry-related
 
@@ -938,7 +872,7 @@ class Pipeline(DBWorkflow):
                         desc = module.module_descriptor
                         if long(module.internal_version) != long(desc.version):
                             exceptions.add(MissingModuleVersion(desc.package, desc.name, desc.namespace, desc.version, desc.package_version, module.id))
-                    except:
+                    except Exception:
                         pass
         try:
             self.ensure_port_specs()
@@ -966,6 +900,8 @@ class Pipeline(DBWorkflow):
                 self.is_valid = False
                 return False
 
+        self.mark_list_depth()
+
         self.is_valid = True
         return True
 
@@ -1045,7 +981,7 @@ class Pipeline(DBWorkflow):
         def find_descriptors(pipeline, module_ids=None):
             registry = get_module_registry()
             conf = get_vistrails_configuration()
-            if module_ids == None:
+            if module_ids is None:
                 module_ids = pipeline.modules.iterkeys()
             exceptions = set()
             for mid in module_ids:
@@ -1166,7 +1102,71 @@ class Pipeline(DBWorkflow):
         for module in self.modules.itervalues():
             if module.is_valid and module.is_abstraction():
                 module.check_latest_version()
-                
+
+    def mark_list_depth(self, module_ids=None):
+        """mark_list_depth() -> list
+
+        Updates list_depth variable on each module according to list depth of
+        connecting port specs. This decides at what list depth the module
+        needs to be executed.
+        List ports have default depth 1
+
+        module_ids: list of module_ids - The id:s of modules that have changed
+        All modules upstream of these will be skipped, since markings only
+        affects downstream. This slightly increases performance.
+
+        """
+        result = []
+        is_upstream = module_ids
+        for module_id in self.graph.vertices_topological_sort():
+            if is_upstream:
+                if module_id in module_ids:
+                    is_upstream = False
+                else:
+                    continue
+            module = self.get_module_by_id(module_id)
+            module.list_depth = 0
+            ports = []
+            for module_from_id, conn_id in self.graph.edges_to(module_id):
+                prev_depth = self.get_module_by_id(module_from_id).list_depth
+                conn = self.get_connection_by_id(conn_id)
+                source_depth = 0
+                from vistrails.core.modules.basic_modules import List, Variant
+                if conn.source.spec:
+                    source_depth = conn.source.spec.depth
+                    src_descs = conn.source.spec.descriptors()
+                    # Lists have depth 1 if dest has depth>1 or is a list
+                    if len(src_descs) == 1 and src_descs[0].module == List:
+                        source_depth += 1
+                dest_depth = 0
+                if conn.destination.spec:
+                    dest_depth = conn.destination.spec.depth
+                    dest_descs = conn.destination.spec.descriptors()
+                    # Lists have depth 1
+                    if len(dest_descs) == 1 and dest_descs[0].module == List:
+                        dest_depth += 1
+                    # special case: if src is List and dst is Variant
+                    # we should treat the Variant as having depth 0
+                    if conn.source.spec:
+                        if len(src_descs)==1 and src_descs[0].module == List and \
+                           len(dest_descs)==1 and dest_descs[0].module == Variant:
+                            source_depth -= 1
+                        if len(src_descs)==1 and src_descs[0].module == Variant and \
+                           len(dest_descs)==1 and dest_descs[0].module == List:
+                            dest_depth -= 1
+                depth = prev_depth + source_depth - dest_depth
+                if depth > 0 and conn.destination.spec.name not in ports:
+                    ports.append(conn.destination.spec.name)
+                # if dest depth is greater the input will be wrapped in a
+                # list to match its depth
+                # if source depth is greater this module will be executed
+                # once for each input in the (possibly nested) list
+                module.list_depth = max(module.list_depth, depth)
+            result.append((module_id, module.list_depth))
+            module.iterated_ports = ports
+        return result
+
+
     ##########################################################################
     # Debugging
 
@@ -1274,7 +1274,7 @@ class TestPipeline(unittest.TestCase):
         # make sure pythonCalc is loaded
         from vistrails.core.packagemanager import get_package_manager
         pm = get_package_manager()
-        if 'pythonCalc' not in pm._package_list: # pragma: no cover # pragma: no partial
+        if 'pythonCalc' not in pm._package_list: # pragma: no cover # pragma: no branch
             pm.late_enable_package('pythonCalc')
 
     def create_default_pipeline(self, id_scope=None):
@@ -1315,11 +1315,18 @@ class TestPipeline(unittest.TestCase):
                 param.strValue = '4.0'
                 f.params.append(param)
                 return f
+            def cp1():
+                f = ModuleControlParam()
+                f.id = id_scope.getNewId(ModuleControlParam.vtType)
+                f.name = 'cpname1'
+                f.value = 'cpvalue[]'
+                return f
             m = Module()
             m.id = id_scope.getNewId(Module.vtType)
             m.name = 'PythonCalc'
-            m.package = '%s.pythoncalc' % get_vistrails_default_pkg_prefix()
+            m.package = 'org.vistrails.vistrails.pythoncalc'
             m.functions.append(f1())
+            m.control_parameters.append(cp1())
             return m
         
         def module2(p):
@@ -1336,7 +1343,7 @@ class TestPipeline(unittest.TestCase):
             m = Module()
             m.id = id_scope.getNewId(Module.vtType)
             m.name = 'PythonCalc'
-            m.package = '%s.pythoncalc' % get_vistrails_default_pkg_prefix()
+            m.package = 'org.vistrails.vistrails.pythoncalc'
             m.functions.append(f1())
             return m
         m1 = module1(p)
@@ -1470,9 +1477,7 @@ class TestPipeline(unittest.TestCase):
         self.assertNotEquals(p1.id, p3.id)
 
     def test_copy2(self):
-        import vistrails.core.db.io
-
-        # nedd to id modules and abstraction_modules with same counter
+        # need to id modules and abstraction_modules with same counter
         id_scope = IdScope(remap={Abstraction.vtType: Module.vtType})
         
         p1 = self.create_pipeline2(id_scope)
@@ -1548,7 +1553,7 @@ class TestPipeline(unittest.TestCase):
     def test_module_signature(self):
         """Tests signatures for modules with similar (but not equal)
         parameter specs."""
-        pycalc_pkg = '%s.pythoncalc' % get_vistrails_default_pkg_prefix()
+        pycalc_pkg = 'org.vistrails.vistrails.pythoncalc'
         p1 = Pipeline()
         p1_functions = [ModuleFunction(name='value1',
                                        parameters=[ModuleParam(type='Float',
@@ -1597,8 +1602,7 @@ class TestPipeline(unittest.TestCase):
                                                                )],
                                        )]
         p1.add_module(Module(name='CacheBug', 
-                            package='%s.console_mode_test' % \
-                             get_vistrails_default_pkg_prefix(),
+                            package='org.vistrails.vistrails.console_mode_test',
                             id=3,
                             functions=p1_functions))
 
@@ -1620,8 +1624,7 @@ class TestPipeline(unittest.TestCase):
                                                                )],
                                        )]
         p1.add_module(Module(name='CacheBug', 
-                            package='%s.console_mode_test' % \
-                             get_vistrails_default_pkg_prefix(),
+                            package='org.vistrails.vistrails.console_mode_test',
                             id=3,
                             functions=p1_functions))
         str(p1)
@@ -1647,14 +1650,6 @@ class TestPipeline(unittest.TestCase):
                              functions=[]))
         assert p1 == p2
 
-#     def test_subpipeline(self):
-#         p = self.create_default_pipeline()
-#         p2 = p.get_subpipeline([0, 1])
-#         for m in p2.modules:
-#             print m
-#         for c in p2.connections:
-#             print c
-
     def test_incorrect_port_spec(self):
         import vistrails.core.modules.basic_modules
         p = Pipeline()
diff --git a/vistrails/core/vistrail/plugin_data.py b/vistrails/core/vistrail/plugin_data.py
index c36b901..2beddcc 100644
--- a/vistrails/core/vistrail/plugin_data.py
+++ b/vistrails/core/vistrail/plugin_data.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBPluginData
 
 import unittest
diff --git a/vistrails/core/vistrail/port.py b/vistrails/core/vistrail/port.py
index 3f17a62..0aa74ff 100644
--- a/vistrails/core/vistrail/port.py
+++ b/vistrails/core/vistrail/port.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
     * Port
 
  """
+from __future__ import division
+
 from vistrails.db.domain import DBPort
 from vistrails.core.utils import VistrailsInternalError, all
 from vistrails.core.vistrail.port_spec import PortSpec, PortEndPoint
diff --git a/vistrails/core/vistrail/port_spec.py b/vistrails/core/vistrail/port_spec.py
index 948c6c0..7c70049 100644
--- a/vistrails/core/vistrail/port_spec.py
+++ b/vistrails/core/vistrail/port_spec.py
@@ -1,53 +1,54 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from itertools import izip
 import operator
 
 from vistrails.core.data_structures.bijectivedict import Bidict
 from vistrails.core.modules.utils import create_port_spec_string, parse_port_spec_string
-from vistrails.core.system import get_vistrails_basic_pkg_id
+from vistrails.core.system import get_vistrails_basic_pkg_id, \
+    get_module_registry
 from vistrails.core.utils import enum, VistrailsInternalError
 from vistrails.core.vistrail.port_spec_item import PortSpecItem
-from vistrails.db.domain import DBPortSpec
+from vistrails.db.domain import DBPortSpec, IdScope
 
+from ast import literal_eval
 import unittest
 import copy
-from vistrails.db.domain import IdScope
-import vistrails.core
-
-################################################################################
 
 PortEndPoint = enum('PortEndPoint',
                     ['Invalid', 'Source', 'Destination'])
@@ -122,6 +123,8 @@ class PortSpec(DBPortSpec):
             
         if 'sort_key' not in kwargs:
             kwargs['sort_key'] = -1
+        if 'depth' not in kwargs:
+            kwargs['depth'] = 0
         if 'id' not in kwargs:
             kwargs['id'] = -1
         if 'tooltip' in kwargs:
@@ -185,8 +188,6 @@ class PortSpec(DBPortSpec):
 
     @staticmethod
     def convert(_port_spec):
-        from vistrails.core.modules.module_registry import module_registry_loaded, \
-            ModuleRegistryException
         if _port_spec.__class__ == PortSpec:
             return
         _port_spec.__class__ = PortSpec
@@ -219,6 +220,7 @@ class PortSpec(DBPortSpec):
     sort_key = DBPortSpec.db_sort_key
     min_conns = DBPortSpec.db_min_conns
     max_conns = DBPortSpec.db_max_conns
+    _depth = DBPortSpec.db_depth
     port_spec_items = DBPortSpec.db_portSpecItems
     items = DBPortSpec.db_portSpecItems
 
@@ -251,6 +253,12 @@ class PortSpec(DBPortSpec):
         return signature
     signature = property(_get_signature)
 
+    def _get_depth(self):
+        return self._depth or 0
+    def _set_depth(self, depth):
+        self._depth = depth
+    depth = property(_get_depth, _set_depth)
+
     def toolTip(self):
         if self._tooltip is None:
             self.create_tooltip()
@@ -290,19 +298,19 @@ class PortSpec(DBPortSpec):
         if defaults is None:
             defaults = []
         elif isinstance(defaults, basestring):
-            defaults = eval(defaults)
+            defaults = literal_eval(defaults)
         if labels is None:
             labels = []
         elif isinstance(labels, basestring):
-            labels = eval(labels)
+            labels = literal_eval(labels)
         if values is None:
             values = []
         elif isinstance(values, basestring):
-            values = eval(values)
+            values = literal_eval(values)
         if entry_types is None:
             entry_types = []
         elif isinstance(entry_types, basestring):
-            entry_types = eval(entry_types)
+            entry_types = literal_eval(entry_types)
         attrs = [defaults, labels, values, entry_types]
         if items:
             self.set_items(items, *attrs)
@@ -330,7 +338,6 @@ class PortSpec(DBPortSpec):
         # multiple parameters, where each parameter can be either of the above:
         # add_input_port(_, _, [Float, (Integer, 'count')])
 
-        from vistrails.core.modules.module_registry import get_module_registry
         registry = get_module_registry()
         entries = []
         def canonicalize(sig_item):
@@ -398,9 +405,11 @@ class PortSpec(DBPortSpec):
             port_string = self.type.capitalize()
         else:
             port_string = 'Invalid'
-        self._tooltip = "%s port %s\n%s" % (port_string,
+        _depth = " (depth %s)" % self.depth if self.depth else ''
+        self._tooltip = "%s port %s\n%s%s" % (port_string,
                                             self.name,
-                                            self._short_sigstring)
+                                            self._short_sigstring,
+                                            _depth)
         
     ##########################################################################
     # Operators
@@ -410,9 +419,9 @@ class PortSpec(DBPortSpec):
         object. 
 
         """
-        rep = "<portSpec id=%s name=%s type=%s signature=%s />"
+        rep = "<portSpec id=%s name=%s type=%s signature=%s depth=%s />"
         return  rep % (str(self.id), str(self.name), 
-                       str(self.type), str(self.sigstring))
+                       str(self.type), str(self.sigstring), str(self.depth))
 
     def __eq__(self, other):
         """ __eq__(other: PortSpec) -> boolean
diff --git a/vistrails/core/vistrail/port_spec_item.py b/vistrails/core/vistrail/port_spec_item.py
index 8d53e6b..4d364ae 100644
--- a/vistrails/core/vistrail/port_spec_item.py
+++ b/vistrails/core/vistrail/port_spec_item.py
@@ -1,44 +1,58 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
+from __future__ import division
+
+from ast import literal_eval
 import copy
+import unittest
+
 from vistrails.core.modules.utils import parse_port_spec_item_string, \
     create_port_spec_item_string
+from vistrails.core.system import get_module_registry
 from vistrails.db.domain import DBPortSpecItem
 
-import unittest
-from vistrails.db.domain import IdScope
+
+_MissingPackage = None
+def get_MissingPackage():
+    global _MissingPackage
+    if _MissingPackage is None:
+        from vistrails.core.modules.module_registry import MissingPackage
+        _MissingPackage = MissingPackage
+    return _MissingPackage
 
 class PortSpecItem(DBPortSpecItem):
 
@@ -70,9 +84,8 @@ class PortSpecItem(DBPortSpecItem):
             org.vistrails.vistrails) and use the current one.
 
             """
-            from vistrails.core.modules.module_registry import \
-                get_module_registry, MissingPackage
             reg = get_module_registry()
+            MissingPackage = get_MissingPackage()
             try:
                 identifier = reg.get_package_by_name(identifier).identifier
             except MissingPackage:
@@ -160,7 +173,6 @@ class PortSpecItem(DBPortSpecItem):
 
     def _get_descriptor(self):
         if self._descriptor is None:
-            from vistrails.core.modules.module_registry import get_module_registry
             reg = get_module_registry()
             if self.package is None:
                 self._descriptor = \
@@ -176,8 +188,7 @@ class PortSpecItem(DBPortSpecItem):
 
     def _get_values(self):
         if self._values is None:
-            # don't use eval here...
-            self._values = eval(self.db_values)
+            self._values = literal_eval(self.db_values)
         return self._values
     def _set_values(self, values):
         if not isinstance(values, basestring):
@@ -185,8 +196,7 @@ class PortSpecItem(DBPortSpecItem):
             self.db_values = str(values)
         else:
             self.db_values = values
-            # don't use eval here...
-            self._values = eval(values)
+            self._values = literal_eval(values)
     values = property(_get_values, _set_values)
 
     def _get_spec_tuple(self):
diff --git a/vistrails/core/vistrail/tag.py b/vistrails/core/vistrail/tag.py
index fdfbfa3..a8a1783 100644
--- a/vistrails/core/vistrail/tag.py
+++ b/vistrails/core/vistrail/tag.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBTag
 
 import unittest
diff --git a/vistrails/core/vistrail/vistrail.py b/vistrails/core/vistrail/vistrail.py
index 07ef0ea..9977066 100644
--- a/vistrails/core/vistrail/vistrail.py
+++ b/vistrails/core/vistrail/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.paramexplore.paramexplore import ParameterExploration
 
 import copy
@@ -294,9 +297,9 @@ class Vistrail(DBVistrail):
             if self.has_upgrade(max_ver):
                 max_ver = long(self.get_upgrade(max_ver))
             return max_ver
-        except:
+        except Exception:
             return 0
-                   
+
     def getPipeline(self, version):
         """getPipeline(number or tagname) -> Pipeline
         Return a pipeline object given a version number or a version name. 
@@ -327,124 +330,6 @@ class Vistrail(DBVistrail):
         workflow = vistrails.core.db.io.get_workflow(self, version)
         return workflow
 
-    def make_actions_from_diff(self, diff):
-        """ make_actions_from_diff(diff) -> [action]
-        Returns a sequence of actions that performs the diff.
-
-        (The point is that this might be smaller than the
-        algebra-based one).
-        """
-        (p1,
-         p2,
-         m_shared,
-         m_to_be_deleted,
-         m_to_be_added,
-         parameter_changes,
-         c_shared,
-         c_to_be_deleted,
-         c_to_be_added) = (diff.p1,
-                           diff.p2,
-                           diff.v1andv2,
-                           diff.v1only,
-                           diff.v2only,
-                           diff.paramchanged,
-                           diff.c1andc2,
-                           diff.c1only,
-                           diff.c2only)
-
-        p1_c = copy.copy(p1)
-        result = []
-
-        module_id_remap = Bidict()
-        module_id_remap.update(m_shared)
-
-        connection_id_remap = Bidict()
-        connection_id_remap.update(c_shared)
-        
-        for ((m_id_from, m_id_to), _) in parameter_changes:
-            module_id_remap[m_id_from] = m_id_to
-
-        # First all the modules to get the remap
-        for p2_m_id in m_to_be_added:
-            add_module = AddModuleAction()
-            add_module.module = copy.copy(p2.modules[p2_m_id])
-            add_module.module.id = p1_c.fresh_module_id()
-            module_id_remap[add_module.module.id] = p2_m_id
-            result.append(add_module)
-            add_module.perform(p1_c)
-
-
-        # Then all the connections using the remap
-        for p2_c_id in c_to_be_added:
-            c2 = p2.connections[p2_c_id]
-            add_connection = AddConnectionAction()
-            new_c = copy.copy(c2)
-            add_connection.connection = new_c
-            new_c.id = p1_c.fresh_connection_id()
-            new_c.sourceId = module_id_remap.inverse[c2.sourceId]
-            new_c.destinationId = module_id_remap.inverse[c2.destinationId]
-            connection_id_remap[c2.id] = new_c.id
-            result.append(add_connection)
-            add_connection.perform(p1_c)
-
-
-        # Now delete all connections:
-        delete_conns = DeleteConnectionAction()
-        delete_conns.ids = copy.copy(c_to_be_deleted)
-        if len(delete_conns.ids) > 0:
-            delete_conns.perform(p1_c)
-            result.append(delete_conns)
-
-        # And then all the modules
-        delete_modules = DeleteModuleAction()
-        delete_modules.ids = copy.copy(m_to_be_deleted)
-        if len(delete_modules.ids) > 0:
-            delete_modules.perform(p1_c)
-            result.append(delete_modules)
-
-        # From now on, module_id_remap is not necessary, we can act
-        # on p1 ids without worry. (they still exist)
-
-        # Now move everyone
-        move_action = MoveModuleAction()
-        for (p1_m_id, p2_m_id) in m_shared.iteritems():
-            delta = p2.modules[p2_m_id].location - p1.modules[p1_m_id].location
-            move_action.addMove(p1_m_id, delta.x, delta.y)
-        move_action.perform(p1_c)
-        result.append(move_action)
-
-        # Now change parameters
-        def make_param_change(fto_name, fto_params,
-                              m_id, f_id, m):
-            action = ChangeParameterAction()
-            for (p_id, param) in enumerate(fto_params):
-                p_name = m.functions[f_id].params[p_id].name
-                p_alias = m.functions[f_id].params[p_id].alias
-                (p_type, p_value) = param
-                action.addParameter(m_id, f_id, p_id, fto_name,
-                                    p_name, p_value, p_type, p_alias)
-            return action
-        
-        if len(parameter_changes):
-            # print parameter_changes
-            for ((m_from_id, m_to_id), plist) in parameter_changes:
-                m_from = p1.modules[m_to_id]
-                for ((ffrom_name, ffrom_params),
-                     (fto_name, fto_params)) in plist:
-                    for (f_id, f) in enumerate(m_from.functions):
-                        if f.name != fto_name: continue
-                        new_action = make_param_change(fto_name,
-                                                       fto_params,
-                                                       m_from_id,
-                                                       f_id,
-                                                       m_from)
-                        new_action.perform(p1_c)
-                        result.append(new_action)
-
-        return (result,
-                module_id_remap,
-                connection_id_remap)
-
     def get_pipeline_diff_with_connections(self, v1, v2):
         """like get_pipeline_diff but returns connection info
         Keyword arguments:
@@ -456,6 +341,8 @@ class Vistrail(DBVistrail):
                     [v1 not v2 modules],
                     [v2 not v1 modules],
                     [parameter-changed modules (see-below)],
+                    [controlParameter-changed modules (see-below)],
+                    [annotation-changed modules (see-below)],
                     [shared connections (id in v1, id in v2) ...],
                     [shared connections [heuristic] (id in v1, id in v2)],
                     [c1 not in v2 connections],
@@ -464,6 +351,12 @@ class Vistrail(DBVistrail):
         parameter-changed modules = [((module id in v1, module id in v2),
                                       [(function in v1, function in v2)...]),
                                       ...]
+        controlParameter-changed modules = [((module id in v1, module id in v2),
+                                             [(cparam in v1, cparam in v2)...]),
+                                             ...]
+        annotation-changed modules = [((module id in v1, module id in v2),
+                                      [(annotation in v1, annotation in v2)...]),
+                                      ...]
         
         """
         return vistrails.core.db.io.get_workflow_diff_with_connections((self, v1), 
@@ -485,11 +378,20 @@ class Vistrail(DBVistrail):
                     [shared modules [heuristic match] (id in v1, id in v2)],
                     [v1 not v2 modules],
                     [v2 not v1 modules],
-                    [parameter-changed modules (see-below)])
+                    [parameter-changed modules (see-below)],
+                    [controlParameter-changed modules (see-below)],
+                    [annotation-changed modules (see-below)])
 
         parameter-changed modules = [((module id in v1, module id in v2),
                                       [(function in v1, function in v2)...]),
                                       ...]
+        controlParameter-changed modules = [((module id in v1, module id in v2),
+                                             [(cparam in v1, cparam in v2)...]),
+                                             ...]
+        annotation-changed modules = [((module id in v1, module id in v2),
+                                       [(annotation in v1, annotation in v2)...]),
+                                       ...]
+
         
         """
         return vistrails.core.db.io.get_workflow_diff((self, v1), (self, v2))
@@ -903,15 +805,18 @@ class Vistrail(DBVistrail):
             added_parameters = 0
             added_connections = 0
             added_annotations = 0
+            added_control_parameters = 0
             added_ports = 0
             moved_modules = 0
             changed_parameters = 0
             changed_annotations = 0
+            changed_control_parameters = 0
             deleted_modules = 0
             deleted_connections = 0
             deleted_parameters = 0
             deleted_functions = 0
             deleted_annotations = 0
+            deleted_control_parameters = 0
             deleted_ports = 0
             for op in ops:
                 if op.vtType == 'add':
@@ -923,6 +828,8 @@ class Vistrail(DBVistrail):
                         added_functions+=1
                     elif op.what == 'parameter':
                         added_parameters+=1
+                    elif op.what == 'controlParameter':
+                        added_control_parameters+=1
                     elif op.what == 'annotation':
                         added_annotations+=1
                     elif op.what == 'portSpec':
@@ -934,6 +841,8 @@ class Vistrail(DBVistrail):
                         moved_modules+=1
                     elif op.what == 'annotation':
                         changed_annotations+=1
+                    elif op.what == 'controlParameter':
+                        changed_control_parameters+=1
                 elif op.vtType == 'delete':
                     if op.what == 'module':
                         deleted_modules+=1
@@ -945,6 +854,8 @@ class Vistrail(DBVistrail):
                         deleted_parameters+=1
                     elif op.what == 'annotation':
                         deleted_annotations+=1
+                    elif op.what == 'controlParameter':
+                        deleted_control_parameters+=1
                     elif op.what == 'portSpec':
                         deleted_ports += 1
                 else:
@@ -962,6 +873,10 @@ class Vistrail(DBVistrail):
                 description = "Added parameter"
                 if added_functions > 1 or added_parameters > 1:
                     description += "s"
+            elif added_control_parameters:
+                description = "Added control parameter"
+                if added_control_parameters > 1:
+                    description += "s"
             elif added_annotations:
                 description = "Added annotation"
                 if added_annotations > 1:
@@ -974,6 +889,10 @@ class Vistrail(DBVistrail):
                 description = "Changed parameter"
                 if changed_parameters > 1:
                     description += "s"
+            elif changed_control_parameters:
+                description = "Changed control parameter"
+                if changed_control_parameters > 1:
+                    description += "s"
             elif moved_modules:
                 description = "Moved module"
                 if moved_modules > 1:
@@ -994,6 +913,10 @@ class Vistrail(DBVistrail):
                 description = "Deleted parameter"
                 if deleted_parameters > 1 or deleted_functions > 1:
                     description += "s"
+            elif deleted_control_parameters:
+                description = "Deleted control parameter"
+                if deleted_control_parameters > 1:
+                    description += "s"
             elif deleted_annotations:
                 description = "Deleted annotation"
                 if deleted_annotations > 1:
@@ -1030,7 +953,6 @@ class Vistrail(DBVistrail):
 
     def getDate(self):
         """ getDate() -> str - Returns the current date and time. """
-    #    return time.strftime("%d %b %Y %H:%M:%S", time.localtime())
         return datetime.datetime.now()
     
     def getUser(self):
@@ -1126,10 +1048,64 @@ class Vistrail(DBVistrail):
                 try:
                     if isinstance(op, AddOp) and op.what == 'module':
                         package_list[op.data.package] = op.data.package
-                except:
-                    pass
+                except AttributeError, e:
+                    debug.unexpected_exception(e)
         return package_list
-                    
+
+    def get_base_upgrade_version(self, version):
+        """Finds the base version in the upgrade chain.
+        """
+        # TODO: use this in search_upgrade_versions(), once the map is cached
+        upgrade_rev_map = {}
+        for ann in self.action_annotations:
+            if ann.key == Vistrail.UPGRADE_ANNOTATION:
+                upgrade_rev_map[int(ann.value)] = ann.action_id
+
+        while version in upgrade_rev_map:
+            version = upgrade_rev_map[version]
+        return version
+
+    def search_upgrade_versions(self, base_version, getter,
+                                start_at_base=None):
+        """Search all upgrades from a version for a specific value.
+
+        :param base_version: version from which to search (upgrades from this
+        version will be recursively searched)
+        :param getter: function that returns the value you are looking for, or
+        None to continue searching
+        :param start_at_base: if None (default), start from given version, then
+        if nothing is found start again from original version. If True, search
+        from the original action (the one that's not an upgrade). If False, go
+        down from given version only.
+        :returns: The result from getter, or None if all upgrades were exhausted
+        """
+        # TODO: cache these maps somewhere
+        upgrade_map = {}
+        upgrade_rev_map = {}
+        for ann in self.action_annotations:
+            if ann.key == Vistrail.UPGRADE_ANNOTATION:
+                upgrade_map[ann.action_id] = int(ann.value)
+                upgrade_rev_map[int(ann.value)] = ann.action_id
+
+        if start_at_base is True:
+            while base_version in upgrade_rev_map:
+                base_version = upgrade_rev_map[base_version]
+
+        version = base_version
+        walked_versions = set()
+        while version is not None and version not in walked_versions:
+            ret = getter(self, version, base_version)
+            if ret is not None:
+                return ret
+            walked_versions.add(version)
+            version = upgrade_map.get(version)
+            if version is None and start_at_base is None:
+                start_at_base = True
+                version = base_version
+                while version in upgrade_rev_map:
+                    version = upgrade_rev_map[version]
+        return None
+
 
 ##############################################################################
 
@@ -1236,7 +1212,6 @@ class TestVistrail(unittest.TestCase):
         # FIXME add checks for equality
 
     def test1(self):
-        import vistrails.core.vistrail
         from vistrails.core.db.locator import XMLFileLocator
         import vistrails.core.system
         v = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
@@ -1259,7 +1234,6 @@ class TestVistrail(unittest.TestCase):
             self.fail("vistrails tree is not single rooted.")
 
     def test2(self):
-        import vistrails.core.vistrail
         from vistrails.core.db.locator import XMLFileLocator
         import vistrails.core.system
         v = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
@@ -1270,6 +1244,8 @@ class TestVistrail(unittest.TestCase):
         v3 = 22
         v.get_pipeline_diff(v1,v2)
         v.get_pipeline_diff(v1,v3)
+        v.get_pipeline_diff_with_connections(v1,v2)
+        v.get_pipeline_diff_with_connections(v1,v3)
 
     def test_empty_action_chain(self):
         """Tests calling action chain on empty version."""
diff --git a/vistrails/core/vistrail/vistrailvariable.py b/vistrails/core/vistrail/vistrailvariable.py
index 19a9eeb..ca0ecf7 100644
--- a/vistrails/core/vistrail/vistrailvariable.py
+++ b/vistrails/core/vistrail/vistrailvariable.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBVistrailVariable
 
 import unittest
diff --git a/vistrails/db/__init__.py b/vistrails/db/__init__.py
index fc3514e..2bc5453 100644
--- a/vistrails/db/__init__.py
+++ b/vistrails/db/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 class VistrailsDBException(Exception):
     """VistrailsDBException is raised when there is any exception in the 
     db code for VisTrails
diff --git a/vistrails/db/bin/__init__.py b/vistrails/db/bin/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/bin/__init__.py
+++ b/vistrails/db/bin/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/bin/auto_gen_objects.py b/vistrails/db/bin/auto_gen_objects.py
index e994737..a15ca11 100644
--- a/vistrails/db/bin/auto_gen_objects.py
+++ b/vistrails/db/bin/auto_gen_objects.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 def capitalizeOne(str):
     result = ''
     strs = str.split('_')
@@ -40,7 +43,7 @@ def capitalizeOne(str):
         result += a_str[0].upper() + a_str[1:]
     return result
 
-class Field:
+class Field(object):
     def __init__(self, params):
         self.params = params
 
@@ -294,7 +297,7 @@ class Property(Field):
     def isChoice(self):
         return False
 
-class Object:
+class Object(object):
     def __init__(self, params, properties, layouts, choices):
         self.params = params
         self.properties = properties
diff --git a/vistrails/db/bin/generate.py b/vistrails/db/bin/generate.py
index c3d624a..19e1f34 100644
--- a/vistrails/db/bin/generate.py
+++ b/vistrails/db/bin/generate.py
@@ -1,34 +1,37 @@
+#!/usr/bin/env python
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -38,6 +41,8 @@
 # uses emacs via subprocess call for python indentation
 # the emacs call is slow because it checks all of the indentation
 
+from __future__ import division
+
 from mako.template import Template
 
 import os
@@ -67,35 +72,36 @@ class DAOList(dict):
 COPYRIGHT_NOTICE = \
 """###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/bin/parser.py b/vistrails/db/bin/parser.py
index 68dfbf1..38d01ca 100644
--- a/vistrails/db/bin/parser.py
+++ b/vistrails/db/bin/parser.py
@@ -1,43 +1,46 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import os
 from xml.dom import minidom, Node
 from auto_gen_objects import Object, Property, Choice
 
-class AutoGenParser:
+class AutoGenParser(object):
     def __init__(self):
         pass
 
diff --git a/vistrails/db/bin/sql_gen_objects.py b/vistrails/db/bin/sql_gen_objects.py
index cf72c4b..ed47241 100644
--- a/vistrails/db/bin/sql_gen_objects.py
+++ b/vistrails/db/bin/sql_gen_objects.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen_objects import Object, Property, Choice
 
 SQL_TYPE = 'sql'
diff --git a/vistrails/db/bin/templates/domain.py.mako b/vistrails/db/bin/templates/domain.py.mako
index 5e2b456..df62c02 100644
--- a/vistrails/db/bin/templates/domain.py.mako
+++ b/vistrails/db/bin/templates/domain.py.mako
@@ -28,35 +28,36 @@ def shouldIgnoreIndexDelete(index):
 %> \\
 <%text>###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -457,6 +458,7 @@ class ${obj.getClassName()}(object):
                 break
         % endif
         % endif
+        % if field.getPythonType() == 'hash' or field.getReferencedObject().getKey() is not None:
         % for index in field.getAllIndices():
         % if shouldIgnoreIndexDelete(index):
         try:
@@ -469,6 +471,7 @@ class ${obj.getClassName()}(object):
             index[${getIndexKey(field.getName(), index)}]
         % endif
         % endfor
+        % endif
     def ${field.getLookup()}(self, key):
         % if field.getPythonType() == 'hash':
         if key in self.${field.getPrivateName()}:
diff --git a/vistrails/db/bin/templates/sql.py.mako b/vistrails/db/bin/templates/sql.py.mako
index f74ad9f..7986160 100644
--- a/vistrails/db/bin/templates/sql.py.mako
+++ b/vistrails/db/bin/templates/sql.py.mako
@@ -1,34 +1,35 @@
 <%text>###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/bin/templates/sql_delete.sql.mako b/vistrails/db/bin/templates/sql_delete.sql.mako
index fcd9736..0d5a46d 100644
--- a/vistrails/db/bin/templates/sql_delete.sql.mako
+++ b/vistrails/db/bin/templates/sql_delete.sql.mako
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/bin/templates/sql_schema.sql.mako b/vistrails/db/bin/templates/sql_schema.sql.mako
index 0410f55..5e38086 100644
--- a/vistrails/db/bin/templates/sql_schema.sql.mako
+++ b/vistrails/db/bin/templates/sql_schema.sql.mako
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/bin/templates/xml.py.mako b/vistrails/db/bin/templates/xml.py.mako
index 93a0e91..e7c093d 100644
--- a/vistrails/db/bin/templates/xml.py.mako
+++ b/vistrails/db/bin/templates/xml.py.mako
@@ -1,34 +1,35 @@
 <%text>###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/bin/templates/xml_schema.xsd.mako b/vistrails/db/bin/templates/xml_schema.xsd.mako
index c722630..87d5f22 100644
--- a/vistrails/db/bin/templates/xml_schema.xsd.mako
+++ b/vistrails/db/bin/templates/xml_schema.xsd.mako
@@ -15,35 +15,36 @@ def writeElement(prop):
 %> \\
 <%text><!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/bin/xml_gen_objects.py b/vistrails/db/bin/xml_gen_objects.py
index d89aec0..ec43d1d 100644
--- a/vistrails/db/bin/xml_gen_objects.py
+++ b/vistrails/db/bin/xml_gen_objects.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen_objects import Object, Property, Choice
 
 XML_TYPE = 'xml'
diff --git a/vistrails/db/domain/__init__.py b/vistrails/db/domain/__init__.py
index 947b0dc..20a8e7c 100644
--- a/vistrails/db/domain/__init__.py
+++ b/vistrails/db/domain/__init__.py
@@ -1,35 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.db.versions.v1_0_3.domain import *
+
+from __future__ import division
+
+from vistrails.db.versions.v1_0_4.domain import *
diff --git a/vistrails/db/persistence/__init__.py b/vistrails/db/persistence/__init__.py
index 06d6c7d..f71700a 100644
--- a/vistrails/db/persistence/__init__.py
+++ b/vistrails/db/persistence/__init__.py
@@ -1,35 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.db.versions.v1_0_3.persistence import *
+
+from __future__ import division
+
+from vistrails.db.versions.v1_0_4.persistence import *
diff --git a/vistrails/db/services/__init__.py b/vistrails/db/services/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/services/__init__.py
+++ b/vistrails/db/services/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/services/abstraction.py b/vistrails/db/services/abstraction.py
index 43a7b51..0124b5f 100644
--- a/vistrails/db/services/abstraction.py
+++ b/vistrails/db/services/abstraction.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBWorkflow
 from vistrails.db.services.action_chain import getActionChain, getCurrentOperationDict, \
     getCurrentOperations
diff --git a/vistrails/db/services/action.py b/vistrails/db/services/action.py
index f2acbf5..cd0cd09 100644
--- a/vistrails/db/services/action.py
+++ b/vistrails/db/services/action.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.services.action_chain import simplify_ops
 from vistrails.db.domain import DBAction, DBAdd, DBDelete, DBChange
 import copy
@@ -136,7 +139,7 @@ def create_action(action_list):
       parent_type=None,
       parent_id=None,
     )
-    Example: create_action([('add', module1), ('delete', connection2)]
+    Example: create_action([('add', module1), ('delete', connection2)])
 
     """
     ops = []
diff --git a/vistrails/db/services/action_chain.py b/vistrails/db/services/action_chain.py
index b5a23c1..fee6d26 100644
--- a/vistrails/db/services/action_chain.py
+++ b/vistrails/db/services/action_chain.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 def getActionChain(obj, version, start=0):
     result = []
     currentId = version
diff --git a/vistrails/db/services/io.py b/vistrails/db/services/io.py
index a1ef3bf..176b953 100644
--- a/vistrails/db/services/io.py
+++ b/vistrails/db/services/io.py
@@ -1,63 +1,61 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from __future__ import with_statement
+from __future__ import division, with_statement
 
 from datetime import datetime
 from vistrails.core import debug
 from vistrails.core.bundles import py_import
-from vistrails.core.system import get_elementtree_library, temporary_directory,\
-     execute_cmdline, systemType, get_executable_path
+from vistrails.core.system import get_elementtree_library, strftime
 from vistrails.core.utils import Chdir
-from vistrails.core.log.log import Log
 from vistrails.core.mashup.mashup_trail import Mashuptrail
 from vistrails.core.modules.sub_module import get_cur_abs_namespace,\
     parse_abstraction_name, read_vistrail_from_db
 
 import vistrails.core.requirements
 
-import sys
-import os
 import os.path
 import shutil
 import tempfile
 import copy
+import zipfile
 
 from vistrails.db import VistrailsDBException
 from vistrails.db.domain import DBVistrail, DBWorkflow, DBLog, DBAbstraction, DBGroup, \
     DBRegistry, DBWorkflowExec, DBOpmGraph, DBProvDocument, DBAnnotation, \
-    DBMashuptrail
+    DBMashuptrail, DBStartup
 import vistrails.db.services.abstraction
 import vistrails.db.services.log
 import vistrails.db.services.opm
@@ -66,7 +64,7 @@ import vistrails.db.services.registry
 import vistrails.db.services.workflow
 import vistrails.db.services.vistrail
 from vistrails.db.versions import getVersionDAO, currentVersion, getVersionSchemaDir, \
-    translate_vistrail, translate_workflow, translate_log, translate_registry
+    translate_vistrail, translate_workflow, translate_log, translate_registry, translate_startup
 
 import unittest
 import vistrails.core.system
@@ -248,7 +246,7 @@ def translate_to_tbl_name(obj_type):
     return map[obj_type]
 
 def date_to_str(date):
-    return date.strftime('%Y-%m-%d %H:%M:%S')
+    return strftime(date, '%Y-%m-%d %H:%M:%S')
 
 def get_db_object_list(config, obj_type):
     
@@ -690,15 +688,17 @@ def open_vistrail_from_xml(filename):
     try:
         daoList = getVersionDAO(version)
         vistrail = daoList.open_from_xml(filename, DBVistrail.vtType, tree)
+        if vistrail is None:
+            raise VistrailsDBException("Couldn't read vistrail from XML")
         vistrail = translate_vistrail(vistrail, version)
         vistrails.db.services.vistrail.update_id_scope(vistrail)
     except VistrailsDBException, e:
         if str(e).startswith('VistrailsDBException: Cannot find DAO for'):
-            msg = "This vistrail was created by a newer version of VisTrails "
-            msg += "and cannot be opened."
-            raise VistrailsDBException(msg)
+            raise VistrailsDBException(
+                "This vistrail was created by a newer version of VisTrails "
+                "and cannot be opened.")
         raise e
-        
+
     return vistrail
 
 def open_vistrail_bundle_from_zip_xml(filename):
@@ -710,16 +710,13 @@ def open_vistrail_bundle_from_zip_xml(filename):
     and thumbnails inside archive are '.png' files in 'thumbs' dir
 
     """
-
-    vistrails.core.requirements.require_executable('unzip')
-
     vt_save_dir = tempfile.mkdtemp(prefix='vt_save')
-    output = []
-    cmdline = ['unzip', '-q','-o','-d', vt_save_dir, filename]
-    result = execute_cmdline(cmdline, output)
 
-    if result != 0 and len(output) != 0:
-        raise VistrailsDBException("Unzip of '%s' failed" % filename)
+    z = zipfile.ZipFile(filename)
+    try:
+        z.extractall(vt_save_dir)
+    finally:
+        z.close()
 
     vistrail = None
     log = None
@@ -801,9 +798,8 @@ def open_vistrail_bundle_from_db(db_connection, vistrail_id, tmp_dir=None):
             save_vistrail_to_xml(abs, fname)
             abstractions.append(fname)
     except Exception, e:
-        import traceback
         debug.critical('Could not load abstraction from database: %s' % str(e),
-                                              traceback.format_exc())
+                       debug.format_exc())
     # open mashuptrails from db
     mashuptrails = []
     try:
@@ -811,9 +807,8 @@ def open_vistrail_bundle_from_db(db_connection, vistrail_id, tmp_dir=None):
             mashup = open_mashuptrail_from_db(db_connection, mashup_id)
             mashuptrails.append(mashup)
     except Exception, e:
-        import traceback
         debug.critical('Could not load mashuptrail from database: %s' % str(e),
-                                              traceback.format_exc())
+                       debug.format_exc())
     thumbnails = open_thumbnails_from_db(db_connection, DBVistrail.vtType,
                                          vistrail_id, tmp_dir)
     return SaveBundle(DBVistrail.vtType, vistrail, log,
@@ -874,10 +869,8 @@ def save_vistrail_bundle_to_zip_xml(save_bundle, filename, vt_save_dir=None, ver
 
     Generates a zip compressed version of vistrail.
     It raises an Exception if there was an error.
-    
-    """
 
-    vistrails.core.requirements.require_executable('zip')
+    """
 
     if save_bundle.vistrail is None:
         raise VistrailsDBException('save_vistrail_bundle_to_zip_xml failed, '
@@ -982,27 +975,15 @@ def save_vistrail_bundle_to_zip_xml(save_bundle, filename, vt_save_dir=None, ver
         debug.warning("Could not call package hooks", str(e))
     tmp_zip_dir = tempfile.mkdtemp(prefix='vt_zip')
     tmp_zip_file = os.path.join(tmp_zip_dir, "vt.zip")
-    output = []
-    rel_vt_save_dir = os.path.split(vt_save_dir)[1]
-
-    # on windows, we assume zip.exe is in the current directory when
-    # running from the binary install
-    zipcmd = 'zip'
-    if systemType in ['Windows', 'Microsoft']:
-        zipcmd = get_executable_path('zip.exe')
-        if not zipcmd or not os.path.exists(zipcmd):
-            zipcmd = 'zip.exe' #assume zip is in path
-    cmdline = [zipcmd, '-r', '-q', tmp_zip_file, '.']
+
+    z = zipfile.ZipFile(tmp_zip_file, 'w')
     try:
-        #if we want that directories are also stored in the zip file
-        # we need to run from the vt directory
         with Chdir(vt_save_dir):
-            result = execute_cmdline(cmdline,output)
-        #print result, output
-        if result != 0 or len(output) != 0:
-            for line in output:
-                if line.find('deflated') == -1:
-                    raise VistrailsDBException(" ".join(output))
+            # zip current directory
+            for root, dirs, files in os.walk('.'):
+                for f in files:
+                    z.write(os.path.join(root, f))
+        z.close()
         shutil.copyfile(tmp_zip_file, filename)
     finally:
         os.unlink(tmp_zip_file)
@@ -1118,6 +1099,8 @@ def open_workflow_from_xml(filename):
     version = get_version_for_xml(tree.getroot())
     daoList = getVersionDAO(version)
     workflow = daoList.open_from_xml(filename, DBWorkflow.vtType, tree)
+    if workflow is None:
+        raise VistrailsDBException("Couldn't read workflow from XML")
     workflow = translate_workflow(workflow, version)
     vistrails.db.services.workflow.update_id_scope(workflow)
     return workflow
@@ -1396,6 +1379,8 @@ def open_registry_from_xml(filename):
     version = get_version_for_xml(tree.getroot())
     daoList = getVersionDAO(version)
     registry = daoList.open_from_xml(filename, DBRegistry.vtType, tree)
+    if registry is None:
+        raise VistrailsDBException("Couldn't read registry from XML")
     registry = translate_registry(registry, version)
     vistrails.db.services.registry.update_id_scope(registry)
     return registry
@@ -1471,60 +1456,6 @@ def save_registry_bundle_to_db(save_bundle, db_connection, do_copy=False,
 ##############################################################################
 # Abstraction I/O
 
-def open_abstraction_from_db(db_connection, id, lock=False):
-    """open_abstraction_from_db(db_connection, id : long: lock: bool) 
-         -> DBAbstraction 
-    DEPRECATED
-    """
-    if db_connection is None:
-        msg = "Need to call open_db_connection() before reading"
-        raise VistrailsDBException(msg)
-    abstraction = read_sql_objects(db_connection, DBAbstraction.vtType, 
-                                   id, lock)[0]
-
-    # not sure where this really should be done...
-    # problem is that db reads the add ops, then change ops, then delete ops
-    # need them ordered by their id
-    for db_action in abstraction.db_get_actions():
-        db_action.db_operations.sort(key=lambda x: x.db_id)
-    vistrails.db.services.abstraction.update_id_scope(abstraction)
-    return abstraction
-
-def save_abstraction_to_db(abstraction, db_connection, do_copy=False):
-    """ DEPRECATED """
-    db_connection.begin()
-    if abstraction.db_last_modified is None:
-        do_copy = True
-    if not do_copy:
-        match_id = get_matching_abstraction_id(db_connection, abstraction)
-        # FIXME remove print
-        #print 'match_id:', match_id
-        if match_id is not None:
-            abstraction.db_id = match_id
-            abstraction.is_new = False
-        else:
-            do_copy = True
-        new_time = get_db_object_modification_time(db_connection, 
-                                                   abstraction.db_id,
-                                                   DBAbstraction.vtType)
-        if new_time > abstraction.db_last_modified:
-            # need synchronization
-            # FIXME remove print
-            #print '*** doing synchronization ***'
-            old_abstraction = open_abstraction_from_db(db_connection, 
-                                                       abstraction.db_id,
-                                                       True)
-            # the "old" one is modified and changes integrated
-            vistrails.db.services.vistrail.synchronize(old_abstraction, abstraction,
-                                             0L)
-            abstraction = old_abstraction
-    if do_copy:
-        abstraction.db_id = None
-    abstraction.db_last_modified = get_current_time(db_connection)
-    write_sql_objects(db_connection, [abstraction], do_copy)
-    db_connection.commit()
-    return abstraction
-
 def save_abstractions_to_db(abstractions, vt_id, db_connection, do_copy=False):
     """save_abstraction_to_db(abs: DBVistrail, db_connection) -> None
     Saves an abstraction to db, and updating existing abstractions
@@ -1683,7 +1614,7 @@ def save_thumbnails_to_db(absfnames, db_connection):
             image_file = open(absfname, 'rb')
             image_bytes = image_file.read()
             image_file.close()
-            c.execute(prepared_statement, (os.path.basename(absfname), image_bytes, get_current_time(db_connection).strftime('%Y-%m-%d %H:%M:%S')))
+            c.execute(prepared_statement, (os.path.basename(absfname), image_bytes, strftime(get_current_time(db_connection), '%Y-%m-%d %H:%M:%S')))
             db_connection.commit()
         c.close()
     except IOError, e:
@@ -1797,6 +1728,34 @@ def save_mashuptrails_to_db(mashuptrails, vt_id, db_connection, do_copy=False):
         except Exception, e:
             debug.critical('Could not save mashuptrail to db: %s' % str(e))
 
+def open_startup_from_xml(filename):
+    tree = ElementTree.parse(filename)
+    version = get_version_for_xml(tree.getroot())
+    if version == '0.1':
+        version = '1.0.3'
+    daoList = getVersionDAO(version)
+    startup = daoList.open_from_xml(filename, DBStartup.vtType, tree)
+    # need this for translation...
+    startup._filename = filename
+    startup = translate_startup(startup, version)
+    # vistrails.db.services.startup.update_id_scope(startup)
+    return startup
+
+def save_startup_to_xml(startup, filename, version=None):
+    tags = {}
+    if version is None:
+        version = currentVersion
+    if not startup.db_version:
+        startup.db_version = currentVersion
+    # FIXME add translation, etc.
+    # startup = translate_startup(startup, startup.db_version, version)
+
+    daoList = getVersionDAO(version)
+    daoList.save_to_xml(startup, filename, tags, version)
+    # startup = translate_startup(startup, version)
+    return startup
+    
+
 ##############################################################################
 # I/O Utilities
 
@@ -1833,7 +1792,7 @@ def get_current_time(db_connection=None):
             if row:
                 # FIXME MySQL versus sqlite3
                 timestamp = row[0]
-                # timestamp = datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S')
+                # timestamp = strptime(row[0], '%Y-%m-%d %H:%M:%S')
             c.close()
         except get_db_lib().Error, e:
             debug.critical("Logger Error %d: %s" % (e.args[0], e.args[1]))
diff --git a/vistrails/db/services/locator.py b/vistrails/db/services/locator.py
index 65fee95..3b24cc0 100644
--- a/vistrails/db/services/locator.py
+++ b/vistrails/db/services/locator.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import cgi
 from datetime import datetime, date
 import hashlib
@@ -39,7 +42,6 @@ import locale
 import os.path
 import re
 import sys
-from time import strptime
 import urllib
 import urlparse
 import uuid
@@ -50,7 +52,8 @@ from vistrails.db.services.io import SaveBundle
 from vistrails.db.domain import DBVistrail, DBWorkflow
 from vistrails.db import VistrailsDBException
 from vistrails.core import debug
-from vistrails.core.system import get_elementtree_library, systemType
+from vistrails.core.system import get_elementtree_library, systemType, \
+    time_strptime
 
 ElementTree = get_elementtree_library()
 
@@ -364,7 +367,7 @@ class SaveTemporariesMixin(object):
         latest one.
 
         """
-        if temporary == None:
+        if temporary is None:
             return self.encode_name(self.get_temp_basename()) + '0'
         else:
             split = temporary.rfind('_')+1
@@ -804,7 +807,7 @@ class DBLocator(BaseLocator):
             return True
         try:
             self.get_connection()
-        except:
+        except Exception:
             return False
         return True
         
@@ -899,7 +902,7 @@ class DBLocator(BaseLocator):
         ts = io.get_db_object_modification_time(self.get_connection(),
                                                 self.obj_id,
                                                 obj_type)
-        ts = datetime(*strptime(str(ts).strip(), '%Y-%m-%d %H:%M:%S')[0:6])
+        ts = datetime(*time_strptime(str(ts).strip(), '%Y-%m-%d %H:%M:%S')[0:6])
         return ts
         
     def serialize(self, dom, element):
@@ -938,7 +941,7 @@ class DBLocator(BaseLocator):
                     name = str(n.firstChild.nodeValue).strip(" \n\t")
                     #print host, port, database, name, vt_id
                     return DBLocator(host, port, database,
-                                     user, passwd, name, vt_id, None)
+                                     user, passwd, name, obj_id=vt_id)
             return None
         else:
             return None
@@ -1024,9 +1027,9 @@ class DBLocator(BaseLocator):
                     elif type == 'bool':
                         return bool_conv(value)
                     elif type == 'date':
-                        return date(*strptime(value, '%Y-%m-%d')[0:3])
+                        return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                     elif type == 'datetime':
-                        return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                        return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
             return None
     
         if node.tag != 'locator':
diff --git a/vistrails/db/services/log.py b/vistrails/db/services/log.py
index d5df8e6..9cef252 100644
--- a/vistrails/db/services/log.py
+++ b/vistrails/db/services/log.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBWorkflowExec
 
 def update_id_scope(log):
diff --git a/vistrails/db/services/opm.py b/vistrails/db/services/opm.py
index d5d00a9..0cb21a8 100644
--- a/vistrails/db/services/opm.py
+++ b/vistrails/db/services/opm.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+from ast import literal_eval
 import copy
 import sys
-from vistrails.core.system import get_vistrails_default_pkg_prefix, \
-    get_vistrails_basic_pkg_id
+from vistrails.core.system import get_vistrails_basic_pkg_id
 import vistrails.db.services.io
 from vistrails.db.domain import DBOpmProcess, DBOpmArtifact, DBOpmUsed, \
     DBOpmWasGeneratedBy, DBOpmProcessIdCause, DBOpmProcessIdEffect, \
@@ -47,8 +50,6 @@ from vistrails.db.domain import DBOpmProcess, DBOpmArtifact, DBOpmUsed, \
     DBParameter
 from vistrails.db.services.vistrail import materializeWorkflow
 
-sys.path.append('/vistrails/src/trunk/vistrails')
-
 def create_process(item_exec, account, id_scope):
     return DBOpmProcess(id='p' + str(id_scope.getNewId(DBOpmProcess.vtType)),
                         value=DBOpmProcessValue(item_exec),
@@ -267,7 +268,7 @@ def create_opm(workflow, version, log, reg):
             input_list_artifact = found_input_ports['InputList']
             result_artifact = found_output_ports.get('Result', None)
             input_port_list = \
-                eval(found_input_ports['InputPort'].db_parameters[0].db_val)
+                literal_eval(found_input_ports['InputPort'].db_parameters[0].db_val)
             output_port = \
                 found_input_ports['OutputPort'].db_parameters[0].db_val
 
@@ -413,7 +414,7 @@ def create_opm(workflow, version, log, reg):
             out_downstream_artifacts = {}
 
 
-        ctrl_flow_pkg = '%s.control_flow' % get_vistrails_default_pkg_prefix()
+        ctrl_flow_pkg = 'org.vistrails.vistrails.control_flow'
         basic_pkg = get_vistrails_basic_pkg_id()
         all_special_ports = {'%s:Map' % ctrl_flow_pkg:
                                  [{'InputPort': False, 
@@ -469,7 +470,7 @@ def create_opm(workflow, version, log, reg):
                 return artifact
 
             if annotation.db_key == 'used_files':
-                used_files = eval(annotation.db_value)
+                used_files = literal_eval(annotation.db_value)
                 for fname in used_files:
                     if fname not in file_artifacts:
                         artifact = create_artifact_from_filename(fname,
@@ -485,7 +486,7 @@ def create_opm(workflow, version, log, reg):
                     dependencies.append(create_used(process, artifact,
                                                     account, id_scope))
             elif annotation.db_key == 'generated_tables':
-                generated_tables = eval(annotation.db_value)
+                generated_tables = literal_eval(annotation.db_value)
                 for db_tuple in generated_tables:
                     artifact = process_db_tuple(db_tuple)
                     dependencies.append(create_was_generated_by(artifact,
@@ -493,7 +494,7 @@ def create_opm(workflow, version, log, reg):
                                                                 account,
                                                                 id_scope))
             elif annotation.db_key == 'used_tables':
-                used_tables = eval(annotation.db_value)
+                used_tables = literal_eval(annotation.db_value)
                 for db_tuple in used_tables:
                     artifact = process_db_tuple(db_tuple)
                     dependencies.append(create_used(process, artifact,
diff --git a/vistrails/db/services/prov.py b/vistrails/db/services/prov.py
index 61999da..39e702b 100644
--- a/vistrails/db/services/prov.py
+++ b/vistrails/db/services/prov.py
@@ -1,41 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 import sys
 import os
-#sys.path.append(os.getenv('VISTRAILS', ''))
 import vistrails.db.services.io
 from vistrails.db.domain import DBProvDocument, DBProvEntity, DBProvActivity, \
     DBProvAgent, DBProvGeneration, DBProvUsage, DBProvAssociation, \
@@ -407,7 +409,7 @@ def create_prov(workflow, version, log):
             
             try:
                 functions = module_functions[exec_._db_module_id]
-            except:
+            except Exception:
                 activities.append(prov_activity)
                 return True
                 
@@ -428,7 +430,7 @@ def create_prov(workflow, version, log):
                     prov_usage = create_prov_usage(prov_activity, prov_input_data)
                     usages.append(prov_usage)
                 
-            if (prov_activity._db_vt_error == None) or (prov_activity._db_vt_error == ''):
+            if (prov_activity._db_vt_error is None) or (prov_activity._db_vt_error == ''):
                 if source_conn.has_key(exec_._db_module_id):
                     connections = source_conn[exec_._db_module_id]
                     for connection in connections:
diff --git a/vistrails/db/services/query.py b/vistrails/db/services/query.py
index 9861e94..a70d9ff 100644
--- a/vistrails/db/services/query.py
+++ b/vistrails/db/services/query.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db import VistrailsDBException
 from vistrails.db.services.io import open_db_connection, close_db_connection, get_db_lib
 
diff --git a/vistrails/db/services/registry.py b/vistrails/db/services/registry.py
index 062e6ce..91ec431 100644
--- a/vistrails/db/services/registry.py
+++ b/vistrails/db/services/registry.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBPackage, DBModuleDescriptor, DBPortSpec
 
 def update_id_scope(registry):
diff --git a/vistrails/db/services/vistrail.py b/vistrails/db/services/vistrail.py
index 2e093c7..faa9778 100644
--- a/vistrails/db/services/vistrail.py
+++ b/vistrails/db/services/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.domain import DBWorkflow, DBAdd, DBDelete, DBAction, DBAbstraction, \
     DBModule, DBConnection, DBPort, DBFunction, DBParameter, DBGroup
 from vistrails.db.services.action_chain import getActionChain, getCurrentOperationDict, \
@@ -44,6 +47,7 @@ import getpass
 
 import unittest
 import vistrails.core.system
+from itertools import chain
 
 def update_id_scope(vistrail):
     if hasattr(vistrail, 'update_id_scope'):
@@ -853,7 +857,44 @@ def heuristicModuleMatch(m1, m2):
                 m2_functions.remove(f2)
             else:
                 return 0
-        if len(m1_functions) == len(m2_functions) == 0:
+        
+        m1_cparams = copy.copy(m1.db_get_controlParameters())
+        m2_cparams = copy.copy(m2.db_get_controlParameters())
+        if len(m1_cparams) != len(m2_cparams):
+            return 0
+        for cp1 in m1_cparams[:]:
+            match = None
+            for cp2 in m2_cparams:
+                isMatch = heuristicControlParameterMatch(cp1, cp2)
+                if isMatch == 1:
+                    match = cp2
+                    break
+            if match is not None:
+                m1_cparams.remove(cp1)
+                m2_cparams.remove(cp2)
+            else:
+                return 0
+        
+        m1_annots = copy.copy(m1.db_get_annotations())
+        m2_annots = copy.copy(m2.db_get_annotations())
+        if len(m1_annots) != len(m2_annots):
+            return 0
+        for a1 in m1_annots[:]:
+            match = None
+            for a2 in m2_annots:
+                isMatch = heuristicAnnotationMatch(a1, a2)
+                if isMatch == 1:
+                    match = a2
+                    break
+            if match is not None:
+                m1_annots.remove(a1)
+                m2_annots.remove(a2)
+            else:
+                return 0
+
+        if len(m1_functions) == len(m2_functions) == \
+           len(m1_cparams  ) == len(m2_cparams  ) == \
+           len(m1_annots   ) == len(m2_annots   ) == 0:
             return 1
         else:
             return 0
@@ -899,6 +940,30 @@ def heuristicParameterMatch(p1, p2):
             return 0
     return -1
 
+def heuristicControlParameterMatch(cp1, cp2):
+    """takes two control parameters and returns 1 if exact match,
+    0 if partial match (types match), -1 if no match
+
+    """
+    if cp1.db_name == cp2.db_name:
+        if cp1.db_value == cp2.db_value:
+            return 1
+        else:
+            return 0
+    return -1
+
+def heuristicAnnotationMatch(a1, a2):
+    """takes two annotations and returns 1 if exact match,
+    0 if partial match (types match), -1 if no match
+
+    """
+    if a1.db_key == a2.db_key:
+        if a1.db_value == a2.db_value:
+            return 1
+        else:
+            return 0
+    return -1
+
 def heuristicConnectionMatch(c1, c2):
     """takes two connections and returns 1 if exact match,
     0 if partial match (currently undefined), -1 if no match
@@ -1016,6 +1081,155 @@ def getParamChanges(m1, m2, same_vt=True, heuristic_match=True):
         
     return paramChanges
 
+def getCParamChanges(m1, m2, same_vt=True, heuristic_match=True):
+    cparamChanges = []
+    # need to check to see if any children of m1 and m2 are affected
+    m1_cparams = m1.db_get_controlParameters()
+    m2_cparams = m2.db_get_controlParameters()
+    m1_unmatched = []
+    m2_unmatched = []
+    if same_vt:
+        for cp1 in m1_cparams:
+            # see if m2 has f1, too
+            cp2 = m2.db_get_controlParameter(cp1.db_id)
+            if cp2 is None:            
+                m1_unmatched.append(cp1)
+            else:
+                # cparam is same, check if it has changed
+                if heuristic_match:
+                    matchValue = heuristicControlParameterMatch(cp1, cp2)
+                    if matchValue != 1:
+                        cparamChanges.append(((cp1.db_name,cp1.db_value), 
+                                              (cp2.db_name,cp2.db_value)))
+                else:
+                    cparamChanges.append(((cp1.db_name,cp1.db_value), 
+                                          (cp2.db_name,cp2.db_value)))
+        for cp2 in m2_cparams:
+            # see if m1 has f2, too
+            if m1.db_get_controlParameter(cp2.db_id) is None:
+                m2_unmatched.append(cp2)
+    else:
+        m1_unmatched.extend(m1_cparams)
+        m2_unmatched.extend(m2_cparams)
+
+#             functionMatch = True
+#             f1_params = f1.db_get_parameters()
+#             f2_params = f2.db_get_parameters()
+#             for p1 in f1_params:
+#                 if f2.db_get_parameter(p1.db_id) is None:
+#                     functionMatch = False
+#                     m1_unmatched.append(f1)
+#                     break
+#             for p2 in f2_params:
+#                 if f1.db_get_parameter(p2.db_id) is None:
+#                     functionMatch = False
+#                     m2_unmatched.append(f2)
+#                     break
+#             if functionMatch:
+
+    if len(m1_unmatched) + len(m2_unmatched) > 0:
+        if heuristic_match and len(m1_unmatched) > 0 and len(m2_unmatched) > 0:
+            # do heuristic matches
+            for cp1 in m1_unmatched[:]:
+                matched = False
+                matchValue = 0
+                for cp2 in m2_unmatched:
+                    matchValue = heuristicControlParameterMatch(cp1, cp2)
+                    if matchValue == 1:
+                        # best match so quit
+                        matched = cp1
+                        break
+                    elif matchValue == 0:
+                        # match, but not exact so continue to look
+                        matched = cp1
+                if matched:
+                    if matchValue != 1:
+                        cparamChanges.append(((cp1.db_name,cp1.db_value), 
+                                              (cp2.db_name,cp2.db_value)))
+                    m1_unmatched.remove(cp1)
+                    m2_unmatched.remove(cp2)
+
+        for cp in m1_unmatched:
+            cparamChanges.append(((cp.db_name,cp.db_value), (None, None)))
+        for cp in m2_unmatched:
+            cparamChanges.append(((None, None), (cp.db_name,cp.db_value)))
+    return cparamChanges
+
+def getAnnotationChanges(m1, m2, same_vt=True, heuristic_match=True):
+    annotChanges = []
+    # need to check to see if any children of m1 and m2 are affected
+    m1_annots = m1.db_get_annotations()
+    m2_annots = m2.db_get_annotations()
+    m1_unmatched = []
+    m2_unmatched = []
+    if same_vt:
+        for a1 in m1_annots:
+            # see if m2 has f1, too
+            a2 = m2.db_get_annotation(a1.db_id)
+            if a2 is None:            
+                m1_unmatched.append(a1)
+            else:
+                # cparam is same, check if it has changed
+                if heuristic_match:
+                    matchValue = heuristicAnnotationMatch(a1, a2)
+                    if matchValue != 1:
+                        annotChanges.append(((a1.db_key,a1.db_value), 
+                                             (a2.db_key,a2.db_value)))
+                else:
+                    annotChanges.append(((a1.db_key,a1.db_value), 
+                                         (a2.db_key,a2.db_value)))
+        for a2 in m2_annots:
+            # see if m1 has f2, too
+            if m1.db_get_annotation(a2.db_id) is None:
+                m2_unmatched.append(a2)
+    else:
+        m1_unmatched.extend(m1_annots)
+        m2_unmatched.extend(m2_annots)
+
+#             functionMatch = True
+#             f1_params = f1.db_get_parameters()
+#             f2_params = f2.db_get_parameters()
+#             for p1 in f1_params:
+#                 if f2.db_get_parameter(p1.db_id) is None:
+#                     functionMatch = False
+#                     m1_unmatched.append(f1)
+#                     break
+#             for p2 in f2_params:
+#                 if f1.db_get_parameter(p2.db_id) is None:
+#                     functionMatch = False
+#                     m2_unmatched.append(f2)
+#                     break
+#             if functionMatch:
+
+    if len(m1_unmatched) + len(m2_unmatched) > 0:
+        if heuristic_match and len(m1_unmatched) > 0 and len(m2_unmatched) > 0:
+            # do heuristic matches
+            for a1 in m1_unmatched[:]:
+                matched = False
+                matchValue = 0
+                for a2 in m2_unmatched:
+                    matchValue = heuristicAnnotationMatch(a1, a2)
+                    if matchValue == 1:
+                        # best match so quit
+                        matched = a1
+                        break
+                    elif matchValue == 0:
+                        # match, but not exact so continue to look
+                        matched = a1
+                if matched:
+                    if matchValue != 1:
+                        annotChanges.append(((a1.db_key,a1.db_value), 
+                                             (a2.db_key,a2.db_value)))
+                    m1_unmatched.remove(a1)
+                    m2_unmatched.remove(a2)
+
+        for cp in m1_unmatched:
+            annotChanges.append(((cp.db_key,cp.db_value), (None, None)))
+        for cp in m2_unmatched:
+            annotChanges.append(((None, None), (cp.db_key,cp.db_value)))
+        
+    return annotChanges
+
 def getOldObjId(operation):
     if operation.vtType == 'change':
         return operation.db_oldObjId
@@ -1058,6 +1272,8 @@ def getWorkflowDiffCommon(vistrail, v1, v2, heuristic_match=True):
     sharedModuleIds = []
     sharedConnectionIds = []
     sharedFunctionIds = {}
+    sharedCParameterIds = {}
+    sharedAnnotationIds = {}
     for op in sharedOps:
         if op.what == 'module' or op.what == 'abstraction' or \
                 op.what == 'group':
@@ -1066,10 +1282,16 @@ def getWorkflowDiffCommon(vistrail, v1, v2, heuristic_match=True):
             sharedConnectionIds.append(getNewObjId(op))
         elif op.what == 'function':
             sharedFunctionIds[getNewObjId(op)] = op.db_parentObjId
+        elif op.what == 'controlParameter':
+            sharedCParameterIds[getNewObjId(op)] = op.db_parentObjId
+        elif op.what == 'annotation':
+            sharedAnnotationIds[getNewObjId(op)] = op.db_parentObjId
     
     vOnlyModules = []
     vOnlyConnections = []
     paramChgModules = {}
+    cparamChgModules = {}
+    annotChgModules = {}
     for (vAdds, vDeletes, _) in vOnlyOps:
         moduleDeleteIds = []
         connectionDeleteIds = []
@@ -1096,6 +1318,24 @@ def getWorkflowDiffCommon(vistrail, v1, v2, heuristic_match=True):
                 if moduleId in sharedModuleIds:
                     paramChgModules[moduleId] = None
                     sharedModuleIds.remove(moduleId)
+            elif op.what == 'controlParameter' and \
+                    (op.db_parentObjType == 'module' or 
+                     op.db_parentObjType == 'abstraction' or 
+                     op.db_parentObjType == 'group') and \
+                    op.db_parentObjId in sharedCParameterIds and \
+                    op.db_parentObjId in sharedModuleIds:
+                # have a control parameter change
+                cparamChgModules[op.db_parentObjId] = None
+                sharedModuleIds.remove(op.db_parentObjId)
+            elif op.what == 'annotation' and \
+                    (op.db_parentObjType == 'module' or 
+                     op.db_parentObjType == 'abstraction' or 
+                     op.db_parentObjType == 'group') and \
+                    op.db_parentObjId in sharedAnnotationIds and \
+                    op.db_parentObjId in sharedModuleIds:
+                # have an annotation change
+                annotChgModules[op.db_parentObjId] = None
+                sharedModuleIds.remove(op.db_parentObjId)
             elif op.what == 'connection':
                 connectionDeleteIds.append(getOldObjId(op))
                 if getOldObjId(op) in sharedConnectionIds:
@@ -1122,6 +1362,24 @@ def getWorkflowDiffCommon(vistrail, v1, v2, heuristic_match=True):
                 if moduleId in sharedModuleIds:
                     paramChgModules[moduleId] = None
                     sharedModuleIds.remove(moduleId)
+            elif (op.what == 'controlParameter' and
+                  (op.db_parentObjType == 'module' or
+                   op.db_parentObjType == 'abstraction' or
+                   op.db_parentObjType == 'group') and
+                  op.db_parentObjId in sharedCParameterIds and
+                  op.db_parentObjId in sharedModuleIds):
+                # have a control parameter change
+                cparamChgModules[op.db_parentObjId] = None
+                sharedModuleIds.remove(op.db_parentObjId)
+            elif (op.what == 'annotation' and
+                  (op.db_parentObjType == 'module' or
+                   op.db_parentObjType == 'abstraction' or
+                   op.db_parentObjType == 'group') and
+                  op.db_parentObjId in sharedAnnotationIds and
+                  op.db_parentObjId in sharedModuleIds):
+                # have an annotation change
+                annotChgModules[op.db_parentObjId] = None
+                sharedModuleIds.remove(op.db_parentObjId)
             elif op.what == 'connection':
                 connectionAddIds.append(getOldObjId(op))
 
@@ -1149,22 +1407,31 @@ def getWorkflowDiffCommon(vistrail, v1, v2, heuristic_match=True):
             c2Only.append(id)
 
     paramChgModulePairs = [(id, id) for id in paramChgModules.keys()]
-
+    cparamChgModulePairs = [(id, id) for id in cparamChgModules.keys()]
+    annotChgModulePairs = [(id, id) for id in annotChgModules.keys()]
     # print "^^^^ SHARED MODULE PAIRS:", sharedModulePairs
+    c1Only, c2Only, heuristicConnectionPairs = [], [], []
+    
     if heuristic_match:
         (heuristicModulePairs, heuristicConnectionPairs, v1Only, v2Only, \
              c1Only, c2Only) = do_heuristic_diff(v1Workflow, v2Workflow, \
                                                      v1Only, v2Only, \
                                                      c1Only, c2Only)
         paramChgModulePairs.extend(heuristicModulePairs)
-
-    (heuristicModulePairs, paramChanges) = \
-        check_params_diff(v1Workflow, v2Workflow, paramChgModulePairs, 
+        cparamChgModulePairs.extend(heuristicModulePairs)
+        annotChgModulePairs.extend(heuristicModulePairs)
+    allChgModulePairs = list(set(chain(paramChgModulePairs,
+                                       cparamChgModulePairs,
+                                       annotChgModulePairs)))
+
+    (heuristicModulePairs, paramChanges, cparam_changes, annot_changes) = \
+        check_params_diff(v1Workflow, v2Workflow, allChgModulePairs, 
                           True, heuristic_match)
 
     return (v1Workflow, v2Workflow, 
             sharedModulePairs, heuristicModulePairs, v1Only, v2Only, 
-            paramChanges, sharedConnectionPairs, heuristicConnectionPairs, 
+            paramChanges, cparam_changes, annot_changes,
+            sharedConnectionPairs, heuristicConnectionPairs, 
             c1Only, c2Only)
 
 def do_heuristic_diff(v1Workflow, v2Workflow, v1_modules, v2_modules, 
@@ -1172,7 +1439,6 @@ def do_heuristic_diff(v1Workflow, v2Workflow, v1_modules, v2_modules,
     # add heuristic matches
     heuristicModulePairs = []
     heuristicConnectionPairs = []
-    paramChgModulePairs = []
     
     v1Only = copy.copy(v1_modules)
     v2Only = copy.copy(v2_modules)
@@ -1205,7 +1471,6 @@ def do_heuristic_diff(v1Workflow, v2Workflow, v1_modules, v2_modules,
             v2Only.remove(match[1])
             # we now check all heuristic pairs for parameter changes
             heuristicModulePairs.append(match)
-            # paramChgModulePairs.append(match)
 
     # match connections
     for c1_id in c1Only[:]:
@@ -1232,6 +1497,8 @@ def check_params_diff(v1Workflow, v2Workflow, paramChgModulePairs,
                       same_vt=True, heuristic_match=True):
     matched = []
     paramChanges = []
+    cparamChanges = []
+    annotChanges = []
     # print "^^^^ PARAM CHG PAIRS:", paramChgModulePairs
     for (m1_id, m2_id) in paramChgModulePairs:
         m1 = v1Workflow.db_get_module(m1_id)
@@ -1239,11 +1506,19 @@ def check_params_diff(v1Workflow, v2Workflow, paramChgModulePairs,
         moduleParamChanges = getParamChanges(m1, m2, same_vt, heuristic_match)
         if len(moduleParamChanges) > 0:
             paramChanges.append(((m1_id, m2_id), moduleParamChanges))
-        else:
+        moduleCParamChanges = getCParamChanges(m1, m2, same_vt,
+                                                              heuristic_match)
+        if len(moduleCParamChanges) > 0:
+            cparamChanges.append(((m1_id, m2_id), moduleCParamChanges))
+        moduleAnnotChanges = getAnnotationChanges(m1, m2, same_vt,
+                                                              heuristic_match)
+        if len(moduleAnnotChanges) > 0:
+            annotChanges.append(((m1_id, m2_id), moduleAnnotChanges))
+        if len(moduleParamChanges) == len(moduleCParamChanges) == \
+           len(moduleAnnotChanges) == 0:
             # heuristicModulePairs.append((m1_id, m2_id))
             matched.append((m1_id, m2_id))
-
-    return (matched, paramChanges)    
+    return (matched, paramChanges, cparamChanges, annotChanges)
 
 def getWorkflowDiff(vt_pair_1, vt_pair_2, heuristic_match=True):
     (vistrail_1, v_1) = vt_pair_1
@@ -1263,13 +1538,14 @@ def getWorkflowDiff(vt_pair_1, vt_pair_2, heuristic_match=True):
         (m_matches, c_matches, modules_1, modules_2, conns_1, conns_2) = \
             do_heuristic_diff(workflow_1, workflow_2, modules_1, modules_2, \
                                   conns_1, conns_2)
-        (m_matches, param_changes) = check_params_diff(workflow_1, workflow_2, 
+        (m_matches, param_changes, cparam_changes, annot_changes) = \
+                                     check_params_diff(workflow_1, workflow_2,
                                                        m_matches, False,
                                                        heuristic_match)
         return (workflow_1, workflow_2, [], m_matches, modules_1, modules_2,
-                param_changes, [], c_matches, conns_1, conns_2)
+                param_changes, cparam_changes, annot_changes, [], c_matches, conns_1, conns_2)
 
-    return (workflow_1, workflow_2, [], [], modules_1, modules_2, [], [], [], 
+    return (workflow_1, workflow_2, [], [], modules_1, modules_2, [], [], [], [], [], 
             conns_1, conns_2)
 
 ################################################################################
diff --git a/vistrails/db/services/workflow.py b/vistrails/db/services/workflow.py
index cbbb77c..57a444e 100644
--- a/vistrails/db/services/workflow.py
+++ b/vistrails/db/services/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 def update_id_scope(workflow):
     if hasattr(workflow, 'update_id_scope'):
         workflow.update_id_scope()
diff --git a/vistrails/db/specs/all.xml b/vistrails/db/specs/all.xml
index 40df0ef..4f750e5 100644
--- a/vistrails/db/specs/all.xml
+++ b/vistrails/db/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -92,7 +93,12 @@
 	      index="key">
       <xml nodeType="xs:element"/>
     </property>
-
+    
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	          index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+    
     <property name="parentType" type="str" inverse="true">
       <sql column="parent_type" type="char(32)"/>
     </property>
@@ -235,6 +241,9 @@
       <property ref="true" object="annotation" mapping="one-to-one">
 	<xml nodeType="xs:element"/>
       </property>
+      <property ref="true" object="controlParameter" mapping="one-to-one">
+        <xml nodeType="xs:element"/>
+      </property>
       <property ref="true" object="function" mapping="one-to-one">
 	<xml nodeType="xs:element"/>
       </property>
@@ -423,6 +432,73 @@
 
   </object>
 
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONTROL PARAMETER +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="controlParameter">
+    <layout>
+      <xml nodeType="xs:element"/>
+      <sql table="control_parameter"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="name" type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="vistrail">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="module">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="abstraction">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+    </choice>
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
   <!--++++++++++++++++++++++++++-->
   <!-- VISTRAIL_VARIABLE +++++++-->
   <!--++++++++++++++++++++++++++-->
@@ -529,6 +605,9 @@
       <property ref="true" object="annotation" mapping="one-to-one">
 	<xml nodeType="xs:element"/>
       </property>
+	  <property ref="true" object="controlParameter" mapping="one-to-one">
+        <xml nodeType="xs:element"/>
+      </property>
       <property ref="true" object="function" mapping="one-to-one">
 	<xml nodeType="xs:element"/>
       </property>
@@ -790,7 +869,12 @@
 	      index="key">
       <xml nodeType="xs:element"/>
     </property>
-
+    
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	          index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+    
     <property name="parentType" type="str" inverse="true">
       <sql column="parent_type" type="char(32)"/>
     </property>
@@ -914,11 +998,6 @@
       <xml nodeType="xs:element"/>
     </property>
 
-    <property ref="true" object="machine" cascade="false" type="list" 
-	      mapping="one-to-many">
-      <xml nodeType="xs:element"/>
-    </property>
-
     <property name="vistrail_id" type="long" foreignKey="true" object="vistrail">
       <xml nodeType="xs:attribute" type="xs:int"/>
       <sql type="int"/>
@@ -971,8 +1050,8 @@
       <sql column="vt_id" type="int"/>
     </property>
 
-    <property ref="true" object="log" type="long" mapping="many-to-one" 
-	      inverse="true">
+    <property ref="true" object="workflow_exec" type="long" 
+	      mapping="many-to-one" inverse="true">
       <sql column="log_id" type="int"/>
     </property>
 
@@ -1039,6 +1118,11 @@
       <xml nodeType="xs:element"/>
     </property>
 
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	      index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+
     <property ref="true" object="portSpec" type="list" mapping="one-to-many"
 	      index="name:type">
       <xml nodeType="xs:element"/>
@@ -1096,10 +1180,67 @@
       <sql type="datetime"/>
     </property>
 
-    <!--<property name="input" type="str">
-      <xml name="input" nodeType="xs:attribute" type="xs:string"/>
-      <sql type="varchar(1023)"/>
-    </property>-->
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="workflow_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+            
+      <property ref="true" object="module_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property ref="true" object="loop_iteration" type="list"
+            mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- LOOP_ITERATION ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="loop_iteration">
+    <layout>
+      <xml name="loopIteration" nodeType="xs:element"/>
+      <sql table="loop_iteration"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="ts_start" type="datetime">
+      <xml name="tsStart" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="ts_end" type="datetime">
+      <xml name="tsEnd" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
 
     <property name="iteration" type="int">
       <xml nodeType="xs:attribute" type="xs:int"/>
@@ -1130,33 +1271,11 @@
       </property>
     </choice>
 
-    <property name="parentType" type="str" inverse="true">
-      <sql column="parent_type" type="char(32)"/>
+    <property name="parent" ref="true" object="loop_exec"
+            mapping="many-to-one" inverse="true">
+      <sql column="parent_id" type="int"/>
     </property>
 
-    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
-            mapping="many-to-one">
-      <property ref="true" object="workflow_exec" type="long" 
-		mapping="many-to-one" inverse="true">
-	<sql column="parent_id" type="int"/>
-      </property>
-
-      <property ref="true" object="group_exec" type="long" 
-		mapping="many-to-one" inverse="true">
-	<sql column="parent_id" type="int"/>
-      </property>
-      
-      <property ref="true" object="loop_exec" type="long" 
-		mapping="many-to-one" inverse="true">
-	<sql column="parent_id" type="int"/>
-      </property>
-      
-      <property ref="true" object="module_exec" type="long" 
-		mapping="many-to-one" inverse="true">
-	<sql column="parent_id" type="int"/>
-      </property>
-    </choice>
-
     <property name="entity_id" type="long" inverse="true">
       <sql type="int"/>
     </property>
@@ -1256,7 +1375,7 @@
 	<sql column="parent_id" type="int"/>
       </property>
 
-      <property ref="true" object="loop_exec" type="long" 
+      <property ref="true" object="loop_iteration" type="long" 
 		mapping="many-to-one" inverse="true">
 	<sql column="parent_id" type="int"/>
       </property>
@@ -1361,7 +1480,7 @@
 	<sql column="parent_id" type="int"/>
       </property>
 
-      <property ref="true" object="loop_exec" type="long" 
+      <property ref="true" object="loop_iteration" type="long" 
 		mapping="many-to-one" inverse="true">
 	<sql column="parent_id" type="int"/>
       </property>
@@ -1640,6 +1759,11 @@
       <sql type="int"/>
     </property>
 
+    <property name="depth" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
     <property name="sort_key" type="int">
       <xml name="sortKey" nodeType="xs:attribute" type="xs:int"/>
       <sql type="int"/>
@@ -2034,6 +2158,11 @@
       <xml nodeType="xs:element"/>
     </property>
 
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	      index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+
     <property ref="true" object="vistrailVariable" type="list" mapping="one-to-many"
 	      index="uuid">
       <xml nodeType="xs:element"/>
@@ -2208,6 +2337,10 @@
       <xml nodeType="xs:element"/>
     </property>
 
+    <property ref="true" object="machine" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
     <choice name="item_exec" type="list" mapping="one-to-many">
       <property name="module_exec" ref="true" object="module_exec">
 	<xml nodeType="xs:element"/>
@@ -3821,4 +3954,186 @@
     </property>
   </object>
 
+  <!--++++++++++++++++++++++++++-->
+  <!-- STARTUP +++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="startup">
+    <layout>
+      <xml name="startup" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <property ref="true" object="configuration" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="enabled_packages" type="list" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>    
+
+    <property ref="true" object="disabled_packages" type="list" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>    
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ENABLED_PACKAGES ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="enabled_packages">
+    <layout>
+      <xml name="packages" nodeType="xs:element"/>
+    </layout>
+  
+    <property name="package" ref="true" object="startup_package" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- DISABLED_PACKAGES +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="disabled_packages">
+    <layout>
+      <xml name="disabledpackages" nodeType="xs:element"/>
+    </layout>
+  
+    <property name="package" ref="true" object="startup_package" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- STARTUP_PACKAGE +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="startup_package">
+    <layout>
+      <xml name="package" nodeType="xs:element"/>
+    </layout>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property ref="true" object="configuration" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element" name="configuration"/>
+    </property>    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIGURATION +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="configuration">
+    <layout>
+      <xml name="configuration" nodeType="xs:element"/>
+    </layout>
+
+    <property ref="true" object="config_key" type="list" 
+	      mapping="one-to-many">
+      <xml name="key" nodeType="xs:element"/>
+    </property>    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_KEY ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_key">
+    <layout>
+      <xml name="key" nodeType="xs:element"/>
+    </layout>
+
+    <property name="name" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <choice name="value" type="object" mapping="one-to-one">
+      <property ref="true" object="config_str">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_int">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_float">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_bool">
+	<xml nodeType="xs:element"/>
+      </property>
+      
+      <property ref="true" object="configuration">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_STR ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_str">
+    <layout>
+      <xml name="str" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_INT ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_int">
+    <layout>
+      <xml name="int" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_FLOAT ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_float">
+    <layout>
+      <xml name="float" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="float">
+      <xml nodeType="xs:attribute" type="xs:float"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_BOOL +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_bool">
+    <layout>
+      <xml name="bool" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
 </objects>
diff --git a/vistrails/db/tests/__init__.py b/vistrails/db/tests/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/db/tests/__init__.py
+++ b/vistrails/db/tests/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/db/tests/setup_db_tables.py b/vistrails/db/tests/setup_db_tables.py
index 00f9fde..3a642a8 100644
--- a/vistrails/db/tests/setup_db_tables.py
+++ b/vistrails/db/tests/setup_db_tables.py
@@ -1,44 +1,45 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # MACOSX binary install stuff
+from __future__ import division
+
 import os
 import sys
 from vistrails.db.services import io
 
-sys.path.append("../..")
-
 def setup_tables(host, port, user, passwd, db):
     config = {'host': host, 
               'port': port,
diff --git a/vistrails/db/tests/sql_to_xml.py b/vistrails/db/tests/sql_to_xml.py
index e9ff98c..e45306d 100644
--- a/vistrails/db/tests/sql_to_xml.py
+++ b/vistrails/db/tests/sql_to_xml.py
@@ -1,49 +1,48 @@
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # MACOSX binary install stuff
+from __future__ import division
+
 import os
 
 import MySQLdb
 
 from vistrails.db.services import io
-import vistrails.tests
 
-if __name__ != '__main__':
-    import vistrails.tests
-    raise vistrails.tests.NotModule('This should not be imported as a module')
-    
 os.environ['EXECUTABLEPATH'] = '/vistrails/VisTrails.app/Contents/MacOS'
 
 
diff --git a/vistrails/db/tests/xml_to_sql.py b/vistrails/db/tests/xml_to_sql.py
index d599836..38b0786 100644
--- a/vistrails/db/tests/xml_to_sql.py
+++ b/vistrails/db/tests/xml_to_sql.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # MACOSX binary install stuff
+from __future__ import division
+
 import os
 
 from vistrails.db.services import io
diff --git a/vistrails/db/versions/__init__.py b/vistrails/db/versions/__init__.py
index ad96364..7a967f3 100644
--- a/vistrails/db/versions/__init__.py
+++ b/vistrails/db/versions/__init__.py
@@ -1,44 +1,48 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from itertools import izip
 import os
 
+from vistrails.core import debug
 from vistrails.core.system import vistrails_root_directory
 from vistrails.db import VistrailsDBException
 
-currentVersion = '1.0.3'
+currentVersion = '1.0.4'
 
 def getVersionDAO(version=None):
     if version is None:
@@ -54,7 +58,7 @@ def getVersionDAO(version=None):
             raise VistrailsDBException(msg)
         # assume other error
         import traceback
-        raise VistrailsDBException(traceback.format_exc())
+        raise VistrailsDBException(debug.format_exc())
     return persistence.DAOList()
 
 def translate_object(obj, method_name, version=None, target_version=None):
@@ -80,9 +84,11 @@ def translate_object(obj, method_name, version=None, target_version=None):
         '1.0.0': '1.0.1',
         '1.0.1': '1.0.2',
         '1.0.2': '1.0.3',
+        '1.0.3': '1.0.4',
         }
 
     rev_version_map = {
+        '1.0.4': '1.0.3',
         '1.0.3': '1.0.2',
         '1.0.2': '1.0.1',
         '1.0.1': '1.0.0',
@@ -153,6 +159,10 @@ def translate_registry(registry, version=None, target_version=None):
     return translate_object(registry, 'translateRegistry', version, 
                             target_version)
 
+def translate_startup(startup, version=None, target_version=None):
+    return translate_object(startup, 'translateStartup', version,
+                            target_version)
+
 def get_version_name(version_no):
     return 'v' + version_no.replace('.', '_')
 
diff --git a/vistrails/db/versions/v0_3_0/__init__.py b/vistrails/db/versions/v0_3_0/__init__.py
index a6ad05c..03c951e 100644
--- a/vistrails/db/versions/v0_3_0/__init__.py
+++ b/vistrails/db/versions/v0_3_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.3.0'
diff --git a/vistrails/db/versions/v0_3_0/domain/__init__.py b/vistrails/db/versions/v0_3_0/domain/__init__.py
index 1870fdf..508b6da 100644
--- a/vistrails/db/versions/v0_3_0/domain/__init__.py
+++ b/vistrails/db/versions/v0_3_0/domain/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
diff --git a/vistrails/db/versions/v0_3_0/domain/auto_gen.py b/vistrails/db/versions/v0_3_0/domain/auto_gen.py
index 9a5f3e6..7fec936 100644
--- a/vistrails/db/versions/v0_3_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_3_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 class DBChangeParameter(object):
 
     vtType = 'changeParameter'
diff --git a/vistrails/db/versions/v0_3_0/persistence/__init__.py b/vistrails/db/versions/v0_3_0/persistence/__init__.py
index fca428d..b6822dd 100644
--- a/vistrails/db/versions/v0_3_0/persistence/__init__.py
+++ b/vistrails/db/versions/v0_3_0/persistence/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 import xml.io
 
diff --git a/vistrails/db/versions/v0_3_0/persistence/xml/__init__.py b/vistrails/db/versions/v0_3_0/persistence/xml/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_3_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_3_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_3_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_3_0/persistence/xml/auto_gen.py
index 7371db2..cab333e 100644
--- a/vistrails/db/versions/v0_3_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_3_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.db.versions.v0_3_0.persistence.xml.xml_dao import XMLDAO
 from vistrails.db.versions.v0_3_0.domain.auto_gen import *
 
diff --git a/vistrails/db/versions/v0_3_0/persistence/xml/io.py b/vistrails/db/versions/v0_3_0/persistence/xml/io.py
index 0b01c45..b339404 100644
--- a/vistrails/db/versions/v0_3_0/persistence/xml/io.py
+++ b/vistrails/db/versions/v0_3_0/persistence/xml/io.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.parsers.expat import ExpatError
 import xml.dom.minidom
 
diff --git a/vistrails/db/versions/v0_3_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_3_0/persistence/xml/xml_dao.py
index de42aa2..e2f4f42 100644
--- a/vistrails/db/versions/v0_3_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_3_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -61,9 +65,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -71,7 +75,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_3_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_3_0/schemas/xml/vistrail.xsd
index b0a275e..5aa12ce 100644
--- a/vistrails/db/versions/v0_3_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_3_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/action.xml b/vistrails/db/versions/v0_3_0/specs/action.xml
index 104c998..49e2150 100644
--- a/vistrails/db/versions/v0_3_0/specs/action.xml
+++ b/vistrails/db/versions/v0_3_0/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/addConnection.xml b/vistrails/db/versions/v0_3_0/specs/addConnection.xml
index 99599cf..ecaf458 100644
--- a/vistrails/db/versions/v0_3_0/specs/addConnection.xml
+++ b/vistrails/db/versions/v0_3_0/specs/addConnection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/addModule.xml b/vistrails/db/versions/v0_3_0/specs/addModule.xml
index d3584c1..84c0536 100644
--- a/vistrails/db/versions/v0_3_0/specs/addModule.xml
+++ b/vistrails/db/versions/v0_3_0/specs/addModule.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/addModulePort.xml b/vistrails/db/versions/v0_3_0/specs/addModulePort.xml
index 5f83e50..7e29827 100644
--- a/vistrails/db/versions/v0_3_0/specs/addModulePort.xml
+++ b/vistrails/db/versions/v0_3_0/specs/addModulePort.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/changeAnnotation.xml b/vistrails/db/versions/v0_3_0/specs/changeAnnotation.xml
index 3915523..e50980c 100644
--- a/vistrails/db/versions/v0_3_0/specs/changeAnnotation.xml
+++ b/vistrails/db/versions/v0_3_0/specs/changeAnnotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/changeParameter.xml b/vistrails/db/versions/v0_3_0/specs/changeParameter.xml
index 8a8de86..7e0ff4a 100644
--- a/vistrails/db/versions/v0_3_0/specs/changeParameter.xml
+++ b/vistrails/db/versions/v0_3_0/specs/changeParameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/deleteAnnotation.xml b/vistrails/db/versions/v0_3_0/specs/deleteAnnotation.xml
index e20c4ae..7a8a56c 100644
--- a/vistrails/db/versions/v0_3_0/specs/deleteAnnotation.xml
+++ b/vistrails/db/versions/v0_3_0/specs/deleteAnnotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/deleteConnection.xml b/vistrails/db/versions/v0_3_0/specs/deleteConnection.xml
index 8ff250a..2fee185 100644
--- a/vistrails/db/versions/v0_3_0/specs/deleteConnection.xml
+++ b/vistrails/db/versions/v0_3_0/specs/deleteConnection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/deleteFunction.xml b/vistrails/db/versions/v0_3_0/specs/deleteFunction.xml
index d647c15..ddcceff 100644
--- a/vistrails/db/versions/v0_3_0/specs/deleteFunction.xml
+++ b/vistrails/db/versions/v0_3_0/specs/deleteFunction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/deleteModule.xml b/vistrails/db/versions/v0_3_0/specs/deleteModule.xml
index a07f569..b03c7db 100644
--- a/vistrails/db/versions/v0_3_0/specs/deleteModule.xml
+++ b/vistrails/db/versions/v0_3_0/specs/deleteModule.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/deleteModulePort.xml b/vistrails/db/versions/v0_3_0/specs/deleteModulePort.xml
index e6e6a7c..295de4b 100644
--- a/vistrails/db/versions/v0_3_0/specs/deleteModulePort.xml
+++ b/vistrails/db/versions/v0_3_0/specs/deleteModulePort.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/moveModule.xml b/vistrails/db/versions/v0_3_0/specs/moveModule.xml
index 3712805..a953ec2 100644
--- a/vistrails/db/versions/v0_3_0/specs/moveModule.xml
+++ b/vistrails/db/versions/v0_3_0/specs/moveModule.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/tag.xml b/vistrails/db/versions/v0_3_0/specs/tag.xml
index 6022ef3..523c701 100644
--- a/vistrails/db/versions/v0_3_0/specs/tag.xml
+++ b/vistrails/db/versions/v0_3_0/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_0/specs/vistrail.xml b/vistrails/db/versions/v0_3_0/specs/vistrail.xml
index aa68d46..e9507f5 100644
--- a/vistrails/db/versions/v0_3_0/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_3_0/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/__init__.py b/vistrails/db/versions/v0_3_1/__init__.py
index 1ba86e3..422ad4c 100644
--- a/vistrails/db/versions/v0_3_1/__init__.py
+++ b/vistrails/db/versions/v0_3_1/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.3.1'
diff --git a/vistrails/db/versions/v0_3_1/domain/__init__.py b/vistrails/db/versions/v0_3_1/domain/__init__.py
index fb50f24..9f153cd 100644
--- a/vistrails/db/versions/v0_3_1/domain/__init__.py
+++ b/vistrails/db/versions/v0_3_1/domain/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_3_0.domain import *
diff --git a/vistrails/db/versions/v0_3_1/persistence/__init__.py b/vistrails/db/versions/v0_3_1/persistence/__init__.py
index 47924e5..ad4c724 100644
--- a/vistrails/db/versions/v0_3_1/persistence/__init__.py
+++ b/vistrails/db/versions/v0_3_1/persistence/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_3_0.persistence import DAOList
diff --git a/vistrails/db/versions/v0_3_1/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_3_1/schemas/xml/vistrail.xsd
index b0a275e..5aa12ce 100644
--- a/vistrails/db/versions/v0_3_1/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_3_1/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/action.xml b/vistrails/db/versions/v0_3_1/specs/action.xml
index 104c998..49e2150 100644
--- a/vistrails/db/versions/v0_3_1/specs/action.xml
+++ b/vistrails/db/versions/v0_3_1/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/addConnection.xml b/vistrails/db/versions/v0_3_1/specs/addConnection.xml
index 99599cf..ecaf458 100644
--- a/vistrails/db/versions/v0_3_1/specs/addConnection.xml
+++ b/vistrails/db/versions/v0_3_1/specs/addConnection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/addModule.xml b/vistrails/db/versions/v0_3_1/specs/addModule.xml
index d3584c1..84c0536 100644
--- a/vistrails/db/versions/v0_3_1/specs/addModule.xml
+++ b/vistrails/db/versions/v0_3_1/specs/addModule.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/addModulePort.xml b/vistrails/db/versions/v0_3_1/specs/addModulePort.xml
index 5f83e50..7e29827 100644
--- a/vistrails/db/versions/v0_3_1/specs/addModulePort.xml
+++ b/vistrails/db/versions/v0_3_1/specs/addModulePort.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/changeAnnotation.xml b/vistrails/db/versions/v0_3_1/specs/changeAnnotation.xml
index 3915523..e50980c 100644
--- a/vistrails/db/versions/v0_3_1/specs/changeAnnotation.xml
+++ b/vistrails/db/versions/v0_3_1/specs/changeAnnotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/changeParameter.xml b/vistrails/db/versions/v0_3_1/specs/changeParameter.xml
index 8a8de86..7e0ff4a 100644
--- a/vistrails/db/versions/v0_3_1/specs/changeParameter.xml
+++ b/vistrails/db/versions/v0_3_1/specs/changeParameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/deleteAnnotation.xml b/vistrails/db/versions/v0_3_1/specs/deleteAnnotation.xml
index e20c4ae..7a8a56c 100644
--- a/vistrails/db/versions/v0_3_1/specs/deleteAnnotation.xml
+++ b/vistrails/db/versions/v0_3_1/specs/deleteAnnotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/deleteConnection.xml b/vistrails/db/versions/v0_3_1/specs/deleteConnection.xml
index 8ff250a..2fee185 100644
--- a/vistrails/db/versions/v0_3_1/specs/deleteConnection.xml
+++ b/vistrails/db/versions/v0_3_1/specs/deleteConnection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/deleteFunction.xml b/vistrails/db/versions/v0_3_1/specs/deleteFunction.xml
index d647c15..ddcceff 100644
--- a/vistrails/db/versions/v0_3_1/specs/deleteFunction.xml
+++ b/vistrails/db/versions/v0_3_1/specs/deleteFunction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/deleteModule.xml b/vistrails/db/versions/v0_3_1/specs/deleteModule.xml
index a07f569..b03c7db 100644
--- a/vistrails/db/versions/v0_3_1/specs/deleteModule.xml
+++ b/vistrails/db/versions/v0_3_1/specs/deleteModule.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/deleteModulePort.xml b/vistrails/db/versions/v0_3_1/specs/deleteModulePort.xml
index e6e6a7c..295de4b 100644
--- a/vistrails/db/versions/v0_3_1/specs/deleteModulePort.xml
+++ b/vistrails/db/versions/v0_3_1/specs/deleteModulePort.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/moveModule.xml b/vistrails/db/versions/v0_3_1/specs/moveModule.xml
index 3712805..a953ec2 100644
--- a/vistrails/db/versions/v0_3_1/specs/moveModule.xml
+++ b/vistrails/db/versions/v0_3_1/specs/moveModule.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/tag.xml b/vistrails/db/versions/v0_3_1/specs/tag.xml
index 6022ef3..523c701 100644
--- a/vistrails/db/versions/v0_3_1/specs/tag.xml
+++ b/vistrails/db/versions/v0_3_1/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/specs/vistrail.xml b/vistrails/db/versions/v0_3_1/specs/vistrail.xml
index aa68d46..e9507f5 100644
--- a/vistrails/db/versions/v0_3_1/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_3_1/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_3_1/translate/__init__.py b/vistrails/db/versions/v0_3_1/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_3_1/translate/__init__.py
+++ b/vistrails/db/versions/v0_3_1/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_3_1/translate/v0_3_0.py b/vistrails/db/versions/v0_3_1/translate/v0_3_0.py
index 13ecea7..1da93d5 100644
--- a/vistrails/db/versions/v0_3_1/translate/v0_3_0.py
+++ b/vistrails/db/versions/v0_3_1/translate/v0_3_0.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 def translateVistrail(_vistrail):
diff --git a/vistrails/db/versions/v0_5_0/__init__.py b/vistrails/db/versions/v0_5_0/__init__.py
index 81e9321..34bcc15 100644
--- a/vistrails/db/versions/v0_5_0/__init__.py
+++ b/vistrails/db/versions/v0_5_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.5.0'
diff --git a/vistrails/db/versions/v0_5_0/domain/__init__.py b/vistrails/db/versions/v0_5_0/domain/__init__.py
index f9f4892..90311b9 100644
--- a/vistrails/db/versions/v0_5_0/domain/__init__.py
+++ b/vistrails/db/versions/v0_5_0/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_5_0/domain/auto_gen.py b/vistrails/db/versions/v0_5_0/domain/auto_gen.py
index ef7ae65..39695c9 100644
--- a/vistrails/db/versions/v0_5_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_5_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_5_0/domain/id_scope.py b/vistrails/db/versions/v0_5_0/domain/id_scope.py
index 3f151ff..a6efc29 100644
--- a/vistrails/db/versions/v0_5_0/domain/id_scope.py
+++ b/vistrails/db/versions/v0_5_0/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_5_0/domain/vistrail.py b/vistrails/db/versions/v0_5_0/domain/vistrail.py
index 4ca792e..f1acef7 100644
--- a/vistrails/db/versions/v0_5_0/domain/vistrail.py
+++ b/vistrails/db/versions/v0_5_0/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBVistrail as _DBVistrail
 from id_scope import IdScope
 
diff --git a/vistrails/db/versions/v0_5_0/domain/workflow.py b/vistrails/db/versions/v0_5_0/domain/workflow.py
index 97cb040..b24ac46 100644
--- a/vistrails/db/versions/v0_5_0/domain/workflow.py
+++ b/vistrails/db/versions/v0_5_0/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from id_scope import IdScope
 
diff --git a/vistrails/db/versions/v0_5_0/persistence/__init__.py b/vistrails/db/versions/v0_5_0/persistence/__init__.py
index 0a10c9d..8d402fc 100644
--- a/vistrails/db/versions/v0_5_0/persistence/__init__.py
+++ b/vistrails/db/versions/v0_5_0/persistence/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 import xml.io
diff --git a/vistrails/db/versions/v0_5_0/persistence/sql/__init__.py b/vistrails/db/versions/v0_5_0/persistence/sql/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_5_0/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_5_0/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_5_0/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_5_0/persistence/sql/auto_gen.py
index a8da624..8cb8f19 100644
--- a/vistrails/db/versions/v0_5_0/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_5_0/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_5_0.domain import *
 
diff --git a/vistrails/db/versions/v0_5_0/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_5_0/persistence/sql/sql_dao.py
index f632eb8..860f0bd 100644
--- a/vistrails/db/versions/v0_5_0/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_5_0/persistence/sql/sql_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class SQLDAO:
     def __init__(self):
@@ -54,13 +58,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -76,7 +80,7 @@ class SQLDAO:
             elif type == 'date':
                 return "'" + value.isoformat() + "'"
             elif type == 'datetime':
-                return "'" + value.strftime('%Y-%m-%d %H:%M:%S') + "'"
+                return "'" + strftime(value, '%Y-%m-%d %H:%M:%S') + "'"
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_5_0/persistence/xml/__init__.py b/vistrails/db/versions/v0_5_0/persistence/xml/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_5_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_5_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_5_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_5_0/persistence/xml/auto_gen.py
index ed948a6..9013dfa 100644
--- a/vistrails/db/versions/v0_5_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_5_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from xml_dao import XMLDAO
 from vistrails.db.versions.v0_5_0.domain import *
 
diff --git a/vistrails/db/versions/v0_5_0/persistence/xml/io.py b/vistrails/db/versions/v0_5_0/persistence/xml/io.py
index 661d937..6925d74 100644
--- a/vistrails/db/versions/v0_5_0/persistence/xml/io.py
+++ b/vistrails/db/versions/v0_5_0/persistence/xml/io.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.parsers.expat import ExpatError
 import xml.dom.minidom
 
diff --git a/vistrails/db/versions/v0_5_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_5_0/persistence/xml/xml_dao.py
index de42aa2..e2f4f42 100644
--- a/vistrails/db/versions/v0_5_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_5_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -61,9 +65,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -71,7 +75,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_5_0/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_5_0/schemas/sql/vistrails.sql
index 8d403eb..b5c9562 100644
--- a/vistrails/db/versions/v0_5_0/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_5_0/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_5_0/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_5_0/schemas/sql/vistrails_drop.sql
index fcb4304..f8c551a 100644
--- a/vistrails/db/versions/v0_5_0/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_5_0/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_5_0/schemas/xml/log.xsd b/vistrails/db/versions/v0_5_0/schemas/xml/log.xsd
index 1871490..234c75b 100644
--- a/vistrails/db/versions/v0_5_0/schemas/xml/log.xsd
+++ b/vistrails/db/versions/v0_5_0/schemas/xml/log.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_5_0/schemas/xml/vistrail.xsd
index 23bdc68..efb2e0f 100644
--- a/vistrails/db/versions/v0_5_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_5_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/schemas/xml/workflow.xsd b/vistrails/db/versions/v0_5_0/schemas/xml/workflow.xsd
index d24c9f8..8beb03e 100644
--- a/vistrails/db/versions/v0_5_0/schemas/xml/workflow.xsd
+++ b/vistrails/db/versions/v0_5_0/schemas/xml/workflow.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/action.xml b/vistrails/db/versions/v0_5_0/specs/action.xml
index 2847761..84c238e 100644
--- a/vistrails/db/versions/v0_5_0/specs/action.xml
+++ b/vistrails/db/versions/v0_5_0/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/add.xml b/vistrails/db/versions/v0_5_0/specs/add.xml
index 0973246..a686e41 100644
--- a/vistrails/db/versions/v0_5_0/specs/add.xml
+++ b/vistrails/db/versions/v0_5_0/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/annotation.xml b/vistrails/db/versions/v0_5_0/specs/annotation.xml
index 58d4dd6..f41444b 100644
--- a/vistrails/db/versions/v0_5_0/specs/annotation.xml
+++ b/vistrails/db/versions/v0_5_0/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/change.xml b/vistrails/db/versions/v0_5_0/specs/change.xml
index 178a19b..9aeba60 100644
--- a/vistrails/db/versions/v0_5_0/specs/change.xml
+++ b/vistrails/db/versions/v0_5_0/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/connection.xml b/vistrails/db/versions/v0_5_0/specs/connection.xml
index 781b127..d074b10 100644
--- a/vistrails/db/versions/v0_5_0/specs/connection.xml
+++ b/vistrails/db/versions/v0_5_0/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/delete.xml b/vistrails/db/versions/v0_5_0/specs/delete.xml
index 9df9273..906e2d9 100644
--- a/vistrails/db/versions/v0_5_0/specs/delete.xml
+++ b/vistrails/db/versions/v0_5_0/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/execRec.xml b/vistrails/db/versions/v0_5_0/specs/execRec.xml
index 29f48ee..f4efc35 100644
--- a/vistrails/db/versions/v0_5_0/specs/execRec.xml
+++ b/vistrails/db/versions/v0_5_0/specs/execRec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/function.xml b/vistrails/db/versions/v0_5_0/specs/function.xml
index 8254645..4f6b03b 100644
--- a/vistrails/db/versions/v0_5_0/specs/function.xml
+++ b/vistrails/db/versions/v0_5_0/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/location.xml b/vistrails/db/versions/v0_5_0/specs/location.xml
index 6e56055..75133fb 100644
--- a/vistrails/db/versions/v0_5_0/specs/location.xml
+++ b/vistrails/db/versions/v0_5_0/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/log.xml b/vistrails/db/versions/v0_5_0/specs/log.xml
index 53d3d43..44557b2 100644
--- a/vistrails/db/versions/v0_5_0/specs/log.xml
+++ b/vistrails/db/versions/v0_5_0/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/machine.xml b/vistrails/db/versions/v0_5_0/specs/machine.xml
index bae6103..8b9e838 100644
--- a/vistrails/db/versions/v0_5_0/specs/machine.xml
+++ b/vistrails/db/versions/v0_5_0/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/macro.xml b/vistrails/db/versions/v0_5_0/specs/macro.xml
index 6c5fb37..e371aad 100644
--- a/vistrails/db/versions/v0_5_0/specs/macro.xml
+++ b/vistrails/db/versions/v0_5_0/specs/macro.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/module.xml b/vistrails/db/versions/v0_5_0/specs/module.xml
index 922ac2b..53f283b 100644
--- a/vistrails/db/versions/v0_5_0/specs/module.xml
+++ b/vistrails/db/versions/v0_5_0/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/other.xml b/vistrails/db/versions/v0_5_0/specs/other.xml
index 40e1388..21a2846 100644
--- a/vistrails/db/versions/v0_5_0/specs/other.xml
+++ b/vistrails/db/versions/v0_5_0/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/parameter.xml b/vistrails/db/versions/v0_5_0/specs/parameter.xml
index 23236b5..6672280 100644
--- a/vistrails/db/versions/v0_5_0/specs/parameter.xml
+++ b/vistrails/db/versions/v0_5_0/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/port.xml b/vistrails/db/versions/v0_5_0/specs/port.xml
index 2a369ff..06f12a5 100644
--- a/vistrails/db/versions/v0_5_0/specs/port.xml
+++ b/vistrails/db/versions/v0_5_0/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/portSpec.xml b/vistrails/db/versions/v0_5_0/specs/portSpec.xml
index e42a5f0..9d21cce 100644
--- a/vistrails/db/versions/v0_5_0/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_5_0/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/session.xml b/vistrails/db/versions/v0_5_0/specs/session.xml
index 0b1a03d..3fdbdba 100644
--- a/vistrails/db/versions/v0_5_0/specs/session.xml
+++ b/vistrails/db/versions/v0_5_0/specs/session.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/tag.xml b/vistrails/db/versions/v0_5_0/specs/tag.xml
index 22af100..8dd3d5a 100644
--- a/vistrails/db/versions/v0_5_0/specs/tag.xml
+++ b/vistrails/db/versions/v0_5_0/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/vistrail.xml b/vistrails/db/versions/v0_5_0/specs/vistrail.xml
index 9ffbb79..12990f0 100644
--- a/vistrails/db/versions/v0_5_0/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_5_0/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/wfExec.xml b/vistrails/db/versions/v0_5_0/specs/wfExec.xml
index aa56ca6..0c55a34 100644
--- a/vistrails/db/versions/v0_5_0/specs/wfExec.xml
+++ b/vistrails/db/versions/v0_5_0/specs/wfExec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/specs/workflow.xml b/vistrails/db/versions/v0_5_0/specs/workflow.xml
index 4f3a576..42bfafa 100644
--- a/vistrails/db/versions/v0_5_0/specs/workflow.xml
+++ b/vistrails/db/versions/v0_5_0/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_5_0/translate/__init__.py b/vistrails/db/versions/v0_5_0/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_5_0/translate/__init__.py
+++ b/vistrails/db/versions/v0_5_0/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_5_0/translate/v0_3_1.py b/vistrails/db/versions/v0_5_0/translate/v0_3_1.py
index eff91ce..dd5c082 100644
--- a/vistrails/db/versions/v0_5_0/translate/v0_3_1.py
+++ b/vistrails/db/versions/v0_5_0/translate/v0_3_1.py
@@ -1,50 +1,53 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import sys
 import copy
 from datetime import datetime
-from time import strptime
 
 from vistrails.core.data_structures.graph import Graph
+from vistrails.core.system import time_strptime
 from vistrails.db.versions.v0_5_0.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
     DBChange, DBDelete, DBAnnotation, DBPort
 
 def convertDate(date):
     if date is not None and date != '':
-        return datetime(*strptime(date, '%d %b %Y %H:%M:%S')[0:6])
+        return datetime(*time_strptime(date, '%d %b %Y %H:%M:%S')[0:6])
     return datetime(1900, 1, 1)
 
 def translateVistrail(_vistrail):
diff --git a/vistrails/db/versions/v0_6_0/__init__.py b/vistrails/db/versions/v0_6_0/__init__.py
index c015978..12cdf9b 100644
--- a/vistrails/db/versions/v0_6_0/__init__.py
+++ b/vistrails/db/versions/v0_6_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.6.0'
diff --git a/vistrails/db/versions/v0_6_0/domain/__init__.py b/vistrails/db/versions/v0_6_0/domain/__init__.py
index f9f4892..90311b9 100644
--- a/vistrails/db/versions/v0_6_0/domain/__init__.py
+++ b/vistrails/db/versions/v0_6_0/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_6_0/domain/auto_gen.py b/vistrails/db/versions/v0_6_0/domain/auto_gen.py
index a95442a..544ed93 100644
--- a/vistrails/db/versions/v0_6_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_6_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_6_0/domain/id_scope.py b/vistrails/db/versions/v0_6_0/domain/id_scope.py
index 3f151ff..a6efc29 100644
--- a/vistrails/db/versions/v0_6_0/domain/id_scope.py
+++ b/vistrails/db/versions/v0_6_0/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_6_0/domain/vistrail.py b/vistrails/db/versions/v0_6_0/domain/vistrail.py
index 4ca792e..f1acef7 100644
--- a/vistrails/db/versions/v0_6_0/domain/vistrail.py
+++ b/vistrails/db/versions/v0_6_0/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBVistrail as _DBVistrail
 from id_scope import IdScope
 
diff --git a/vistrails/db/versions/v0_6_0/domain/workflow.py b/vistrails/db/versions/v0_6_0/domain/workflow.py
index 97cb040..b24ac46 100644
--- a/vistrails/db/versions/v0_6_0/domain/workflow.py
+++ b/vistrails/db/versions/v0_6_0/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from id_scope import IdScope
 
diff --git a/vistrails/db/versions/v0_6_0/persistence/__init__.py b/vistrails/db/versions/v0_6_0/persistence/__init__.py
index 0a10c9d..8d402fc 100644
--- a/vistrails/db/versions/v0_6_0/persistence/__init__.py
+++ b/vistrails/db/versions/v0_6_0/persistence/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 import xml.io
diff --git a/vistrails/db/versions/v0_6_0/persistence/sql/__init__.py b/vistrails/db/versions/v0_6_0/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_6_0/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_6_0/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_6_0/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_6_0/persistence/sql/auto_gen.py
index dffd921..29d165b 100644
--- a/vistrails/db/versions/v0_6_0/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_6_0/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_6_0.domain import *
 
diff --git a/vistrails/db/versions/v0_6_0/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_6_0/persistence/sql/sql_dao.py
index 7f92a24..5dd992c 100644
--- a/vistrails/db/versions/v0_6_0/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_6_0/persistence/sql/sql_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class SQLDAO:
     def __init__(self):
@@ -54,13 +58,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -76,7 +80,7 @@ class SQLDAO:
             elif type == 'date':
                 return "'" + value.isoformat() + "'"
             elif type == 'datetime':
-                return "'" + value.strftime('%Y-%m-%d %H:%M:%S') + "'"
+                return "'" + strftime(value, '%Y-%m-%d %H:%M:%S') + "'"
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_6_0/persistence/xml/__init__.py b/vistrails/db/versions/v0_6_0/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_6_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_6_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_6_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_6_0/persistence/xml/auto_gen.py
index 78e1469..a3a314d 100644
--- a/vistrails/db/versions/v0_6_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_6_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from xml_dao import XMLDAO
 from vistrails.db.versions.v0_6_0.domain import *
 
diff --git a/vistrails/db/versions/v0_6_0/persistence/xml/io.py b/vistrails/db/versions/v0_6_0/persistence/xml/io.py
index 4b5116f..cd4cd9d 100644
--- a/vistrails/db/versions/v0_6_0/persistence/xml/io.py
+++ b/vistrails/db/versions/v0_6_0/persistence/xml/io.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.parsers.expat import ExpatError
 import xml.dom.minidom
 
diff --git a/vistrails/db/versions/v0_6_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_6_0/persistence/xml/xml_dao.py
index 955c01a..ee24db4 100644
--- a/vistrails/db/versions/v0_6_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_6_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_6_0/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_6_0/schemas/sql/vistrails.sql
index 05eeb79..54225c4 100644
--- a/vistrails/db/versions/v0_6_0/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_6_0/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_6_0/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_6_0/schemas/sql/vistrails_drop.sql
index 4540fbb..0738359 100644
--- a/vistrails/db/versions/v0_6_0/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_6_0/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_6_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_6_0/schemas/xml/vistrail.xsd
index 9471940..00f0e33 100644
--- a/vistrails/db/versions/v0_6_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_6_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/abstraction.xml b/vistrails/db/versions/v0_6_0/specs/abstraction.xml
index 6f76c61..aaef828 100644
--- a/vistrails/db/versions/v0_6_0/specs/abstraction.xml
+++ b/vistrails/db/versions/v0_6_0/specs/abstraction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/abstractionRef.xml b/vistrails/db/versions/v0_6_0/specs/abstractionRef.xml
index 5645c3d..04a6754 100644
--- a/vistrails/db/versions/v0_6_0/specs/abstractionRef.xml
+++ b/vistrails/db/versions/v0_6_0/specs/abstractionRef.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/action.xml b/vistrails/db/versions/v0_6_0/specs/action.xml
index d9c259f..28a9b6f 100644
--- a/vistrails/db/versions/v0_6_0/specs/action.xml
+++ b/vistrails/db/versions/v0_6_0/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/add.xml b/vistrails/db/versions/v0_6_0/specs/add.xml
index 7cbca5c..4ae7d38 100644
--- a/vistrails/db/versions/v0_6_0/specs/add.xml
+++ b/vistrails/db/versions/v0_6_0/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/annotation.xml b/vistrails/db/versions/v0_6_0/specs/annotation.xml
index 19e9a54..f3f9e29 100644
--- a/vistrails/db/versions/v0_6_0/specs/annotation.xml
+++ b/vistrails/db/versions/v0_6_0/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/change.xml b/vistrails/db/versions/v0_6_0/specs/change.xml
index 54b348f..bda170d 100644
--- a/vistrails/db/versions/v0_6_0/specs/change.xml
+++ b/vistrails/db/versions/v0_6_0/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/connection.xml b/vistrails/db/versions/v0_6_0/specs/connection.xml
index b559fab..eefd6a4 100644
--- a/vistrails/db/versions/v0_6_0/specs/connection.xml
+++ b/vistrails/db/versions/v0_6_0/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/delete.xml b/vistrails/db/versions/v0_6_0/specs/delete.xml
index 9df9273..906e2d9 100644
--- a/vistrails/db/versions/v0_6_0/specs/delete.xml
+++ b/vistrails/db/versions/v0_6_0/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/function.xml b/vistrails/db/versions/v0_6_0/specs/function.xml
index 8254645..4f6b03b 100644
--- a/vistrails/db/versions/v0_6_0/specs/function.xml
+++ b/vistrails/db/versions/v0_6_0/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/location.xml b/vistrails/db/versions/v0_6_0/specs/location.xml
index 6e56055..75133fb 100644
--- a/vistrails/db/versions/v0_6_0/specs/location.xml
+++ b/vistrails/db/versions/v0_6_0/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/log.xml b/vistrails/db/versions/v0_6_0/specs/log.xml
index c2554e3..16e317e 100644
--- a/vistrails/db/versions/v0_6_0/specs/log.xml
+++ b/vistrails/db/versions/v0_6_0/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/machine.xml b/vistrails/db/versions/v0_6_0/specs/machine.xml
index dea813d..57e7ee3 100644
--- a/vistrails/db/versions/v0_6_0/specs/machine.xml
+++ b/vistrails/db/versions/v0_6_0/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/module.xml b/vistrails/db/versions/v0_6_0/specs/module.xml
index 3a89cf8..5768f1b 100644
--- a/vistrails/db/versions/v0_6_0/specs/module.xml
+++ b/vistrails/db/versions/v0_6_0/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/module_exec.xml b/vistrails/db/versions/v0_6_0/specs/module_exec.xml
index 465407b..e109829 100644
--- a/vistrails/db/versions/v0_6_0/specs/module_exec.xml
+++ b/vistrails/db/versions/v0_6_0/specs/module_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/other.xml b/vistrails/db/versions/v0_6_0/specs/other.xml
index 40e1388..21a2846 100644
--- a/vistrails/db/versions/v0_6_0/specs/other.xml
+++ b/vistrails/db/versions/v0_6_0/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/parameter.xml b/vistrails/db/versions/v0_6_0/specs/parameter.xml
index 78f6cf7..f34fb2c 100644
--- a/vistrails/db/versions/v0_6_0/specs/parameter.xml
+++ b/vistrails/db/versions/v0_6_0/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/port.xml b/vistrails/db/versions/v0_6_0/specs/port.xml
index 2a369ff..06f12a5 100644
--- a/vistrails/db/versions/v0_6_0/specs/port.xml
+++ b/vistrails/db/versions/v0_6_0/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/portSpec.xml b/vistrails/db/versions/v0_6_0/specs/portSpec.xml
index e42a5f0..9d21cce 100644
--- a/vistrails/db/versions/v0_6_0/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_6_0/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/tag.xml b/vistrails/db/versions/v0_6_0/specs/tag.xml
index f8412b9..5169bff 100644
--- a/vistrails/db/versions/v0_6_0/specs/tag.xml
+++ b/vistrails/db/versions/v0_6_0/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/vistrail.xml b/vistrails/db/versions/v0_6_0/specs/vistrail.xml
index 4f139cb..c706ac9 100644
--- a/vistrails/db/versions/v0_6_0/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_6_0/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/workflow.xml b/vistrails/db/versions/v0_6_0/specs/workflow.xml
index 486e3f8..622287c 100644
--- a/vistrails/db/versions/v0_6_0/specs/workflow.xml
+++ b/vistrails/db/versions/v0_6_0/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/specs/workflow_exec.xml b/vistrails/db/versions/v0_6_0/specs/workflow_exec.xml
index 6944ede..83e1b09 100644
--- a/vistrails/db/versions/v0_6_0/specs/workflow_exec.xml
+++ b/vistrails/db/versions/v0_6_0/specs/workflow_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_6_0/translate/__init__.py b/vistrails/db/versions/v0_6_0/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_6_0/translate/__init__.py
+++ b/vistrails/db/versions/v0_6_0/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_6_0/translate/v0_3_1.py b/vistrails/db/versions/v0_6_0/translate/v0_3_1.py
index 27f5a80..379b25a 100644
--- a/vistrails/db/versions/v0_6_0/translate/v0_3_1.py
+++ b/vistrails/db/versions/v0_6_0/translate/v0_3_1.py
@@ -1,50 +1,52 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-import sys
-import copy
+from __future__ import division
+
 from datetime import datetime
-from time import strptime
+import sys
 
 from vistrails.core.data_structures.graph import Graph
+from vistrails.core.system import time_strptime
 from vistrails.db.versions.v0_6_0.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
     DBChange, DBDelete, DBAnnotation, DBPort
 
 def convertDate(date):
     if date is not None and date != '':
-        return datetime(*strptime(date, '%d %b %Y %H:%M:%S')[0:6])
+        return datetime(*time_strptime(date, '%d %b %Y %H:%M:%S')[0:6])
     return datetime(1900, 1, 1)
 
 def translateVistrail(_vistrail):
diff --git a/vistrails/db/versions/v0_6_0/translate/v0_5_0.py b/vistrails/db/versions/v0_6_0/translate/v0_5_0.py
index c267ab2..0838329 100644
--- a/vistrails/db/versions/v0_6_0/translate/v0_5_0.py
+++ b/vistrails/db/versions/v0_6_0/translate/v0_5_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_6_0.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_7_0/__init__.py b/vistrails/db/versions/v0_7_0/__init__.py
index 98fe4b0..43fc4f4 100644
--- a/vistrails/db/versions/v0_7_0/__init__.py
+++ b/vistrails/db/versions/v0_7_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.7.0'
diff --git a/vistrails/db/versions/v0_7_0/domain/__init__.py b/vistrails/db/versions/v0_7_0/domain/__init__.py
index f8bbb47..702e5bf 100644
--- a/vistrails/db/versions/v0_7_0/domain/__init__.py
+++ b/vistrails/db/versions/v0_7_0/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_7_0/domain/abstraction.py b/vistrails/db/versions/v0_7_0/domain/abstraction.py
index 5972a93..4835c37 100644
--- a/vistrails/db/versions/v0_7_0/domain/abstraction.py
+++ b/vistrails/db/versions/v0_7_0/domain/abstraction.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 from auto_gen import DBAbstraction as _DBAbstraction
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_7_0/domain/auto_gen.py b/vistrails/db/versions/v0_7_0/domain/auto_gen.py
index ee3f826..d7c4262 100644
--- a/vistrails/db/versions/v0_7_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_7_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_7_0/domain/id_scope.py b/vistrails/db/versions/v0_7_0/domain/id_scope.py
index c510efa..49b9d49 100644
--- a/vistrails/db/versions/v0_7_0/domain/id_scope.py
+++ b/vistrails/db/versions/v0_7_0/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_7_0/domain/vistrail.py b/vistrails/db/versions/v0_7_0/domain/vistrail.py
index 4fdb6e2..86ba69c 100644
--- a/vistrails/db/versions/v0_7_0/domain/vistrail.py
+++ b/vistrails/db/versions/v0_7_0/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_7_0/domain/workflow.py b/vistrails/db/versions/v0_7_0/domain/workflow.py
index 20dacf1..bac228b 100644
--- a/vistrails/db/versions/v0_7_0/domain/workflow.py
+++ b/vistrails/db/versions/v0_7_0/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from id_scope import IdScope
 
diff --git a/vistrails/db/versions/v0_7_0/persistence/__init__.py b/vistrails/db/versions/v0_7_0/persistence/__init__.py
index 0a10c9d..8d402fc 100644
--- a/vistrails/db/versions/v0_7_0/persistence/__init__.py
+++ b/vistrails/db/versions/v0_7_0/persistence/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 import xml.io
diff --git a/vistrails/db/versions/v0_7_0/persistence/sql/__init__.py b/vistrails/db/versions/v0_7_0/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_7_0/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_7_0/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_7_0/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_7_0/persistence/sql/auto_gen.py
index 9b987f0..f49fdfb 100644
--- a/vistrails/db/versions/v0_7_0/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_7_0/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_7_0.domain import *
 
diff --git a/vistrails/db/versions/v0_7_0/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_7_0/persistence/sql/sql_dao.py
index 7f92a24..5dd992c 100644
--- a/vistrails/db/versions/v0_7_0/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_7_0/persistence/sql/sql_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class SQLDAO:
     def __init__(self):
@@ -54,13 +58,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -76,7 +80,7 @@ class SQLDAO:
             elif type == 'date':
                 return "'" + value.isoformat() + "'"
             elif type == 'datetime':
-                return "'" + value.strftime('%Y-%m-%d %H:%M:%S') + "'"
+                return "'" + strftime(value, '%Y-%m-%d %H:%M:%S') + "'"
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_7_0/persistence/xml/__init__.py b/vistrails/db/versions/v0_7_0/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_7_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_7_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_7_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_7_0/persistence/xml/auto_gen.py
index 623548b..039fc35 100644
--- a/vistrails/db/versions/v0_7_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_7_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from xml_dao import XMLDAO
 from vistrails.db.versions.v0_7_0.domain import *
 
diff --git a/vistrails/db/versions/v0_7_0/persistence/xml/io.py b/vistrails/db/versions/v0_7_0/persistence/xml/io.py
index f01beb5..a9cbeb9 100644
--- a/vistrails/db/versions/v0_7_0/persistence/xml/io.py
+++ b/vistrails/db/versions/v0_7_0/persistence/xml/io.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.parsers.expat import ExpatError
 import xml.dom.minidom
 
diff --git a/vistrails/db/versions/v0_7_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_7_0/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v0_7_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_7_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_7_0/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_7_0/schemas/sql/vistrails.sql
index 494b6b3..006de55 100644
--- a/vistrails/db/versions/v0_7_0/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_7_0/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_7_0/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_7_0/schemas/sql/vistrails_drop.sql
index a4fd64c..258296f 100644
--- a/vistrails/db/versions/v0_7_0/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_7_0/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_7_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_7_0/schemas/xml/vistrail.xsd
index 2f84013..e382542 100644
--- a/vistrails/db/versions/v0_7_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_7_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/abstraction.xml b/vistrails/db/versions/v0_7_0/specs/abstraction.xml
index 3cbb63a..0209e32 100644
--- a/vistrails/db/versions/v0_7_0/specs/abstraction.xml
+++ b/vistrails/db/versions/v0_7_0/specs/abstraction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/abstractionRef.xml b/vistrails/db/versions/v0_7_0/specs/abstractionRef.xml
index 9cf4d55..80a23e6 100644
--- a/vistrails/db/versions/v0_7_0/specs/abstractionRef.xml
+++ b/vistrails/db/versions/v0_7_0/specs/abstractionRef.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/action.xml b/vistrails/db/versions/v0_7_0/specs/action.xml
index 1c7d3c5..2129005 100644
--- a/vistrails/db/versions/v0_7_0/specs/action.xml
+++ b/vistrails/db/versions/v0_7_0/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/add.xml b/vistrails/db/versions/v0_7_0/specs/add.xml
index 11f560c..4354010 100644
--- a/vistrails/db/versions/v0_7_0/specs/add.xml
+++ b/vistrails/db/versions/v0_7_0/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/annotation.xml b/vistrails/db/versions/v0_7_0/specs/annotation.xml
index 19e9a54..f3f9e29 100644
--- a/vistrails/db/versions/v0_7_0/specs/annotation.xml
+++ b/vistrails/db/versions/v0_7_0/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/change.xml b/vistrails/db/versions/v0_7_0/specs/change.xml
index 8135c18..1078b59 100644
--- a/vistrails/db/versions/v0_7_0/specs/change.xml
+++ b/vistrails/db/versions/v0_7_0/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/connection.xml b/vistrails/db/versions/v0_7_0/specs/connection.xml
index b559fab..eefd6a4 100644
--- a/vistrails/db/versions/v0_7_0/specs/connection.xml
+++ b/vistrails/db/versions/v0_7_0/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/delete.xml b/vistrails/db/versions/v0_7_0/specs/delete.xml
index abcdfdb..544bfcf 100644
--- a/vistrails/db/versions/v0_7_0/specs/delete.xml
+++ b/vistrails/db/versions/v0_7_0/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/function.xml b/vistrails/db/versions/v0_7_0/specs/function.xml
index 8254645..4f6b03b 100644
--- a/vistrails/db/versions/v0_7_0/specs/function.xml
+++ b/vistrails/db/versions/v0_7_0/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/location.xml b/vistrails/db/versions/v0_7_0/specs/location.xml
index 99c62f7..48714a6 100644
--- a/vistrails/db/versions/v0_7_0/specs/location.xml
+++ b/vistrails/db/versions/v0_7_0/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/log.xml b/vistrails/db/versions/v0_7_0/specs/log.xml
index ca8720e..d5b08ce 100644
--- a/vistrails/db/versions/v0_7_0/specs/log.xml
+++ b/vistrails/db/versions/v0_7_0/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/machine.xml b/vistrails/db/versions/v0_7_0/specs/machine.xml
index dea813d..57e7ee3 100644
--- a/vistrails/db/versions/v0_7_0/specs/machine.xml
+++ b/vistrails/db/versions/v0_7_0/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/module.xml b/vistrails/db/versions/v0_7_0/specs/module.xml
index 263ba14..0f3c29f 100644
--- a/vistrails/db/versions/v0_7_0/specs/module.xml
+++ b/vistrails/db/versions/v0_7_0/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/module_exec.xml b/vistrails/db/versions/v0_7_0/specs/module_exec.xml
index 465407b..e109829 100644
--- a/vistrails/db/versions/v0_7_0/specs/module_exec.xml
+++ b/vistrails/db/versions/v0_7_0/specs/module_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/other.xml b/vistrails/db/versions/v0_7_0/specs/other.xml
index 40e1388..21a2846 100644
--- a/vistrails/db/versions/v0_7_0/specs/other.xml
+++ b/vistrails/db/versions/v0_7_0/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/parameter.xml b/vistrails/db/versions/v0_7_0/specs/parameter.xml
index 78f6cf7..f34fb2c 100644
--- a/vistrails/db/versions/v0_7_0/specs/parameter.xml
+++ b/vistrails/db/versions/v0_7_0/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/port.xml b/vistrails/db/versions/v0_7_0/specs/port.xml
index 94f7671..a9611d4 100644
--- a/vistrails/db/versions/v0_7_0/specs/port.xml
+++ b/vistrails/db/versions/v0_7_0/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/portSpec.xml b/vistrails/db/versions/v0_7_0/specs/portSpec.xml
index e42a5f0..9d21cce 100644
--- a/vistrails/db/versions/v0_7_0/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_7_0/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/tag.xml b/vistrails/db/versions/v0_7_0/specs/tag.xml
index f8412b9..5169bff 100644
--- a/vistrails/db/versions/v0_7_0/specs/tag.xml
+++ b/vistrails/db/versions/v0_7_0/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/vistrail.xml b/vistrails/db/versions/v0_7_0/specs/vistrail.xml
index b7b98d7..f46520b 100644
--- a/vistrails/db/versions/v0_7_0/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_7_0/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/workflow.xml b/vistrails/db/versions/v0_7_0/specs/workflow.xml
index b420aa0..c0e9bd9 100644
--- a/vistrails/db/versions/v0_7_0/specs/workflow.xml
+++ b/vistrails/db/versions/v0_7_0/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/specs/workflow_exec.xml b/vistrails/db/versions/v0_7_0/specs/workflow_exec.xml
index b616623..6da61b8 100644
--- a/vistrails/db/versions/v0_7_0/specs/workflow_exec.xml
+++ b/vistrails/db/versions/v0_7_0/specs/workflow_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_7_0/translate/__init__.py b/vistrails/db/versions/v0_7_0/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_7_0/translate/__init__.py
+++ b/vistrails/db/versions/v0_7_0/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_7_0/translate/v0_6_0.py b/vistrails/db/versions/v0_7_0/translate/v0_6_0.py
index ea4d612..718740b 100644
--- a/vistrails/db/versions/v0_7_0/translate/v0_6_0.py
+++ b/vistrails/db/versions/v0_7_0/translate/v0_6_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_7_0.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_8_0/__init__.py b/vistrails/db/versions/v0_8_0/__init__.py
index 692e9d5..742fda7 100644
--- a/vistrails/db/versions/v0_8_0/__init__.py
+++ b/vistrails/db/versions/v0_8_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.8.0'
diff --git a/vistrails/db/versions/v0_8_0/domain/__init__.py b/vistrails/db/versions/v0_8_0/domain/__init__.py
index f8bbb47..702e5bf 100644
--- a/vistrails/db/versions/v0_8_0/domain/__init__.py
+++ b/vistrails/db/versions/v0_8_0/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_8_0/domain/abstraction.py b/vistrails/db/versions/v0_8_0/domain/abstraction.py
index 5972a93..4835c37 100644
--- a/vistrails/db/versions/v0_8_0/domain/abstraction.py
+++ b/vistrails/db/versions/v0_8_0/domain/abstraction.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 from auto_gen import DBAbstraction as _DBAbstraction
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_8_0/domain/auto_gen.py b/vistrails/db/versions/v0_8_0/domain/auto_gen.py
index b17a214..bdf7326 100644
--- a/vistrails/db/versions/v0_8_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_8_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_8_0/domain/id_scope.py b/vistrails/db/versions/v0_8_0/domain/id_scope.py
index c510efa..49b9d49 100644
--- a/vistrails/db/versions/v0_8_0/domain/id_scope.py
+++ b/vistrails/db/versions/v0_8_0/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_8_0/domain/vistrail.py b/vistrails/db/versions/v0_8_0/domain/vistrail.py
index 9c9b23c..44ad7fd 100644
--- a/vistrails/db/versions/v0_8_0/domain/vistrail.py
+++ b/vistrails/db/versions/v0_8_0/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstractionRef, DBModule
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_8_0/domain/workflow.py b/vistrails/db/versions/v0_8_0/domain/workflow.py
index 2a8f059..0856048 100644
--- a/vistrails/db/versions/v0_8_0/domain/workflow.py
+++ b/vistrails/db/versions/v0_8_0/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from id_scope import IdScope
 
diff --git a/vistrails/db/versions/v0_8_0/persistence/__init__.py b/vistrails/db/versions/v0_8_0/persistence/__init__.py
index 37eacf9..97fb6d0 100644
--- a/vistrails/db/versions/v0_8_0/persistence/__init__.py
+++ b/vistrails/db/versions/v0_8_0/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v0_8_0/persistence/sql/__init__.py b/vistrails/db/versions/v0_8_0/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_8_0/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_8_0/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_8_0/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_8_0/persistence/sql/auto_gen.py
index a8c910c..929e0a9 100644
--- a/vistrails/db/versions/v0_8_0/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_8_0/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_8_0.domain import *
 
diff --git a/vistrails/db/versions/v0_8_0/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_8_0/persistence/sql/sql_dao.py
index c54eb03..5d9d4e6 100644
--- a/vistrails/db/versions/v0_8_0/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_8_0/persistence/sql/sql_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class SQLDAO:
     def __init__(self):
@@ -54,13 +58,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -76,7 +80,7 @@ class SQLDAO:
             elif type == 'date':
                 return "'" + value.isoformat() + "'"
             elif type == 'datetime':
-                return "'" + value.strftime('%Y-%m-%d %H:%M:%S') + "'"
+                return "'" + strftime(value, '%Y-%m-%d %H:%M:%S') + "'"
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_8_0/persistence/xml/__init__.py b/vistrails/db/versions/v0_8_0/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_8_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_8_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_8_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_8_0/persistence/xml/auto_gen.py
index 1c4a266..fa9bb2b 100644
--- a/vistrails/db/versions/v0_8_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_8_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v0_8_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_8_0/persistence/xml/xml_dao.py
index 955c01a..ef4ddec 100644
--- a/vistrails/db/versions/v0_8_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_8_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,10 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value,
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +79,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_8_0/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_8_0/schemas/sql/vistrails.sql
index bbb4a0c..43f50b9 100644
--- a/vistrails/db/versions/v0_8_0/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_8_0/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_8_0/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_8_0/schemas/sql/vistrails_drop.sql
index a4fd64c..258296f 100644
--- a/vistrails/db/versions/v0_8_0/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_8_0/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_8_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_8_0/schemas/xml/vistrail.xsd
index 276a2c0..ef24d85 100644
--- a/vistrails/db/versions/v0_8_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_8_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/abstraction.xml b/vistrails/db/versions/v0_8_0/specs/abstraction.xml
index 3cbb63a..0209e32 100644
--- a/vistrails/db/versions/v0_8_0/specs/abstraction.xml
+++ b/vistrails/db/versions/v0_8_0/specs/abstraction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/abstractionRef.xml b/vistrails/db/versions/v0_8_0/specs/abstractionRef.xml
index 46b61ba..dd24047 100644
--- a/vistrails/db/versions/v0_8_0/specs/abstractionRef.xml
+++ b/vistrails/db/versions/v0_8_0/specs/abstractionRef.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/action.xml b/vistrails/db/versions/v0_8_0/specs/action.xml
index 1c7d3c5..2129005 100644
--- a/vistrails/db/versions/v0_8_0/specs/action.xml
+++ b/vistrails/db/versions/v0_8_0/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/add.xml b/vistrails/db/versions/v0_8_0/specs/add.xml
index 11f560c..4354010 100644
--- a/vistrails/db/versions/v0_8_0/specs/add.xml
+++ b/vistrails/db/versions/v0_8_0/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/annotation.xml b/vistrails/db/versions/v0_8_0/specs/annotation.xml
index ba8194f..3cef2ab 100644
--- a/vistrails/db/versions/v0_8_0/specs/annotation.xml
+++ b/vistrails/db/versions/v0_8_0/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/change.xml b/vistrails/db/versions/v0_8_0/specs/change.xml
index 8135c18..1078b59 100644
--- a/vistrails/db/versions/v0_8_0/specs/change.xml
+++ b/vistrails/db/versions/v0_8_0/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/connection.xml b/vistrails/db/versions/v0_8_0/specs/connection.xml
index b559fab..eefd6a4 100644
--- a/vistrails/db/versions/v0_8_0/specs/connection.xml
+++ b/vistrails/db/versions/v0_8_0/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/delete.xml b/vistrails/db/versions/v0_8_0/specs/delete.xml
index abcdfdb..544bfcf 100644
--- a/vistrails/db/versions/v0_8_0/specs/delete.xml
+++ b/vistrails/db/versions/v0_8_0/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/function.xml b/vistrails/db/versions/v0_8_0/specs/function.xml
index a95590d..48244b6 100644
--- a/vistrails/db/versions/v0_8_0/specs/function.xml
+++ b/vistrails/db/versions/v0_8_0/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/location.xml b/vistrails/db/versions/v0_8_0/specs/location.xml
index 99c62f7..48714a6 100644
--- a/vistrails/db/versions/v0_8_0/specs/location.xml
+++ b/vistrails/db/versions/v0_8_0/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/log.xml b/vistrails/db/versions/v0_8_0/specs/log.xml
index ca8720e..d5b08ce 100644
--- a/vistrails/db/versions/v0_8_0/specs/log.xml
+++ b/vistrails/db/versions/v0_8_0/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/machine.xml b/vistrails/db/versions/v0_8_0/specs/machine.xml
index dea813d..57e7ee3 100644
--- a/vistrails/db/versions/v0_8_0/specs/machine.xml
+++ b/vistrails/db/versions/v0_8_0/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/module.xml b/vistrails/db/versions/v0_8_0/specs/module.xml
index fc9ed2a..b77188d 100644
--- a/vistrails/db/versions/v0_8_0/specs/module.xml
+++ b/vistrails/db/versions/v0_8_0/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/module_exec.xml b/vistrails/db/versions/v0_8_0/specs/module_exec.xml
index 465407b..e109829 100644
--- a/vistrails/db/versions/v0_8_0/specs/module_exec.xml
+++ b/vistrails/db/versions/v0_8_0/specs/module_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/other.xml b/vistrails/db/versions/v0_8_0/specs/other.xml
index 40e1388..21a2846 100644
--- a/vistrails/db/versions/v0_8_0/specs/other.xml
+++ b/vistrails/db/versions/v0_8_0/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/parameter.xml b/vistrails/db/versions/v0_8_0/specs/parameter.xml
index 78f6cf7..f34fb2c 100644
--- a/vistrails/db/versions/v0_8_0/specs/parameter.xml
+++ b/vistrails/db/versions/v0_8_0/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/port.xml b/vistrails/db/versions/v0_8_0/specs/port.xml
index 94f7671..a9611d4 100644
--- a/vistrails/db/versions/v0_8_0/specs/port.xml
+++ b/vistrails/db/versions/v0_8_0/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/portSpec.xml b/vistrails/db/versions/v0_8_0/specs/portSpec.xml
index e42a5f0..9d21cce 100644
--- a/vistrails/db/versions/v0_8_0/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_8_0/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/tag.xml b/vistrails/db/versions/v0_8_0/specs/tag.xml
index f8412b9..5169bff 100644
--- a/vistrails/db/versions/v0_8_0/specs/tag.xml
+++ b/vistrails/db/versions/v0_8_0/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/vistrail.xml b/vistrails/db/versions/v0_8_0/specs/vistrail.xml
index ccbd34c..48c7435 100644
--- a/vistrails/db/versions/v0_8_0/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_8_0/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/workflow.xml b/vistrails/db/versions/v0_8_0/specs/workflow.xml
index 56189f1..72b388a 100644
--- a/vistrails/db/versions/v0_8_0/specs/workflow.xml
+++ b/vistrails/db/versions/v0_8_0/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/specs/workflow_exec.xml b/vistrails/db/versions/v0_8_0/specs/workflow_exec.xml
index b616623..6da61b8 100644
--- a/vistrails/db/versions/v0_8_0/specs/workflow_exec.xml
+++ b/vistrails/db/versions/v0_8_0/specs/workflow_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_0/translate/__init__.py b/vistrails/db/versions/v0_8_0/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_8_0/translate/__init__.py
+++ b/vistrails/db/versions/v0_8_0/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_8_0/translate/v0_7_0.py b/vistrails/db/versions/v0_8_0/translate/v0_7_0.py
index 67ade06..7310dac 100644
--- a/vistrails/db/versions/v0_8_0/translate/v0_7_0.py
+++ b/vistrails/db/versions/v0_8_0/translate/v0_7_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_8_0.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_8_1/__init__.py b/vistrails/db/versions/v0_8_1/__init__.py
index f5dd2ba..f582bfd 100644
--- a/vistrails/db/versions/v0_8_1/__init__.py
+++ b/vistrails/db/versions/v0_8_1/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.8.1'
diff --git a/vistrails/db/versions/v0_8_1/domain/__init__.py b/vistrails/db/versions/v0_8_1/domain/__init__.py
index 5537997..890b3b5 100644
--- a/vistrails/db/versions/v0_8_1/domain/__init__.py
+++ b/vistrails/db/versions/v0_8_1/domain/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_8_0.domain import *
diff --git a/vistrails/db/versions/v0_8_1/persistence/__init__.py b/vistrails/db/versions/v0_8_1/persistence/__init__.py
index b24b280..0663274 100644
--- a/vistrails/db/versions/v0_8_1/persistence/__init__.py
+++ b/vistrails/db/versions/v0_8_1/persistence/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_8_0.persistence import DAOList
diff --git a/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql
index bbb4a0c..43f50b9 100644
--- a/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql.bkp b/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql.bkp
deleted file mode 100644
index 4f11895..0000000
--- a/vistrails/db/versions/v0_8_1/schemas/sql/vistrails.sql.bkp
+++ /dev/null
@@ -1,248 +0,0 @@
---#############################################################################
---
--- Copyright (C) 2006-2011, University of Utah. 
--- All rights reserved.
--- Contact: vistrails at sci.utah.edu
---
--- This file is part of VisTrails.
---
--- "Redistribution and use in source and binary forms, with or without 
--- modification, are permitted provided that the following conditions are met:
---
---  - Redistributions of source code must retain the above copyright notice, 
---    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
---    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
---    this software without specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
--- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
---
---#############################################################################
-
--- generated automatically by auto_dao.py
-
-CREATE TABLE port_spec(
-    id int,
-    name varchar(22),
-    type varchar(255),
-    spec varchar(255),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE module(
-    id int,
-    cache int,
-    name varchar(255),
-    package varchar(511),
-    version varchar(255),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE tag(
-    id int,
-    name varchar(255),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE port(
-    id int,
-    type varchar(255),
-    moduleId int,
-    moduleName varchar(255),
-    name varchar(255),
-    spec varchar(4095),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE log_tbl(
-    id int,
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE machine(
-    id int,
-    name varchar(255),
-    os varchar(255),
-    architecture varchar(255),
-    processor varchar(255),
-    ram int,
-    vt_id int,
-    log_id int,
-    module_exec_id int
-) type=InnoDB;
-
-CREATE TABLE add_tbl(
-    id int,
-    what varchar(255),
-    object_id int,
-    par_obj_id int,
-    par_obj_type char(16),
-    action_id int,
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE other(
-    id int,
-    okey varchar(255),
-    value varchar(255),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE location(
-    id int,
-    x DECIMAL(18,12),
-    y DECIMAL(18,12),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE workflow_exec(
-    id int,
-    user varchar(255),
-    ip varchar(255),
-    vt_version varchar(255),
-    ts_start datetime,
-    ts_end datetime,
-    parent_id int,
-    parent_type varchar(255),
-    parent_version int,
-    name varchar(255),
-    log_id int,
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE function(
-    id int,
-    pos int,
-    name varchar(255),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE abstraction(
-    id int,
-    name varchar(255),
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE workflow(
-    id int,
-    name varchar(255),
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE abstraction_ref(
-    id int,
-    name varchar(1023),
-    cache int,
-    abstraction_id int,
-    version int,
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE annotation(
-    id int,
-    akey varchar(255),
-    value varchar(8191),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE change_tbl(
-    id int,
-    what varchar(255),
-    old_obj_id int,
-    new_obj_id int,
-    par_obj_id int,
-    par_obj_type char(16),
-    action_id int,
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE parameter(
-    id int,
-    pos int,
-    name varchar(255),
-    type varchar(255),
-    val varchar(8191),
-    alias varchar(255),
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE connection_tbl(
-    id int,
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE action(
-    id int,
-    prev_id int,
-    date datetime,
-    session varchar(1023),
-    user varchar(255),
-    prune int,
-    parent_type char(16),
-    vt_id int,
-    parent_id int
-) type=InnoDB;
-
-CREATE TABLE delete_tbl(
-    id int,
-    what varchar(255),
-    object_id int,
-    par_obj_id int,
-    par_obj_type char(16),
-    action_id int,
-    vt_id int
-) type=InnoDB;
-
-CREATE TABLE vistrail(
-    id int not null auto_increment primary key,
-    version char(16),
-    name varchar(255),
-    last_modified datetime
-) type=InnoDB;
-
-CREATE TABLE module_exec(
-    id int,
-    ts_start datetime,
-    ts_end datetime,
-    module_id int,
-    module_name varchar(255),
-    machine_id int,
-    wf_exec_id int,
-    vt_id int
-) type=InnoDB;
-
diff --git a/vistrails/db/versions/v0_8_1/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_8_1/schemas/sql/vistrails_drop.sql
index a4fd64c..258296f 100644
--- a/vistrails/db/versions/v0_8_1/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_8_1/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_8_1/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_8_1/schemas/xml/vistrail.xsd
index 276a2c0..ef24d85 100644
--- a/vistrails/db/versions/v0_8_1/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_8_1/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/abstraction.xml b/vistrails/db/versions/v0_8_1/specs/abstraction.xml
index 3cbb63a..0209e32 100644
--- a/vistrails/db/versions/v0_8_1/specs/abstraction.xml
+++ b/vistrails/db/versions/v0_8_1/specs/abstraction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/abstractionRef.xml b/vistrails/db/versions/v0_8_1/specs/abstractionRef.xml
index 46b61ba..dd24047 100644
--- a/vistrails/db/versions/v0_8_1/specs/abstractionRef.xml
+++ b/vistrails/db/versions/v0_8_1/specs/abstractionRef.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/action.xml b/vistrails/db/versions/v0_8_1/specs/action.xml
index 1c7d3c5..2129005 100644
--- a/vistrails/db/versions/v0_8_1/specs/action.xml
+++ b/vistrails/db/versions/v0_8_1/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/add.xml b/vistrails/db/versions/v0_8_1/specs/add.xml
index 11f560c..4354010 100644
--- a/vistrails/db/versions/v0_8_1/specs/add.xml
+++ b/vistrails/db/versions/v0_8_1/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/annotation.xml b/vistrails/db/versions/v0_8_1/specs/annotation.xml
index ba8194f..3cef2ab 100644
--- a/vistrails/db/versions/v0_8_1/specs/annotation.xml
+++ b/vistrails/db/versions/v0_8_1/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/change.xml b/vistrails/db/versions/v0_8_1/specs/change.xml
index 8135c18..1078b59 100644
--- a/vistrails/db/versions/v0_8_1/specs/change.xml
+++ b/vistrails/db/versions/v0_8_1/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/connection.xml b/vistrails/db/versions/v0_8_1/specs/connection.xml
index b559fab..eefd6a4 100644
--- a/vistrails/db/versions/v0_8_1/specs/connection.xml
+++ b/vistrails/db/versions/v0_8_1/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/delete.xml b/vistrails/db/versions/v0_8_1/specs/delete.xml
index abcdfdb..544bfcf 100644
--- a/vistrails/db/versions/v0_8_1/specs/delete.xml
+++ b/vistrails/db/versions/v0_8_1/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/function.xml b/vistrails/db/versions/v0_8_1/specs/function.xml
index a95590d..48244b6 100644
--- a/vistrails/db/versions/v0_8_1/specs/function.xml
+++ b/vistrails/db/versions/v0_8_1/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/location.xml b/vistrails/db/versions/v0_8_1/specs/location.xml
index 99c62f7..48714a6 100644
--- a/vistrails/db/versions/v0_8_1/specs/location.xml
+++ b/vistrails/db/versions/v0_8_1/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/log.xml b/vistrails/db/versions/v0_8_1/specs/log.xml
index ca8720e..d5b08ce 100644
--- a/vistrails/db/versions/v0_8_1/specs/log.xml
+++ b/vistrails/db/versions/v0_8_1/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/machine.xml b/vistrails/db/versions/v0_8_1/specs/machine.xml
index dea813d..57e7ee3 100644
--- a/vistrails/db/versions/v0_8_1/specs/machine.xml
+++ b/vistrails/db/versions/v0_8_1/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/module.xml b/vistrails/db/versions/v0_8_1/specs/module.xml
index fc9ed2a..b77188d 100644
--- a/vistrails/db/versions/v0_8_1/specs/module.xml
+++ b/vistrails/db/versions/v0_8_1/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/module_exec.xml b/vistrails/db/versions/v0_8_1/specs/module_exec.xml
index 465407b..e109829 100644
--- a/vistrails/db/versions/v0_8_1/specs/module_exec.xml
+++ b/vistrails/db/versions/v0_8_1/specs/module_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/other.xml b/vistrails/db/versions/v0_8_1/specs/other.xml
index 40e1388..21a2846 100644
--- a/vistrails/db/versions/v0_8_1/specs/other.xml
+++ b/vistrails/db/versions/v0_8_1/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/parameter.xml b/vistrails/db/versions/v0_8_1/specs/parameter.xml
index 78f6cf7..f34fb2c 100644
--- a/vistrails/db/versions/v0_8_1/specs/parameter.xml
+++ b/vistrails/db/versions/v0_8_1/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/port.xml b/vistrails/db/versions/v0_8_1/specs/port.xml
index 94f7671..a9611d4 100644
--- a/vistrails/db/versions/v0_8_1/specs/port.xml
+++ b/vistrails/db/versions/v0_8_1/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/portSpec.xml b/vistrails/db/versions/v0_8_1/specs/portSpec.xml
index e42a5f0..9d21cce 100644
--- a/vistrails/db/versions/v0_8_1/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_8_1/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/tag.xml b/vistrails/db/versions/v0_8_1/specs/tag.xml
index f8412b9..5169bff 100644
--- a/vistrails/db/versions/v0_8_1/specs/tag.xml
+++ b/vistrails/db/versions/v0_8_1/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/vistrail.xml b/vistrails/db/versions/v0_8_1/specs/vistrail.xml
index ccbd34c..48c7435 100644
--- a/vistrails/db/versions/v0_8_1/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_8_1/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/workflow.xml b/vistrails/db/versions/v0_8_1/specs/workflow.xml
index 56189f1..72b388a 100644
--- a/vistrails/db/versions/v0_8_1/specs/workflow.xml
+++ b/vistrails/db/versions/v0_8_1/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/specs/workflow_exec.xml b/vistrails/db/versions/v0_8_1/specs/workflow_exec.xml
index b616623..6da61b8 100644
--- a/vistrails/db/versions/v0_8_1/specs/workflow_exec.xml
+++ b/vistrails/db/versions/v0_8_1/specs/workflow_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_8_1/translate/__init__.py b/vistrails/db/versions/v0_8_1/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_8_1/translate/__init__.py
+++ b/vistrails/db/versions/v0_8_1/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_8_1/translate/v0_8_0.py b/vistrails/db/versions/v0_8_1/translate/v0_8_0.py
index c007351..b4eded7 100644
--- a/vistrails/db/versions/v0_8_1/translate/v0_8_0.py
+++ b/vistrails/db/versions/v0_8_1/translate/v0_8_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db import VistrailsDBException
 from vistrails.db.versions.v0_8_0.domain import DBAdd, DBAnnotation, DBChange, DBDelete
 
diff --git a/vistrails/db/versions/v0_9_0/__init__.py b/vistrails/db/versions/v0_9_0/__init__.py
index e8a8036..1bb21ae 100644
--- a/vistrails/db/versions/v0_9_0/__init__.py
+++ b/vistrails/db/versions/v0_9_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.0'
diff --git a/vistrails/db/versions/v0_9_0/domain/__init__.py b/vistrails/db/versions/v0_9_0/domain/__init__.py
index 1fd287d..570ee28 100644
--- a/vistrails/db/versions/v0_9_0/domain/__init__.py
+++ b/vistrails/db/versions/v0_9_0/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_9_0/domain/abstraction.py b/vistrails/db/versions/v0_9_0/domain/abstraction.py
index 6c3ecb5..c420e64 100644
--- a/vistrails/db/versions/v0_9_0/domain/abstraction.py
+++ b/vistrails/db/versions/v0_9_0/domain/abstraction.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 from auto_gen import DBAbstraction as _DBAbstraction
 from auto_gen import DBAbstractionRef, DBModule
diff --git a/vistrails/db/versions/v0_9_0/domain/auto_gen.py b/vistrails/db/versions/v0_9_0/domain/auto_gen.py
index bfc1313..e65fa06 100644
--- a/vistrails/db/versions/v0_9_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_9_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_9_0/domain/id_scope.py b/vistrails/db/versions/v0_9_0/domain/id_scope.py
index c510efa..49b9d49 100644
--- a/vistrails/db/versions/v0_9_0/domain/id_scope.py
+++ b/vistrails/db/versions/v0_9_0/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_9_0/domain/log.py b/vistrails/db/versions/v0_9_0/domain/log.py
index 5f56556..b243e11 100644
--- a/vistrails/db/versions/v0_9_0/domain/log.py
+++ b/vistrails/db/versions/v0_9_0/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstractionRef, DBModule
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_0/domain/vistrail.py b/vistrails/db/versions/v0_9_0/domain/vistrail.py
index 8edc340..2ffde3a 100644
--- a/vistrails/db/versions/v0_9_0/domain/vistrail.py
+++ b/vistrails/db/versions/v0_9_0/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstractionRef, DBModule
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_0/domain/workflow.py b/vistrails/db/versions/v0_9_0/domain/workflow.py
index 04db38e..2570e3c 100644
--- a/vistrails/db/versions/v0_9_0/domain/workflow.py
+++ b/vistrails/db/versions/v0_9_0/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstractionRef, DBModule
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_0/persistence/__init__.py b/vistrails/db/versions/v0_9_0/persistence/__init__.py
index 5fc0ad4..d1d55b8 100644
--- a/vistrails/db/versions/v0_9_0/persistence/__init__.py
+++ b/vistrails/db/versions/v0_9_0/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v0_9_0/persistence/sql/__init__.py b/vistrails/db/versions/v0_9_0/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_0/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_9_0/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_0/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_9_0/persistence/sql/auto_gen.py
index 50d5fcd..2ab94d2 100644
--- a/vistrails/db/versions/v0_9_0/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_9_0/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_9_0.domain import *
 
diff --git a/vistrails/db/versions/v0_9_0/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_9_0/persistence/sql/sql_dao.py
index c54eb03..5d9d4e6 100644
--- a/vistrails/db/versions/v0_9_0/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_9_0/persistence/sql/sql_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class SQLDAO:
     def __init__(self):
@@ -54,13 +58,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -76,7 +80,7 @@ class SQLDAO:
             elif type == 'date':
                 return "'" + value.isoformat() + "'"
             elif type == 'datetime':
-                return "'" + value.strftime('%Y-%m-%d %H:%M:%S') + "'"
+                return "'" + strftime(value, '%Y-%m-%d %H:%M:%S') + "'"
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_9_0/persistence/xml/__init__.py b/vistrails/db/versions/v0_9_0/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_9_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_9_0/persistence/xml/auto_gen.py
index c939ec8..24444ca 100644
--- a/vistrails/db/versions/v0_9_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_9_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v0_9_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_9_0/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v0_9_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_9_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_9_0/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_9_0/schemas/sql/vistrails.sql
index e4ad867..2cc6ab6 100644
--- a/vistrails/db/versions/v0_9_0/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_9_0/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_0/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_9_0/schemas/sql/vistrails_drop.sql
index a4fd64c..258296f 100644
--- a/vistrails/db/versions/v0_9_0/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_9_0/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_9_0/schemas/xml/vistrail.xsd
index a6c8708..f80c635 100644
--- a/vistrails/db/versions/v0_9_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_9_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/abstraction.xml b/vistrails/db/versions/v0_9_0/specs/abstraction.xml
index aa63aee..a0051c8 100644
--- a/vistrails/db/versions/v0_9_0/specs/abstraction.xml
+++ b/vistrails/db/versions/v0_9_0/specs/abstraction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/abstractionRef.xml b/vistrails/db/versions/v0_9_0/specs/abstractionRef.xml
index f92f174..170eba8 100644
--- a/vistrails/db/versions/v0_9_0/specs/abstractionRef.xml
+++ b/vistrails/db/versions/v0_9_0/specs/abstractionRef.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/action.xml b/vistrails/db/versions/v0_9_0/specs/action.xml
index e1048ab..d7bf056 100644
--- a/vistrails/db/versions/v0_9_0/specs/action.xml
+++ b/vistrails/db/versions/v0_9_0/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/add.xml b/vistrails/db/versions/v0_9_0/specs/add.xml
index 0236869..74e7ce7 100644
--- a/vistrails/db/versions/v0_9_0/specs/add.xml
+++ b/vistrails/db/versions/v0_9_0/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/annotation.xml b/vistrails/db/versions/v0_9_0/specs/annotation.xml
index ccf678f..9e56341 100644
--- a/vistrails/db/versions/v0_9_0/specs/annotation.xml
+++ b/vistrails/db/versions/v0_9_0/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/change.xml b/vistrails/db/versions/v0_9_0/specs/change.xml
index 92cff57..b536c58 100644
--- a/vistrails/db/versions/v0_9_0/specs/change.xml
+++ b/vistrails/db/versions/v0_9_0/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/connection.xml b/vistrails/db/versions/v0_9_0/specs/connection.xml
index 2f6cefd..dfdb697 100644
--- a/vistrails/db/versions/v0_9_0/specs/connection.xml
+++ b/vistrails/db/versions/v0_9_0/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/delete.xml b/vistrails/db/versions/v0_9_0/specs/delete.xml
index 86d8855..ba23cd6 100644
--- a/vistrails/db/versions/v0_9_0/specs/delete.xml
+++ b/vistrails/db/versions/v0_9_0/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/function.xml b/vistrails/db/versions/v0_9_0/specs/function.xml
index 61f349f..91af1f2 100644
--- a/vistrails/db/versions/v0_9_0/specs/function.xml
+++ b/vistrails/db/versions/v0_9_0/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/location.xml b/vistrails/db/versions/v0_9_0/specs/location.xml
index 2a7ea61..211527e 100644
--- a/vistrails/db/versions/v0_9_0/specs/location.xml
+++ b/vistrails/db/versions/v0_9_0/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/log.xml b/vistrails/db/versions/v0_9_0/specs/log.xml
index adb6466..669a9a4 100644
--- a/vistrails/db/versions/v0_9_0/specs/log.xml
+++ b/vistrails/db/versions/v0_9_0/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/machine.xml b/vistrails/db/versions/v0_9_0/specs/machine.xml
index 2cf9416..873c2e9 100644
--- a/vistrails/db/versions/v0_9_0/specs/machine.xml
+++ b/vistrails/db/versions/v0_9_0/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/module.xml b/vistrails/db/versions/v0_9_0/specs/module.xml
index 05f8454..2247728 100644
--- a/vistrails/db/versions/v0_9_0/specs/module.xml
+++ b/vistrails/db/versions/v0_9_0/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/module_exec.xml b/vistrails/db/versions/v0_9_0/specs/module_exec.xml
index 8b86b73..c5ebbc3 100644
--- a/vistrails/db/versions/v0_9_0/specs/module_exec.xml
+++ b/vistrails/db/versions/v0_9_0/specs/module_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/other.xml b/vistrails/db/versions/v0_9_0/specs/other.xml
index a87b179..e99eb17 100644
--- a/vistrails/db/versions/v0_9_0/specs/other.xml
+++ b/vistrails/db/versions/v0_9_0/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/parameter.xml b/vistrails/db/versions/v0_9_0/specs/parameter.xml
index 0a3a4b4..b2e8f33 100644
--- a/vistrails/db/versions/v0_9_0/specs/parameter.xml
+++ b/vistrails/db/versions/v0_9_0/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/port.xml b/vistrails/db/versions/v0_9_0/specs/port.xml
index 9073a77..0f101d6 100644
--- a/vistrails/db/versions/v0_9_0/specs/port.xml
+++ b/vistrails/db/versions/v0_9_0/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/portSpec.xml b/vistrails/db/versions/v0_9_0/specs/portSpec.xml
index bc52103..104fc9a 100644
--- a/vistrails/db/versions/v0_9_0/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_9_0/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/tag.xml b/vistrails/db/versions/v0_9_0/specs/tag.xml
index a5c380d..4b670ff 100644
--- a/vistrails/db/versions/v0_9_0/specs/tag.xml
+++ b/vistrails/db/versions/v0_9_0/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/vistrail.xml b/vistrails/db/versions/v0_9_0/specs/vistrail.xml
index a97310b..2a32976 100644
--- a/vistrails/db/versions/v0_9_0/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_9_0/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/workflow.xml b/vistrails/db/versions/v0_9_0/specs/workflow.xml
index 61523ba..1205607 100644
--- a/vistrails/db/versions/v0_9_0/specs/workflow.xml
+++ b/vistrails/db/versions/v0_9_0/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/specs/workflow_exec.xml b/vistrails/db/versions/v0_9_0/specs/workflow_exec.xml
index d20253c..fe638fd 100644
--- a/vistrails/db/versions/v0_9_0/specs/workflow_exec.xml
+++ b/vistrails/db/versions/v0_9_0/specs/workflow_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_0/translate/__init__.py b/vistrails/db/versions/v0_9_0/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_9_0/translate/__init__.py
+++ b/vistrails/db/versions/v0_9_0/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_9_0/translate/v0_8_1.py b/vistrails/db/versions/v0_9_0/translate/v0_8_1.py
index 23b811e..94c0b95 100644
--- a/vistrails/db/versions/v0_9_0/translate/v0_8_1.py
+++ b/vistrails/db/versions/v0_9_0/translate/v0_8_1.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_9_0.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_9_1/__init__.py b/vistrails/db/versions/v0_9_1/__init__.py
index b324ecf..2dc0c98 100644
--- a/vistrails/db/versions/v0_9_1/__init__.py
+++ b/vistrails/db/versions/v0_9_1/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.1'
diff --git a/vistrails/db/versions/v0_9_1/domain/__init__.py b/vistrails/db/versions/v0_9_1/domain/__init__.py
index 1fd287d..570ee28 100644
--- a/vistrails/db/versions/v0_9_1/domain/__init__.py
+++ b/vistrails/db/versions/v0_9_1/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_9_1/domain/abstraction.py b/vistrails/db/versions/v0_9_1/domain/abstraction.py
index 6c3ecb5..c420e64 100644
--- a/vistrails/db/versions/v0_9_1/domain/abstraction.py
+++ b/vistrails/db/versions/v0_9_1/domain/abstraction.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 from auto_gen import DBAbstraction as _DBAbstraction
 from auto_gen import DBAbstractionRef, DBModule
diff --git a/vistrails/db/versions/v0_9_1/domain/auto_gen.py b/vistrails/db/versions/v0_9_1/domain/auto_gen.py
index c1e54b5..aacdf22 100644
--- a/vistrails/db/versions/v0_9_1/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_9_1/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_9_1/domain/id_scope.py b/vistrails/db/versions/v0_9_1/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v0_9_1/domain/id_scope.py
+++ b/vistrails/db/versions/v0_9_1/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_9_1/domain/log.py b/vistrails/db/versions/v0_9_1/domain/log.py
index 5f56556..b243e11 100644
--- a/vistrails/db/versions/v0_9_1/domain/log.py
+++ b/vistrails/db/versions/v0_9_1/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstractionRef, DBModule
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_1/domain/vistrail.py b/vistrails/db/versions/v0_9_1/domain/vistrail.py
index fe0f902..dff2822 100644
--- a/vistrails/db/versions/v0_9_1/domain/vistrail.py
+++ b/vistrails/db/versions/v0_9_1/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstractionRef, DBGroup, \
     DBModule
diff --git a/vistrails/db/versions/v0_9_1/domain/workflow.py b/vistrails/db/versions/v0_9_1/domain/workflow.py
index cb1f6fe..562c22e 100644
--- a/vistrails/db/versions/v0_9_1/domain/workflow.py
+++ b/vistrails/db/versions/v0_9_1/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstractionRef, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_1/persistence/__init__.py b/vistrails/db/versions/v0_9_1/persistence/__init__.py
index d727263..7bd3676 100644
--- a/vistrails/db/versions/v0_9_1/persistence/__init__.py
+++ b/vistrails/db/versions/v0_9_1/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v0_9_1/persistence/sql/__init__.py b/vistrails/db/versions/v0_9_1/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_1/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_9_1/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_1/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_9_1/persistence/sql/auto_gen.py
index d64a45e..445773d 100644
--- a/vistrails/db/versions/v0_9_1/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_9_1/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_9_1.domain import *
 
diff --git a/vistrails/db/versions/v0_9_1/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_9_1/persistence/sql/sql_dao.py
index c54eb03..5d9d4e6 100644
--- a/vistrails/db/versions/v0_9_1/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_9_1/persistence/sql/sql_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class SQLDAO:
     def __init__(self):
@@ -54,13 +58,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -76,7 +80,7 @@ class SQLDAO:
             elif type == 'date':
                 return "'" + value.isoformat() + "'"
             elif type == 'datetime':
-                return "'" + value.strftime('%Y-%m-%d %H:%M:%S') + "'"
+                return "'" + strftime(value, '%Y-%m-%d %H:%M:%S') + "'"
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_9_1/persistence/xml/__init__.py b/vistrails/db/versions/v0_9_1/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_1/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_9_1/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_1/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_9_1/persistence/xml/auto_gen.py
index e31a2bf..2c74cc6 100644
--- a/vistrails/db/versions/v0_9_1/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_9_1/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v0_9_1/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_9_1/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v0_9_1/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_9_1/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_9_1/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_9_1/schemas/sql/vistrails.sql
index 1e45703..bafdcb5 100644
--- a/vistrails/db/versions/v0_9_1/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_9_1/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_1/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_9_1/schemas/sql/vistrails_drop.sql
index 3cb6da4..e901e85 100644
--- a/vistrails/db/versions/v0_9_1/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_9_1/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_1/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_9_1/schemas/xml/vistrail.xsd
index 22bdf2a..998ac8b 100644
--- a/vistrails/db/versions/v0_9_1/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_9_1/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/schemas/xml/vtlink.xsd b/vistrails/db/versions/v0_9_1/schemas/xml/vtlink.xsd
index e1ec5d0..f397341 100644
--- a/vistrails/db/versions/v0_9_1/schemas/xml/vtlink.xsd
+++ b/vistrails/db/versions/v0_9_1/schemas/xml/vtlink.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/abstraction.xml b/vistrails/db/versions/v0_9_1/specs/abstraction.xml
index aa63aee..a0051c8 100644
--- a/vistrails/db/versions/v0_9_1/specs/abstraction.xml
+++ b/vistrails/db/versions/v0_9_1/specs/abstraction.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/abstractionRef.xml b/vistrails/db/versions/v0_9_1/specs/abstractionRef.xml
index f92f174..170eba8 100644
--- a/vistrails/db/versions/v0_9_1/specs/abstractionRef.xml
+++ b/vistrails/db/versions/v0_9_1/specs/abstractionRef.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/action.xml b/vistrails/db/versions/v0_9_1/specs/action.xml
index e1048ab..d7bf056 100644
--- a/vistrails/db/versions/v0_9_1/specs/action.xml
+++ b/vistrails/db/versions/v0_9_1/specs/action.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/add.xml b/vistrails/db/versions/v0_9_1/specs/add.xml
index 20c1cc6..071dd93 100644
--- a/vistrails/db/versions/v0_9_1/specs/add.xml
+++ b/vistrails/db/versions/v0_9_1/specs/add.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/annotation.xml b/vistrails/db/versions/v0_9_1/specs/annotation.xml
index 49323ec..2f8aa64 100644
--- a/vistrails/db/versions/v0_9_1/specs/annotation.xml
+++ b/vistrails/db/versions/v0_9_1/specs/annotation.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/change.xml b/vistrails/db/versions/v0_9_1/specs/change.xml
index e24ac1d..aa60fa0 100644
--- a/vistrails/db/versions/v0_9_1/specs/change.xml
+++ b/vistrails/db/versions/v0_9_1/specs/change.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/connection.xml b/vistrails/db/versions/v0_9_1/specs/connection.xml
index 2f6cefd..dfdb697 100644
--- a/vistrails/db/versions/v0_9_1/specs/connection.xml
+++ b/vistrails/db/versions/v0_9_1/specs/connection.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/delete.xml b/vistrails/db/versions/v0_9_1/specs/delete.xml
index 86d8855..ba23cd6 100644
--- a/vistrails/db/versions/v0_9_1/specs/delete.xml
+++ b/vistrails/db/versions/v0_9_1/specs/delete.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/function.xml b/vistrails/db/versions/v0_9_1/specs/function.xml
index 02710b2..0dd2bf5 100644
--- a/vistrails/db/versions/v0_9_1/specs/function.xml
+++ b/vistrails/db/versions/v0_9_1/specs/function.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/group.xml b/vistrails/db/versions/v0_9_1/specs/group.xml
index f275b60..3fb06d9 100644
--- a/vistrails/db/versions/v0_9_1/specs/group.xml
+++ b/vistrails/db/versions/v0_9_1/specs/group.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/location.xml b/vistrails/db/versions/v0_9_1/specs/location.xml
index 6fd8c11..431f55a 100644
--- a/vistrails/db/versions/v0_9_1/specs/location.xml
+++ b/vistrails/db/versions/v0_9_1/specs/location.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/log.xml b/vistrails/db/versions/v0_9_1/specs/log.xml
index adb6466..669a9a4 100644
--- a/vistrails/db/versions/v0_9_1/specs/log.xml
+++ b/vistrails/db/versions/v0_9_1/specs/log.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/machine.xml b/vistrails/db/versions/v0_9_1/specs/machine.xml
index 2cf9416..873c2e9 100644
--- a/vistrails/db/versions/v0_9_1/specs/machine.xml
+++ b/vistrails/db/versions/v0_9_1/specs/machine.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/module.xml b/vistrails/db/versions/v0_9_1/specs/module.xml
index 0c70031..d309161 100644
--- a/vistrails/db/versions/v0_9_1/specs/module.xml
+++ b/vistrails/db/versions/v0_9_1/specs/module.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/module_exec.xml b/vistrails/db/versions/v0_9_1/specs/module_exec.xml
index 8b86b73..c5ebbc3 100644
--- a/vistrails/db/versions/v0_9_1/specs/module_exec.xml
+++ b/vistrails/db/versions/v0_9_1/specs/module_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/other.xml b/vistrails/db/versions/v0_9_1/specs/other.xml
index a87b179..e99eb17 100644
--- a/vistrails/db/versions/v0_9_1/specs/other.xml
+++ b/vistrails/db/versions/v0_9_1/specs/other.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/parameter.xml b/vistrails/db/versions/v0_9_1/specs/parameter.xml
index 0a3a4b4..b2e8f33 100644
--- a/vistrails/db/versions/v0_9_1/specs/parameter.xml
+++ b/vistrails/db/versions/v0_9_1/specs/parameter.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/port.xml b/vistrails/db/versions/v0_9_1/specs/port.xml
index 9073a77..0f101d6 100644
--- a/vistrails/db/versions/v0_9_1/specs/port.xml
+++ b/vistrails/db/versions/v0_9_1/specs/port.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/portSpec.xml b/vistrails/db/versions/v0_9_1/specs/portSpec.xml
index bc52103..104fc9a 100644
--- a/vistrails/db/versions/v0_9_1/specs/portSpec.xml
+++ b/vistrails/db/versions/v0_9_1/specs/portSpec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/tag.xml b/vistrails/db/versions/v0_9_1/specs/tag.xml
index a5c380d..4b670ff 100644
--- a/vistrails/db/versions/v0_9_1/specs/tag.xml
+++ b/vistrails/db/versions/v0_9_1/specs/tag.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/vistrail.xml b/vistrails/db/versions/v0_9_1/specs/vistrail.xml
index a97310b..2a32976 100644
--- a/vistrails/db/versions/v0_9_1/specs/vistrail.xml
+++ b/vistrails/db/versions/v0_9_1/specs/vistrail.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/workflow.xml b/vistrails/db/versions/v0_9_1/specs/workflow.xml
index 1601ddb..9c8d712 100644
--- a/vistrails/db/versions/v0_9_1/specs/workflow.xml
+++ b/vistrails/db/versions/v0_9_1/specs/workflow.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/specs/workflow_exec.xml b/vistrails/db/versions/v0_9_1/specs/workflow_exec.xml
index d20253c..fe638fd 100644
--- a/vistrails/db/versions/v0_9_1/specs/workflow_exec.xml
+++ b/vistrails/db/versions/v0_9_1/specs/workflow_exec.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_1/translate/__init__.py b/vistrails/db/versions/v0_9_1/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_9_1/translate/__init__.py
+++ b/vistrails/db/versions/v0_9_1/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_9_1/translate/v0_9_0.py b/vistrails/db/versions/v0_9_1/translate/v0_9_0.py
index 668247e..d36d118 100644
--- a/vistrails/db/versions/v0_9_1/translate/v0_9_0.py
+++ b/vistrails/db/versions/v0_9_1/translate/v0_9_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_9_1.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_9_2/__init__.py b/vistrails/db/versions/v0_9_2/__init__.py
index 75bdbf3..9fb4229 100644
--- a/vistrails/db/versions/v0_9_2/__init__.py
+++ b/vistrails/db/versions/v0_9_2/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.2'
diff --git a/vistrails/db/versions/v0_9_2/domain/__init__.py b/vistrails/db/versions/v0_9_2/domain/__init__.py
index 057dce6..45cd24d 100644
--- a/vistrails/db/versions/v0_9_2/domain/__init__.py
+++ b/vistrails/db/versions/v0_9_2/domain/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_9_1.domain import *
diff --git a/vistrails/db/versions/v0_9_2/persistence/__init__.py b/vistrails/db/versions/v0_9_2/persistence/__init__.py
index 533a33e..9750a8f 100644
--- a/vistrails/db/versions/v0_9_2/persistence/__init__.py
+++ b/vistrails/db/versions/v0_9_2/persistence/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_9_1.persistence import DAOList
diff --git a/vistrails/db/versions/v0_9_2/translate/__init__.py b/vistrails/db/versions/v0_9_2/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_9_2/translate/__init__.py
+++ b/vistrails/db/versions/v0_9_2/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_9_2/translate/v0_9_1.py b/vistrails/db/versions/v0_9_2/translate/v0_9_1.py
index a5b0d4c..e749a69 100644
--- a/vistrails/db/versions/v0_9_2/translate/v0_9_1.py
+++ b/vistrails/db/versions/v0_9_2/translate/v0_9_1.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db import VistrailsDBException
 from vistrails.db.versions.v0_9_1.domain import DBAdd, DBAnnotation, DBChange, DBDelete
 
diff --git a/vistrails/db/versions/v0_9_3/__init__.py b/vistrails/db/versions/v0_9_3/__init__.py
index e628fc0..3c46539 100644
--- a/vistrails/db/versions/v0_9_3/__init__.py
+++ b/vistrails/db/versions/v0_9_3/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.3'
diff --git a/vistrails/db/versions/v0_9_3/domain/__init__.py b/vistrails/db/versions/v0_9_3/domain/__init__.py
index 1fd287d..570ee28 100644
--- a/vistrails/db/versions/v0_9_3/domain/__init__.py
+++ b/vistrails/db/versions/v0_9_3/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_9_3/domain/abstraction.py b/vistrails/db/versions/v0_9_3/domain/abstraction.py
index 6c3ecb5..c420e64 100644
--- a/vistrails/db/versions/v0_9_3/domain/abstraction.py
+++ b/vistrails/db/versions/v0_9_3/domain/abstraction.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 from auto_gen import DBAbstraction as _DBAbstraction
 from auto_gen import DBAbstractionRef, DBModule
diff --git a/vistrails/db/versions/v0_9_3/domain/auto_gen.py b/vistrails/db/versions/v0_9_3/domain/auto_gen.py
index 87512da..c32f723 100644
--- a/vistrails/db/versions/v0_9_3/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_9_3/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_9_3/domain/id_scope.py b/vistrails/db/versions/v0_9_3/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v0_9_3/domain/id_scope.py
+++ b/vistrails/db/versions/v0_9_3/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_9_3/domain/log.py b/vistrails/db/versions/v0_9_3/domain/log.py
index effb9f1..c39ca80 100644
--- a/vistrails/db/versions/v0_9_3/domain/log.py
+++ b/vistrails/db/versions/v0_9_3/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstractionRef, DBModule
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_3/domain/vistrail.py b/vistrails/db/versions/v0_9_3/domain/vistrail.py
index 22eb0ab..51b0e8e 100644
--- a/vistrails/db/versions/v0_9_3/domain/vistrail.py
+++ b/vistrails/db/versions/v0_9_3/domain/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstractionRef, DBGroup, \
diff --git a/vistrails/db/versions/v0_9_3/domain/workflow.py b/vistrails/db/versions/v0_9_3/domain/workflow.py
index cfe0dca..7de4e79 100644
--- a/vistrails/db/versions/v0_9_3/domain/workflow.py
+++ b/vistrails/db/versions/v0_9_3/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstractionRef, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_3/persistence/__init__.py b/vistrails/db/versions/v0_9_3/persistence/__init__.py
index ce764d5..80adbd4 100644
--- a/vistrails/db/versions/v0_9_3/persistence/__init__.py
+++ b/vistrails/db/versions/v0_9_3/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v0_9_3/persistence/sql/__init__.py b/vistrails/db/versions/v0_9_3/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_3/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_9_3/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_3/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_9_3/persistence/sql/auto_gen.py
index e6ffdd4..ac0844d 100644
--- a/vistrails/db/versions/v0_9_3/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_9_3/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_9_3.domain import *
 
diff --git a/vistrails/db/versions/v0_9_3/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_9_3/persistence/sql/sql_dao.py
index ad01dc5..5c5afe6 100644
--- a/vistrails/db/versions/v0_9_3/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_9_3/persistence/sql/sql_dao.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 
 class SQLDAO:
@@ -56,13 +59,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -79,7 +82,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_9_3/persistence/xml/__init__.py b/vistrails/db/versions/v0_9_3/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_3/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_9_3/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_3/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_9_3/persistence/xml/auto_gen.py
index e491b17..c5b9388 100644
--- a/vistrails/db/versions/v0_9_3/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_9_3/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v0_9_3/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_9_3/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v0_9_3/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_9_3/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_9_3/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_9_3/schemas/sql/vistrails.sql
index 633e54e..f6d5bf3 100644
--- a/vistrails/db/versions/v0_9_3/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_9_3/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_3/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_9_3/schemas/sql/vistrails_drop.sql
index fa131e2..67662eb 100644
--- a/vistrails/db/versions/v0_9_3/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_9_3/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_3/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_9_3/schemas/xml/vistrail.xsd
index 911ca0a..613e6da 100644
--- a/vistrails/db/versions/v0_9_3/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_9_3/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_3/specs/all.xml b/vistrails/db/versions/v0_9_3/specs/all.xml
index 9adece8..36f0828 100644
--- a/vistrails/db/versions/v0_9_3/specs/all.xml
+++ b/vistrails/db/versions/v0_9_3/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_3/translate/__init__.py b/vistrails/db/versions/v0_9_3/translate/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/db/versions/v0_9_3/translate/__init__.py
+++ b/vistrails/db/versions/v0_9_3/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/db/versions/v0_9_3/translate/v0_9_1.py b/vistrails/db/versions/v0_9_3/translate/v0_9_1.py
index 437b595..2cf46dd 100644
--- a/vistrails/db/versions/v0_9_3/translate/v0_9_1.py
+++ b/vistrails/db/versions/v0_9_3/translate/v0_9_1.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_9_3.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_9_3/translate/v0_9_2.py b/vistrails/db/versions/v0_9_3/translate/v0_9_2.py
index 848c2ab..39ef6a6 100644
--- a/vistrails/db/versions/v0_9_3/translate/v0_9_2.py
+++ b/vistrails/db/versions/v0_9_3/translate/v0_9_2.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_9_3.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_9_3/translate/v0_9_4.py b/vistrails/db/versions/v0_9_3/translate/v0_9_4.py
index 7a32422..a7a6b79 100644
--- a/vistrails/db/versions/v0_9_3/translate/v0_9_4.py
+++ b/vistrails/db/versions/v0_9_3/translate/v0_9_4.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v0_9_3.domain import DBVistrail, DBWorkflow, DBLog, \
     DBAbstractionRef, DBAdd, DBChange, DBDelete, DBAbstractionRef, DBGroup, \
     DBModule
diff --git a/vistrails/db/versions/v0_9_4/__init__.py b/vistrails/db/versions/v0_9_4/__init__.py
index 5cf1ec6..eb00579 100644
--- a/vistrails/db/versions/v0_9_4/__init__.py
+++ b/vistrails/db/versions/v0_9_4/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.4'
diff --git a/vistrails/db/versions/v0_9_4/domain/__init__.py b/vistrails/db/versions/v0_9_4/domain/__init__.py
index 370b564..542de19 100644
--- a/vistrails/db/versions/v0_9_4/domain/__init__.py
+++ b/vistrails/db/versions/v0_9_4/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from workflow import DBWorkflow
 from vistrail import DBVistrail
diff --git a/vistrails/db/versions/v0_9_4/domain/auto_gen.py b/vistrails/db/versions/v0_9_4/domain/auto_gen.py
index 7a9a33c..6744eab 100644
--- a/vistrails/db/versions/v0_9_4/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_9_4/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_9_4/domain/id_scope.py b/vistrails/db/versions/v0_9_4/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v0_9_4/domain/id_scope.py
+++ b/vistrails/db/versions/v0_9_4/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_9_4/domain/log.py b/vistrails/db/versions/v0_9_4/domain/log.py
index 0328b80..110177a 100644
--- a/vistrails/db/versions/v0_9_4/domain/log.py
+++ b/vistrails/db/versions/v0_9_4/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_4/domain/vistrail.py b/vistrails/db/versions/v0_9_4/domain/vistrail.py
index eaac9d4..5c3e53e 100644
--- a/vistrails/db/versions/v0_9_4/domain/vistrail.py
+++ b/vistrails/db/versions/v0_9_4/domain/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstraction, DBGroup, \
diff --git a/vistrails/db/versions/v0_9_4/domain/workflow.py b/vistrails/db/versions/v0_9_4/domain/workflow.py
index af484e6..71aaef7 100644
--- a/vistrails/db/versions/v0_9_4/domain/workflow.py
+++ b/vistrails/db/versions/v0_9_4/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_4/persistence/__init__.py b/vistrails/db/versions/v0_9_4/persistence/__init__.py
index d0234ba..28f2fbe 100644
--- a/vistrails/db/versions/v0_9_4/persistence/__init__.py
+++ b/vistrails/db/versions/v0_9_4/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v0_9_4/persistence/sql/__init__.py b/vistrails/db/versions/v0_9_4/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_4/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_9_4/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_4/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_9_4/persistence/sql/auto_gen.py
index 96b999b..4d07c2a 100644
--- a/vistrails/db/versions/v0_9_4/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_9_4/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_9_4.domain import *
 
diff --git a/vistrails/db/versions/v0_9_4/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_9_4/persistence/sql/sql_dao.py
index ad01dc5..5c5afe6 100644
--- a/vistrails/db/versions/v0_9_4/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_9_4/persistence/sql/sql_dao.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 
 class SQLDAO:
@@ -56,13 +59,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -79,7 +82,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_9_4/persistence/xml/__init__.py b/vistrails/db/versions/v0_9_4/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_4/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_9_4/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_4/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_9_4/persistence/xml/auto_gen.py
index 7f93e6c..f2fc3db 100644
--- a/vistrails/db/versions/v0_9_4/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_9_4/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v0_9_4/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_9_4/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v0_9_4/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_9_4/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_9_4/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_9_4/schemas/sql/vistrails.sql
index 3cb4dc2..dae35fe 100644
--- a/vistrails/db/versions/v0_9_4/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_9_4/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_4/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_9_4/schemas/sql/vistrails_drop.sql
index 6b29819..335a2dd 100644
--- a/vistrails/db/versions/v0_9_4/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_9_4/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_4/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_9_4/schemas/xml/vistrail.xsd
index 42ceda0..666ddb9 100644
--- a/vistrails/db/versions/v0_9_4/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_9_4/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_4/specs/all.xml b/vistrails/db/versions/v0_9_4/specs/all.xml
index c1863b0..cf4fb33 100644
--- a/vistrails/db/versions/v0_9_4/specs/all.xml
+++ b/vistrails/db/versions/v0_9_4/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_4/translate/__init__.py b/vistrails/db/versions/v0_9_4/translate/__init__.py
index 5cf1ec6..eb00579 100644
--- a/vistrails/db/versions/v0_9_4/translate/__init__.py
+++ b/vistrails/db/versions/v0_9_4/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.4'
diff --git a/vistrails/db/versions/v0_9_4/translate/v0_9_3.py b/vistrails/db/versions/v0_9_4/translate/v0_9_3.py
index 8bde2da..3972e30 100644
--- a/vistrails/db/versions/v0_9_4/translate/v0_9_3.py
+++ b/vistrails/db/versions/v0_9_4/translate/v0_9_3.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_9_4.domain import DBVistrail, DBAction, DBTag, DBModule, \
     DBConnection, DBPortSpec, DBFunction, DBParameter, DBLocation, DBAdd, \
diff --git a/vistrails/db/versions/v0_9_4/translate/v0_9_5.py b/vistrails/db/versions/v0_9_4/translate/v0_9_5.py
index 46837d4..219996c 100644
--- a/vistrails/db/versions/v0_9_4/translate/v0_9_5.py
+++ b/vistrails/db/versions/v0_9_4/translate/v0_9_5.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.core import debug
 from vistrails.db.versions.v0_9_4.domain import DBVistrail, DBWorkflow, DBLog, DBGroup, DBModuleExec
diff --git a/vistrails/db/versions/v0_9_5/__init__.py b/vistrails/db/versions/v0_9_5/__init__.py
index 89c7f9a..5a3be75 100644
--- a/vistrails/db/versions/v0_9_5/__init__.py
+++ b/vistrails/db/versions/v0_9_5/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.5'
diff --git a/vistrails/db/versions/v0_9_5/domain/__init__.py b/vistrails/db/versions/v0_9_5/domain/__init__.py
index a8208f6..40b3fbf 100644
--- a/vistrails/db/versions/v0_9_5/domain/__init__.py
+++ b/vistrails/db/versions/v0_9_5/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from registry import DBRegistry
 from workflow import DBWorkflow
diff --git a/vistrails/db/versions/v0_9_5/domain/auto_gen.py b/vistrails/db/versions/v0_9_5/domain/auto_gen.py
index c78266f..19e0f73 100644
--- a/vistrails/db/versions/v0_9_5/domain/auto_gen.py
+++ b/vistrails/db/versions/v0_9_5/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBPortSpec(object):
diff --git a/vistrails/db/versions/v0_9_5/domain/id_scope.py b/vistrails/db/versions/v0_9_5/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v0_9_5/domain/id_scope.py
+++ b/vistrails/db/versions/v0_9_5/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v0_9_5/domain/log.py b/vistrails/db/versions/v0_9_5/domain/log.py
index 0328b80..110177a 100644
--- a/vistrails/db/versions/v0_9_5/domain/log.py
+++ b/vistrails/db/versions/v0_9_5/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_5/domain/registry.py b/vistrails/db/versions/v0_9_5/domain/registry.py
index 70e47ab..cfcb751 100644
--- a/vistrails/db/versions/v0_9_5/domain/registry.py
+++ b/vistrails/db/versions/v0_9_5/domain/registry.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBRegistry as _DBRegistry, DBPackage, DBModuleDescriptor, \
     DBPortSpec
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_5/domain/vistrail.py b/vistrails/db/versions/v0_9_5/domain/vistrail.py
index a007a32..b9a55b8 100644
--- a/vistrails/db/versions/v0_9_5/domain/vistrail.py
+++ b/vistrails/db/versions/v0_9_5/domain/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstraction, DBGroup, \
diff --git a/vistrails/db/versions/v0_9_5/domain/workflow.py b/vistrails/db/versions/v0_9_5/domain/workflow.py
index af484e6..71aaef7 100644
--- a/vistrails/db/versions/v0_9_5/domain/workflow.py
+++ b/vistrails/db/versions/v0_9_5/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v0_9_5/persistence/__init__.py b/vistrails/db/versions/v0_9_5/persistence/__init__.py
index d005047..616afb7 100644
--- a/vistrails/db/versions/v0_9_5/persistence/__init__.py
+++ b/vistrails/db/versions/v0_9_5/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v0_9_5/persistence/sql/__init__.py b/vistrails/db/versions/v0_9_5/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_5/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v0_9_5/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_5/persistence/sql/auto_gen.py b/vistrails/db/versions/v0_9_5/persistence/sql/auto_gen.py
index 4fec1b4..b2608c0 100644
--- a/vistrails/db/versions/v0_9_5/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v0_9_5/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v0_9_5.domain import *
 
diff --git a/vistrails/db/versions/v0_9_5/persistence/sql/sql_dao.py b/vistrails/db/versions/v0_9_5/persistence/sql/sql_dao.py
index ad01dc5..5c5afe6 100644
--- a/vistrails/db/versions/v0_9_5/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v0_9_5/persistence/sql/sql_dao.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 
 class SQLDAO:
@@ -56,13 +59,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -79,7 +82,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v0_9_5/persistence/xml/__init__.py b/vistrails/db/versions/v0_9_5/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v0_9_5/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v0_9_5/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v0_9_5/persistence/xml/auto_gen.py b/vistrails/db/versions/v0_9_5/persistence/xml/auto_gen.py
index 016e5fa..ae4b115 100644
--- a/vistrails/db/versions/v0_9_5/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v0_9_5/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v0_9_5/persistence/xml/xml_dao.py b/vistrails/db/versions/v0_9_5/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v0_9_5/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v0_9_5/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v0_9_5/schemas/sql/vistrails.sql b/vistrails/db/versions/v0_9_5/schemas/sql/vistrails.sql
index 2019bdc..ec35aab 100644
--- a/vistrails/db/versions/v0_9_5/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v0_9_5/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_5/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v0_9_5/schemas/sql/vistrails_drop.sql
index 558226e..b8f8924 100644
--- a/vistrails/db/versions/v0_9_5/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v0_9_5/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v0_9_5/schemas/xml/vistrail.xsd b/vistrails/db/versions/v0_9_5/schemas/xml/vistrail.xsd
index 51f02b3..90559d7 100644
--- a/vistrails/db/versions/v0_9_5/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v0_9_5/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_5/specs/all.xml b/vistrails/db/versions/v0_9_5/specs/all.xml
index d7b5e5a..7a658c0 100644
--- a/vistrails/db/versions/v0_9_5/specs/all.xml
+++ b/vistrails/db/versions/v0_9_5/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v0_9_5/translate/__init__.py b/vistrails/db/versions/v0_9_5/translate/__init__.py
index 89c7f9a..5a3be75 100644
--- a/vistrails/db/versions/v0_9_5/translate/__init__.py
+++ b/vistrails/db/versions/v0_9_5/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '0.9.5'
diff --git a/vistrails/db/versions/v0_9_5/translate/v0_9_4.py b/vistrails/db/versions/v0_9_5/translate/v0_9_4.py
index 0ed2be6..fda1b43 100644
--- a/vistrails/db/versions/v0_9_5/translate/v0_9_4.py
+++ b/vistrails/db/versions/v0_9_5/translate/v0_9_4.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v0_9_5.domain import DBVistrail, DBWorkflow, DBLog, \
     DBRegistry, DBModuleExec
diff --git a/vistrails/db/versions/v0_9_5/translate/v1_0_0.py b/vistrails/db/versions/v0_9_5/translate/v1_0_0.py
index fe40509..4976f21 100644
--- a/vistrails/db/versions/v0_9_5/translate/v1_0_0.py
+++ b/vistrails/db/versions/v0_9_5/translate/v1_0_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.core import debug
 
diff --git a/vistrails/db/versions/v1_0_0/__init__.py b/vistrails/db/versions/v1_0_0/__init__.py
index 85cbe3f..65a07bd 100644
--- a/vistrails/db/versions/v1_0_0/__init__.py
+++ b/vistrails/db/versions/v1_0_0/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.0'
diff --git a/vistrails/db/versions/v1_0_0/domain/__init__.py b/vistrails/db/versions/v1_0_0/domain/__init__.py
index a8208f6..40b3fbf 100644
--- a/vistrails/db/versions/v1_0_0/domain/__init__.py
+++ b/vistrails/db/versions/v1_0_0/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from registry import DBRegistry
 from workflow import DBWorkflow
diff --git a/vistrails/db/versions/v1_0_0/domain/auto_gen.py b/vistrails/db/versions/v1_0_0/domain/auto_gen.py
index c2aa908..b72e0fe 100644
--- a/vistrails/db/versions/v1_0_0/domain/auto_gen.py
+++ b/vistrails/db/versions/v1_0_0/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBOpmProcessIdEffect(object):
diff --git a/vistrails/db/versions/v1_0_0/domain/id_scope.py b/vistrails/db/versions/v1_0_0/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v1_0_0/domain/id_scope.py
+++ b/vistrails/db/versions/v1_0_0/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v1_0_0/domain/log.py b/vistrails/db/versions/v1_0_0/domain/log.py
index eedf100..cb6af60 100644
--- a/vistrails/db/versions/v1_0_0/domain/log.py
+++ b/vistrails/db/versions/v1_0_0/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstraction, DBModule, DBGroup, DBLoopExec, \
     DBGroupExec, DBModuleExec
diff --git a/vistrails/db/versions/v1_0_0/domain/registry.py b/vistrails/db/versions/v1_0_0/domain/registry.py
index 323ebbd..677b3d1 100644
--- a/vistrails/db/versions/v1_0_0/domain/registry.py
+++ b/vistrails/db/versions/v1_0_0/domain/registry.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBRegistry as _DBRegistry, DBPackage, DBModuleDescriptor, \
     DBPortSpec
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_0/domain/vistrail.py b/vistrails/db/versions/v1_0_0/domain/vistrail.py
index 8c4177e..aa3f83f 100644
--- a/vistrails/db/versions/v1_0_0/domain/vistrail.py
+++ b/vistrails/db/versions/v1_0_0/domain/vistrail.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from auto_gen import DBVistrail as _DBVistrail
 from auto_gen import DBAdd, DBChange, DBDelete, DBAbstraction, DBGroup, \
diff --git a/vistrails/db/versions/v1_0_0/domain/workflow.py b/vistrails/db/versions/v1_0_0/domain/workflow.py
index af484e6..71aaef7 100644
--- a/vistrails/db/versions/v1_0_0/domain/workflow.py
+++ b/vistrails/db/versions/v1_0_0/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_0/persistence/__init__.py b/vistrails/db/versions/v1_0_0/persistence/__init__.py
index 1144a31..c13e1fc 100644
--- a/vistrails/db/versions/v1_0_0/persistence/__init__.py
+++ b/vistrails/db/versions/v1_0_0/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v1_0_0/persistence/sql/__init__.py b/vistrails/db/versions/v1_0_0/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_0/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v1_0_0/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_0/persistence/sql/auto_gen.py b/vistrails/db/versions/v1_0_0/persistence/sql/auto_gen.py
index 34e919c..49c45e3 100644
--- a/vistrails/db/versions/v1_0_0/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v1_0_0/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v1_0_0.domain import *
 
diff --git a/vistrails/db/versions/v1_0_0/persistence/sql/sql_dao.py b/vistrails/db/versions/v1_0_0/persistence/sql/sql_dao.py
index ad01dc5..5c5afe6 100644
--- a/vistrails/db/versions/v1_0_0/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v1_0_0/persistence/sql/sql_dao.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 
 class SQLDAO:
@@ -56,13 +59,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -79,7 +82,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v1_0_0/persistence/xml/__init__.py b/vistrails/db/versions/v1_0_0/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_0/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v1_0_0/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_0/persistence/xml/auto_gen.py b/vistrails/db/versions/v1_0_0/persistence/xml/auto_gen.py
index d7fbe3c..193e024 100644
--- a/vistrails/db/versions/v1_0_0/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v1_0_0/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v1_0_0/persistence/xml/xml_dao.py b/vistrails/db/versions/v1_0_0/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v1_0_0/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v1_0_0/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v1_0_0/schemas/sql/vistrails.sql b/vistrails/db/versions/v1_0_0/schemas/sql/vistrails.sql
index b3f5adb..91f23c2 100644
--- a/vistrails/db/versions/v1_0_0/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v1_0_0/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v1_0_0/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v1_0_0/schemas/sql/vistrails_drop.sql
index 0a71def..53415d1 100644
--- a/vistrails/db/versions/v1_0_0/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v1_0_0/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v1_0_0/schemas/xml/vistrail.xsd b/vistrails/db/versions/v1_0_0/schemas/xml/vistrail.xsd
index 51f02b3..90559d7 100644
--- a/vistrails/db/versions/v1_0_0/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v1_0_0/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_0/specs/all.xml b/vistrails/db/versions/v1_0_0/specs/all.xml
index d9560c3..887fcd5 100644
--- a/vistrails/db/versions/v1_0_0/specs/all.xml
+++ b/vistrails/db/versions/v1_0_0/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_0/translate/__init__.py b/vistrails/db/versions/v1_0_0/translate/__init__.py
index 85cbe3f..65a07bd 100644
--- a/vistrails/db/versions/v1_0_0/translate/__init__.py
+++ b/vistrails/db/versions/v1_0_0/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.0'
diff --git a/vistrails/db/versions/v1_0_0/translate/v0_9_5.py b/vistrails/db/versions/v1_0_0/translate/v0_9_5.py
index 71e3d60..9ab21b0 100644
--- a/vistrails/db/versions/v1_0_0/translate/v0_9_5.py
+++ b/vistrails/db/versions/v1_0_0/translate/v0_9_5.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v1_0_0.domain import DBVistrail, DBWorkflow, DBLog, \
     DBRegistry, DBModuleExec, DBGroupExec, DBLoopExec, DBGroup
diff --git a/vistrails/db/versions/v1_0_0/translate/v1_0_1.py b/vistrails/db/versions/v1_0_0/translate/v1_0_1.py
index ab1aa8e..1023bf5 100644
--- a/vistrails/db/versions/v1_0_0/translate/v1_0_1.py
+++ b/vistrails/db/versions/v1_0_0/translate/v1_0_1.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v1_0_0.domain import DBVistrail, DBWorkflow, DBLog, \
     DBRegistry
diff --git a/vistrails/db/versions/v1_0_1/__init__.py b/vistrails/db/versions/v1_0_1/__init__.py
index ecda317..c651811 100644
--- a/vistrails/db/versions/v1_0_1/__init__.py
+++ b/vistrails/db/versions/v1_0_1/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.1'
diff --git a/vistrails/db/versions/v1_0_1/domain/__init__.py b/vistrails/db/versions/v1_0_1/domain/__init__.py
index a8208f6..40b3fbf 100644
--- a/vistrails/db/versions/v1_0_1/domain/__init__.py
+++ b/vistrails/db/versions/v1_0_1/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from registry import DBRegistry
 from workflow import DBWorkflow
diff --git a/vistrails/db/versions/v1_0_1/domain/auto_gen.py b/vistrails/db/versions/v1_0_1/domain/auto_gen.py
index 451d158..aff557d 100644
--- a/vistrails/db/versions/v1_0_1/domain/auto_gen.py
+++ b/vistrails/db/versions/v1_0_1/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBOpmProcessIdEffect(object):
diff --git a/vistrails/db/versions/v1_0_1/domain/id_scope.py b/vistrails/db/versions/v1_0_1/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v1_0_1/domain/id_scope.py
+++ b/vistrails/db/versions/v1_0_1/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v1_0_1/domain/log.py b/vistrails/db/versions/v1_0_1/domain/log.py
index a127726..49b1497 100644
--- a/vistrails/db/versions/v1_0_1/domain/log.py
+++ b/vistrails/db/versions/v1_0_1/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstraction, DBModule, DBGroup, DBLoopExec, \
     DBGroupExec, DBModuleExec
diff --git a/vistrails/db/versions/v1_0_1/domain/registry.py b/vistrails/db/versions/v1_0_1/domain/registry.py
index 323ebbd..677b3d1 100644
--- a/vistrails/db/versions/v1_0_1/domain/registry.py
+++ b/vistrails/db/versions/v1_0_1/domain/registry.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBRegistry as _DBRegistry, DBPackage, DBModuleDescriptor, \
     DBPortSpec
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_1/domain/vistrail.py b/vistrails/db/versions/v1_0_1/domain/vistrail.py
index c76edd7..37639fd 100644
--- a/vistrails/db/versions/v1_0_1/domain/vistrail.py
+++ b/vistrails/db/versions/v1_0_1/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 import hashlib
 from auto_gen import DBVistrail as _DBVistrail
diff --git a/vistrails/db/versions/v1_0_1/domain/workflow.py b/vistrails/db/versions/v1_0_1/domain/workflow.py
index af484e6..71aaef7 100644
--- a/vistrails/db/versions/v1_0_1/domain/workflow.py
+++ b/vistrails/db/versions/v1_0_1/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_1/persistence/__init__.py b/vistrails/db/versions/v1_0_1/persistence/__init__.py
index f7c0477..f10eee9 100644
--- a/vistrails/db/versions/v1_0_1/persistence/__init__.py
+++ b/vistrails/db/versions/v1_0_1/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v1_0_1/persistence/sql/__init__.py b/vistrails/db/versions/v1_0_1/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_1/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v1_0_1/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_1/persistence/sql/auto_gen.py b/vistrails/db/versions/v1_0_1/persistence/sql/auto_gen.py
index a083843..e0ab456 100644
--- a/vistrails/db/versions/v1_0_1/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v1_0_1/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v1_0_1.domain import *
 
diff --git a/vistrails/db/versions/v1_0_1/persistence/sql/sql_dao.py b/vistrails/db/versions/v1_0_1/persistence/sql/sql_dao.py
index ad01dc5..5c5afe6 100644
--- a/vistrails/db/versions/v1_0_1/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v1_0_1/persistence/sql/sql_dao.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 
 class SQLDAO:
@@ -56,13 +59,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToDB(self, value, type, db_type):
@@ -79,7 +82,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v1_0_1/persistence/xml/__init__.py b/vistrails/db/versions/v1_0_1/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_1/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v1_0_1/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_1/persistence/xml/auto_gen.py b/vistrails/db/versions/v1_0_1/persistence/xml/auto_gen.py
index 95973ad..a765921 100644
--- a/vistrails/db/versions/v1_0_1/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v1_0_1/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v1_0_1/persistence/xml/xml_dao.py b/vistrails/db/versions/v1_0_1/persistence/xml/xml_dao.py
index 955c01a..9ad9160 100644
--- a/vistrails/db/versions/v1_0_1/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v1_0_1/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -64,9 +68,9 @@ class XMLDAO:
                 elif type == 'int':
                     return int(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -74,7 +78,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v1_0_1/schemas/sql/vistrails.sql b/vistrails/db/versions/v1_0_1/schemas/sql/vistrails.sql
index badb7af..0ff5047 100644
--- a/vistrails/db/versions/v1_0_1/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v1_0_1/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v1_0_1/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v1_0_1/schemas/sql/vistrails_drop.sql
index 47043c1..74167a6 100644
--- a/vistrails/db/versions/v1_0_1/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v1_0_1/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v1_0_1/schemas/xml/vistrail.xsd b/vistrails/db/versions/v1_0_1/schemas/xml/vistrail.xsd
index 997f9da..d397aba 100644
--- a/vistrails/db/versions/v1_0_1/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v1_0_1/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_1/schemas/xml/vtlink.xsd b/vistrails/db/versions/v1_0_1/schemas/xml/vtlink.xsd
index 6ae8bca..6291d8e 100644
--- a/vistrails/db/versions/v1_0_1/schemas/xml/vtlink.xsd
+++ b/vistrails/db/versions/v1_0_1/schemas/xml/vtlink.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_1/specs/all.xml b/vistrails/db/versions/v1_0_1/specs/all.xml
index 60a5dba..d31e57a 100644
--- a/vistrails/db/versions/v1_0_1/specs/all.xml
+++ b/vistrails/db/versions/v1_0_1/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_1/translate/__init__.py b/vistrails/db/versions/v1_0_1/translate/__init__.py
index ecda317..c651811 100644
--- a/vistrails/db/versions/v1_0_1/translate/__init__.py
+++ b/vistrails/db/versions/v1_0_1/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.1'
diff --git a/vistrails/db/versions/v1_0_1/translate/v1_0_0.py b/vistrails/db/versions/v1_0_1/translate/v1_0_0.py
index 8cc7274..c9e463f 100644
--- a/vistrails/db/versions/v1_0_1/translate/v1_0_0.py
+++ b/vistrails/db/versions/v1_0_1/translate/v1_0_0.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v1_0_1.domain import DBVistrail, DBWorkflow, DBLog, \
     DBRegistry, DBModuleDescriptor, DBGroup
diff --git a/vistrails/db/versions/v1_0_1/translate/v1_0_2.py b/vistrails/db/versions/v1_0_1/translate/v1_0_2.py
index 6f16c1c..a58a7aa 100644
--- a/vistrails/db/versions/v1_0_1/translate/v1_0_2.py
+++ b/vistrails/db/versions/v1_0_1/translate/v1_0_2.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v1_0_1.domain import DBVistrail, DBWorkflow, DBLog, \
     DBRegistry, DBGroup, DBTag, DBAnnotation, DBAction, IdScope
diff --git a/vistrails/db/versions/v1_0_2/__init__.py b/vistrails/db/versions/v1_0_2/__init__.py
index 0e024b6..c494e0b 100644
--- a/vistrails/db/versions/v1_0_2/__init__.py
+++ b/vistrails/db/versions/v1_0_2/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.2'
diff --git a/vistrails/db/versions/v1_0_2/domain/__init__.py b/vistrails/db/versions/v1_0_2/domain/__init__.py
index a8208f6..40b3fbf 100644
--- a/vistrails/db/versions/v1_0_2/domain/__init__.py
+++ b/vistrails/db/versions/v1_0_2/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from registry import DBRegistry
 from workflow import DBWorkflow
diff --git a/vistrails/db/versions/v1_0_2/domain/auto_gen.py b/vistrails/db/versions/v1_0_2/domain/auto_gen.py
index 3934e4f..90c414b 100644
--- a/vistrails/db/versions/v1_0_2/domain/auto_gen.py
+++ b/vistrails/db/versions/v1_0_2/domain/auto_gen.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
 class DBOpmProcessIdEffect(object):
diff --git a/vistrails/db/versions/v1_0_2/domain/id_scope.py b/vistrails/db/versions/v1_0_2/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v1_0_2/domain/id_scope.py
+++ b/vistrails/db/versions/v1_0_2/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v1_0_2/domain/log.py b/vistrails/db/versions/v1_0_2/domain/log.py
index a127726..49b1497 100644
--- a/vistrails/db/versions/v1_0_2/domain/log.py
+++ b/vistrails/db/versions/v1_0_2/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstraction, DBModule, DBGroup, DBLoopExec, \
     DBGroupExec, DBModuleExec
diff --git a/vistrails/db/versions/v1_0_2/domain/registry.py b/vistrails/db/versions/v1_0_2/domain/registry.py
index 323ebbd..677b3d1 100644
--- a/vistrails/db/versions/v1_0_2/domain/registry.py
+++ b/vistrails/db/versions/v1_0_2/domain/registry.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBRegistry as _DBRegistry, DBPackage, DBModuleDescriptor, \
     DBPortSpec
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_2/domain/vistrail.py b/vistrails/db/versions/v1_0_2/domain/vistrail.py
index 29962da..e8f146c 100644
--- a/vistrails/db/versions/v1_0_2/domain/vistrail.py
+++ b/vistrails/db/versions/v1_0_2/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 import hashlib
 from auto_gen import DBVistrail as _DBVistrail
diff --git a/vistrails/db/versions/v1_0_2/domain/workflow.py b/vistrails/db/versions/v1_0_2/domain/workflow.py
index af484e6..71aaef7 100644
--- a/vistrails/db/versions/v1_0_2/domain/workflow.py
+++ b/vistrails/db/versions/v1_0_2/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_2/persistence/__init__.py b/vistrails/db/versions/v1_0_2/persistence/__init__.py
index d992cd3..3216552 100644
--- a/vistrails/db/versions/v1_0_2/persistence/__init__.py
+++ b/vistrails/db/versions/v1_0_2/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v1_0_2/persistence/sql/__init__.py b/vistrails/db/versions/v1_0_2/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_2/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v1_0_2/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_2/persistence/sql/auto_gen.py b/vistrails/db/versions/v1_0_2/persistence/sql/auto_gen.py
index 95ec735..8bc1684 100644
--- a/vistrails/db/versions/v1_0_2/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v1_0_2/persistence/sql/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v1_0_2.domain import *
 
diff --git a/vistrails/db/versions/v1_0_2/persistence/sql/sql_dao.py b/vistrails/db/versions/v1_0_2/persistence/sql/sql_dao.py
index eab1acc..9eb069d 100644
--- a/vistrails/db/versions/v1_0_2/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v1_0_2/persistence/sql/sql_dao.py
@@ -1,44 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core import debug
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 from vistrails.db.services.io import get_db_lib
-from vistrails.core import debug
 
 class SQLDAO:
     def __init__(self):
@@ -58,13 +61,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertWarning(self, before, after, _from, to):
@@ -121,7 +124,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v1_0_2/persistence/xml/__init__.py b/vistrails/db/versions/v1_0_2/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_2/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v1_0_2/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_2/persistence/xml/auto_gen.py b/vistrails/db/versions/v1_0_2/persistence/xml/auto_gen.py
index d17b767..5026a6d 100644
--- a/vistrails/db/versions/v1_0_2/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v1_0_2/persistence/xml/auto_gen.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 
 from xml_dao import XMLDAO
diff --git a/vistrails/db/versions/v1_0_2/persistence/xml/xml_dao.py b/vistrails/db/versions/v1_0_2/persistence/xml/xml_dao.py
index c7a78ca..4194b76 100644
--- a/vistrails/db/versions/v1_0_2/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v1_0_2/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -70,9 +74,9 @@ class XMLDAO:
                         else:
                             return 0
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                   return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                   return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -80,7 +84,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v1_0_2/schemas/sql/vistrails.sql b/vistrails/db/versions/v1_0_2/schemas/sql/vistrails.sql
index a6e8e43..6da537c 100644
--- a/vistrails/db/versions/v1_0_2/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v1_0_2/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v1_0_2/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v1_0_2/schemas/sql/vistrails_drop.sql
index 42c5b42..fa4ef90 100644
--- a/vistrails/db/versions/v1_0_2/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v1_0_2/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/db/versions/v1_0_2/schemas/xml/log.xsd b/vistrails/db/versions/v1_0_2/schemas/xml/log.xsd
index 2f6a6af..e7e4a7a 100644
--- a/vistrails/db/versions/v1_0_2/schemas/xml/log.xsd
+++ b/vistrails/db/versions/v1_0_2/schemas/xml/log.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_2/schemas/xml/vistrail.xsd b/vistrails/db/versions/v1_0_2/schemas/xml/vistrail.xsd
index 5174ac7..5a8974c 100644
--- a/vistrails/db/versions/v1_0_2/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v1_0_2/schemas/xml/vistrail.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_2/schemas/xml/vtlink.xsd b/vistrails/db/versions/v1_0_2/schemas/xml/vtlink.xsd
index 011b59c..3453317 100644
--- a/vistrails/db/versions/v1_0_2/schemas/xml/vtlink.xsd
+++ b/vistrails/db/versions/v1_0_2/schemas/xml/vtlink.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_2/schemas/xml/workflow.xsd b/vistrails/db/versions/v1_0_2/schemas/xml/workflow.xsd
index 9f7fbda..6566e5e 100644
--- a/vistrails/db/versions/v1_0_2/schemas/xml/workflow.xsd
+++ b/vistrails/db/versions/v1_0_2/schemas/xml/workflow.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_2/specs/all.xml b/vistrails/db/versions/v1_0_2/specs/all.xml
index 6fba3a2..d275765 100644
--- a/vistrails/db/versions/v1_0_2/specs/all.xml
+++ b/vistrails/db/versions/v1_0_2/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_2/translate/__init__.py b/vistrails/db/versions/v1_0_2/translate/__init__.py
index 0e024b6..c494e0b 100644
--- a/vistrails/db/versions/v1_0_2/translate/__init__.py
+++ b/vistrails/db/versions/v1_0_2/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.2'
diff --git a/vistrails/db/versions/v1_0_2/translate/v1_0_1.py b/vistrails/db/versions/v1_0_2/translate/v1_0_1.py
index 375c11f..e8ba462 100644
--- a/vistrails/db/versions/v1_0_2/translate/v1_0_1.py
+++ b/vistrails/db/versions/v1_0_2/translate/v1_0_1.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import copy
 from vistrails.db.versions.v1_0_2.domain import DBVistrail, DBWorkflow, DBLog, \
     DBRegistry, DBGroup, DBActionAnnotation, DBAnnotation, DBAction, IdScope
diff --git a/vistrails/db/versions/v1_0_2/translate/v1_0_3.py b/vistrails/db/versions/v1_0_2/translate/v1_0_3.py
index d4d7a8c..11eacac 100644
--- a/vistrails/db/versions/v1_0_2/translate/v1_0_3.py
+++ b/vistrails/db/versions/v1_0_2/translate/v1_0_3.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v1_0_2.domain import DBVistrail, DBAnnotation, \
                                       DBWorkflow, DBLog, DBRegistry, \
                                       DBPortSpec, DBAdd, DBChange, DBDelete
@@ -200,7 +203,7 @@ class TestTranslate(unittest.TestCase):
 
 if __name__ == '__main__':
     from vistrails.gui.application import start_application
-    v = start_application({'interactiveMode': False,
+    v = start_application({'batch': True,
                            'nologger': True,
                            'singleInstance': False,
                            'fixedSpreadsheetCells': True})
diff --git a/vistrails/db/versions/v1_0_3/__init__.py b/vistrails/db/versions/v1_0_3/__init__.py
index aee1abc..fe71b86 100644
--- a/vistrails/db/versions/v1_0_3/__init__.py
+++ b/vistrails/db/versions/v1_0_3/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.3'
diff --git a/vistrails/db/versions/v1_0_3/domain/__init__.py b/vistrails/db/versions/v1_0_3/domain/__init__.py
index a8208f6..40b3fbf 100644
--- a/vistrails/db/versions/v1_0_3/domain/__init__.py
+++ b/vistrails/db/versions/v1_0_3/domain/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import *
 from registry import DBRegistry
 from workflow import DBWorkflow
diff --git a/vistrails/db/versions/v1_0_3/domain/auto_gen.py b/vistrails/db/versions/v1_0_3/domain/auto_gen.py
index 57be93c..06bce0b 100644
--- a/vistrails/db/versions/v1_0_3/domain/auto_gen.py
+++ b/vistrails/db/versions/v1_0_3/domain/auto_gen.py
@@ -1,56 +1,88 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 import copy
 
-class DBOpmProcessIdEffect(object):
+class DBOpmWasGeneratedBy(object):
 
-    vtType = 'opm_process_id_effect'
+    vtType = 'opm_was_generated_by'
 
-    def __init__(self, id=None):
-        self._db_id = id
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmProcessIdEffect.do_copy(self)
+        return DBOpmWasGeneratedBy.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmProcessIdEffect(id=self._db_id)
+        cp = DBOpmWasGeneratedBy()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
         
         # set new ids
         if new_ids:
@@ -60,8 +92,6 @@ class DBOpmProcessIdEffect(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('opm_process', self._db_id) in id_remap:
-                cp._db_id = id_remap[('opm_process', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -72,67 +102,231 @@ class DBOpmProcessIdEffect(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmProcessIdEffect()
+            new_obj = DBOpmWasGeneratedBy()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmArtifactIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmArtifactIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmProcessIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmProcessIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
+        self.is_dirty = True
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
     
 
 
-class DBVistrailVariable(object):
+class DBConfigKey(object):
 
-    vtType = 'vistrailVariable'
+    vtType = 'config_key'
 
-    def __init__(self, name=None, uuid=None, package=None, module=None, namespace=None, value=None):
+    def __init__(self, value=None, name=None):
+        self.db_deleted_value = []
+        self._db_value = value
         self._db_name = name
-        self._db_uuid = uuid
-        self._db_package = package
-        self._db_module = module
-        self._db_namespace = namespace
-        self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBVistrailVariable.do_copy(self)
+        return DBConfigKey.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBVistrailVariable(name=self._db_name,
-                                uuid=self._db_uuid,
-                                package=self._db_package,
-                                module=self._db_module,
-                                namespace=self._db_namespace,
-                                value=self._db_value)
+        cp = DBConfigKey(name=self._db_name)
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -152,118 +346,71 @@ class DBVistrailVariable(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBVistrailVariable()
+            new_obj = DBConfigKey()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            if obj.vtType == 'config_str':
+                new_obj.db_add_value(DBConfigStr.update_version(obj, trans_dict))
+            elif obj.vtType == 'config_int':
+                new_obj.db_add_value(DBConfigInt.update_version(obj, trans_dict))
+            elif obj.vtType == 'config_float':
+                new_obj.db_add_value(DBConfigFloat.update_version(obj, trans_dict))
+            elif obj.vtType == 'config_bool':
+                new_obj.db_add_value(DBConfigBool.update_version(obj, trans_dict))
+            elif obj.vtType == 'configuration':
+                new_obj.db_add_value(DBConfiguration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                if obj.vtType == 'config_str':
+                    n_obj = DBConfigStr.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'config_int':
+                    n_obj = DBConfigInt.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'config_float':
+                    n_obj = DBConfigFloat.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'config_bool':
+                    n_obj = DBConfigBool.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'configuration':
+                    n_obj = DBConfiguration.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'uuid' in class_dict:
-            res = class_dict['uuid'](old_obj, trans_dict)
-            new_obj.db_uuid = res
-        elif hasattr(old_obj, 'db_uuid') and old_obj.db_uuid is not None:
-            new_obj.db_uuid = old_obj.db_uuid
-        if 'package' in class_dict:
-            res = class_dict['package'](old_obj, trans_dict)
-            new_obj.db_package = res
-        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
-            new_obj.db_package = old_obj.db_package
-        if 'module' in class_dict:
-            res = class_dict['module'](old_obj, trans_dict)
-            new_obj.db_module = res
-        elif hasattr(old_obj, 'db_module') and old_obj.db_module is not None:
-            new_obj.db_module = old_obj.db_module
-        if 'namespace' in class_dict:
-            res = class_dict['namespace'](old_obj, trans_dict)
-            new_obj.db_namespace = res
-        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
-            new_obj.db_namespace = old_obj.db_namespace
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            new_obj.db_value = old_obj.db_value
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_value)
+        if remove:
+            self.db_deleted_value = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
         return False
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_uuid(self):
-        return self._db_uuid
-    def __set_db_uuid(self, uuid):
-        self._db_uuid = uuid
-        self.is_dirty = True
-    db_uuid = property(__get_db_uuid, __set_db_uuid)
-    def db_add_uuid(self, uuid):
-        self._db_uuid = uuid
-    def db_change_uuid(self, uuid):
-        self._db_uuid = uuid
-    def db_delete_uuid(self, uuid):
-        self._db_uuid = None
-    
-    def __get_db_package(self):
-        return self._db_package
-    def __set_db_package(self, package):
-        self._db_package = package
-        self.is_dirty = True
-    db_package = property(__get_db_package, __set_db_package)
-    def db_add_package(self, package):
-        self._db_package = package
-    def db_change_package(self, package):
-        self._db_package = package
-    def db_delete_package(self, package):
-        self._db_package = None
-    
-    def __get_db_module(self):
-        return self._db_module
-    def __set_db_module(self, module):
-        self._db_module = module
-        self.is_dirty = True
-    db_module = property(__get_db_module, __set_db_module)
-    def db_add_module(self, module):
-        self._db_module = module
-    def db_change_module(self, module):
-        self._db_module = module
-    def db_delete_module(self, module):
-        self._db_module = None
-    
-    def __get_db_namespace(self):
-        return self._db_namespace
-    def __set_db_namespace(self, namespace):
-        self._db_namespace = namespace
-        self.is_dirty = True
-    db_namespace = property(__get_db_namespace, __set_db_namespace)
-    def db_add_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_change_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_delete_namespace(self, namespace):
-        self._db_namespace = None
-    
     def __get_db_value(self):
         return self._db_value
     def __set_db_value(self, value):
@@ -275,39 +422,45 @@ class DBVistrailVariable(object):
     def db_change_value(self, value):
         self._db_value = value
     def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
         self._db_value = None
     
-    def getPrimaryKey(self):
+    def __get_db_name(self):
         return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
 
-class DBProvAgent(object):
 
-    vtType = 'prov_agent'
+class DBMashupAlias(object):
 
-    def __init__(self, id=None, vt_id=None, prov_type=None, prov_label=None, vt_machine_os=None, vt_machine_architecture=None, vt_machine_processor=None, vt_machine_ram=None):
+    vtType = 'mashup_alias'
+
+    def __init__(self, id=None, name=None, component=None):
         self._db_id = id
-        self._db_vt_id = vt_id
-        self._db_prov_type = prov_type
-        self._db_prov_label = prov_label
-        self._db_vt_machine_os = vt_machine_os
-        self._db_vt_machine_architecture = vt_machine_architecture
-        self._db_vt_machine_processor = vt_machine_processor
-        self._db_vt_machine_ram = vt_machine_ram
+        self._db_name = name
+        self.db_deleted_component = []
+        self._db_component = component
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBProvAgent.do_copy(self)
+        return DBMashupAlias.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBProvAgent(id=self._db_id,
-                         vt_id=self._db_vt_id,
-                         prov_type=self._db_prov_type,
-                         prov_label=self._db_prov_label,
-                         vt_machine_os=self._db_vt_machine_os,
-                         vt_machine_architecture=self._db_vt_machine_architecture,
-                         vt_machine_processor=self._db_vt_machine_processor,
-                         vt_machine_ram=self._db_vt_machine_ram)
+        cp = DBMashupAlias(id=self._db_id,
+                           name=self._db_name)
+        if self._db_component is not None:
+            cp._db_component = self._db_component.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -327,7 +480,7 @@ class DBProvAgent(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBProvAgent()
+            new_obj = DBMashupAlias()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -336,53 +489,44 @@ class DBProvAgent(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'vt_id' in class_dict:
-            res = class_dict['vt_id'](old_obj, trans_dict)
-            new_obj.db_vt_id = res
-        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
-            new_obj.db_vt_id = old_obj.db_vt_id
-        if 'prov_type' in class_dict:
-            res = class_dict['prov_type'](old_obj, trans_dict)
-            new_obj.db_prov_type = res
-        elif hasattr(old_obj, 'db_prov_type') and old_obj.db_prov_type is not None:
-            new_obj.db_prov_type = old_obj.db_prov_type
-        if 'prov_label' in class_dict:
-            res = class_dict['prov_label'](old_obj, trans_dict)
-            new_obj.db_prov_label = res
-        elif hasattr(old_obj, 'db_prov_label') and old_obj.db_prov_label is not None:
-            new_obj.db_prov_label = old_obj.db_prov_label
-        if 'vt_machine_os' in class_dict:
-            res = class_dict['vt_machine_os'](old_obj, trans_dict)
-            new_obj.db_vt_machine_os = res
-        elif hasattr(old_obj, 'db_vt_machine_os') and old_obj.db_vt_machine_os is not None:
-            new_obj.db_vt_machine_os = old_obj.db_vt_machine_os
-        if 'vt_machine_architecture' in class_dict:
-            res = class_dict['vt_machine_architecture'](old_obj, trans_dict)
-            new_obj.db_vt_machine_architecture = res
-        elif hasattr(old_obj, 'db_vt_machine_architecture') and old_obj.db_vt_machine_architecture is not None:
-            new_obj.db_vt_machine_architecture = old_obj.db_vt_machine_architecture
-        if 'vt_machine_processor' in class_dict:
-            res = class_dict['vt_machine_processor'](old_obj, trans_dict)
-            new_obj.db_vt_machine_processor = res
-        elif hasattr(old_obj, 'db_vt_machine_processor') and old_obj.db_vt_machine_processor is not None:
-            new_obj.db_vt_machine_processor = old_obj.db_vt_machine_processor
-        if 'vt_machine_ram' in class_dict:
-            res = class_dict['vt_machine_ram'](old_obj, trans_dict)
-            new_obj.db_vt_machine_ram = res
-        elif hasattr(old_obj, 'db_vt_machine_ram') and old_obj.db_vt_machine_ram is not None:
-            new_obj.db_vt_machine_ram = old_obj.db_vt_machine_ram
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'component' in class_dict:
+            res = class_dict['component'](old_obj, trans_dict)
+            new_obj.db_component = res
+        elif hasattr(old_obj, 'db_component') and old_obj.db_component is not None:
+            obj = old_obj.db_component
+            new_obj.db_add_component(DBMashupComponent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_component') and hasattr(new_obj, 'db_deleted_component'):
+            for obj in old_obj.db_deleted_component:
+                n_obj = DBMashupComponent.update_version(obj, trans_dict)
+                new_obj.db_deleted_component.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if self._db_component is not None:
+            children.extend(self._db_component.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_component = None
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_component)
+        if remove:
+            self.db_deleted_component = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_component is not None and self._db_component.has_changes():
+            return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -397,143 +541,95 @@ class DBProvAgent(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_vt_id(self):
-        return self._db_vt_id
-    def __set_db_vt_id(self, vt_id):
-        self._db_vt_id = vt_id
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
-    def db_add_vt_id(self, vt_id):
-        self._db_vt_id = vt_id
-    def db_change_vt_id(self, vt_id):
-        self._db_vt_id = vt_id
-    def db_delete_vt_id(self, vt_id):
-        self._db_vt_id = None
-    
-    def __get_db_prov_type(self):
-        return self._db_prov_type
-    def __set_db_prov_type(self, prov_type):
-        self._db_prov_type = prov_type
-        self.is_dirty = True
-    db_prov_type = property(__get_db_prov_type, __set_db_prov_type)
-    def db_add_prov_type(self, prov_type):
-        self._db_prov_type = prov_type
-    def db_change_prov_type(self, prov_type):
-        self._db_prov_type = prov_type
-    def db_delete_prov_type(self, prov_type):
-        self._db_prov_type = None
-    
-    def __get_db_prov_label(self):
-        return self._db_prov_label
-    def __set_db_prov_label(self, prov_label):
-        self._db_prov_label = prov_label
-        self.is_dirty = True
-    db_prov_label = property(__get_db_prov_label, __set_db_prov_label)
-    def db_add_prov_label(self, prov_label):
-        self._db_prov_label = prov_label
-    def db_change_prov_label(self, prov_label):
-        self._db_prov_label = prov_label
-    def db_delete_prov_label(self, prov_label):
-        self._db_prov_label = None
-    
-    def __get_db_vt_machine_os(self):
-        return self._db_vt_machine_os
-    def __set_db_vt_machine_os(self, vt_machine_os):
-        self._db_vt_machine_os = vt_machine_os
-        self.is_dirty = True
-    db_vt_machine_os = property(__get_db_vt_machine_os, __set_db_vt_machine_os)
-    def db_add_vt_machine_os(self, vt_machine_os):
-        self._db_vt_machine_os = vt_machine_os
-    def db_change_vt_machine_os(self, vt_machine_os):
-        self._db_vt_machine_os = vt_machine_os
-    def db_delete_vt_machine_os(self, vt_machine_os):
-        self._db_vt_machine_os = None
-    
-    def __get_db_vt_machine_architecture(self):
-        return self._db_vt_machine_architecture
-    def __set_db_vt_machine_architecture(self, vt_machine_architecture):
-        self._db_vt_machine_architecture = vt_machine_architecture
-        self.is_dirty = True
-    db_vt_machine_architecture = property(__get_db_vt_machine_architecture, __set_db_vt_machine_architecture)
-    def db_add_vt_machine_architecture(self, vt_machine_architecture):
-        self._db_vt_machine_architecture = vt_machine_architecture
-    def db_change_vt_machine_architecture(self, vt_machine_architecture):
-        self._db_vt_machine_architecture = vt_machine_architecture
-    def db_delete_vt_machine_architecture(self, vt_machine_architecture):
-        self._db_vt_machine_architecture = None
-    
-    def __get_db_vt_machine_processor(self):
-        return self._db_vt_machine_processor
-    def __set_db_vt_machine_processor(self, vt_machine_processor):
-        self._db_vt_machine_processor = vt_machine_processor
-        self.is_dirty = True
-    db_vt_machine_processor = property(__get_db_vt_machine_processor, __set_db_vt_machine_processor)
-    def db_add_vt_machine_processor(self, vt_machine_processor):
-        self._db_vt_machine_processor = vt_machine_processor
-    def db_change_vt_machine_processor(self, vt_machine_processor):
-        self._db_vt_machine_processor = vt_machine_processor
-    def db_delete_vt_machine_processor(self, vt_machine_processor):
-        self._db_vt_machine_processor = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
-    def __get_db_vt_machine_ram(self):
-        return self._db_vt_machine_ram
-    def __set_db_vt_machine_ram(self, vt_machine_ram):
-        self._db_vt_machine_ram = vt_machine_ram
+    def __get_db_component(self):
+        return self._db_component
+    def __set_db_component(self, component):
+        self._db_component = component
         self.is_dirty = True
-    db_vt_machine_ram = property(__get_db_vt_machine_ram, __set_db_vt_machine_ram)
-    def db_add_vt_machine_ram(self, vt_machine_ram):
-        self._db_vt_machine_ram = vt_machine_ram
-    def db_change_vt_machine_ram(self, vt_machine_ram):
-        self._db_vt_machine_ram = vt_machine_ram
-    def db_delete_vt_machine_ram(self, vt_machine_ram):
-        self._db_vt_machine_ram = None
+    db_component = property(__get_db_component, __set_db_component)
+    def db_add_component(self, component):
+        self._db_component = component
+    def db_change_component(self, component):
+        self._db_component = component
+    def db_delete_component(self, component):
+        if not self.is_new:
+            self.db_deleted_component.append(self._db_component)
+        self._db_component = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmWasGeneratedBy(object):
+class DBGroup(object):
 
-    vtType = 'opm_was_generated_by'
+    vtType = 'group'
 
-    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
-        self.db_deleted_effect = []
-        self._db_effect = effect
-        self.db_deleted_role = []
-        self._db_role = role
-        self.db_deleted_cause = []
-        self._db_cause = cause
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
+    def __init__(self, id=None, workflow=None, cache=None, name=None, namespace=None, package=None, version=None, location=None, functions=None, annotations=None):
+        self._db_id = id
+        self.db_deleted_workflow = []
+        self._db_workflow = workflow
+        self._db_cache = cache
+        self._db_name = name
+        self._db_namespace = namespace
+        self._db_package = package
+        self._db_version = version
+        self.db_deleted_location = []
+        self._db_location = location
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
         else:
-            self._db_accounts = accounts
-        self.db_deleted_opm_times = []
-        if opm_times is None:
-            self._db_opm_times = []
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
         else:
-            self._db_opm_times = opm_times
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmWasGeneratedBy.do_copy(self)
+        return DBGroup.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmWasGeneratedBy()
-        if self._db_effect is not None:
-            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
-        if self._db_role is not None:
-            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
-        if self._db_cause is not None:
-            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
+        cp = DBGroup(id=self._db_id,
+                     cache=self._db_cache,
+                     name=self._db_name,
+                     namespace=self._db_namespace,
+                     package=self._db_package,
+                     version=self._db_version)
+        if self._db_workflow is not None:
+            cp._db_workflow = self._db_workflow.do_copy()
+        if self._db_location is not None:
+            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
+        if self._db_functions is None:
+            cp._db_functions = []
         else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        if self._db_opm_times is None:
-            cp._db_opm_times = []
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
         else:
-            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
         
         # set new ids
         if new_ids:
@@ -545,6 +641,9 @@ class DBOpmWasGeneratedBy(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -553,247 +652,388 @@ class DBOpmWasGeneratedBy(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmWasGeneratedBy()
+            new_obj = DBGroup()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'effect' in class_dict:
-            res = class_dict['effect'](old_obj, trans_dict)
-            new_obj.db_effect = res
-        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
-            obj = old_obj.db_effect
-            new_obj.db_add_effect(DBOpmArtifactIdEffect.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
-            for obj in old_obj.db_deleted_effect:
-                n_obj = DBOpmArtifactIdEffect.update_version(obj, trans_dict)
-                new_obj.db_deleted_effect.append(n_obj)
-        if 'role' in class_dict:
-            res = class_dict['role'](old_obj, trans_dict)
-            new_obj.db_role = res
-        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
-            obj = old_obj.db_role
-            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
-            for obj in old_obj.db_deleted_role:
-                n_obj = DBOpmRole.update_version(obj, trans_dict)
-                new_obj.db_deleted_role.append(n_obj)
-        if 'cause' in class_dict:
-            res = class_dict['cause'](old_obj, trans_dict)
-            new_obj.db_cause = res
-        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
-            obj = old_obj.db_cause
-            new_obj.db_add_cause(DBOpmProcessIdCause.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
-            for obj in old_obj.db_deleted_cause:
-                n_obj = DBOpmProcessIdCause.update_version(obj, trans_dict)
-                new_obj.db_deleted_cause.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
-        if 'opm_times' in class_dict:
-            res = class_dict['opm_times'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_opm_time(obj)
-        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
-            for obj in old_obj.db_opm_times:
-                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
-            for obj in old_obj.db_deleted_opm_times:
-                n_obj = DBOpmTime.update_version(obj, trans_dict)
-                new_obj.db_deleted_opm_times.append(n_obj)
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_effect is not None:
-            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_effect = None
-        if self._db_role is not None:
-            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_role = None
-        if self._db_cause is not None:
-            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_cause = None
-        to_del = []
-        for child in self.db_accounts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_account(child)
-        to_del = []
-        for child in self.db_opm_times:
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'workflow' in class_dict:
+            res = class_dict['workflow'](old_obj, trans_dict)
+            new_obj.db_workflow = res
+        elif hasattr(old_obj, 'db_workflow') and old_obj.db_workflow is not None:
+            obj = old_obj.db_workflow
+            new_obj.db_add_workflow(DBWorkflow.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_workflow') and hasattr(new_obj, 'db_deleted_workflow'):
+            for obj in old_obj.db_deleted_workflow:
+                n_obj = DBWorkflow.update_version(obj, trans_dict)
+                new_obj.db_deleted_workflow.append(n_obj)
+        if 'cache' in class_dict:
+            res = class_dict['cache'](old_obj, trans_dict)
+            new_obj.db_cache = res
+        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
+            new_obj.db_cache = old_obj.db_cache
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'location' in class_dict:
+            res = class_dict['location'](old_obj, trans_dict)
+            new_obj.db_location = res
+        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
+            obj = old_obj.db_location
+            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
+            for obj in old_obj.db_deleted_location:
+                n_obj = DBLocation.update_version(obj, trans_dict)
+                new_obj.db_deleted_location.append(n_obj)
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_location is not None:
+            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_location = None
+        to_del = []
+        for child in self.db_functions:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_opm_time(child)
+            self.db_delete_function(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_effect)
-        children.extend(self.db_deleted_role)
-        children.extend(self.db_deleted_cause)
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_opm_times)
+        children.extend(self.db_deleted_workflow)
+        children.extend(self.db_deleted_location)
+        children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_annotations)
         if remove:
-            self.db_deleted_effect = []
-            self.db_deleted_role = []
-            self.db_deleted_cause = []
-            self.db_deleted_accounts = []
-            self.db_deleted_opm_times = []
+            self.db_deleted_workflow = []
+            self.db_deleted_location = []
+            self.db_deleted_functions = []
+            self.db_deleted_annotations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_effect is not None and self._db_effect.has_changes():
-            return True
-        if self._db_role is not None and self._db_role.has_changes():
+        if self._db_workflow is not None and self._db_workflow.has_changes():
             return True
-        if self._db_cause is not None and self._db_cause.has_changes():
+        if self._db_location is not None and self._db_location.has_changes():
             return True
-        for child in self._db_accounts:
+        for child in self._db_functions:
             if child.has_changes():
                 return True
-        for child in self._db_opm_times:
+        for child in self._db_annotations:
             if child.has_changes():
                 return True
         return False
-    def __get_db_effect(self):
-        return self._db_effect
-    def __set_db_effect(self, effect):
-        self._db_effect = effect
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_effect = property(__get_db_effect, __set_db_effect)
-    def db_add_effect(self, effect):
-        self._db_effect = effect
-    def db_change_effect(self, effect):
-        self._db_effect = effect
-    def db_delete_effect(self, effect):
-        if not self.is_new:
-            self.db_deleted_effect.append(self._db_effect)
-        self._db_effect = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_role(self):
-        return self._db_role
-    def __set_db_role(self, role):
-        self._db_role = role
+    def __get_db_workflow(self):
+        return self._db_workflow
+    def __set_db_workflow(self, workflow):
+        self._db_workflow = workflow
         self.is_dirty = True
-    db_role = property(__get_db_role, __set_db_role)
-    def db_add_role(self, role):
-        self._db_role = role
-    def db_change_role(self, role):
-        self._db_role = role
-    def db_delete_role(self, role):
+    db_workflow = property(__get_db_workflow, __set_db_workflow)
+    def db_add_workflow(self, workflow):
+        self._db_workflow = workflow
+    def db_change_workflow(self, workflow):
+        self._db_workflow = workflow
+    def db_delete_workflow(self, workflow):
         if not self.is_new:
-            self.db_deleted_role.append(self._db_role)
-        self._db_role = None
+            self.db_deleted_workflow.append(self._db_workflow)
+        self._db_workflow = None
     
-    def __get_db_cause(self):
-        return self._db_cause
-    def __set_db_cause(self, cause):
-        self._db_cause = cause
+    def __get_db_cache(self):
+        return self._db_cache
+    def __set_db_cache(self, cache):
+        self._db_cache = cache
         self.is_dirty = True
-    db_cause = property(__get_db_cause, __set_db_cause)
-    def db_add_cause(self, cause):
-        self._db_cause = cause
-    def db_change_cause(self, cause):
-        self._db_cause = cause
-    def db_delete_cause(self, cause):
-        if not self.is_new:
-            self.db_deleted_cause.append(self._db_cause)
-        self._db_cause = None
+    db_cache = property(__get_db_cache, __set_db_cache)
+    def db_add_cache(self, cache):
+        self._db_cache = cache
+    def db_change_cache(self, cache):
+        self._db_cache = cache
+    def db_delete_cache(self, cache):
+        self._db_cache = None
     
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
-        self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
-        return None
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
     
-    def __get_db_opm_times(self):
-        return self._db_opm_times
-    def __set_db_opm_times(self, opm_times):
-        self._db_opm_times = opm_times
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
         self.is_dirty = True
-    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
-    def db_get_opm_times(self):
-        return self._db_opm_times
-    def db_add_opm_time(self, opm_time):
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_location(self):
+        return self._db_location
+    def __set_db_location(self, location):
+        self._db_location = location
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_change_opm_time(self, opm_time):
+    db_location = property(__get_db_location, __set_db_location)
+    def db_add_location(self, location):
+        self._db_location = location
+    def db_change_location(self, location):
+        self._db_location = location
+    def db_delete_location(self, location):
+        if not self.is_new:
+            self.db_deleted_location.append(self._db_location)
+        self._db_location = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_delete_opm_time(self, opm_time):
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_opm_time(self, key):
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
+                found = True
+                break
+        if not found:
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
+        self.is_dirty = True
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
+                break
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
+        return None
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
         return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
     
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBOpmWasControlledBy(object):
 
-class DBOpmAccounts(object):
-
-    vtType = 'opm_accounts'
+    vtType = 'opm_was_controlled_by'
 
-    def __init__(self, accounts=None, opm_overlapss=None):
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, starts=None, ends=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
         self.db_deleted_accounts = []
-        self.db_accounts_id_index = {}
         if accounts is None:
             self._db_accounts = []
         else:
             self._db_accounts = accounts
-            for v in self._db_accounts:
-                self.db_accounts_id_index[v.db_id] = v
-        self.db_deleted_opm_overlapss = []
-        if opm_overlapss is None:
-            self._db_opm_overlapss = []
+        self.db_deleted_starts = []
+        if starts is None:
+            self._db_starts = []
         else:
-            self._db_opm_overlapss = opm_overlapss
+            self._db_starts = starts
+        self.db_deleted_ends = []
+        if ends is None:
+            self._db_ends = []
+        else:
+            self._db_ends = ends
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmAccounts.do_copy(self)
+        return DBOpmWasControlledBy.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmAccounts()
+        cp = DBOpmWasControlledBy()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
         if self._db_accounts is None:
             cp._db_accounts = []
         else:
             cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        if self._db_opm_overlapss is None:
-            cp._db_opm_overlapss = []
+        if self._db_starts is None:
+            cp._db_starts = []
         else:
-            cp._db_opm_overlapss = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_overlapss]
+            cp._db_starts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_starts]
+        if self._db_ends is None:
+            cp._db_ends = []
+        else:
+            cp._db_ends = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_ends]
         
         # set new ids
         if new_ids:
@@ -805,7 +1045,6 @@ class DBOpmAccounts(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_accounts_id_index = dict((v.db_id, v) for v in cp._db_accounts)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -814,38 +1053,91 @@ class DBOpmAccounts(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmAccounts()
+            new_obj = DBOpmWasControlledBy()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmAgentId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmAgentId.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
         if 'accounts' in class_dict:
             res = class_dict['accounts'](old_obj, trans_dict)
             for obj in res:
                 new_obj.db_add_account(obj)
         elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
             for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccount.update_version(obj, trans_dict))
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
         if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
             for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccount.update_version(obj, trans_dict)
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
                 new_obj.db_deleted_accounts.append(n_obj)
-        if 'opm_overlapss' in class_dict:
-            res = class_dict['opm_overlapss'](old_obj, trans_dict)
+        if 'starts' in class_dict:
+            res = class_dict['starts'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_opm_overlaps(obj)
-        elif hasattr(old_obj, 'db_opm_overlapss') and old_obj.db_opm_overlapss is not None:
-            for obj in old_obj.db_opm_overlapss:
-                new_obj.db_add_opm_overlaps(DBOpmOverlaps.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_opm_overlapss') and hasattr(new_obj, 'db_deleted_opm_overlapss'):
-            for obj in old_obj.db_deleted_opm_overlapss:
-                n_obj = DBOpmOverlaps.update_version(obj, trans_dict)
-                new_obj.db_deleted_opm_overlapss.append(n_obj)
+                new_obj.db_add_start(obj)
+        elif hasattr(old_obj, 'db_starts') and old_obj.db_starts is not None:
+            for obj in old_obj.db_starts:
+                new_obj.db_add_start(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_starts') and hasattr(new_obj, 'db_deleted_starts'):
+            for obj in old_obj.db_deleted_starts:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_starts.append(n_obj)
+        if 'ends' in class_dict:
+            res = class_dict['ends'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_end(obj)
+        elif hasattr(old_obj, 'db_ends') and old_obj.db_ends is not None:
+            for obj in old_obj.db_ends:
+                new_obj.db_add_end(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_ends') and hasattr(new_obj, 'db_deleted_ends'):
+            for obj in old_obj.db_deleted_ends:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_ends.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
         to_del = []
         for child in self.db_accounts:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
@@ -854,32 +1146,101 @@ class DBOpmAccounts(object):
         for child in to_del:
             self.db_delete_account(child)
         to_del = []
-        for child in self.db_opm_overlapss:
+        for child in self.db_starts:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_opm_overlaps(child)
-        children.append((self, parent[0], parent[1]))
-        return children
-    def db_deleted_children(self, remove=False):
-        children = []
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_opm_overlapss)
-        if remove:
+            self.db_delete_start(child)
+        to_del = []
+        for child in self.db_ends:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_end(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_starts)
+        children.extend(self.db_deleted_ends)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
             self.db_deleted_accounts = []
-            self.db_deleted_opm_overlapss = []
+            self.db_deleted_starts = []
+            self.db_deleted_ends = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
         for child in self._db_accounts:
             if child.has_changes():
                 return True
-        for child in self._db_opm_overlapss:
+        for child in self._db_starts:
+            if child.has_changes():
+                return True
+        for child in self._db_ends:
             if child.has_changes():
                 return True
         return False
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
+        self.is_dirty = True
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
     def __get_db_accounts(self):
         return self._db_accounts
     def __set_db_accounts(self, accounts):
@@ -891,73 +1252,83 @@ class DBOpmAccounts(object):
     def db_add_account(self, account):
         self.is_dirty = True
         self._db_accounts.append(account)
-        self.db_accounts_id_index[account.db_id] = account
     def db_change_account(self, account):
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_accounts)):
-            if self._db_accounts[i].db_id == account.db_id:
-                self._db_accounts[i] = account
-                found = True
-                break
-        if not found:
-            self._db_accounts.append(account)
-        self.db_accounts_id_index[account.db_id] = account
+        self._db_accounts.append(account)
     def db_delete_account(self, account):
         self.is_dirty = True
-        for i in xrange(len(self._db_accounts)):
-            if self._db_accounts[i].db_id == account.db_id:
-                if not self._db_accounts[i].is_new:
-                    self.db_deleted_accounts.append(self._db_accounts[i])
-                del self._db_accounts[i]
-                break
-        del self.db_accounts_id_index[account.db_id]
+        raise Exception('Cannot delete a non-keyed object')
     def db_get_account(self, key):
-        for i in xrange(len(self._db_accounts)):
-            if self._db_accounts[i].db_id == key:
-                return self._db_accounts[i]
         return None
-    def db_get_account_by_id(self, key):
-        return self.db_accounts_id_index[key]
-    def db_has_account_with_id(self, key):
-        return key in self.db_accounts_id_index
     
-    def __get_db_opm_overlapss(self):
-        return self._db_opm_overlapss
-    def __set_db_opm_overlapss(self, opm_overlapss):
-        self._db_opm_overlapss = opm_overlapss
+    def __get_db_starts(self):
+        return self._db_starts
+    def __set_db_starts(self, starts):
+        self._db_starts = starts
         self.is_dirty = True
-    db_opm_overlapss = property(__get_db_opm_overlapss, __set_db_opm_overlapss)
-    def db_get_opm_overlapss(self):
-        return self._db_opm_overlapss
-    def db_add_opm_overlaps(self, opm_overlaps):
+    db_starts = property(__get_db_starts, __set_db_starts)
+    def db_get_starts(self):
+        return self._db_starts
+    def db_add_start(self, start):
         self.is_dirty = True
-        self._db_opm_overlapss.append(opm_overlaps)
-    def db_change_opm_overlaps(self, opm_overlaps):
+        self._db_starts.append(start)
+    def db_change_start(self, start):
         self.is_dirty = True
-        self._db_opm_overlapss.append(opm_overlaps)
-    def db_delete_opm_overlaps(self, opm_overlaps):
+        self._db_starts.append(start)
+    def db_delete_start(self, start):
         self.is_dirty = True
         raise Exception('Cannot delete a non-keyed object')
-    def db_get_opm_overlaps(self, key):
+    def db_get_start(self, key):
+        return None
+    
+    def __get_db_ends(self):
+        return self._db_ends
+    def __set_db_ends(self, ends):
+        self._db_ends = ends
+        self.is_dirty = True
+    db_ends = property(__get_db_ends, __set_db_ends)
+    def db_get_ends(self):
+        return self._db_ends
+    def db_add_end(self, end):
+        self.is_dirty = True
+        self._db_ends.append(end)
+    def db_change_end(self, end):
+        self.is_dirty = True
+        self._db_ends.append(end)
+    def db_delete_end(self, end):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_end(self, key):
         return None
     
 
 
-class DBRefProvAgent(object):
+class DBAdd(object):
 
-    vtType = 'ref_prov_agent'
+    vtType = 'add'
 
-    def __init__(self, prov_ref=None):
-        self._db_prov_ref = prov_ref
+    def __init__(self, data=None, id=None, what=None, objectId=None, parentObjId=None, parentObjType=None):
+        self.db_deleted_data = []
+        self._db_data = data
+        self._db_id = id
+        self._db_what = what
+        self._db_objectId = objectId
+        self._db_parentObjId = parentObjId
+        self._db_parentObjType = parentObjType
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBRefProvAgent.do_copy(self)
+        return DBAdd.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBRefProvAgent(prov_ref=self._db_prov_ref)
+        cp = DBAdd(id=self._db_id,
+                   what=self._db_what,
+                   objectId=self._db_objectId,
+                   parentObjId=self._db_parentObjId,
+                   parentObjType=self._db_parentObjType)
+        if self._db_data is not None:
+            cp._db_data = self._db_data.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -967,8 +1338,10 @@ class DBRefProvAgent(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_prov_ref') and ('prov_agent', self._db_prov_ref) in id_remap:
-                cp._db_prov_ref = id_remap[('prov_agent', self._db_prov_ref)]
+            if hasattr(self, 'db_objectId') and (self._db_what, self._db_objectId) in id_remap:
+                cp._db_objectId = id_remap[(self._db_what, self._db_objectId)]
+            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
+                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -979,175 +1352,141 @@ class DBRefProvAgent(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBRefProvAgent()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_ref' in class_dict:
-            res = class_dict['prov_ref'](old_obj, trans_dict)
-            new_obj.db_prov_ref = res
-        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
-            new_obj.db_prov_ref = old_obj.db_prov_ref
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
-    def db_deleted_children(self, remove=False):
-        children = []
-        return children
-    def has_changes(self):
-        if self.is_dirty:
-            return True
-        return False
-    def __get_db_prov_ref(self):
-        return self._db_prov_ref
-    def __set_db_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-        self.is_dirty = True
-    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
-    def db_add_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_change_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_delete_prov_ref(self, prov_ref):
-        self._db_prov_ref = None
-    
-
-
-class DBPortSpec(object):
-
-    vtType = 'portSpec'
-
-    def __init__(self, id=None, name=None, type=None, optional=None, sort_key=None, portSpecItems=None, min_conns=None, max_conns=None):
-        self._db_id = id
-        self._db_name = name
-        self._db_type = type
-        self._db_optional = optional
-        self._db_sort_key = sort_key
-        self.db_deleted_portSpecItems = []
-        self.db_portSpecItems_id_index = {}
-        if portSpecItems is None:
-            self._db_portSpecItems = []
-        else:
-            self._db_portSpecItems = portSpecItems
-            for v in self._db_portSpecItems:
-                self.db_portSpecItems_id_index[v.db_id] = v
-        self._db_min_conns = min_conns
-        self._db_max_conns = max_conns
-        self.is_dirty = True
-        self.is_new = True
-    
-    def __copy__(self):
-        return DBPortSpec.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPortSpec(id=self._db_id,
-                        name=self._db_name,
-                        type=self._db_type,
-                        optional=self._db_optional,
-                        sort_key=self._db_sort_key,
-                        min_conns=self._db_min_conns,
-                        max_conns=self._db_max_conns)
-        if self._db_portSpecItems is None:
-            cp._db_portSpecItems = []
-        else:
-            cp._db_portSpecItems = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecItems]
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
-            if self.vtType in id_scope.remap:
-                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-        
-        # recreate indices and set flags
-        cp.db_portSpecItems_id_index = dict((v.db_id, v) for v in cp._db_portSpecItems)
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBPortSpec()
+            new_obj = DBAdd()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'data' in class_dict:
+            res = class_dict['data'](old_obj, trans_dict)
+            new_obj.db_data = res
+        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
+            obj = old_obj.db_data
+            if obj.vtType == 'module':
+                new_obj.db_add_data(DBModule.update_version(obj, trans_dict))
+            elif obj.vtType == 'location':
+                new_obj.db_add_data(DBLocation.update_version(obj, trans_dict))
+            elif obj.vtType == 'annotation':
+                new_obj.db_add_data(DBAnnotation.update_version(obj, trans_dict))
+            elif obj.vtType == 'function':
+                new_obj.db_add_data(DBFunction.update_version(obj, trans_dict))
+            elif obj.vtType == 'connection':
+                new_obj.db_add_data(DBConnection.update_version(obj, trans_dict))
+            elif obj.vtType == 'port':
+                new_obj.db_add_data(DBPort.update_version(obj, trans_dict))
+            elif obj.vtType == 'parameter':
+                new_obj.db_add_data(DBParameter.update_version(obj, trans_dict))
+            elif obj.vtType == 'portSpec':
+                new_obj.db_add_data(DBPortSpec.update_version(obj, trans_dict))
+            elif obj.vtType == 'abstraction':
+                new_obj.db_add_data(DBAbstraction.update_version(obj, trans_dict))
+            elif obj.vtType == 'group':
+                new_obj.db_add_data(DBGroup.update_version(obj, trans_dict))
+            elif obj.vtType == 'other':
+                new_obj.db_add_data(DBOther.update_version(obj, trans_dict))
+            elif obj.vtType == 'plugin_data':
+                new_obj.db_add_data(DBPluginData.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_data') and hasattr(new_obj, 'db_deleted_data'):
+            for obj in old_obj.db_deleted_data:
+                if obj.vtType == 'module':
+                    n_obj = DBModule.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'location':
+                    n_obj = DBLocation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'annotation':
+                    n_obj = DBAnnotation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'function':
+                    n_obj = DBFunction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'connection':
+                    n_obj = DBConnection.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'port':
+                    n_obj = DBPort.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'parameter':
+                    n_obj = DBParameter.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'portSpec':
+                    n_obj = DBPortSpec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'abstraction':
+                    n_obj = DBAbstraction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'group':
+                    n_obj = DBGroup.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'other':
+                    n_obj = DBOther.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'plugin_data':
+                    n_obj = DBPluginData.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
         if 'id' in class_dict:
             res = class_dict['id'](old_obj, trans_dict)
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'type' in class_dict:
-            res = class_dict['type'](old_obj, trans_dict)
-            new_obj.db_type = res
-        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
-            new_obj.db_type = old_obj.db_type
-        if 'optional' in class_dict:
-            res = class_dict['optional'](old_obj, trans_dict)
-            new_obj.db_optional = res
-        elif hasattr(old_obj, 'db_optional') and old_obj.db_optional is not None:
-            new_obj.db_optional = old_obj.db_optional
-        if 'sort_key' in class_dict:
-            res = class_dict['sort_key'](old_obj, trans_dict)
-            new_obj.db_sort_key = res
-        elif hasattr(old_obj, 'db_sort_key') and old_obj.db_sort_key is not None:
-            new_obj.db_sort_key = old_obj.db_sort_key
-        if 'portSpecItems' in class_dict:
-            res = class_dict['portSpecItems'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_portSpecItem(obj)
-        elif hasattr(old_obj, 'db_portSpecItems') and old_obj.db_portSpecItems is not None:
-            for obj in old_obj.db_portSpecItems:
-                new_obj.db_add_portSpecItem(DBPortSpecItem.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_portSpecItems') and hasattr(new_obj, 'db_deleted_portSpecItems'):
-            for obj in old_obj.db_deleted_portSpecItems:
-                n_obj = DBPortSpecItem.update_version(obj, trans_dict)
-                new_obj.db_deleted_portSpecItems.append(n_obj)
-        if 'min_conns' in class_dict:
-            res = class_dict['min_conns'](old_obj, trans_dict)
-            new_obj.db_min_conns = res
-        elif hasattr(old_obj, 'db_min_conns') and old_obj.db_min_conns is not None:
-            new_obj.db_min_conns = old_obj.db_min_conns
-        if 'max_conns' in class_dict:
-            res = class_dict['max_conns'](old_obj, trans_dict)
-            new_obj.db_max_conns = res
-        elif hasattr(old_obj, 'db_max_conns') and old_obj.db_max_conns is not None:
-            new_obj.db_max_conns = old_obj.db_max_conns
+        if 'what' in class_dict:
+            res = class_dict['what'](old_obj, trans_dict)
+            new_obj.db_what = res
+        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
+            new_obj.db_what = old_obj.db_what
+        if 'objectId' in class_dict:
+            res = class_dict['objectId'](old_obj, trans_dict)
+            new_obj.db_objectId = res
+        elif hasattr(old_obj, 'db_objectId') and old_obj.db_objectId is not None:
+            new_obj.db_objectId = old_obj.db_objectId
+        if 'parentObjId' in class_dict:
+            res = class_dict['parentObjId'](old_obj, trans_dict)
+            new_obj.db_parentObjId = res
+        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
+            new_obj.db_parentObjId = old_obj.db_parentObjId
+        if 'parentObjType' in class_dict:
+            res = class_dict['parentObjType'](old_obj, trans_dict)
+            new_obj.db_parentObjType = res
+        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
+            new_obj.db_parentObjType = old_obj.db_parentObjType
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if not for_action:
-            for child in self.db_portSpecItems:
-                children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_data is not None:
+            children.extend(self._db_data.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_data = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_portSpecItems)
+        children.extend(self.db_deleted_data)
         if remove:
-            self.db_deleted_portSpecItems = []
+            self.db_deleted_data = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_portSpecItems:
-            if child.has_changes():
-                return True
+        if self._db_data is not None and self._db_data.has_changes():
+            return True
         return False
+    def __get_db_data(self):
+        return self._db_data
+    def __set_db_data(self, data):
+        self._db_data = data
+        self.is_dirty = True
+    db_data = property(__get_db_data, __set_db_data)
+    def db_add_data(self, data):
+        self._db_data = data
+    def db_change_data(self, data):
+        self._db_data = data
+    def db_delete_data(self, data):
+        if not self.is_new:
+            self.db_deleted_data.append(self._db_data)
+        self._db_data = None
+    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -1161,197 +1500,83 @@ class DBPortSpec(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
+    def __get_db_what(self):
+        return self._db_what
+    def __set_db_what(self, what):
+        self._db_what = what
         self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
+    db_what = property(__get_db_what, __set_db_what)
+    def db_add_what(self, what):
+        self._db_what = what
+    def db_change_what(self, what):
+        self._db_what = what
+    def db_delete_what(self, what):
+        self._db_what = None
     
-    def __get_db_type(self):
-        return self._db_type
-    def __set_db_type(self, type):
-        self._db_type = type
+    def __get_db_objectId(self):
+        return self._db_objectId
+    def __set_db_objectId(self, objectId):
+        self._db_objectId = objectId
         self.is_dirty = True
-    db_type = property(__get_db_type, __set_db_type)
-    def db_add_type(self, type):
-        self._db_type = type
-    def db_change_type(self, type):
-        self._db_type = type
-    def db_delete_type(self, type):
-        self._db_type = None
+    db_objectId = property(__get_db_objectId, __set_db_objectId)
+    def db_add_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_change_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_delete_objectId(self, objectId):
+        self._db_objectId = None
     
-    def __get_db_optional(self):
-        return self._db_optional
-    def __set_db_optional(self, optional):
-        self._db_optional = optional
+    def __get_db_parentObjId(self):
+        return self._db_parentObjId
+    def __set_db_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
         self.is_dirty = True
-    db_optional = property(__get_db_optional, __set_db_optional)
-    def db_add_optional(self, optional):
-        self._db_optional = optional
-    def db_change_optional(self, optional):
-        self._db_optional = optional
-    def db_delete_optional(self, optional):
-        self._db_optional = None
+    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
+    def db_add_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_change_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_delete_parentObjId(self, parentObjId):
+        self._db_parentObjId = None
     
-    def __get_db_sort_key(self):
-        return self._db_sort_key
-    def __set_db_sort_key(self, sort_key):
-        self._db_sort_key = sort_key
-        self.is_dirty = True
-    db_sort_key = property(__get_db_sort_key, __set_db_sort_key)
-    def db_add_sort_key(self, sort_key):
-        self._db_sort_key = sort_key
-    def db_change_sort_key(self, sort_key):
-        self._db_sort_key = sort_key
-    def db_delete_sort_key(self, sort_key):
-        self._db_sort_key = None
-    
-    def __get_db_portSpecItems(self):
-        return self._db_portSpecItems
-    def __set_db_portSpecItems(self, portSpecItems):
-        self._db_portSpecItems = portSpecItems
-        self.is_dirty = True
-    db_portSpecItems = property(__get_db_portSpecItems, __set_db_portSpecItems)
-    def db_get_portSpecItems(self):
-        return self._db_portSpecItems
-    def db_add_portSpecItem(self, portSpecItem):
-        self.is_dirty = True
-        self._db_portSpecItems.append(portSpecItem)
-        self.db_portSpecItems_id_index[portSpecItem.db_id] = portSpecItem
-    def db_change_portSpecItem(self, portSpecItem):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_portSpecItems)):
-            if self._db_portSpecItems[i].db_id == portSpecItem.db_id:
-                self._db_portSpecItems[i] = portSpecItem
-                found = True
-                break
-        if not found:
-            self._db_portSpecItems.append(portSpecItem)
-        self.db_portSpecItems_id_index[portSpecItem.db_id] = portSpecItem
-    def db_delete_portSpecItem(self, portSpecItem):
-        self.is_dirty = True
-        for i in xrange(len(self._db_portSpecItems)):
-            if self._db_portSpecItems[i].db_id == portSpecItem.db_id:
-                if not self._db_portSpecItems[i].is_new:
-                    self.db_deleted_portSpecItems.append(self._db_portSpecItems[i])
-                del self._db_portSpecItems[i]
-                break
-        del self.db_portSpecItems_id_index[portSpecItem.db_id]
-    def db_get_portSpecItem(self, key):
-        for i in xrange(len(self._db_portSpecItems)):
-            if self._db_portSpecItems[i].db_id == key:
-                return self._db_portSpecItems[i]
-        return None
-    def db_get_portSpecItem_by_id(self, key):
-        return self.db_portSpecItems_id_index[key]
-    def db_has_portSpecItem_with_id(self, key):
-        return key in self.db_portSpecItems_id_index
-    
-    def __get_db_min_conns(self):
-        return self._db_min_conns
-    def __set_db_min_conns(self, min_conns):
-        self._db_min_conns = min_conns
-        self.is_dirty = True
-    db_min_conns = property(__get_db_min_conns, __set_db_min_conns)
-    def db_add_min_conns(self, min_conns):
-        self._db_min_conns = min_conns
-    def db_change_min_conns(self, min_conns):
-        self._db_min_conns = min_conns
-    def db_delete_min_conns(self, min_conns):
-        self._db_min_conns = None
-    
-    def __get_db_max_conns(self):
-        return self._db_max_conns
-    def __set_db_max_conns(self, max_conns):
-        self._db_max_conns = max_conns
+    def __get_db_parentObjType(self):
+        return self._db_parentObjType
+    def __set_db_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
         self.is_dirty = True
-    db_max_conns = property(__get_db_max_conns, __set_db_max_conns)
-    def db_add_max_conns(self, max_conns):
-        self._db_max_conns = max_conns
-    def db_change_max_conns(self, max_conns):
-        self._db_max_conns = max_conns
-    def db_delete_max_conns(self, max_conns):
-        self._db_max_conns = None
+    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
+    def db_add_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_change_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_delete_parentObjType(self, parentObjType):
+        self._db_parentObjType = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBModule(object):
+class DBProvGeneration(object):
 
-    vtType = 'module'
+    vtType = 'prov_generation'
 
-    def __init__(self, id=None, cache=None, name=None, namespace=None, package=None, version=None, location=None, functions=None, annotations=None, portSpecs=None):
-        self._db_id = id
-        self._db_cache = cache
-        self._db_name = name
-        self._db_namespace = namespace
-        self._db_package = package
-        self._db_version = version
-        self.db_deleted_location = []
-        self._db_location = location
-        self.db_deleted_functions = []
-        self.db_functions_id_index = {}
-        if functions is None:
-            self._db_functions = []
-        else:
-            self._db_functions = functions
-            for v in self._db_functions:
-                self.db_functions_id_index[v.db_id] = v
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        self.db_annotations_key_index = {}
-        if annotations is None:
-            self._db_annotations = []
-        else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
-                self.db_annotations_key_index[v.db_key] = v
-        self.db_deleted_portSpecs = []
-        self.db_portSpecs_id_index = {}
-        self.db_portSpecs_name_index = {}
-        if portSpecs is None:
-            self._db_portSpecs = []
-        else:
-            self._db_portSpecs = portSpecs
-            for v in self._db_portSpecs:
-                self.db_portSpecs_id_index[v.db_id] = v
-                self.db_portSpecs_name_index[(v.db_name,v.db_type)] = v
+    def __init__(self, prov_entity=None, prov_activity=None, prov_role=None):
+        self.db_deleted_prov_entity = []
+        self._db_prov_entity = prov_entity
+        self.db_deleted_prov_activity = []
+        self._db_prov_activity = prov_activity
+        self._db_prov_role = prov_role
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBModule.do_copy(self)
+        return DBProvGeneration.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBModule(id=self._db_id,
-                      cache=self._db_cache,
-                      name=self._db_name,
-                      namespace=self._db_namespace,
-                      package=self._db_package,
-                      version=self._db_version)
-        if self._db_location is not None:
-            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
-        if self._db_functions is None:
-            cp._db_functions = []
-        else:
-            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
-        if self._db_annotations is None:
-            cp._db_annotations = []
-        else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
-        if self._db_portSpecs is None:
-            cp._db_portSpecs = []
-        else:
-            cp._db_portSpecs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecs]
+        cp = DBProvGeneration(prov_role=self._db_prov_role)
+        if self._db_prov_entity is not None:
+            cp._db_prov_entity = self._db_prov_entity.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_activity is not None:
+            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -1363,11 +1588,6 @@ class DBModule(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
-        cp.db_portSpecs_id_index = dict((v.db_id, v) for v in cp._db_portSpecs)
-        cp.db_portSpecs_name_index = dict(((v.db_name,v.db_type), v) for v in cp._db_portSpecs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -1376,419 +1596,155 @@ class DBModule(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBModule()
+            new_obj = DBProvGeneration()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'cache' in class_dict:
-            res = class_dict['cache'](old_obj, trans_dict)
-            new_obj.db_cache = res
-        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
-            new_obj.db_cache = old_obj.db_cache
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'namespace' in class_dict:
-            res = class_dict['namespace'](old_obj, trans_dict)
-            new_obj.db_namespace = res
-        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
-            new_obj.db_namespace = old_obj.db_namespace
-        if 'package' in class_dict:
-            res = class_dict['package'](old_obj, trans_dict)
-            new_obj.db_package = res
-        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
-            new_obj.db_package = old_obj.db_package
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'location' in class_dict:
-            res = class_dict['location'](old_obj, trans_dict)
-            new_obj.db_location = res
-        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
-            obj = old_obj.db_location
-            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
-            for obj in old_obj.db_deleted_location:
-                n_obj = DBLocation.update_version(obj, trans_dict)
-                new_obj.db_deleted_location.append(n_obj)
-        if 'functions' in class_dict:
-            res = class_dict['functions'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_function(obj)
-        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
-            for obj in old_obj.db_functions:
-                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
-            for obj in old_obj.db_deleted_functions:
-                n_obj = DBFunction.update_version(obj, trans_dict)
-                new_obj.db_deleted_functions.append(n_obj)
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
-        if 'portSpecs' in class_dict:
-            res = class_dict['portSpecs'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_portSpec(obj)
-        elif hasattr(old_obj, 'db_portSpecs') and old_obj.db_portSpecs is not None:
-            for obj in old_obj.db_portSpecs:
-                new_obj.db_add_portSpec(DBPortSpec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_portSpecs') and hasattr(new_obj, 'db_deleted_portSpecs'):
-            for obj in old_obj.db_deleted_portSpecs:
-                n_obj = DBPortSpec.update_version(obj, trans_dict)
-                new_obj.db_deleted_portSpecs.append(n_obj)
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_location is not None:
-            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_location = None
-        to_del = []
-        for child in self.db_functions:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_function(child)
-        to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        if 'prov_entity' in class_dict:
+            res = class_dict['prov_entity'](old_obj, trans_dict)
+            new_obj.db_prov_entity = res
+        elif hasattr(old_obj, 'db_prov_entity') and old_obj.db_prov_entity is not None:
+            obj = old_obj.db_prov_entity
+            new_obj.db_add_prov_entity(DBRefProvEntity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_entity') and hasattr(new_obj, 'db_deleted_prov_entity'):
+            for obj in old_obj.db_deleted_prov_entity:
+                n_obj = DBRefProvEntity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_entity.append(n_obj)
+        if 'prov_activity' in class_dict:
+            res = class_dict['prov_activity'](old_obj, trans_dict)
+            new_obj.db_prov_activity = res
+        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
+            obj = old_obj.db_prov_activity
+            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
+            for obj in old_obj.db_deleted_prov_activity:
+                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activity.append(n_obj)
+        if 'prov_role' in class_dict:
+            res = class_dict['prov_role'](old_obj, trans_dict)
+            new_obj.db_prov_role = res
+        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
+            new_obj.db_prov_role = old_obj.db_prov_role
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_prov_entity is not None:
+            children.extend(self._db_prov_entity.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        to_del = []
-        for child in self.db_portSpecs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+                self._db_prov_entity = None
+        if self._db_prov_activity is not None:
+            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_portSpec(child)
+                self._db_prov_activity = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_location)
-        children.extend(self.db_deleted_functions)
-        children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_portSpecs)
+        children.extend(self.db_deleted_prov_entity)
+        children.extend(self.db_deleted_prov_activity)
         if remove:
-            self.db_deleted_location = []
-            self.db_deleted_functions = []
-            self.db_deleted_annotations = []
-            self.db_deleted_portSpecs = []
+            self.db_deleted_prov_entity = []
+            self.db_deleted_prov_activity = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_location is not None and self._db_location.has_changes():
+        if self._db_prov_entity is not None and self._db_prov_entity.has_changes():
+            return True
+        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
             return True
-        for child in self._db_functions:
-            if child.has_changes():
-                return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
-        for child in self._db_portSpecs:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_cache(self):
-        return self._db_cache
-    def __set_db_cache(self, cache):
-        self._db_cache = cache
-        self.is_dirty = True
-    db_cache = property(__get_db_cache, __set_db_cache)
-    def db_add_cache(self, cache):
-        self._db_cache = cache
-    def db_change_cache(self, cache):
-        self._db_cache = cache
-    def db_delete_cache(self, cache):
-        self._db_cache = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_namespace(self):
-        return self._db_namespace
-    def __set_db_namespace(self, namespace):
-        self._db_namespace = namespace
+    def __get_db_prov_entity(self):
+        return self._db_prov_entity
+    def __set_db_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
         self.is_dirty = True
-    db_namespace = property(__get_db_namespace, __set_db_namespace)
-    def db_add_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_change_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_delete_namespace(self, namespace):
-        self._db_namespace = None
+    db_prov_entity = property(__get_db_prov_entity, __set_db_prov_entity)
+    def db_add_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_change_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_delete_prov_entity(self, prov_entity):
+        if not self.is_new:
+            self.db_deleted_prov_entity.append(self._db_prov_entity)
+        self._db_prov_entity = None
     
-    def __get_db_package(self):
-        return self._db_package
-    def __set_db_package(self, package):
-        self._db_package = package
+    def __get_db_prov_activity(self):
+        return self._db_prov_activity
+    def __set_db_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
         self.is_dirty = True
-    db_package = property(__get_db_package, __set_db_package)
-    def db_add_package(self, package):
-        self._db_package = package
-    def db_change_package(self, package):
-        self._db_package = package
-    def db_delete_package(self, package):
-        self._db_package = None
+    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
+    def db_add_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        if not self.is_new:
+            self.db_deleted_prov_activity.append(self._db_prov_activity)
+        self._db_prov_activity = None
     
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
+    def __get_db_prov_role(self):
+        return self._db_prov_role
+    def __set_db_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
         self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
+    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
+    def db_add_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_change_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_delete_prov_role(self, prov_role):
+        self._db_prov_role = None
     
-    def __get_db_location(self):
-        return self._db_location
-    def __set_db_location(self, location):
-        self._db_location = location
+
+
+class DBOpmUsed(object):
+
+    vtType = 'opm_used'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
         self.is_dirty = True
-    db_location = property(__get_db_location, __set_db_location)
-    def db_add_location(self, location):
-        self._db_location = location
-    def db_change_location(self, location):
-        self._db_location = location
-    def db_delete_location(self, location):
-        if not self.is_new:
-            self.db_deleted_location.append(self._db_location)
-        self._db_location = None
-    
-    def __get_db_functions(self):
-        return self._db_functions
-    def __set_db_functions(self, functions):
-        self._db_functions = functions
-        self.is_dirty = True
-    db_functions = property(__get_db_functions, __set_db_functions)
-    def db_get_functions(self):
-        return self._db_functions
-    def db_add_function(self, function):
-        self.is_dirty = True
-        self._db_functions.append(function)
-        self.db_functions_id_index[function.db_id] = function
-    def db_change_function(self, function):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == function.db_id:
-                self._db_functions[i] = function
-                found = True
-                break
-        if not found:
-            self._db_functions.append(function)
-        self.db_functions_id_index[function.db_id] = function
-    def db_delete_function(self, function):
-        self.is_dirty = True
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == function.db_id:
-                if not self._db_functions[i].is_new:
-                    self.db_deleted_functions.append(self._db_functions[i])
-                del self._db_functions[i]
-                break
-        del self.db_functions_id_index[function.db_id]
-    def db_get_function(self, key):
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == key:
-                return self._db_functions[i]
-        return None
-    def db_get_function_by_id(self, key):
-        return self.db_functions_id_index[key]
-    def db_has_function_with_id(self, key):
-        return key in self.db_functions_id_index
-    
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
-        self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
-        self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_change_annotation(self, annotation):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
-                found = True
-                break
-        if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_delete_annotation(self, annotation):
-        self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
-                break
-        del self.db_annotations_id_index[annotation.db_id]
-        del self.db_annotations_key_index[annotation.db_key]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
-        return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
-    def db_get_annotation_by_key(self, key):
-        return self.db_annotations_key_index[key]
-    def db_has_annotation_with_key(self, key):
-        return key in self.db_annotations_key_index
-    
-    def __get_db_portSpecs(self):
-        return self._db_portSpecs
-    def __set_db_portSpecs(self, portSpecs):
-        self._db_portSpecs = portSpecs
-        self.is_dirty = True
-    db_portSpecs = property(__get_db_portSpecs, __set_db_portSpecs)
-    def db_get_portSpecs(self):
-        return self._db_portSpecs
-    def db_add_portSpec(self, portSpec):
-        self.is_dirty = True
-        self._db_portSpecs.append(portSpec)
-        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
-        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
-    def db_change_portSpec(self, portSpec):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_portSpecs)):
-            if self._db_portSpecs[i].db_id == portSpec.db_id:
-                self._db_portSpecs[i] = portSpec
-                found = True
-                break
-        if not found:
-            self._db_portSpecs.append(portSpec)
-        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
-        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
-    def db_delete_portSpec(self, portSpec):
-        self.is_dirty = True
-        for i in xrange(len(self._db_portSpecs)):
-            if self._db_portSpecs[i].db_id == portSpec.db_id:
-                if not self._db_portSpecs[i].is_new:
-                    self.db_deleted_portSpecs.append(self._db_portSpecs[i])
-                del self._db_portSpecs[i]
-                break
-        del self.db_portSpecs_id_index[portSpec.db_id]
-        del self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)]
-    def db_get_portSpec(self, key):
-        for i in xrange(len(self._db_portSpecs)):
-            if self._db_portSpecs[i].db_id == key:
-                return self._db_portSpecs[i]
-        return None
-    def db_get_portSpec_by_id(self, key):
-        return self.db_portSpecs_id_index[key]
-    def db_has_portSpec_with_id(self, key):
-        return key in self.db_portSpecs_id_index
-    def db_get_portSpec_by_name(self, key):
-        return self.db_portSpecs_name_index[key]
-    def db_has_portSpec_with_name(self, key):
-        return key in self.db_portSpecs_name_index
-    
-    def getPrimaryKey(self):
-        return self._db_id
-
-class DBModuleDescriptor(object):
-
-    vtType = 'module_descriptor'
-
-    def __init__(self, id=None, name=None, package=None, namespace=None, package_version=None, version=None, base_descriptor_id=None, portSpecs=None):
-        self._db_id = id
-        self._db_name = name
-        self._db_package = package
-        self._db_namespace = namespace
-        self._db_package_version = package_version
-        self._db_version = version
-        self._db_base_descriptor_id = base_descriptor_id
-        self.db_deleted_portSpecs = []
-        self.db_portSpecs_id_index = {}
-        self.db_portSpecs_name_index = {}
-        if portSpecs is None:
-            self._db_portSpecs = []
-        else:
-            self._db_portSpecs = portSpecs
-            for v in self._db_portSpecs:
-                self.db_portSpecs_id_index[v.db_id] = v
-                self.db_portSpecs_name_index[(v.db_name,v.db_type)] = v
-        self.is_dirty = True
-        self.is_new = True
+        self.is_new = True
     
     def __copy__(self):
-        return DBModuleDescriptor.do_copy(self)
+        return DBOpmUsed.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBModuleDescriptor(id=self._db_id,
-                                name=self._db_name,
-                                package=self._db_package,
-                                namespace=self._db_namespace,
-                                package_version=self._db_package_version,
-                                version=self._db_version,
-                                base_descriptor_id=self._db_base_descriptor_id)
-        if self._db_portSpecs is None:
-            cp._db_portSpecs = []
+        cp = DBOpmUsed()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
         else:
-            cp._db_portSpecs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecs]
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
         
         # set new ids
         if new_ids:
@@ -1798,12 +1754,8 @@ class DBModuleDescriptor(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_base_descriptor_id') and ('module_descriptor', self._db_base_descriptor_id) in id_remap:
-                cp._db_base_descriptor_id = id_remap[('module_descriptor', self._db_base_descriptor_id)]
         
         # recreate indices and set flags
-        cp.db_portSpecs_id_index = dict((v.db_id, v) for v in cp._db_portSpecs)
-        cp.db_portSpecs_name_index = dict(((v.db_name,v.db_type), v) for v in cp._db_portSpecs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -1812,243 +1764,227 @@ class DBModuleDescriptor(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBModuleDescriptor()
+            new_obj = DBOpmUsed()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'package' in class_dict:
-            res = class_dict['package'](old_obj, trans_dict)
-            new_obj.db_package = res
-        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
-            new_obj.db_package = old_obj.db_package
-        if 'namespace' in class_dict:
-            res = class_dict['namespace'](old_obj, trans_dict)
-            new_obj.db_namespace = res
-        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
-            new_obj.db_namespace = old_obj.db_namespace
-        if 'package_version' in class_dict:
-            res = class_dict['package_version'](old_obj, trans_dict)
-            new_obj.db_package_version = res
-        elif hasattr(old_obj, 'db_package_version') and old_obj.db_package_version is not None:
-            new_obj.db_package_version = old_obj.db_package_version
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'base_descriptor_id' in class_dict:
-            res = class_dict['base_descriptor_id'](old_obj, trans_dict)
-            new_obj.db_base_descriptor_id = res
-        elif hasattr(old_obj, 'db_base_descriptor_id') and old_obj.db_base_descriptor_id is not None:
-            new_obj.db_base_descriptor_id = old_obj.db_base_descriptor_id
-        if 'portSpecs' in class_dict:
-            res = class_dict['portSpecs'](old_obj, trans_dict)
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmArtifactIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmArtifactIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_portSpec(obj)
-        elif hasattr(old_obj, 'db_portSpecs') and old_obj.db_portSpecs is not None:
-            for obj in old_obj.db_portSpecs:
-                new_obj.db_add_portSpec(DBPortSpec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_portSpecs') and hasattr(new_obj, 'db_deleted_portSpecs'):
-            for obj in old_obj.db_deleted_portSpecs:
-                n_obj = DBPortSpec.update_version(obj, trans_dict)
-                new_obj.db_deleted_portSpecs.append(n_obj)
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_portSpecs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_portSpec(child)
-        children.append((self, parent[0], parent[1]))
-        return children
-    def db_deleted_children(self, remove=False):
-        children = []
-        children.extend(self.db_deleted_portSpecs)
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
         if remove:
-            self.db_deleted_portSpecs = []
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_portSpecs:
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
             if child.has_changes():
                 return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
     
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
         self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
     
-    def __get_db_package(self):
-        return self._db_package
-    def __set_db_package(self, package):
-        self._db_package = package
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
         self.is_dirty = True
-    db_package = property(__get_db_package, __set_db_package)
-    def db_add_package(self, package):
-        self._db_package = package
-    def db_change_package(self, package):
-        self._db_package = package
-    def db_delete_package(self, package):
-        self._db_package = None
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
     
-    def __get_db_namespace(self):
-        return self._db_namespace
-    def __set_db_namespace(self, namespace):
-        self._db_namespace = namespace
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
         self.is_dirty = True
-    db_namespace = property(__get_db_namespace, __set_db_namespace)
-    def db_add_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_change_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_delete_namespace(self, namespace):
-        self._db_namespace = None
-    
-    def __get_db_package_version(self):
-        return self._db_package_version
-    def __set_db_package_version(self, package_version):
-        self._db_package_version = package_version
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
         self.is_dirty = True
-    db_package_version = property(__get_db_package_version, __set_db_package_version)
-    def db_add_package_version(self, package_version):
-        self._db_package_version = package_version
-    def db_change_package_version(self, package_version):
-        self._db_package_version = package_version
-    def db_delete_package_version(self, package_version):
-        self._db_package_version = None
-    
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
         self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
-    
-    def __get_db_base_descriptor_id(self):
-        return self._db_base_descriptor_id
-    def __set_db_base_descriptor_id(self, base_descriptor_id):
-        self._db_base_descriptor_id = base_descriptor_id
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
         self.is_dirty = True
-    db_base_descriptor_id = property(__get_db_base_descriptor_id, __set_db_base_descriptor_id)
-    def db_add_base_descriptor_id(self, base_descriptor_id):
-        self._db_base_descriptor_id = base_descriptor_id
-    def db_change_base_descriptor_id(self, base_descriptor_id):
-        self._db_base_descriptor_id = base_descriptor_id
-    def db_delete_base_descriptor_id(self, base_descriptor_id):
-        self._db_base_descriptor_id = None
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
     
-    def __get_db_portSpecs(self):
-        return self._db_portSpecs
-    def __set_db_portSpecs(self, portSpecs):
-        self._db_portSpecs = portSpecs
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
         self.is_dirty = True
-    db_portSpecs = property(__get_db_portSpecs, __set_db_portSpecs)
-    def db_get_portSpecs(self):
-        return self._db_portSpecs
-    def db_add_portSpec(self, portSpec):
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
         self.is_dirty = True
-        self._db_portSpecs.append(portSpec)
-        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
-        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
-    def db_change_portSpec(self, portSpec):
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_portSpecs)):
-            if self._db_portSpecs[i].db_id == portSpec.db_id:
-                self._db_portSpecs[i] = portSpec
-                found = True
-                break
-        if not found:
-            self._db_portSpecs.append(portSpec)
-        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
-        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
-    def db_delete_portSpec(self, portSpec):
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
         self.is_dirty = True
-        for i in xrange(len(self._db_portSpecs)):
-            if self._db_portSpecs[i].db_id == portSpec.db_id:
-                if not self._db_portSpecs[i].is_new:
-                    self.db_deleted_portSpecs.append(self._db_portSpecs[i])
-                del self._db_portSpecs[i]
-                break
-        del self.db_portSpecs_id_index[portSpec.db_id]
-        del self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)]
-    def db_get_portSpec(self, key):
-        for i in xrange(len(self._db_portSpecs)):
-            if self._db_portSpecs[i].db_id == key:
-                return self._db_portSpecs[i]
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
         return None
-    def db_get_portSpec_by_id(self, key):
-        return self.db_portSpecs_id_index[key]
-    def db_has_portSpec_with_id(self, key):
-        return key in self.db_portSpecs_id_index
-    def db_get_portSpec_by_name(self, key):
-        return self.db_portSpecs_name_index[key]
-    def db_has_portSpec_with_name(self, key):
-        return key in self.db_portSpecs_name_index
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBTag(object):
 
-    vtType = 'tag'
+class DBOpmArtifactIdCause(object):
 
-    def __init__(self, id=None, name=None):
+    vtType = 'opm_artifact_id_cause'
+
+    def __init__(self, id=None):
         self._db_id = id
-        self._db_name = name
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBTag.do_copy(self)
+        return DBOpmArtifactIdCause.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBTag(id=self._db_id,
-                   name=self._db_name)
+        cp = DBOpmArtifactIdCause(id=self._db_id)
         
         # set new ids
         if new_ids:
@@ -2058,8 +1994,8 @@ class DBTag(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('action', self._db_id) in id_remap:
-                cp._db_id = id_remap[('action', self._db_id)]
+            if hasattr(self, 'db_id') and ('opm_artifact', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_artifact', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -2070,7 +2006,7 @@ class DBTag(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBTag()
+            new_obj = DBOpmArtifactIdCause()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -2079,11 +2015,6 @@ class DBTag(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -2110,36 +2041,22 @@ class DBTag(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBOpmRole(object):
 
-    vtType = 'opm_role'
+class DBRefProvEntity(object):
 
-    def __init__(self, value=None):
-        self._db_value = value
+    vtType = 'ref_prov_entity'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmRole.do_copy(self)
+        return DBRefProvEntity.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmRole(value=self._db_value)
+        cp = DBRefProvEntity(prov_ref=self._db_prov_ref)
         
         # set new ids
         if new_ids:
@@ -2149,6 +2066,8 @@ class DBOpmRole(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_entity', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_entity', self._db_prov_ref)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -2159,15 +2078,15 @@ class DBOpmRole(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmRole()
+            new_obj = DBRefProvEntity()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            new_obj.db_value = old_obj.db_value
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -2181,109 +2100,47 @@ class DBOpmRole(object):
         if self.is_dirty:
             return True
         return False
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
-        self._db_value = None
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
     
 
 
-class DBProvDocument(object):
+class DBVtConnection(object):
 
-    vtType = 'prov_document'
+    vtType = 'vt_connection'
 
-    def __init__(self, prov_entitys=None, prov_activitys=None, prov_agents=None, vt_connections=None, prov_usages=None, prov_generations=None, prov_associations=None):
-        self.db_deleted_prov_entitys = []
-        self.db_prov_entitys_id_index = {}
-        if prov_entitys is None:
-            self._db_prov_entitys = []
-        else:
-            self._db_prov_entitys = prov_entitys
-            for v in self._db_prov_entitys:
-                self.db_prov_entitys_id_index[v.db_id] = v
-        self.db_deleted_prov_activitys = []
-        self.db_prov_activitys_id_index = {}
-        if prov_activitys is None:
-            self._db_prov_activitys = []
-        else:
-            self._db_prov_activitys = prov_activitys
-            for v in self._db_prov_activitys:
-                self.db_prov_activitys_id_index[v.db_id] = v
-        self.db_deleted_prov_agents = []
-        self.db_prov_agents_id_index = {}
-        if prov_agents is None:
-            self._db_prov_agents = []
-        else:
-            self._db_prov_agents = prov_agents
-            for v in self._db_prov_agents:
-                self.db_prov_agents_id_index[v.db_id] = v
-        self.db_deleted_vt_connections = []
-        self.db_vt_connections_id_index = {}
-        if vt_connections is None:
-            self._db_vt_connections = []
-        else:
-            self._db_vt_connections = vt_connections
-            for v in self._db_vt_connections:
-                self.db_vt_connections_id_index[v.db_id] = v
-        self.db_deleted_prov_usages = []
-        if prov_usages is None:
-            self._db_prov_usages = []
-        else:
-            self._db_prov_usages = prov_usages
-        self.db_deleted_prov_generations = []
-        if prov_generations is None:
-            self._db_prov_generations = []
-        else:
-            self._db_prov_generations = prov_generations
-        self.db_deleted_prov_associations = []
-        if prov_associations is None:
-            self._db_prov_associations = []
-        else:
-            self._db_prov_associations = prov_associations
+    def __init__(self, id=None, vt_source=None, vt_dest=None, vt_source_port=None, vt_dest_port=None, vt_source_signature=None, vt_dest_signature=None):
+        self._db_id = id
+        self._db_vt_source = vt_source
+        self._db_vt_dest = vt_dest
+        self._db_vt_source_port = vt_source_port
+        self._db_vt_dest_port = vt_dest_port
+        self._db_vt_source_signature = vt_source_signature
+        self._db_vt_dest_signature = vt_dest_signature
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBProvDocument.do_copy(self)
+        return DBVtConnection.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBProvDocument()
-        if self._db_prov_entitys is None:
-            cp._db_prov_entitys = []
-        else:
-            cp._db_prov_entitys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_entitys]
-        if self._db_prov_activitys is None:
-            cp._db_prov_activitys = []
-        else:
-            cp._db_prov_activitys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_activitys]
-        if self._db_prov_agents is None:
-            cp._db_prov_agents = []
-        else:
-            cp._db_prov_agents = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_agents]
-        if self._db_vt_connections is None:
-            cp._db_vt_connections = []
-        else:
-            cp._db_vt_connections = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_vt_connections]
-        if self._db_prov_usages is None:
-            cp._db_prov_usages = []
-        else:
-            cp._db_prov_usages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_usages]
-        if self._db_prov_generations is None:
-            cp._db_prov_generations = []
-        else:
-            cp._db_prov_generations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_generations]
-        if self._db_prov_associations is None:
-            cp._db_prov_associations = []
-        else:
-            cp._db_prov_associations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_associations]
+        cp = DBVtConnection(id=self._db_id,
+                            vt_source=self._db_vt_source,
+                            vt_dest=self._db_vt_dest,
+                            vt_source_port=self._db_vt_source_port,
+                            vt_dest_port=self._db_vt_dest_port,
+                            vt_source_signature=self._db_vt_source_signature,
+                            vt_dest_signature=self._db_vt_dest_signature)
         
         # set new ids
         if new_ids:
@@ -2295,10 +2152,6 @@ class DBProvDocument(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_prov_entitys_id_index = dict((v.db_id, v) for v in cp._db_prov_entitys)
-        cp.db_prov_activitys_id_index = dict((v.db_id, v) for v in cp._db_prov_activitys)
-        cp.db_prov_agents_id_index = dict((v.db_id, v) for v in cp._db_prov_agents)
-        cp.db_vt_connections_id_index = dict((v.db_id, v) for v in cp._db_vt_connections)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -2307,416 +2160,151 @@ class DBProvDocument(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBProvDocument()
+            new_obj = DBVtConnection()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_entitys' in class_dict:
-            res = class_dict['prov_entitys'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_prov_entity(obj)
-        elif hasattr(old_obj, 'db_prov_entitys') and old_obj.db_prov_entitys is not None:
-            for obj in old_obj.db_prov_entitys:
-                new_obj.db_add_prov_entity(DBProvEntity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_entitys') and hasattr(new_obj, 'db_deleted_prov_entitys'):
-            for obj in old_obj.db_deleted_prov_entitys:
-                n_obj = DBProvEntity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_entitys.append(n_obj)
-        if 'prov_activitys' in class_dict:
-            res = class_dict['prov_activitys'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_prov_activity(obj)
-        elif hasattr(old_obj, 'db_prov_activitys') and old_obj.db_prov_activitys is not None:
-            for obj in old_obj.db_prov_activitys:
-                new_obj.db_add_prov_activity(DBProvActivity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_activitys') and hasattr(new_obj, 'db_deleted_prov_activitys'):
-            for obj in old_obj.db_deleted_prov_activitys:
-                n_obj = DBProvActivity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_activitys.append(n_obj)
-        if 'prov_agents' in class_dict:
-            res = class_dict['prov_agents'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_prov_agent(obj)
-        elif hasattr(old_obj, 'db_prov_agents') and old_obj.db_prov_agents is not None:
-            for obj in old_obj.db_prov_agents:
-                new_obj.db_add_prov_agent(DBProvAgent.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_agents') and hasattr(new_obj, 'db_deleted_prov_agents'):
-            for obj in old_obj.db_deleted_prov_agents:
-                n_obj = DBProvAgent.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_agents.append(n_obj)
-        if 'vt_connections' in class_dict:
-            res = class_dict['vt_connections'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_vt_connection(obj)
-        elif hasattr(old_obj, 'db_vt_connections') and old_obj.db_vt_connections is not None:
-            for obj in old_obj.db_vt_connections:
-                new_obj.db_add_vt_connection(DBVtConnection.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_vt_connections') and hasattr(new_obj, 'db_deleted_vt_connections'):
-            for obj in old_obj.db_deleted_vt_connections:
-                n_obj = DBVtConnection.update_version(obj, trans_dict)
-                new_obj.db_deleted_vt_connections.append(n_obj)
-        if 'prov_usages' in class_dict:
-            res = class_dict['prov_usages'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_prov_usage(obj)
-        elif hasattr(old_obj, 'db_prov_usages') and old_obj.db_prov_usages is not None:
-            for obj in old_obj.db_prov_usages:
-                new_obj.db_add_prov_usage(DBProvUsage.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_usages') and hasattr(new_obj, 'db_deleted_prov_usages'):
-            for obj in old_obj.db_deleted_prov_usages:
-                n_obj = DBProvUsage.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_usages.append(n_obj)
-        if 'prov_generations' in class_dict:
-            res = class_dict['prov_generations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_prov_generation(obj)
-        elif hasattr(old_obj, 'db_prov_generations') and old_obj.db_prov_generations is not None:
-            for obj in old_obj.db_prov_generations:
-                new_obj.db_add_prov_generation(DBProvGeneration.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_generations') and hasattr(new_obj, 'db_deleted_prov_generations'):
-            for obj in old_obj.db_deleted_prov_generations:
-                n_obj = DBProvGeneration.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_generations.append(n_obj)
-        if 'prov_associations' in class_dict:
-            res = class_dict['prov_associations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_prov_association(obj)
-        elif hasattr(old_obj, 'db_prov_associations') and old_obj.db_prov_associations is not None:
-            for obj in old_obj.db_prov_associations:
-                new_obj.db_add_prov_association(DBProvAssociation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_associations') and hasattr(new_obj, 'db_deleted_prov_associations'):
-            for obj in old_obj.db_deleted_prov_associations:
-                n_obj = DBProvAssociation.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_associations.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'vt_source' in class_dict:
+            res = class_dict['vt_source'](old_obj, trans_dict)
+            new_obj.db_vt_source = res
+        elif hasattr(old_obj, 'db_vt_source') and old_obj.db_vt_source is not None:
+            new_obj.db_vt_source = old_obj.db_vt_source
+        if 'vt_dest' in class_dict:
+            res = class_dict['vt_dest'](old_obj, trans_dict)
+            new_obj.db_vt_dest = res
+        elif hasattr(old_obj, 'db_vt_dest') and old_obj.db_vt_dest is not None:
+            new_obj.db_vt_dest = old_obj.db_vt_dest
+        if 'vt_source_port' in class_dict:
+            res = class_dict['vt_source_port'](old_obj, trans_dict)
+            new_obj.db_vt_source_port = res
+        elif hasattr(old_obj, 'db_vt_source_port') and old_obj.db_vt_source_port is not None:
+            new_obj.db_vt_source_port = old_obj.db_vt_source_port
+        if 'vt_dest_port' in class_dict:
+            res = class_dict['vt_dest_port'](old_obj, trans_dict)
+            new_obj.db_vt_dest_port = res
+        elif hasattr(old_obj, 'db_vt_dest_port') and old_obj.db_vt_dest_port is not None:
+            new_obj.db_vt_dest_port = old_obj.db_vt_dest_port
+        if 'vt_source_signature' in class_dict:
+            res = class_dict['vt_source_signature'](old_obj, trans_dict)
+            new_obj.db_vt_source_signature = res
+        elif hasattr(old_obj, 'db_vt_source_signature') and old_obj.db_vt_source_signature is not None:
+            new_obj.db_vt_source_signature = old_obj.db_vt_source_signature
+        if 'vt_dest_signature' in class_dict:
+            res = class_dict['vt_dest_signature'](old_obj, trans_dict)
+            new_obj.db_vt_dest_signature = res
+        elif hasattr(old_obj, 'db_vt_dest_signature') and old_obj.db_vt_dest_signature is not None:
+            new_obj.db_vt_dest_signature = old_obj.db_vt_dest_signature
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_prov_entitys:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_prov_entity(child)
-        to_del = []
-        for child in self.db_prov_activitys:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_prov_activity(child)
-        to_del = []
-        for child in self.db_prov_agents:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_prov_agent(child)
-        to_del = []
-        for child in self.db_vt_connections:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_vt_connection(child)
-        to_del = []
-        for child in self.db_prov_usages:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_prov_usage(child)
-        to_del = []
-        for child in self.db_prov_generations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_prov_generation(child)
-        to_del = []
-        for child in self.db_prov_associations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_prov_association(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_prov_entitys)
-        children.extend(self.db_deleted_prov_activitys)
-        children.extend(self.db_deleted_prov_agents)
-        children.extend(self.db_deleted_vt_connections)
-        children.extend(self.db_deleted_prov_usages)
-        children.extend(self.db_deleted_prov_generations)
-        children.extend(self.db_deleted_prov_associations)
-        if remove:
-            self.db_deleted_prov_entitys = []
-            self.db_deleted_prov_activitys = []
-            self.db_deleted_prov_agents = []
-            self.db_deleted_vt_connections = []
-            self.db_deleted_prov_usages = []
-            self.db_deleted_prov_generations = []
-            self.db_deleted_prov_associations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_prov_entitys:
-            if child.has_changes():
-                return True
-        for child in self._db_prov_activitys:
-            if child.has_changes():
-                return True
-        for child in self._db_prov_agents:
-            if child.has_changes():
-                return True
-        for child in self._db_vt_connections:
-            if child.has_changes():
-                return True
-        for child in self._db_prov_usages:
-            if child.has_changes():
-                return True
-        for child in self._db_prov_generations:
-            if child.has_changes():
-                return True
-        for child in self._db_prov_associations:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_prov_entitys(self):
-        return self._db_prov_entitys
-    def __set_db_prov_entitys(self, prov_entitys):
-        self._db_prov_entitys = prov_entitys
-        self.is_dirty = True
-    db_prov_entitys = property(__get_db_prov_entitys, __set_db_prov_entitys)
-    def db_get_prov_entitys(self):
-        return self._db_prov_entitys
-    def db_add_prov_entity(self, prov_entity):
-        self.is_dirty = True
-        self._db_prov_entitys.append(prov_entity)
-        self.db_prov_entitys_id_index[prov_entity.db_id] = prov_entity
-    def db_change_prov_entity(self, prov_entity):
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_prov_entitys)):
-            if self._db_prov_entitys[i].db_id == prov_entity.db_id:
-                self._db_prov_entitys[i] = prov_entity
-                found = True
-                break
-        if not found:
-            self._db_prov_entitys.append(prov_entity)
-        self.db_prov_entitys_id_index[prov_entity.db_id] = prov_entity
-    def db_delete_prov_entity(self, prov_entity):
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_vt_source(self):
+        return self._db_vt_source
+    def __set_db_vt_source(self, vt_source):
+        self._db_vt_source = vt_source
         self.is_dirty = True
-        for i in xrange(len(self._db_prov_entitys)):
-            if self._db_prov_entitys[i].db_id == prov_entity.db_id:
-                if not self._db_prov_entitys[i].is_new:
-                    self.db_deleted_prov_entitys.append(self._db_prov_entitys[i])
-                del self._db_prov_entitys[i]
-                break
-        del self.db_prov_entitys_id_index[prov_entity.db_id]
-    def db_get_prov_entity(self, key):
-        for i in xrange(len(self._db_prov_entitys)):
-            if self._db_prov_entitys[i].db_id == key:
-                return self._db_prov_entitys[i]
-        return None
-    def db_get_prov_entity_by_id(self, key):
-        return self.db_prov_entitys_id_index[key]
-    def db_has_prov_entity_with_id(self, key):
-        return key in self.db_prov_entitys_id_index
+    db_vt_source = property(__get_db_vt_source, __set_db_vt_source)
+    def db_add_vt_source(self, vt_source):
+        self._db_vt_source = vt_source
+    def db_change_vt_source(self, vt_source):
+        self._db_vt_source = vt_source
+    def db_delete_vt_source(self, vt_source):
+        self._db_vt_source = None
     
-    def __get_db_prov_activitys(self):
-        return self._db_prov_activitys
-    def __set_db_prov_activitys(self, prov_activitys):
-        self._db_prov_activitys = prov_activitys
+    def __get_db_vt_dest(self):
+        return self._db_vt_dest
+    def __set_db_vt_dest(self, vt_dest):
+        self._db_vt_dest = vt_dest
         self.is_dirty = True
-    db_prov_activitys = property(__get_db_prov_activitys, __set_db_prov_activitys)
-    def db_get_prov_activitys(self):
-        return self._db_prov_activitys
-    def db_add_prov_activity(self, prov_activity):
+    db_vt_dest = property(__get_db_vt_dest, __set_db_vt_dest)
+    def db_add_vt_dest(self, vt_dest):
+        self._db_vt_dest = vt_dest
+    def db_change_vt_dest(self, vt_dest):
+        self._db_vt_dest = vt_dest
+    def db_delete_vt_dest(self, vt_dest):
+        self._db_vt_dest = None
+    
+    def __get_db_vt_source_port(self):
+        return self._db_vt_source_port
+    def __set_db_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = vt_source_port
         self.is_dirty = True
-        self._db_prov_activitys.append(prov_activity)
-        self.db_prov_activitys_id_index[prov_activity.db_id] = prov_activity
-    def db_change_prov_activity(self, prov_activity):
+    db_vt_source_port = property(__get_db_vt_source_port, __set_db_vt_source_port)
+    def db_add_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = vt_source_port
+    def db_change_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = vt_source_port
+    def db_delete_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = None
+    
+    def __get_db_vt_dest_port(self):
+        return self._db_vt_dest_port
+    def __set_db_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = vt_dest_port
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_prov_activitys)):
-            if self._db_prov_activitys[i].db_id == prov_activity.db_id:
-                self._db_prov_activitys[i] = prov_activity
-                found = True
-                break
-        if not found:
-            self._db_prov_activitys.append(prov_activity)
-        self.db_prov_activitys_id_index[prov_activity.db_id] = prov_activity
-    def db_delete_prov_activity(self, prov_activity):
-        self.is_dirty = True
-        for i in xrange(len(self._db_prov_activitys)):
-            if self._db_prov_activitys[i].db_id == prov_activity.db_id:
-                if not self._db_prov_activitys[i].is_new:
-                    self.db_deleted_prov_activitys.append(self._db_prov_activitys[i])
-                del self._db_prov_activitys[i]
-                break
-        del self.db_prov_activitys_id_index[prov_activity.db_id]
-    def db_get_prov_activity(self, key):
-        for i in xrange(len(self._db_prov_activitys)):
-            if self._db_prov_activitys[i].db_id == key:
-                return self._db_prov_activitys[i]
-        return None
-    def db_get_prov_activity_by_id(self, key):
-        return self.db_prov_activitys_id_index[key]
-    def db_has_prov_activity_with_id(self, key):
-        return key in self.db_prov_activitys_id_index
-    
-    def __get_db_prov_agents(self):
-        return self._db_prov_agents
-    def __set_db_prov_agents(self, prov_agents):
-        self._db_prov_agents = prov_agents
-        self.is_dirty = True
-    db_prov_agents = property(__get_db_prov_agents, __set_db_prov_agents)
-    def db_get_prov_agents(self):
-        return self._db_prov_agents
-    def db_add_prov_agent(self, prov_agent):
-        self.is_dirty = True
-        self._db_prov_agents.append(prov_agent)
-        self.db_prov_agents_id_index[prov_agent.db_id] = prov_agent
-    def db_change_prov_agent(self, prov_agent):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_prov_agents)):
-            if self._db_prov_agents[i].db_id == prov_agent.db_id:
-                self._db_prov_agents[i] = prov_agent
-                found = True
-                break
-        if not found:
-            self._db_prov_agents.append(prov_agent)
-        self.db_prov_agents_id_index[prov_agent.db_id] = prov_agent
-    def db_delete_prov_agent(self, prov_agent):
-        self.is_dirty = True
-        for i in xrange(len(self._db_prov_agents)):
-            if self._db_prov_agents[i].db_id == prov_agent.db_id:
-                if not self._db_prov_agents[i].is_new:
-                    self.db_deleted_prov_agents.append(self._db_prov_agents[i])
-                del self._db_prov_agents[i]
-                break
-        del self.db_prov_agents_id_index[prov_agent.db_id]
-    def db_get_prov_agent(self, key):
-        for i in xrange(len(self._db_prov_agents)):
-            if self._db_prov_agents[i].db_id == key:
-                return self._db_prov_agents[i]
-        return None
-    def db_get_prov_agent_by_id(self, key):
-        return self.db_prov_agents_id_index[key]
-    def db_has_prov_agent_with_id(self, key):
-        return key in self.db_prov_agents_id_index
-    
-    def __get_db_vt_connections(self):
-        return self._db_vt_connections
-    def __set_db_vt_connections(self, vt_connections):
-        self._db_vt_connections = vt_connections
-        self.is_dirty = True
-    db_vt_connections = property(__get_db_vt_connections, __set_db_vt_connections)
-    def db_get_vt_connections(self):
-        return self._db_vt_connections
-    def db_add_vt_connection(self, vt_connection):
-        self.is_dirty = True
-        self._db_vt_connections.append(vt_connection)
-        self.db_vt_connections_id_index[vt_connection.db_id] = vt_connection
-    def db_change_vt_connection(self, vt_connection):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_vt_connections)):
-            if self._db_vt_connections[i].db_id == vt_connection.db_id:
-                self._db_vt_connections[i] = vt_connection
-                found = True
-                break
-        if not found:
-            self._db_vt_connections.append(vt_connection)
-        self.db_vt_connections_id_index[vt_connection.db_id] = vt_connection
-    def db_delete_vt_connection(self, vt_connection):
-        self.is_dirty = True
-        for i in xrange(len(self._db_vt_connections)):
-            if self._db_vt_connections[i].db_id == vt_connection.db_id:
-                if not self._db_vt_connections[i].is_new:
-                    self.db_deleted_vt_connections.append(self._db_vt_connections[i])
-                del self._db_vt_connections[i]
-                break
-        del self.db_vt_connections_id_index[vt_connection.db_id]
-    def db_get_vt_connection(self, key):
-        for i in xrange(len(self._db_vt_connections)):
-            if self._db_vt_connections[i].db_id == key:
-                return self._db_vt_connections[i]
-        return None
-    def db_get_vt_connection_by_id(self, key):
-        return self.db_vt_connections_id_index[key]
-    def db_has_vt_connection_with_id(self, key):
-        return key in self.db_vt_connections_id_index
-    
-    def __get_db_prov_usages(self):
-        return self._db_prov_usages
-    def __set_db_prov_usages(self, prov_usages):
-        self._db_prov_usages = prov_usages
-        self.is_dirty = True
-    db_prov_usages = property(__get_db_prov_usages, __set_db_prov_usages)
-    def db_get_prov_usages(self):
-        return self._db_prov_usages
-    def db_add_prov_usage(self, prov_usage):
-        self.is_dirty = True
-        self._db_prov_usages.append(prov_usage)
-    def db_change_prov_usage(self, prov_usage):
-        self.is_dirty = True
-        self._db_prov_usages.append(prov_usage)
-    def db_delete_prov_usage(self, prov_usage):
-        self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_prov_usage(self, key):
-        return None
+    db_vt_dest_port = property(__get_db_vt_dest_port, __set_db_vt_dest_port)
+    def db_add_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = vt_dest_port
+    def db_change_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = vt_dest_port
+    def db_delete_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = None
     
-    def __get_db_prov_generations(self):
-        return self._db_prov_generations
-    def __set_db_prov_generations(self, prov_generations):
-        self._db_prov_generations = prov_generations
-        self.is_dirty = True
-    db_prov_generations = property(__get_db_prov_generations, __set_db_prov_generations)
-    def db_get_prov_generations(self):
-        return self._db_prov_generations
-    def db_add_prov_generation(self, prov_generation):
-        self.is_dirty = True
-        self._db_prov_generations.append(prov_generation)
-    def db_change_prov_generation(self, prov_generation):
-        self.is_dirty = True
-        self._db_prov_generations.append(prov_generation)
-    def db_delete_prov_generation(self, prov_generation):
+    def __get_db_vt_source_signature(self):
+        return self._db_vt_source_signature
+    def __set_db_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = vt_source_signature
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_prov_generation(self, key):
-        return None
+    db_vt_source_signature = property(__get_db_vt_source_signature, __set_db_vt_source_signature)
+    def db_add_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = vt_source_signature
+    def db_change_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = vt_source_signature
+    def db_delete_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = None
     
-    def __get_db_prov_associations(self):
-        return self._db_prov_associations
-    def __set_db_prov_associations(self, prov_associations):
-        self._db_prov_associations = prov_associations
-        self.is_dirty = True
-    db_prov_associations = property(__get_db_prov_associations, __set_db_prov_associations)
-    def db_get_prov_associations(self):
-        return self._db_prov_associations
-    def db_add_prov_association(self, prov_association):
-        self.is_dirty = True
-        self._db_prov_associations.append(prov_association)
-    def db_change_prov_association(self, prov_association):
-        self.is_dirty = True
-        self._db_prov_associations.append(prov_association)
-    def db_delete_prov_association(self, prov_association):
+    def __get_db_vt_dest_signature(self):
+        return self._db_vt_dest_signature
+    def __set_db_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = vt_dest_signature
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_prov_association(self, key):
-        return None
+    db_vt_dest_signature = property(__get_db_vt_dest_signature, __set_db_vt_dest_signature)
+    def db_add_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = vt_dest_signature
+    def db_change_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = vt_dest_signature
+    def db_delete_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = None
     
-
+    def getPrimaryKey(self):
+        return self._db_id
 
 class DBOpmAccount(object):
 
@@ -2809,43 +2397,79 @@ class DBOpmAccount(object):
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmProcesses(object):
+class DBGroupExec(object):
 
-    vtType = 'opm_processes'
+    vtType = 'group_exec'
 
-    def __init__(self, processs=None):
-        self.db_deleted_processs = []
-        self.db_processs_id_index = {}
-        if processs is None:
-            self._db_processs = []
+    def __init__(self, item_execs=None, id=None, ts_start=None, ts_end=None, cached=None, module_id=None, group_name=None, group_type=None, completed=None, error=None, machine_id=None, annotations=None):
+        self.db_deleted_item_execs = []
+        self.db_item_execs_id_index = {}
+        if item_execs is None:
+            self._db_item_execs = []
         else:
-            self._db_processs = processs
-            for v in self._db_processs:
-                self.db_processs_id_index[v.db_id] = v
+            self._db_item_execs = item_execs
+            for v in self._db_item_execs:
+                self.db_item_execs_id_index[v.db_id] = v
+        self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_cached = cached
+        self._db_module_id = module_id
+        self._db_group_name = group_name
+        self._db_group_type = group_type
+        self._db_completed = completed
+        self._db_error = error
+        self._db_machine_id = machine_id
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmProcesses.do_copy(self)
+        return DBGroupExec.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmProcesses()
-        if self._db_processs is None:
-            cp._db_processs = []
+        cp = DBGroupExec(id=self._db_id,
+                         ts_start=self._db_ts_start,
+                         ts_end=self._db_ts_end,
+                         cached=self._db_cached,
+                         module_id=self._db_module_id,
+                         group_name=self._db_group_name,
+                         group_type=self._db_group_type,
+                         completed=self._db_completed,
+                         error=self._db_error,
+                         machine_id=self._db_machine_id)
+        if self._db_item_execs is None:
+            cp._db_item_execs = []
         else:
-            cp._db_processs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_processs]
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
+            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
             if self.vtType in id_scope.remap:
                 id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
+                cp._db_module_id = id_remap[('module', self._db_module_id)]
+            if hasattr(self, 'db_machine_id') and ('machine', self._db_machine_id) in id_remap:
+                cp._db_machine_id = id_remap[('machine', self._db_machine_id)]
         
         # recreate indices and set flags
-        cp.db_processs_id_index = dict((v.db_id, v) for v in cp._db_processs)
+        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -2854,21 +2478,94 @@ class DBOpmProcesses(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmProcesses()
+            new_obj = DBGroupExec()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'processs' in class_dict:
-            res = class_dict['processs'](old_obj, trans_dict)
+        if 'item_execs' in class_dict:
+            res = class_dict['item_execs'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_process(obj)
-        elif hasattr(old_obj, 'db_processs') and old_obj.db_processs is not None:
-            for obj in old_obj.db_processs:
-                new_obj.db_add_process(DBOpmProcess.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_processs') and hasattr(new_obj, 'db_deleted_processs'):
-            for obj in old_obj.db_deleted_processs:
-                n_obj = DBOpmProcess.update_version(obj, trans_dict)
-                new_obj.db_deleted_processs.append(n_obj)
+                new_obj.db_add_item_exec(obj)
+        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
+            for obj in old_obj.db_item_execs:
+                if obj.vtType == 'module_exec':
+                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'group_exec':
+                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'loop_exec':
+                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
+            for obj in old_obj.db_deleted_item_execs:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'cached' in class_dict:
+            res = class_dict['cached'](old_obj, trans_dict)
+            new_obj.db_cached = res
+        elif hasattr(old_obj, 'db_cached') and old_obj.db_cached is not None:
+            new_obj.db_cached = old_obj.db_cached
+        if 'module_id' in class_dict:
+            res = class_dict['module_id'](old_obj, trans_dict)
+            new_obj.db_module_id = res
+        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
+            new_obj.db_module_id = old_obj.db_module_id
+        if 'group_name' in class_dict:
+            res = class_dict['group_name'](old_obj, trans_dict)
+            new_obj.db_group_name = res
+        elif hasattr(old_obj, 'db_group_name') and old_obj.db_group_name is not None:
+            new_obj.db_group_name = old_obj.db_group_name
+        if 'group_type' in class_dict:
+            res = class_dict['group_type'](old_obj, trans_dict)
+            new_obj.db_group_type = res
+        elif hasattr(old_obj, 'db_group_type') and old_obj.db_group_type is not None:
+            new_obj.db_group_type = old_obj.db_group_type
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'error' in class_dict:
+            res = class_dict['error'](old_obj, trans_dict)
+            new_obj.db_error = res
+        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
+            new_obj.db_error = old_obj.db_error
+        if 'machine_id' in class_dict:
+            res = class_dict['machine_id'](old_obj, trans_dict)
+            new_obj.db_machine_id = res
+        elif hasattr(old_obj, 'db_machine_id') and old_obj.db_machine_id is not None:
+            new_obj.db_machine_id = old_obj.db_machine_id
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -2876,146 +2573,259 @@ class DBOpmProcesses(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_processs:
+        for child in self.db_annotations:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_process(child)
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_item_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_item_exec(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_processs)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_item_execs)
         if remove:
-            self.db_deleted_processs = []
+            self.db_deleted_annotations = []
+            self.db_deleted_item_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_processs:
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_item_execs:
             if child.has_changes():
                 return True
         return False
-    def __get_db_processs(self):
-        return self._db_processs
-    def __set_db_processs(self, processs):
-        self._db_processs = processs
+    def __get_db_item_execs(self):
+        return self._db_item_execs
+    def __set_db_item_execs(self, item_execs):
+        self._db_item_execs = item_execs
         self.is_dirty = True
-    db_processs = property(__get_db_processs, __set_db_processs)
-    def db_get_processs(self):
-        return self._db_processs
-    def db_add_process(self, process):
+    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
+    def db_get_item_execs(self):
+        return self._db_item_execs
+    def db_add_item_exec(self, item_exec):
         self.is_dirty = True
-        self._db_processs.append(process)
-        self.db_processs_id_index[process.db_id] = process
-    def db_change_process(self, process):
+        self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_change_item_exec(self, item_exec):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_processs)):
-            if self._db_processs[i].db_id == process.db_id:
-                self._db_processs[i] = process
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                self._db_item_execs[i] = item_exec
                 found = True
                 break
         if not found:
-            self._db_processs.append(process)
-        self.db_processs_id_index[process.db_id] = process
-    def db_delete_process(self, process):
+            self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_delete_item_exec(self, item_exec):
         self.is_dirty = True
-        for i in xrange(len(self._db_processs)):
-            if self._db_processs[i].db_id == process.db_id:
-                if not self._db_processs[i].is_new:
-                    self.db_deleted_processs.append(self._db_processs[i])
-                del self._db_processs[i]
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                if not self._db_item_execs[i].is_new:
+                    self.db_deleted_item_execs.append(self._db_item_execs[i])
+                del self._db_item_execs[i]
                 break
-        del self.db_processs_id_index[process.db_id]
-    def db_get_process(self, key):
-        for i in xrange(len(self._db_processs)):
-            if self._db_processs[i].db_id == key:
-                return self._db_processs[i]
+        del self.db_item_execs_id_index[item_exec.db_id]
+    def db_get_item_exec(self, key):
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == key:
+                return self._db_item_execs[i]
         return None
-    def db_get_process_by_id(self, key):
-        return self.db_processs_id_index[key]
-    def db_has_process_with_id(self, key):
-        return key in self.db_processs_id_index
+    def db_get_item_exec_by_id(self, key):
+        return self.db_item_execs_id_index[key]
+    def db_has_item_exec_with_id(self, key):
+        return key in self.db_item_execs_id_index
     
-
-
-class DBRefProvActivity(object):
-
-    vtType = 'ref_prov_activity'
-
-    def __init__(self, prov_ref=None):
-        self._db_prov_ref = prov_ref
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-        self.is_new = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __copy__(self):
-        return DBRefProvActivity.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBRefProvActivity(prov_ref=self._db_prov_ref)
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
-            if self.vtType in id_scope.remap:
-                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-            if hasattr(self, 'db_prov_ref') and ('prov_activity', self._db_prov_ref) in id_remap:
-                cp._db_prov_ref = id_remap[('prov_activity', self._db_prov_ref)]
-        
-        # recreate indices and set flags
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBRefProvActivity()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_ref' in class_dict:
-            res = class_dict['prov_ref'](old_obj, trans_dict)
-            new_obj.db_prov_ref = res
-        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
-            new_obj.db_prov_ref = old_obj.db_prov_ref
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
-    def db_deleted_children(self, remove=False):
-        children = []
-        return children
-    def has_changes(self):
-        if self.is_dirty:
-            return True
-        return False
-    def __get_db_prov_ref(self):
-        return self._db_prov_ref
-    def __set_db_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
         self.is_dirty = True
-    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
-    def db_add_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_change_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_delete_prov_ref(self, prov_ref):
-        self._db_prov_ref = None
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
     
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_cached(self):
+        return self._db_cached
+    def __set_db_cached(self, cached):
+        self._db_cached = cached
+        self.is_dirty = True
+    db_cached = property(__get_db_cached, __set_db_cached)
+    def db_add_cached(self, cached):
+        self._db_cached = cached
+    def db_change_cached(self, cached):
+        self._db_cached = cached
+    def db_delete_cached(self, cached):
+        self._db_cached = None
+    
+    def __get_db_module_id(self):
+        return self._db_module_id
+    def __set_db_module_id(self, module_id):
+        self._db_module_id = module_id
+        self.is_dirty = True
+    db_module_id = property(__get_db_module_id, __set_db_module_id)
+    def db_add_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_change_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_delete_module_id(self, module_id):
+        self._db_module_id = None
+    
+    def __get_db_group_name(self):
+        return self._db_group_name
+    def __set_db_group_name(self, group_name):
+        self._db_group_name = group_name
+        self.is_dirty = True
+    db_group_name = property(__get_db_group_name, __set_db_group_name)
+    def db_add_group_name(self, group_name):
+        self._db_group_name = group_name
+    def db_change_group_name(self, group_name):
+        self._db_group_name = group_name
+    def db_delete_group_name(self, group_name):
+        self._db_group_name = None
+    
+    def __get_db_group_type(self):
+        return self._db_group_type
+    def __set_db_group_type(self, group_type):
+        self._db_group_type = group_type
+        self.is_dirty = True
+    db_group_type = property(__get_db_group_type, __set_db_group_type)
+    def db_add_group_type(self, group_type):
+        self._db_group_type = group_type
+    def db_change_group_type(self, group_type):
+        self._db_group_type = group_type
+    def db_delete_group_type(self, group_type):
+        self._db_group_type = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_error(self):
+        return self._db_error
+    def __set_db_error(self, error):
+        self._db_error = error
+        self.is_dirty = True
+    db_error = property(__get_db_error, __set_db_error)
+    def db_add_error(self, error):
+        self._db_error = error
+    def db_change_error(self, error):
+        self._db_error = error
+    def db_delete_error(self, error):
+        self._db_error = None
+    
+    def __get_db_machine_id(self):
+        return self._db_machine_id
+    def __set_db_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+        self.is_dirty = True
+    db_machine_id = property(__get_db_machine_id, __set_db_machine_id)
+    def db_add_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_change_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_delete_machine_id(self, machine_id):
+        self._db_machine_id = None
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBOpmAgentId(object):
 
-class DBOpmAccountId(object):
-
-    vtType = 'opm_account_id'
+    vtType = 'opm_agent_id'
 
     def __init__(self, id=None):
         self._db_id = id
@@ -3023,10 +2833,10 @@ class DBOpmAccountId(object):
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmAccountId.do_copy(self)
+        return DBOpmAgentId.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmAccountId(id=self._db_id)
+        cp = DBOpmAgentId(id=self._db_id)
         
         # set new ids
         if new_ids:
@@ -3036,8 +2846,8 @@ class DBOpmAccountId(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('opm_account', self._db_id) in id_remap:
-                cp._db_id = id_remap[('opm_account', self._db_id)]
+            if hasattr(self, 'db_id') and ('opm_agent', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_agent', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -3048,7 +2858,7 @@ class DBOpmAccountId(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmAccountId()
+            new_obj = DBOpmAgentId()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -3085,30 +2895,30 @@ class DBOpmAccountId(object):
     
 
 
-class DBPort(object):
+class DBParameter(object):
 
-    vtType = 'port'
+    vtType = 'parameter'
 
-    def __init__(self, id=None, type=None, moduleId=None, moduleName=None, name=None, signature=None):
+    def __init__(self, id=None, pos=None, name=None, type=None, val=None, alias=None):
         self._db_id = id
-        self._db_type = type
-        self._db_moduleId = moduleId
-        self._db_moduleName = moduleName
+        self._db_pos = pos
         self._db_name = name
-        self._db_signature = signature
+        self._db_type = type
+        self._db_val = val
+        self._db_alias = alias
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBPort.do_copy(self)
+        return DBParameter.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPort(id=self._db_id,
-                    type=self._db_type,
-                    moduleId=self._db_moduleId,
-                    moduleName=self._db_moduleName,
-                    name=self._db_name,
-                    signature=self._db_signature)
+        cp = DBParameter(id=self._db_id,
+                         pos=self._db_pos,
+                         name=self._db_name,
+                         type=self._db_type,
+                         val=self._db_val,
+                         alias=self._db_alias)
         
         # set new ids
         if new_ids:
@@ -3118,8 +2928,6 @@ class DBPort(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_moduleId') and ('module', self._db_moduleId) in id_remap:
-                cp._db_moduleId = id_remap[('module', self._db_moduleId)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -3130,7 +2938,7 @@ class DBPort(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBPort()
+            new_obj = DBParameter()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -3139,38 +2947,38 @@ class DBPort(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'type' in class_dict:
-            res = class_dict['type'](old_obj, trans_dict)
-            new_obj.db_type = res
-        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
-            new_obj.db_type = old_obj.db_type
-        if 'moduleId' in class_dict:
-            res = class_dict['moduleId'](old_obj, trans_dict)
-            new_obj.db_moduleId = res
-        elif hasattr(old_obj, 'db_moduleId') and old_obj.db_moduleId is not None:
-            new_obj.db_moduleId = old_obj.db_moduleId
-        if 'moduleName' in class_dict:
-            res = class_dict['moduleName'](old_obj, trans_dict)
-            new_obj.db_moduleName = res
-        elif hasattr(old_obj, 'db_moduleName') and old_obj.db_moduleName is not None:
-            new_obj.db_moduleName = old_obj.db_moduleName
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'signature' in class_dict:
-            res = class_dict['signature'](old_obj, trans_dict)
-            new_obj.db_signature = res
-        elif hasattr(old_obj, 'db_signature') and old_obj.db_signature is not None:
-            new_obj.db_signature = old_obj.db_signature
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
-    def db_deleted_children(self, remove=False):
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'val' in class_dict:
+            res = class_dict['val'](old_obj, trans_dict)
+            new_obj.db_val = res
+        elif hasattr(old_obj, 'db_val') and old_obj.db_val is not None:
+            new_obj.db_val = old_obj.db_val
+        if 'alias' in class_dict:
+            res = class_dict['alias'](old_obj, trans_dict)
+            new_obj.db_alias = res
+        elif hasattr(old_obj, 'db_alias') and old_obj.db_alias is not None:
+            new_obj.db_alias = old_obj.db_alias
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
         children = []
         return children
     def has_changes(self):
@@ -3190,44 +2998,18 @@ class DBPort(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_type(self):
-        return self._db_type
-    def __set_db_type(self, type):
-        self._db_type = type
-        self.is_dirty = True
-    db_type = property(__get_db_type, __set_db_type)
-    def db_add_type(self, type):
-        self._db_type = type
-    def db_change_type(self, type):
-        self._db_type = type
-    def db_delete_type(self, type):
-        self._db_type = None
-    
-    def __get_db_moduleId(self):
-        return self._db_moduleId
-    def __set_db_moduleId(self, moduleId):
-        self._db_moduleId = moduleId
-        self.is_dirty = True
-    db_moduleId = property(__get_db_moduleId, __set_db_moduleId)
-    def db_add_moduleId(self, moduleId):
-        self._db_moduleId = moduleId
-    def db_change_moduleId(self, moduleId):
-        self._db_moduleId = moduleId
-    def db_delete_moduleId(self, moduleId):
-        self._db_moduleId = None
-    
-    def __get_db_moduleName(self):
-        return self._db_moduleName
-    def __set_db_moduleName(self, moduleName):
-        self._db_moduleName = moduleName
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
         self.is_dirty = True
-    db_moduleName = property(__get_db_moduleName, __set_db_moduleName)
-    def db_add_moduleName(self, moduleName):
-        self._db_moduleName = moduleName
-    def db_change_moduleName(self, moduleName):
-        self._db_moduleName = moduleName
-    def db_delete_moduleName(self, moduleName):
-        self._db_moduleName = None
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
     
     def __get_db_name(self):
         return self._db_name
@@ -3242,36 +3024,152 @@ class DBPort(object):
     def db_delete_name(self, name):
         self._db_name = None
     
-    def __get_db_signature(self):
-        return self._db_signature
-    def __set_db_signature(self, signature):
-        self._db_signature = signature
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
         self.is_dirty = True
-    db_signature = property(__get_db_signature, __set_db_signature)
-    def db_add_signature(self, signature):
-        self._db_signature = signature
-    def db_change_signature(self, signature):
-        self._db_signature = signature
-    def db_delete_signature(self, signature):
-        self._db_signature = None
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_val(self):
+        return self._db_val
+    def __set_db_val(self, val):
+        self._db_val = val
+        self.is_dirty = True
+    db_val = property(__get_db_val, __set_db_val)
+    def db_add_val(self, val):
+        self._db_val = val
+    def db_change_val(self, val):
+        self._db_val = val
+    def db_delete_val(self, val):
+        self._db_val = None
+    
+    def __get_db_alias(self):
+        return self._db_alias
+    def __set_db_alias(self, alias):
+        self._db_alias = alias
+        self.is_dirty = True
+    db_alias = property(__get_db_alias, __set_db_alias)
+    def db_add_alias(self, alias):
+        self._db_alias = alias
+    def db_change_alias(self, alias):
+        self._db_alias = alias
+    def db_delete_alias(self, alias):
+        self._db_alias = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBRefProvPlan(object):
+class DBVistrail(object):
 
-    vtType = 'ref_prov_plan'
+    vtType = 'vistrail'
 
-    def __init__(self, prov_ref=None):
-        self._db_prov_ref = prov_ref
+    def __init__(self, id=None, entity_type=None, version=None, name=None, last_modified=None, actions=None, tags=None, annotations=None, vistrailVariables=None, parameter_explorations=None, actionAnnotations=None):
+        self._db_id = id
+        self._db_entity_type = entity_type
+        self._db_version = version
+        self._db_name = name
+        self._db_last_modified = last_modified
+        self.db_deleted_actions = []
+        self.db_actions_id_index = {}
+        if actions is None:
+            self._db_actions = []
+        else:
+            self._db_actions = actions
+            for v in self._db_actions:
+                self.db_actions_id_index[v.db_id] = v
+        self.db_deleted_tags = []
+        self.db_tags_id_index = {}
+        self.db_tags_name_index = {}
+        if tags is None:
+            self._db_tags = []
+        else:
+            self._db_tags = tags
+            for v in self._db_tags:
+                self.db_tags_id_index[v.db_id] = v
+                self.db_tags_name_index[v.db_name] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_vistrailVariables = []
+        self.db_vistrailVariables_name_index = {}
+        self.db_vistrailVariables_uuid_index = {}
+        if vistrailVariables is None:
+            self._db_vistrailVariables = []
+        else:
+            self._db_vistrailVariables = vistrailVariables
+            for v in self._db_vistrailVariables:
+                self.db_vistrailVariables_name_index[v.db_name] = v
+                self.db_vistrailVariables_uuid_index[v.db_uuid] = v
+        self.db_deleted_parameter_explorations = []
+        self.db_parameter_explorations_id_index = {}
+        if parameter_explorations is None:
+            self._db_parameter_explorations = []
+        else:
+            self._db_parameter_explorations = parameter_explorations
+            for v in self._db_parameter_explorations:
+                self.db_parameter_explorations_id_index[v.db_id] = v
+        self.db_deleted_actionAnnotations = []
+        self.db_actionAnnotations_id_index = {}
+        self.db_actionAnnotations_action_id_index = {}
+        self.db_actionAnnotations_key_index = {}
+        if actionAnnotations is None:
+            self._db_actionAnnotations = []
+        else:
+            self._db_actionAnnotations = actionAnnotations
+            for v in self._db_actionAnnotations:
+                self.db_actionAnnotations_id_index[v.db_id] = v
+                self.db_actionAnnotations_action_id_index[(v.db_action_id,v.db_key)] = v
+                self.db_actionAnnotations_key_index[(v.db_key,v.db_value)] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBRefProvPlan.do_copy(self)
+        return DBVistrail.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBRefProvPlan(prov_ref=self._db_prov_ref)
+        cp = DBVistrail(id=self._db_id,
+                        entity_type=self._db_entity_type,
+                        version=self._db_version,
+                        name=self._db_name,
+                        last_modified=self._db_last_modified)
+        if self._db_actions is None:
+            cp._db_actions = []
+        else:
+            cp._db_actions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actions]
+        if self._db_tags is None:
+            cp._db_tags = []
+        else:
+            cp._db_tags = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_tags]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_vistrailVariables is None:
+            cp._db_vistrailVariables = []
+        else:
+            cp._db_vistrailVariables = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_vistrailVariables]
+        if self._db_parameter_explorations is None:
+            cp._db_parameter_explorations = []
+        else:
+            cp._db_parameter_explorations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameter_explorations]
+        if self._db_actionAnnotations is None:
+            cp._db_actionAnnotations = []
+        else:
+            cp._db_actionAnnotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actionAnnotations]
         
         # set new ids
         if new_ids:
@@ -3281,10 +3179,19 @@ class DBRefProvPlan(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_prov_ref') and ('prov_entity', self._db_prov_ref) in id_remap:
-                cp._db_prov_ref = id_remap[('prov_entity', self._db_prov_ref)]
         
         # recreate indices and set flags
+        cp.db_actions_id_index = dict((v.db_id, v) for v in cp._db_actions)
+        cp.db_tags_id_index = dict((v.db_id, v) for v in cp._db_tags)
+        cp.db_tags_name_index = dict((v.db_name, v) for v in cp._db_tags)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_vistrailVariables_name_index = dict((v.db_name, v) for v in cp._db_vistrailVariables)
+        cp.db_vistrailVariables_uuid_index = dict((v.db_uuid, v) for v in cp._db_vistrailVariables)
+        cp.db_parameter_explorations_id_index = dict((v.db_id, v) for v in cp._db_parameter_explorations)
+        cp.db_actionAnnotations_id_index = dict((v.db_id, v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_action_id_index = dict(((v.db_action_id,v.db_key), v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_key_index = dict(((v.db_key,v.db_value), v) for v in cp._db_actionAnnotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -3293,90 +3200,7 @@ class DBRefProvPlan(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBRefProvPlan()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_ref' in class_dict:
-            res = class_dict['prov_ref'](old_obj, trans_dict)
-            new_obj.db_prov_ref = res
-        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
-            new_obj.db_prov_ref = old_obj.db_prov_ref
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
-    def db_deleted_children(self, remove=False):
-        children = []
-        return children
-    def has_changes(self):
-        if self.is_dirty:
-            return True
-        return False
-    def __get_db_prov_ref(self):
-        return self._db_prov_ref
-    def __set_db_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-        self.is_dirty = True
-    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
-    def db_add_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_change_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_delete_prov_ref(self, prov_ref):
-        self._db_prov_ref = None
-    
-
-
-class DBOpmArtifact(object):
-
-    vtType = 'opm_artifact'
-
-    def __init__(self, id=None, value=None, accounts=None):
-        self._db_id = id
-        self.db_deleted_value = []
-        self._db_value = value
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
-        else:
-            self._db_accounts = accounts
-        self.is_dirty = True
-        self.is_new = True
-    
-    def __copy__(self):
-        return DBOpmArtifact.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmArtifact(id=self._db_id)
-        if self._db_value is not None:
-            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
-        else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
-            if self.vtType in id_scope.remap:
-                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-        
-        # recreate indices and set flags
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBOpmArtifact()
+            new_obj = DBVistrail()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -3385,60 +3209,177 @@ class DBOpmArtifact(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            obj = old_obj.db_value
-            new_obj.db_add_value(DBOpmArtifactValue.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
-            for obj in old_obj.db_deleted_value:
-                n_obj = DBOpmArtifactValue.update_version(obj, trans_dict)
-                new_obj.db_deleted_value.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'actions' in class_dict:
+            res = class_dict['actions'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
+                new_obj.db_add_action(obj)
+        elif hasattr(old_obj, 'db_actions') and old_obj.db_actions is not None:
+            for obj in old_obj.db_actions:
+                new_obj.db_add_action(DBAction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actions') and hasattr(new_obj, 'db_deleted_actions'):
+            for obj in old_obj.db_deleted_actions:
+                n_obj = DBAction.update_version(obj, trans_dict)
+                new_obj.db_deleted_actions.append(n_obj)
+        if 'tags' in class_dict:
+            res = class_dict['tags'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_tag(obj)
+        elif hasattr(old_obj, 'db_tags') and old_obj.db_tags is not None:
+            for obj in old_obj.db_tags:
+                new_obj.db_add_tag(DBTag.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_tags') and hasattr(new_obj, 'db_deleted_tags'):
+            for obj in old_obj.db_deleted_tags:
+                n_obj = DBTag.update_version(obj, trans_dict)
+                new_obj.db_deleted_tags.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'vistrailVariables' in class_dict:
+            res = class_dict['vistrailVariables'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_vistrailVariable(obj)
+        elif hasattr(old_obj, 'db_vistrailVariables') and old_obj.db_vistrailVariables is not None:
+            for obj in old_obj.db_vistrailVariables:
+                new_obj.db_add_vistrailVariable(DBVistrailVariable.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_vistrailVariables') and hasattr(new_obj, 'db_deleted_vistrailVariables'):
+            for obj in old_obj.db_deleted_vistrailVariables:
+                n_obj = DBVistrailVariable.update_version(obj, trans_dict)
+                new_obj.db_deleted_vistrailVariables.append(n_obj)
+        if 'parameter_explorations' in class_dict:
+            res = class_dict['parameter_explorations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_parameter_exploration(obj)
+        elif hasattr(old_obj, 'db_parameter_explorations') and old_obj.db_parameter_explorations is not None:
+            for obj in old_obj.db_parameter_explorations:
+                new_obj.db_add_parameter_exploration(DBParameterExploration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_parameter_explorations') and hasattr(new_obj, 'db_deleted_parameter_explorations'):
+            for obj in old_obj.db_deleted_parameter_explorations:
+                n_obj = DBParameterExploration.update_version(obj, trans_dict)
+                new_obj.db_deleted_parameter_explorations.append(n_obj)
+        if 'actionAnnotations' in class_dict:
+            res = class_dict['actionAnnotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_actionAnnotation(obj)
+        elif hasattr(old_obj, 'db_actionAnnotations') and old_obj.db_actionAnnotations is not None:
+            for obj in old_obj.db_actionAnnotations:
+                new_obj.db_add_actionAnnotation(DBActionAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actionAnnotations') and hasattr(new_obj, 'db_deleted_actionAnnotations'):
+            for obj in old_obj.db_deleted_actionAnnotations:
+                n_obj = DBActionAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_actionAnnotations.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_value is not None:
-            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+        to_del = []
+        for child in self.db_actions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_value = None
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_action(child)
         to_del = []
-        for child in self.db_accounts:
+        for child in self.db_tags:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_account(child)
+            self.db_delete_tag(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_vistrailVariables:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_vistrailVariable(child)
+        to_del = []
+        for child in self.db_parameter_explorations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_parameter_exploration(child)
+        to_del = []
+        for child in self.db_actionAnnotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_actionAnnotation(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_value)
-        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_actions)
+        children.extend(self.db_deleted_tags)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_vistrailVariables)
+        children.extend(self.db_deleted_parameter_explorations)
+        children.extend(self.db_deleted_actionAnnotations)
         if remove:
-            self.db_deleted_value = []
-            self.db_deleted_accounts = []
+            self.db_deleted_actions = []
+            self.db_deleted_tags = []
+            self.db_deleted_annotations = []
+            self.db_deleted_vistrailVariables = []
+            self.db_deleted_parameter_explorations = []
+            self.db_deleted_actionAnnotations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_value is not None and self._db_value.has_changes():
-            return True
-        for child in self._db_accounts:
+        for child in self._db_actions:
+            if child.has_changes():
+                return True
+        for child in self._db_tags:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_vistrailVariables:
+            if child.has_changes():
+                return True
+        for child in self._db_parameter_explorations:
+            if child.has_changes():
+                return True
+        for child in self._db_actionAnnotations:
             if child.has_changes():
                 return True
         return False
@@ -3455,102 +3396,1899 @@ class DBOpmArtifact(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_actions(self):
+        return self._db_actions
+    def __set_db_actions(self, actions):
+        self._db_actions = actions
+        self.is_dirty = True
+    db_actions = property(__get_db_actions, __set_db_actions)
+    def db_get_actions(self):
+        return self._db_actions
+    def db_add_action(self, action):
+        self.is_dirty = True
+        self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_change_action(self, action):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                self._db_actions[i] = action
+                found = True
+                break
+        if not found:
+            self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_delete_action(self, action):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                if not self._db_actions[i].is_new:
+                    self.db_deleted_actions.append(self._db_actions[i])
+                del self._db_actions[i]
+                break
+        del self.db_actions_id_index[action.db_id]
+    def db_get_action(self, key):
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == key:
+                return self._db_actions[i]
+        return None
+    def db_get_action_by_id(self, key):
+        return self.db_actions_id_index[key]
+    def db_has_action_with_id(self, key):
+        return key in self.db_actions_id_index
+    
+    def __get_db_tags(self):
+        return self._db_tags
+    def __set_db_tags(self, tags):
+        self._db_tags = tags
+        self.is_dirty = True
+    db_tags = property(__get_db_tags, __set_db_tags)
+    def db_get_tags(self):
+        return self._db_tags
+    def db_add_tag(self, tag):
+        self.is_dirty = True
+        self._db_tags.append(tag)
+        self.db_tags_id_index[tag.db_id] = tag
+        self.db_tags_name_index[tag.db_name] = tag
+    def db_change_tag(self, tag):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_tags)):
+            if self._db_tags[i].db_id == tag.db_id:
+                self._db_tags[i] = tag
+                found = True
+                break
+        if not found:
+            self._db_tags.append(tag)
+        self.db_tags_id_index[tag.db_id] = tag
+        self.db_tags_name_index[tag.db_name] = tag
+    def db_delete_tag(self, tag):
+        self.is_dirty = True
+        for i in xrange(len(self._db_tags)):
+            if self._db_tags[i].db_id == tag.db_id:
+                if not self._db_tags[i].is_new:
+                    self.db_deleted_tags.append(self._db_tags[i])
+                del self._db_tags[i]
+                break
+        del self.db_tags_id_index[tag.db_id]
+        del self.db_tags_name_index[tag.db_name]
+    def db_get_tag(self, key):
+        for i in xrange(len(self._db_tags)):
+            if self._db_tags[i].db_id == key:
+                return self._db_tags[i]
+        return None
+    def db_get_tag_by_id(self, key):
+        return self.db_tags_id_index[key]
+    def db_has_tag_with_id(self, key):
+        return key in self.db_tags_id_index
+    def db_get_tag_by_name(self, key):
+        return self.db_tags_name_index[key]
+    def db_has_tag_with_name(self, key):
+        return key in self.db_tags_name_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_vistrailVariables(self):
+        return self._db_vistrailVariables
+    def __set_db_vistrailVariables(self, vistrailVariables):
+        self._db_vistrailVariables = vistrailVariables
+        self.is_dirty = True
+    db_vistrailVariables = property(__get_db_vistrailVariables, __set_db_vistrailVariables)
+    def db_get_vistrailVariables(self):
+        return self._db_vistrailVariables
+    def db_add_vistrailVariable(self, vistrailVariable):
+        self.is_dirty = True
+        self._db_vistrailVariables.append(vistrailVariable)
+        self.db_vistrailVariables_name_index[vistrailVariable.db_name] = vistrailVariable
+        self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid] = vistrailVariable
+    def db_change_vistrailVariable(self, vistrailVariable):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_vistrailVariables)):
+            if self._db_vistrailVariables[i].db_name == vistrailVariable.db_name:
+                self._db_vistrailVariables[i] = vistrailVariable
+                found = True
+                break
+        if not found:
+            self._db_vistrailVariables.append(vistrailVariable)
+        self.db_vistrailVariables_name_index[vistrailVariable.db_name] = vistrailVariable
+        self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid] = vistrailVariable
+    def db_delete_vistrailVariable(self, vistrailVariable):
+        self.is_dirty = True
+        for i in xrange(len(self._db_vistrailVariables)):
+            if self._db_vistrailVariables[i].db_name == vistrailVariable.db_name:
+                if not self._db_vistrailVariables[i].is_new:
+                    self.db_deleted_vistrailVariables.append(self._db_vistrailVariables[i])
+                del self._db_vistrailVariables[i]
+                break
+        del self.db_vistrailVariables_name_index[vistrailVariable.db_name]
+        del self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid]
+    def db_get_vistrailVariable(self, key):
+        for i in xrange(len(self._db_vistrailVariables)):
+            if self._db_vistrailVariables[i].db_name == key:
+                return self._db_vistrailVariables[i]
+        return None
+    def db_get_vistrailVariable_by_name(self, key):
+        return self.db_vistrailVariables_name_index[key]
+    def db_has_vistrailVariable_with_name(self, key):
+        return key in self.db_vistrailVariables_name_index
+    def db_get_vistrailVariable_by_uuid(self, key):
+        return self.db_vistrailVariables_uuid_index[key]
+    def db_has_vistrailVariable_with_uuid(self, key):
+        return key in self.db_vistrailVariables_uuid_index
+    
+    def __get_db_parameter_explorations(self):
+        return self._db_parameter_explorations
+    def __set_db_parameter_explorations(self, parameter_explorations):
+        self._db_parameter_explorations = parameter_explorations
+        self.is_dirty = True
+    db_parameter_explorations = property(__get_db_parameter_explorations, __set_db_parameter_explorations)
+    def db_get_parameter_explorations(self):
+        return self._db_parameter_explorations
+    def db_add_parameter_exploration(self, parameter_exploration):
+        self.is_dirty = True
+        self._db_parameter_explorations.append(parameter_exploration)
+        self.db_parameter_explorations_id_index[parameter_exploration.db_id] = parameter_exploration
+    def db_change_parameter_exploration(self, parameter_exploration):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_parameter_explorations)):
+            if self._db_parameter_explorations[i].db_id == parameter_exploration.db_id:
+                self._db_parameter_explorations[i] = parameter_exploration
+                found = True
+                break
+        if not found:
+            self._db_parameter_explorations.append(parameter_exploration)
+        self.db_parameter_explorations_id_index[parameter_exploration.db_id] = parameter_exploration
+    def db_delete_parameter_exploration(self, parameter_exploration):
+        self.is_dirty = True
+        for i in xrange(len(self._db_parameter_explorations)):
+            if self._db_parameter_explorations[i].db_id == parameter_exploration.db_id:
+                if not self._db_parameter_explorations[i].is_new:
+                    self.db_deleted_parameter_explorations.append(self._db_parameter_explorations[i])
+                del self._db_parameter_explorations[i]
+                break
+        del self.db_parameter_explorations_id_index[parameter_exploration.db_id]
+    def db_get_parameter_exploration(self, key):
+        for i in xrange(len(self._db_parameter_explorations)):
+            if self._db_parameter_explorations[i].db_id == key:
+                return self._db_parameter_explorations[i]
+        return None
+    def db_get_parameter_exploration_by_id(self, key):
+        return self.db_parameter_explorations_id_index[key]
+    def db_has_parameter_exploration_with_id(self, key):
+        return key in self.db_parameter_explorations_id_index
+    
+    def __get_db_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def __set_db_actionAnnotations(self, actionAnnotations):
+        self._db_actionAnnotations = actionAnnotations
+        self.is_dirty = True
+    db_actionAnnotations = property(__get_db_actionAnnotations, __set_db_actionAnnotations)
+    def db_get_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def db_add_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_change_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                self._db_actionAnnotations[i] = actionAnnotation
+                found = True
+                break
+        if not found:
+            self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_delete_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                if not self._db_actionAnnotations[i].is_new:
+                    self.db_deleted_actionAnnotations.append(self._db_actionAnnotations[i])
+                del self._db_actionAnnotations[i]
+                break
+        del self.db_actionAnnotations_id_index[actionAnnotation.db_id]
+        del self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)]
+        try:
+            del self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)]
+        except KeyError:
+            pass
+    def db_get_actionAnnotation(self, key):
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == key:
+                return self._db_actionAnnotations[i]
+        return None
+    def db_get_actionAnnotation_by_id(self, key):
+        return self.db_actionAnnotations_id_index[key]
+    def db_has_actionAnnotation_with_id(self, key):
+        return key in self.db_actionAnnotations_id_index
+    def db_get_actionAnnotation_by_action_id(self, key):
+        return self.db_actionAnnotations_action_id_index[key]
+    def db_has_actionAnnotation_with_action_id(self, key):
+        return key in self.db_actionAnnotations_action_id_index
+    def db_get_actionAnnotation_by_key(self, key):
+        return self.db_actionAnnotations_key_index[key]
+    def db_has_actionAnnotation_with_key(self, key):
+        return key in self.db_actionAnnotations_key_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmArtifactValue(object):
+
+    vtType = 'opm_artifact_value'
+
+    def __init__(self, value=None):
+        self.db_deleted_value = []
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmArtifactValue.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmArtifactValue()
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmArtifactValue()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            if obj.vtType == 'portSpec':
+                new_obj.db_add_value(DBPortSpec.update_version(obj, trans_dict))
+            elif obj.vtType == 'function':
+                new_obj.db_add_value(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                if obj.vtType == 'portSpec':
+                    n_obj = DBPortSpec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'function':
+                    n_obj = DBFunction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_value)
+        if remove:
+            self.db_deleted_value = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+
+
+class DBConfigStr(object):
+
+    vtType = 'config_str'
+
+    def __init__(self, value=None):
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfigStr.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigStr(value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigStr()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
     def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBStartup(object):
+
+    vtType = 'startup'
+
+    def __init__(self, version=None, configuration=None, enabled_packages=None, disabled_packages=None):
+        self._db_version = version
+        self.db_deleted_configuration = []
+        self._db_configuration = configuration
+        self.db_deleted_enabled_packages = []
+        self._db_enabled_packages = enabled_packages
+        self.db_deleted_disabled_packages = []
+        self._db_disabled_packages = disabled_packages
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBStartup.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBStartup(version=self._db_version)
+        if self._db_configuration is not None:
+            cp._db_configuration = self._db_configuration.do_copy(new_ids, id_scope, id_remap)
+        if self._db_enabled_packages is not None:
+            cp._db_enabled_packages = self._db_enabled_packages.do_copy(new_ids, id_scope, id_remap)
+        if self._db_disabled_packages is not None:
+            cp._db_disabled_packages = self._db_disabled_packages.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBStartup()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'configuration' in class_dict:
+            res = class_dict['configuration'](old_obj, trans_dict)
+            new_obj.db_configuration = res
+        elif hasattr(old_obj, 'db_configuration') and old_obj.db_configuration is not None:
+            obj = old_obj.db_configuration
+            new_obj.db_add_configuration(DBConfiguration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_configuration') and hasattr(new_obj, 'db_deleted_configuration'):
+            for obj in old_obj.db_deleted_configuration:
+                n_obj = DBConfiguration.update_version(obj, trans_dict)
+                new_obj.db_deleted_configuration.append(n_obj)
+        if 'enabled_packages' in class_dict:
+            res = class_dict['enabled_packages'](old_obj, trans_dict)
+            new_obj.db_enabled_packages = res
+        elif hasattr(old_obj, 'db_enabled_packages') and old_obj.db_enabled_packages is not None:
+            obj = old_obj.db_enabled_packages
+            new_obj.db_add_enabled_packages(DBEnabledPackages.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_enabled_packages') and hasattr(new_obj, 'db_deleted_enabled_packages'):
+            for obj in old_obj.db_deleted_enabled_packages:
+                n_obj = DBEnabledPackages.update_version(obj, trans_dict)
+                new_obj.db_deleted_enabled_packages.append(n_obj)
+        if 'disabled_packages' in class_dict:
+            res = class_dict['disabled_packages'](old_obj, trans_dict)
+            new_obj.db_disabled_packages = res
+        elif hasattr(old_obj, 'db_disabled_packages') and old_obj.db_disabled_packages is not None:
+            obj = old_obj.db_disabled_packages
+            new_obj.db_add_disabled_packages(DBDisabledPackages.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_disabled_packages') and hasattr(new_obj, 'db_deleted_disabled_packages'):
+            for obj in old_obj.db_deleted_disabled_packages:
+                n_obj = DBDisabledPackages.update_version(obj, trans_dict)
+                new_obj.db_deleted_disabled_packages.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_configuration is not None:
+            children.extend(self._db_configuration.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_configuration = None
+        if self._db_enabled_packages is not None:
+            children.extend(self._db_enabled_packages.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_enabled_packages = None
+        if self._db_disabled_packages is not None:
+            children.extend(self._db_disabled_packages.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_disabled_packages = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_configuration)
+        children.extend(self.db_deleted_enabled_packages)
+        children.extend(self.db_deleted_disabled_packages)
+        if remove:
+            self.db_deleted_configuration = []
+            self.db_deleted_enabled_packages = []
+            self.db_deleted_disabled_packages = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_configuration is not None and self._db_configuration.has_changes():
+            return True
+        if self._db_enabled_packages is not None and self._db_enabled_packages.has_changes():
+            return True
+        if self._db_disabled_packages is not None and self._db_disabled_packages.has_changes():
+            return True
+        return False
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_configuration(self):
+        return self._db_configuration
+    def __set_db_configuration(self, configuration):
+        self._db_configuration = configuration
+        self.is_dirty = True
+    db_configuration = property(__get_db_configuration, __set_db_configuration)
+    def db_add_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_change_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_delete_configuration(self, configuration):
+        if not self.is_new:
+            self.db_deleted_configuration.append(self._db_configuration)
+        self._db_configuration = None
+    
+    def __get_db_enabled_packages(self):
+        return self._db_enabled_packages
+    def __set_db_enabled_packages(self, enabled_packages):
+        self._db_enabled_packages = enabled_packages
+        self.is_dirty = True
+    db_enabled_packages = property(__get_db_enabled_packages, __set_db_enabled_packages)
+    def db_add_enabled_packages(self, enabled_packages):
+        self._db_enabled_packages = enabled_packages
+    def db_change_enabled_packages(self, enabled_packages):
+        self._db_enabled_packages = enabled_packages
+    def db_delete_enabled_packages(self, enabled_packages):
+        if not self.is_new:
+            self.db_deleted_enabled_packages.append(self._db_enabled_packages)
+        self._db_enabled_packages = None
+    
+    def __get_db_disabled_packages(self):
+        return self._db_disabled_packages
+    def __set_db_disabled_packages(self, disabled_packages):
+        self._db_disabled_packages = disabled_packages
+        self.is_dirty = True
+    db_disabled_packages = property(__get_db_disabled_packages, __set_db_disabled_packages)
+    def db_add_disabled_packages(self, disabled_packages):
+        self._db_disabled_packages = disabled_packages
+    def db_change_disabled_packages(self, disabled_packages):
+        self._db_disabled_packages = disabled_packages
+    def db_delete_disabled_packages(self, disabled_packages):
+        if not self.is_new:
+            self.db_deleted_disabled_packages.append(self._db_disabled_packages)
+        self._db_disabled_packages = None
+    
+
+
+class DBModule(object):
+
+    vtType = 'module'
+
+    def __init__(self, id=None, cache=None, name=None, namespace=None, package=None, version=None, location=None, functions=None, annotations=None, portSpecs=None):
+        self._db_id = id
+        self._db_cache = cache
+        self._db_name = name
+        self._db_namespace = namespace
+        self._db_package = package
+        self._db_version = version
+        self.db_deleted_location = []
+        self._db_location = location
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
+        else:
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_portSpecs = []
+        self.db_portSpecs_id_index = {}
+        self.db_portSpecs_name_index = {}
+        if portSpecs is None:
+            self._db_portSpecs = []
+        else:
+            self._db_portSpecs = portSpecs
+            for v in self._db_portSpecs:
+                self.db_portSpecs_id_index[v.db_id] = v
+                self.db_portSpecs_name_index[(v.db_name,v.db_type)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBModule.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBModule(id=self._db_id,
+                      cache=self._db_cache,
+                      name=self._db_name,
+                      namespace=self._db_namespace,
+                      package=self._db_package,
+                      version=self._db_version)
+        if self._db_location is not None:
+            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
+        if self._db_functions is None:
+            cp._db_functions = []
+        else:
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_portSpecs is None:
+            cp._db_portSpecs = []
+        else:
+            cp._db_portSpecs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_portSpecs_id_index = dict((v.db_id, v) for v in cp._db_portSpecs)
+        cp.db_portSpecs_name_index = dict(((v.db_name,v.db_type), v) for v in cp._db_portSpecs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBModule()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'cache' in class_dict:
+            res = class_dict['cache'](old_obj, trans_dict)
+            new_obj.db_cache = res
+        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
+            new_obj.db_cache = old_obj.db_cache
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'location' in class_dict:
+            res = class_dict['location'](old_obj, trans_dict)
+            new_obj.db_location = res
+        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
+            obj = old_obj.db_location
+            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
+            for obj in old_obj.db_deleted_location:
+                n_obj = DBLocation.update_version(obj, trans_dict)
+                new_obj.db_deleted_location.append(n_obj)
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'portSpecs' in class_dict:
+            res = class_dict['portSpecs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_portSpec(obj)
+        elif hasattr(old_obj, 'db_portSpecs') and old_obj.db_portSpecs is not None:
+            for obj in old_obj.db_portSpecs:
+                new_obj.db_add_portSpec(DBPortSpec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_portSpecs') and hasattr(new_obj, 'db_deleted_portSpecs'):
+            for obj in old_obj.db_deleted_portSpecs:
+                n_obj = DBPortSpec.update_version(obj, trans_dict)
+                new_obj.db_deleted_portSpecs.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_location is not None:
+            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_location = None
+        to_del = []
+        for child in self.db_functions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_function(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_portSpecs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_portSpec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_location)
+        children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_portSpecs)
+        if remove:
+            self.db_deleted_location = []
+            self.db_deleted_functions = []
+            self.db_deleted_annotations = []
+            self.db_deleted_portSpecs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_location is not None and self._db_location.has_changes():
+            return True
+        for child in self._db_functions:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_portSpecs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_cache(self):
+        return self._db_cache
+    def __set_db_cache(self, cache):
+        self._db_cache = cache
+        self.is_dirty = True
+    db_cache = property(__get_db_cache, __set_db_cache)
+    def db_add_cache(self, cache):
+        self._db_cache = cache
+    def db_change_cache(self, cache):
+        self._db_cache = cache
+    def db_delete_cache(self, cache):
+        self._db_cache = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_location(self):
+        return self._db_location
+    def __set_db_location(self, location):
+        self._db_location = location
+        self.is_dirty = True
+    db_location = property(__get_db_location, __set_db_location)
+    def db_add_location(self, location):
+        self._db_location = location
+    def db_change_location(self, location):
+        self._db_location = location
+    def db_delete_location(self, location):
         if not self.is_new:
-            self.db_deleted_value.append(self._db_value)
-        self._db_value = None
+            self.db_deleted_location.append(self._db_location)
+        self._db_location = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
+        self.is_dirty = True
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
+        self.is_dirty = True
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
+                found = True
+                break
+        if not found:
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
+        self.is_dirty = True
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
+                break
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
+        return None
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_portSpecs(self):
+        return self._db_portSpecs
+    def __set_db_portSpecs(self, portSpecs):
+        self._db_portSpecs = portSpecs
+        self.is_dirty = True
+    db_portSpecs = property(__get_db_portSpecs, __set_db_portSpecs)
+    def db_get_portSpecs(self):
+        return self._db_portSpecs
+    def db_add_portSpec(self, portSpec):
+        self.is_dirty = True
+        self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_change_portSpec(self, portSpec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                self._db_portSpecs[i] = portSpec
+                found = True
+                break
+        if not found:
+            self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_delete_portSpec(self, portSpec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                if not self._db_portSpecs[i].is_new:
+                    self.db_deleted_portSpecs.append(self._db_portSpecs[i])
+                del self._db_portSpecs[i]
+                break
+        del self.db_portSpecs_id_index[portSpec.db_id]
+        del self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)]
+    def db_get_portSpec(self, key):
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == key:
+                return self._db_portSpecs[i]
+        return None
+    def db_get_portSpec_by_id(self, key):
+        return self.db_portSpecs_id_index[key]
+    def db_has_portSpec_with_id(self, key):
+        return key in self.db_portSpecs_id_index
+    def db_get_portSpec_by_name(self, key):
+        return self.db_portSpecs_name_index[key]
+    def db_has_portSpec_with_name(self, key):
+        return key in self.db_portSpecs_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBPort(object):
+
+    vtType = 'port'
+
+    def __init__(self, id=None, type=None, moduleId=None, moduleName=None, name=None, signature=None):
+        self._db_id = id
+        self._db_type = type
+        self._db_moduleId = moduleId
+        self._db_moduleName = moduleName
+        self._db_name = name
+        self._db_signature = signature
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPort.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPort(id=self._db_id,
+                    type=self._db_type,
+                    moduleId=self._db_moduleId,
+                    moduleName=self._db_moduleName,
+                    name=self._db_name,
+                    signature=self._db_signature)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_moduleId') and ('module', self._db_moduleId) in id_remap:
+                cp._db_moduleId = id_remap[('module', self._db_moduleId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPort()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'moduleId' in class_dict:
+            res = class_dict['moduleId'](old_obj, trans_dict)
+            new_obj.db_moduleId = res
+        elif hasattr(old_obj, 'db_moduleId') and old_obj.db_moduleId is not None:
+            new_obj.db_moduleId = old_obj.db_moduleId
+        if 'moduleName' in class_dict:
+            res = class_dict['moduleName'](old_obj, trans_dict)
+            new_obj.db_moduleName = res
+        elif hasattr(old_obj, 'db_moduleName') and old_obj.db_moduleName is not None:
+            new_obj.db_moduleName = old_obj.db_moduleName
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'signature' in class_dict:
+            res = class_dict['signature'](old_obj, trans_dict)
+            new_obj.db_signature = res
+        elif hasattr(old_obj, 'db_signature') and old_obj.db_signature is not None:
+            new_obj.db_signature = old_obj.db_signature
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_moduleId(self):
+        return self._db_moduleId
+    def __set_db_moduleId(self, moduleId):
+        self._db_moduleId = moduleId
+        self.is_dirty = True
+    db_moduleId = property(__get_db_moduleId, __set_db_moduleId)
+    def db_add_moduleId(self, moduleId):
+        self._db_moduleId = moduleId
+    def db_change_moduleId(self, moduleId):
+        self._db_moduleId = moduleId
+    def db_delete_moduleId(self, moduleId):
+        self._db_moduleId = None
+    
+    def __get_db_moduleName(self):
+        return self._db_moduleName
+    def __set_db_moduleName(self, moduleName):
+        self._db_moduleName = moduleName
+        self.is_dirty = True
+    db_moduleName = property(__get_db_moduleName, __set_db_moduleName)
+    def db_add_moduleName(self, moduleName):
+        self._db_moduleName = moduleName
+    def db_change_moduleName(self, moduleName):
+        self._db_moduleName = moduleName
+    def db_delete_moduleName(self, moduleName):
+        self._db_moduleName = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_signature(self):
+        return self._db_signature
+    def __set_db_signature(self, signature):
+        self._db_signature = signature
+        self.is_dirty = True
+    db_signature = property(__get_db_signature, __set_db_signature)
+    def db_add_signature(self, signature):
+        self._db_signature = signature
+    def db_change_signature(self, signature):
+        self._db_signature = signature
+    def db_delete_signature(self, signature):
+        self._db_signature = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmAgents(object):
+
+    vtType = 'opm_agents'
+
+    def __init__(self, agents=None):
+        self.db_deleted_agents = []
+        self.db_agents_id_index = {}
+        if agents is None:
+            self._db_agents = []
+        else:
+            self._db_agents = agents
+            for v in self._db_agents:
+                self.db_agents_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAgents.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAgents()
+        if self._db_agents is None:
+            cp._db_agents = []
+        else:
+            cp._db_agents = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_agents]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_agents_id_index = dict((v.db_id, v) for v in cp._db_agents)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAgents()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'agents' in class_dict:
+            res = class_dict['agents'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_agent(obj)
+        elif hasattr(old_obj, 'db_agents') and old_obj.db_agents is not None:
+            for obj in old_obj.db_agents:
+                new_obj.db_add_agent(DBOpmAgent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_agents') and hasattr(new_obj, 'db_deleted_agents'):
+            for obj in old_obj.db_deleted_agents:
+                n_obj = DBOpmAgent.update_version(obj, trans_dict)
+                new_obj.db_deleted_agents.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_agents:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_agent(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_agents)
+        if remove:
+            self.db_deleted_agents = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_agents:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_agents(self):
+        return self._db_agents
+    def __set_db_agents(self, agents):
+        self._db_agents = agents
+        self.is_dirty = True
+    db_agents = property(__get_db_agents, __set_db_agents)
+    def db_get_agents(self):
+        return self._db_agents
+    def db_add_agent(self, agent):
+        self.is_dirty = True
+        self._db_agents.append(agent)
+        self.db_agents_id_index[agent.db_id] = agent
+    def db_change_agent(self, agent):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_agents)):
+            if self._db_agents[i].db_id == agent.db_id:
+                self._db_agents[i] = agent
+                found = True
+                break
+        if not found:
+            self._db_agents.append(agent)
+        self.db_agents_id_index[agent.db_id] = agent
+    def db_delete_agent(self, agent):
+        self.is_dirty = True
+        for i in xrange(len(self._db_agents)):
+            if self._db_agents[i].db_id == agent.db_id:
+                if not self._db_agents[i].is_new:
+                    self.db_deleted_agents.append(self._db_agents[i])
+                del self._db_agents[i]
+                break
+        del self.db_agents_id_index[agent.db_id]
+    def db_get_agent(self, key):
+        for i in xrange(len(self._db_agents)):
+            if self._db_agents[i].db_id == key:
+                return self._db_agents[i]
+        return None
+    def db_get_agent_by_id(self, key):
+        return self.db_agents_id_index[key]
+    def db_has_agent_with_id(self, key):
+        return key in self.db_agents_id_index
+    
+
+
+class DBOpmDependencies(object):
+
+    vtType = 'opm_dependencies'
+
+    def __init__(self, dependencys=None):
+        self.db_deleted_dependencys = []
+        if dependencys is None:
+            self._db_dependencys = []
+        else:
+            self._db_dependencys = dependencys
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmDependencies.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmDependencies()
+        if self._db_dependencys is None:
+            cp._db_dependencys = []
+        else:
+            cp._db_dependencys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_dependencys]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmDependencies()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'dependencys' in class_dict:
+            res = class_dict['dependencys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_dependency(obj)
+        elif hasattr(old_obj, 'db_dependencys') and old_obj.db_dependencys is not None:
+            for obj in old_obj.db_dependencys:
+                if obj.vtType == 'opm_used':
+                    new_obj.db_add_dependency(DBOpmUsed.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_generated_by':
+                    new_obj.db_add_dependency(DBOpmWasGeneratedBy.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_triggered_by':
+                    new_obj.db_add_dependency(DBOpmWasTriggeredBy.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_derived_from':
+                    new_obj.db_add_dependency(DBOpmWasDerivedFrom.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_controlled_by':
+                    new_obj.db_add_dependency(DBOpmWasControlledBy.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_dependencys') and hasattr(new_obj, 'db_deleted_dependencys'):
+            for obj in old_obj.db_deleted_dependencys:
+                if obj.vtType == 'opm_used':
+                    n_obj = DBOpmUsed.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_generated_by':
+                    n_obj = DBOpmWasGeneratedBy.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_triggered_by':
+                    n_obj = DBOpmWasTriggeredBy.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_derived_from':
+                    n_obj = DBOpmWasDerivedFrom.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_controlled_by':
+                    n_obj = DBOpmWasControlledBy.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_dependencys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_dependency(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_dependencys)
+        if remove:
+            self.db_deleted_dependencys = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_dependencys:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_dependencys(self):
+        return self._db_dependencys
+    def __set_db_dependencys(self, dependencys):
+        self._db_dependencys = dependencys
+        self.is_dirty = True
+    db_dependencys = property(__get_db_dependencys, __set_db_dependencys)
+    def db_get_dependencys(self):
+        return self._db_dependencys
+    def db_add_dependency(self, dependency):
+        self.is_dirty = True
+        self._db_dependencys.append(dependency)
+    def db_change_dependency(self, dependency):
+        self.is_dirty = True
+        self._db_dependencys.append(dependency)
+    def db_delete_dependency(self, dependency):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_dependency(self, key):
+        return None
+    
+
+
+class DBPEFunction(object):
+
+    vtType = 'pe_function'
+
+    def __init__(self, id=None, module_id=None, port_name=None, is_alias=None, parameters=None):
+        self._db_id = id
+        self._db_module_id = module_id
+        self._db_port_name = port_name
+        self._db_is_alias = is_alias
+        self.db_deleted_parameters = []
+        self.db_parameters_id_index = {}
+        if parameters is None:
+            self._db_parameters = []
+        else:
+            self._db_parameters = parameters
+            for v in self._db_parameters:
+                self.db_parameters_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPEFunction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPEFunction(id=self._db_id,
+                          module_id=self._db_module_id,
+                          port_name=self._db_port_name,
+                          is_alias=self._db_is_alias)
+        if self._db_parameters is None:
+            cp._db_parameters = []
+        else:
+            cp._db_parameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameters]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
+                cp._db_module_id = id_remap[('module', self._db_module_id)]
+        
+        # recreate indices and set flags
+        cp.db_parameters_id_index = dict((v.db_id, v) for v in cp._db_parameters)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPEFunction()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'module_id' in class_dict:
+            res = class_dict['module_id'](old_obj, trans_dict)
+            new_obj.db_module_id = res
+        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
+            new_obj.db_module_id = old_obj.db_module_id
+        if 'port_name' in class_dict:
+            res = class_dict['port_name'](old_obj, trans_dict)
+            new_obj.db_port_name = res
+        elif hasattr(old_obj, 'db_port_name') and old_obj.db_port_name is not None:
+            new_obj.db_port_name = old_obj.db_port_name
+        if 'is_alias' in class_dict:
+            res = class_dict['is_alias'](old_obj, trans_dict)
+            new_obj.db_is_alias = res
+        elif hasattr(old_obj, 'db_is_alias') and old_obj.db_is_alias is not None:
+            new_obj.db_is_alias = old_obj.db_is_alias
+        if 'parameters' in class_dict:
+            res = class_dict['parameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_parameter(obj)
+        elif hasattr(old_obj, 'db_parameters') and old_obj.db_parameters is not None:
+            for obj in old_obj.db_parameters:
+                new_obj.db_add_parameter(DBPEParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_parameters') and hasattr(new_obj, 'db_deleted_parameters'):
+            for obj in old_obj.db_deleted_parameters:
+                n_obj = DBPEParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_parameters.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_parameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_parameter(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_parameters)
+        if remove:
+            self.db_deleted_parameters = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_parameters:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
+    def __get_db_module_id(self):
+        return self._db_module_id
+    def __set_db_module_id(self, module_id):
+        self._db_module_id = module_id
         self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
+    db_module_id = property(__get_db_module_id, __set_db_module_id)
+    def db_add_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_change_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_delete_module_id(self, module_id):
+        self._db_module_id = None
+    
+    def __get_db_port_name(self):
+        return self._db_port_name
+    def __set_db_port_name(self, port_name):
+        self._db_port_name = port_name
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
+    db_port_name = property(__get_db_port_name, __set_db_port_name)
+    def db_add_port_name(self, port_name):
+        self._db_port_name = port_name
+    def db_change_port_name(self, port_name):
+        self._db_port_name = port_name
+    def db_delete_port_name(self, port_name):
+        self._db_port_name = None
+    
+    def __get_db_is_alias(self):
+        return self._db_is_alias
+    def __set_db_is_alias(self, is_alias):
+        self._db_is_alias = is_alias
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
+    db_is_alias = property(__get_db_is_alias, __set_db_is_alias)
+    def db_add_is_alias(self, is_alias):
+        self._db_is_alias = is_alias
+    def db_change_is_alias(self, is_alias):
+        self._db_is_alias = is_alias
+    def db_delete_is_alias(self, is_alias):
+        self._db_is_alias = None
+    
+    def __get_db_parameters(self):
+        return self._db_parameters
+    def __set_db_parameters(self, parameters):
+        self._db_parameters = parameters
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
+    db_parameters = property(__get_db_parameters, __set_db_parameters)
+    def db_get_parameters(self):
+        return self._db_parameters
+    def db_add_parameter(self, parameter):
+        self.is_dirty = True
+        self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_change_parameter(self, parameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                self._db_parameters[i] = parameter
+                found = True
+                break
+        if not found:
+            self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_delete_parameter(self, parameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                if not self._db_parameters[i].is_new:
+                    self.db_deleted_parameters.append(self._db_parameters[i])
+                del self._db_parameters[i]
+                break
+        del self.db_parameters_id_index[parameter.db_id]
+    def db_get_parameter(self, key):
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == key:
+                return self._db_parameters[i]
         return None
+    def db_get_parameter_by_id(self, key):
+        return self.db_parameters_id_index[key]
+    def db_has_parameter_with_id(self, key):
+        return key in self.db_parameters_id_index
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBGroup(object):
+class DBWorkflow(object):
 
-    vtType = 'group'
+    vtType = 'workflow'
 
-    def __init__(self, id=None, workflow=None, cache=None, name=None, namespace=None, package=None, version=None, location=None, functions=None, annotations=None):
+    def __init__(self, modules=None, id=None, entity_type=None, name=None, version=None, last_modified=None, connections=None, annotations=None, plugin_datas=None, others=None, vistrail_id=None):
+        self.db_deleted_modules = []
+        self.db_modules_id_index = {}
+        if modules is None:
+            self._db_modules = []
+        else:
+            self._db_modules = modules
+            for v in self._db_modules:
+                self.db_modules_id_index[v.db_id] = v
         self._db_id = id
-        self.db_deleted_workflow = []
-        self._db_workflow = workflow
-        self._db_cache = cache
+        self._db_entity_type = entity_type
         self._db_name = name
-        self._db_namespace = namespace
-        self._db_package = package
         self._db_version = version
-        self.db_deleted_location = []
-        self._db_location = location
-        self.db_deleted_functions = []
-        self.db_functions_id_index = {}
-        if functions is None:
-            self._db_functions = []
+        self._db_last_modified = last_modified
+        self.db_deleted_connections = []
+        self.db_connections_id_index = {}
+        if connections is None:
+            self._db_connections = []
         else:
-            self._db_functions = functions
-            for v in self._db_functions:
-                self.db_functions_id_index[v.db_id] = v
+            self._db_connections = connections
+            for v in self._db_connections:
+                self.db_connections_id_index[v.db_id] = v
         self.db_deleted_annotations = []
         self.db_annotations_id_index = {}
-        self.db_annotations_key_index = {}
         if annotations is None:
             self._db_annotations = []
         else:
             self._db_annotations = annotations
             for v in self._db_annotations:
                 self.db_annotations_id_index[v.db_id] = v
-                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_plugin_datas = []
+        self.db_plugin_datas_id_index = {}
+        if plugin_datas is None:
+            self._db_plugin_datas = []
+        else:
+            self._db_plugin_datas = plugin_datas
+            for v in self._db_plugin_datas:
+                self.db_plugin_datas_id_index[v.db_id] = v
+        self.db_deleted_others = []
+        self.db_others_id_index = {}
+        if others is None:
+            self._db_others = []
+        else:
+            self._db_others = others
+            for v in self._db_others:
+                self.db_others_id_index[v.db_id] = v
+        self._db_vistrail_id = vistrail_id
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBGroup.do_copy(self)
+        return DBWorkflow.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBGroup(id=self._db_id,
-                     cache=self._db_cache,
-                     name=self._db_name,
-                     namespace=self._db_namespace,
-                     package=self._db_package,
-                     version=self._db_version)
-        if self._db_workflow is not None:
-            cp._db_workflow = self._db_workflow.do_copy()
-        if self._db_location is not None:
-            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
-        if self._db_functions is None:
-            cp._db_functions = []
+        cp = DBWorkflow(id=self._db_id,
+                        entity_type=self._db_entity_type,
+                        name=self._db_name,
+                        version=self._db_version,
+                        last_modified=self._db_last_modified,
+                        vistrail_id=self._db_vistrail_id)
+        if self._db_modules is None:
+            cp._db_modules = []
         else:
-            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+            cp._db_modules = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_modules]
+        if self._db_connections is None:
+            cp._db_connections = []
+        else:
+            cp._db_connections = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_connections]
         if self._db_annotations is None:
             cp._db_annotations = []
         else:
             cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_plugin_datas is None:
+            cp._db_plugin_datas = []
+        else:
+            cp._db_plugin_datas = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_plugin_datas]
+        if self._db_others is None:
+            cp._db_others = []
+        else:
+            cp._db_others = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_others]
         
         # set new ids
         if new_ids:
@@ -3560,11 +5298,15 @@ class DBGroup(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_vistrail_id') and ('vistrail', self._db_vistrail_id) in id_remap:
+                cp._db_vistrail_id = id_remap[('vistrail', self._db_vistrail_id)]
         
         # recreate indices and set flags
-        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_modules_id_index = dict((v.db_id, v) for v in cp._db_modules)
+        cp.db_connections_id_index = dict((v.db_id, v) for v in cp._db_connections)
         cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_plugin_datas_id_index = dict((v.db_id, v) for v in cp._db_plugin_datas)
+        cp.db_others_id_index = dict((v.db_id, v) for v in cp._db_others)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -3573,71 +5315,69 @@ class DBGroup(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBGroup()
+            new_obj = DBWorkflow()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'workflow' in class_dict:
-            res = class_dict['workflow'](old_obj, trans_dict)
-            new_obj.db_workflow = res
-        elif hasattr(old_obj, 'db_workflow') and old_obj.db_workflow is not None:
-            obj = old_obj.db_workflow
-            new_obj.db_add_workflow(DBWorkflow.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_workflow') and hasattr(new_obj, 'db_deleted_workflow'):
-            for obj in old_obj.db_deleted_workflow:
-                n_obj = DBWorkflow.update_version(obj, trans_dict)
-                new_obj.db_deleted_workflow.append(n_obj)
-        if 'cache' in class_dict:
-            res = class_dict['cache'](old_obj, trans_dict)
-            new_obj.db_cache = res
-        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
-            new_obj.db_cache = old_obj.db_cache
+        if 'modules' in class_dict:
+            res = class_dict['modules'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_module(obj)
+        elif hasattr(old_obj, 'db_modules') and old_obj.db_modules is not None:
+            for obj in old_obj.db_modules:
+                if obj.vtType == 'module':
+                    new_obj.db_add_module(DBModule.update_version(obj, trans_dict))
+                elif obj.vtType == 'abstraction':
+                    new_obj.db_add_module(DBAbstraction.update_version(obj, trans_dict))
+                elif obj.vtType == 'group':
+                    new_obj.db_add_module(DBGroup.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_modules') and hasattr(new_obj, 'db_deleted_modules'):
+            for obj in old_obj.db_deleted_modules:
+                if obj.vtType == 'module':
+                    n_obj = DBModule.update_version(obj, trans_dict)
+                    new_obj.db_deleted_modules.append(n_obj)
+                elif obj.vtType == 'abstraction':
+                    n_obj = DBAbstraction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_modules.append(n_obj)
+                elif obj.vtType == 'group':
+                    n_obj = DBGroup.update_version(obj, trans_dict)
+                    new_obj.db_deleted_modules.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'namespace' in class_dict:
-            res = class_dict['namespace'](old_obj, trans_dict)
-            new_obj.db_namespace = res
-        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
-            new_obj.db_namespace = old_obj.db_namespace
-        if 'package' in class_dict:
-            res = class_dict['package'](old_obj, trans_dict)
-            new_obj.db_package = res
-        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
-            new_obj.db_package = old_obj.db_package
         if 'version' in class_dict:
             res = class_dict['version'](old_obj, trans_dict)
             new_obj.db_version = res
         elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
             new_obj.db_version = old_obj.db_version
-        if 'location' in class_dict:
-            res = class_dict['location'](old_obj, trans_dict)
-            new_obj.db_location = res
-        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
-            obj = old_obj.db_location
-            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
-            for obj in old_obj.db_deleted_location:
-                n_obj = DBLocation.update_version(obj, trans_dict)
-                new_obj.db_deleted_location.append(n_obj)
-        if 'functions' in class_dict:
-            res = class_dict['functions'](old_obj, trans_dict)
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'connections' in class_dict:
+            res = class_dict['connections'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_function(obj)
-        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
-            for obj in old_obj.db_functions:
-                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
-            for obj in old_obj.db_deleted_functions:
-                n_obj = DBFunction.update_version(obj, trans_dict)
-                new_obj.db_deleted_functions.append(n_obj)
+                new_obj.db_add_connection(obj)
+        elif hasattr(old_obj, 'db_connections') and old_obj.db_connections is not None:
+            for obj in old_obj.db_connections:
+                new_obj.db_add_connection(DBConnection.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_connections') and hasattr(new_obj, 'db_deleted_connections'):
+            for obj in old_obj.db_deleted_connections:
+                n_obj = DBConnection.update_version(obj, trans_dict)
+                new_obj.db_deleted_connections.append(n_obj)
         if 'annotations' in class_dict:
             res = class_dict['annotations'](old_obj, trans_dict)
             for obj in res:
@@ -3649,23 +5389,46 @@ class DBGroup(object):
             for obj in old_obj.db_deleted_annotations:
                 n_obj = DBAnnotation.update_version(obj, trans_dict)
                 new_obj.db_deleted_annotations.append(n_obj)
+        if 'plugin_datas' in class_dict:
+            res = class_dict['plugin_datas'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_plugin_data(obj)
+        elif hasattr(old_obj, 'db_plugin_datas') and old_obj.db_plugin_datas is not None:
+            for obj in old_obj.db_plugin_datas:
+                new_obj.db_add_plugin_data(DBPluginData.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_plugin_datas') and hasattr(new_obj, 'db_deleted_plugin_datas'):
+            for obj in old_obj.db_deleted_plugin_datas:
+                n_obj = DBPluginData.update_version(obj, trans_dict)
+                new_obj.db_deleted_plugin_datas.append(n_obj)
+        if 'others' in class_dict:
+            res = class_dict['others'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_other(obj)
+        elif hasattr(old_obj, 'db_others') and old_obj.db_others is not None:
+            for obj in old_obj.db_others:
+                new_obj.db_add_other(DBOther.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_others') and hasattr(new_obj, 'db_deleted_others'):
+            for obj in old_obj.db_deleted_others:
+                n_obj = DBOther.update_version(obj, trans_dict)
+                new_obj.db_deleted_others.append(n_obj)
+        if 'vistrail_id' in class_dict:
+            res = class_dict['vistrail_id'](old_obj, trans_dict)
+            new_obj.db_vistrail_id = res
+        elif hasattr(old_obj, 'db_vistrail_id') and old_obj.db_vistrail_id is not None:
+            new_obj.db_vistrail_id = old_obj.db_vistrail_id
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_location is not None:
-            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_location = None
         to_del = []
-        for child in self.db_functions:
+        for child in self.db_connections:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_function(child)
+            self.db_delete_connection(child)
         to_del = []
         for child in self.db_annotations:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
@@ -3673,34 +5436,104 @@ class DBGroup(object):
                 to_del.append(child)
         for child in to_del:
             self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_plugin_datas:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_plugin_data(child)
+        to_del = []
+        for child in self.db_others:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_other(child)
+        to_del = []
+        for child in self.db_modules:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_module(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_workflow)
-        children.extend(self.db_deleted_location)
-        children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_connections)
         children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_plugin_datas)
+        children.extend(self.db_deleted_others)
+        children.extend(self.db_deleted_modules)
         if remove:
-            self.db_deleted_workflow = []
-            self.db_deleted_location = []
-            self.db_deleted_functions = []
+            self.db_deleted_connections = []
             self.db_deleted_annotations = []
+            self.db_deleted_plugin_datas = []
+            self.db_deleted_others = []
+            self.db_deleted_modules = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_workflow is not None and self._db_workflow.has_changes():
-            return True
-        if self._db_location is not None and self._db_location.has_changes():
-            return True
-        for child in self._db_functions:
+        for child in self._db_connections:
             if child.has_changes():
                 return True
         for child in self._db_annotations:
             if child.has_changes():
                 return True
+        for child in self._db_plugin_datas:
+            if child.has_changes():
+                return True
+        for child in self._db_others:
+            if child.has_changes():
+                return True
+        for child in self._db_modules:
+            if child.has_changes():
+                return True
         return False
+    def __get_db_modules(self):
+        return self._db_modules
+    def __set_db_modules(self, modules):
+        self._db_modules = modules
+        self.is_dirty = True
+    db_modules = property(__get_db_modules, __set_db_modules)
+    def db_get_modules(self):
+        return self._db_modules
+    def db_add_module(self, module):
+        self.is_dirty = True
+        self._db_modules.append(module)
+        self.db_modules_id_index[module.db_id] = module
+    def db_change_module(self, module):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_modules)):
+            if self._db_modules[i].db_id == module.db_id:
+                self._db_modules[i] = module
+                found = True
+                break
+        if not found:
+            self._db_modules.append(module)
+        self.db_modules_id_index[module.db_id] = module
+    def db_delete_module(self, module):
+        self.is_dirty = True
+        for i in xrange(len(self._db_modules)):
+            if self._db_modules[i].db_id == module.db_id:
+                if not self._db_modules[i].is_new:
+                    self.db_deleted_modules.append(self._db_modules[i])
+                del self._db_modules[i]
+                break
+        del self.db_modules_id_index[module.db_id]
+    def db_get_module(self, key):
+        for i in xrange(len(self._db_modules)):
+            if self._db_modules[i].db_id == key:
+                return self._db_modules[i]
+        return None
+    def db_get_module_by_id(self, key):
+        return self.db_modules_id_index[key]
+    def db_has_module_with_id(self, key):
+        return key in self.db_modules_id_index
+    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -3714,72 +5547,31 @@ class DBGroup(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_workflow(self):
-        return self._db_workflow
-    def __set_db_workflow(self, workflow):
-        self._db_workflow = workflow
-        self.is_dirty = True
-    db_workflow = property(__get_db_workflow, __set_db_workflow)
-    def db_add_workflow(self, workflow):
-        self._db_workflow = workflow
-    def db_change_workflow(self, workflow):
-        self._db_workflow = workflow
-    def db_delete_workflow(self, workflow):
-        if not self.is_new:
-            self.db_deleted_workflow.append(self._db_workflow)
-        self._db_workflow = None
-    
-    def __get_db_cache(self):
-        return self._db_cache
-    def __set_db_cache(self, cache):
-        self._db_cache = cache
-        self.is_dirty = True
-    db_cache = property(__get_db_cache, __set_db_cache)
-    def db_add_cache(self, cache):
-        self._db_cache = cache
-    def db_change_cache(self, cache):
-        self._db_cache = cache
-    def db_delete_cache(self, cache):
-        self._db_cache = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_namespace(self):
-        return self._db_namespace
-    def __set_db_namespace(self, namespace):
-        self._db_namespace = namespace
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
         self.is_dirty = True
-    db_namespace = property(__get_db_namespace, __set_db_namespace)
-    def db_add_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_change_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_delete_namespace(self, namespace):
-        self._db_namespace = None
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
     
-    def __get_db_package(self):
-        return self._db_package
-    def __set_db_package(self, package):
-        self._db_package = package
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_package = property(__get_db_package, __set_db_package)
-    def db_add_package(self, package):
-        self._db_package = package
-    def db_change_package(self, package):
-        self._db_package = package
-    def db_delete_package(self, package):
-        self._db_package = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
     def __get_db_version(self):
         return self._db_version
@@ -3794,62 +5586,60 @@ class DBGroup(object):
     def db_delete_version(self, version):
         self._db_version = None
     
-    def __get_db_location(self):
-        return self._db_location
-    def __set_db_location(self, location):
-        self._db_location = location
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
         self.is_dirty = True
-    db_location = property(__get_db_location, __set_db_location)
-    def db_add_location(self, location):
-        self._db_location = location
-    def db_change_location(self, location):
-        self._db_location = location
-    def db_delete_location(self, location):
-        if not self.is_new:
-            self.db_deleted_location.append(self._db_location)
-        self._db_location = None
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
     
-    def __get_db_functions(self):
-        return self._db_functions
-    def __set_db_functions(self, functions):
-        self._db_functions = functions
+    def __get_db_connections(self):
+        return self._db_connections
+    def __set_db_connections(self, connections):
+        self._db_connections = connections
         self.is_dirty = True
-    db_functions = property(__get_db_functions, __set_db_functions)
-    def db_get_functions(self):
-        return self._db_functions
-    def db_add_function(self, function):
+    db_connections = property(__get_db_connections, __set_db_connections)
+    def db_get_connections(self):
+        return self._db_connections
+    def db_add_connection(self, connection):
         self.is_dirty = True
-        self._db_functions.append(function)
-        self.db_functions_id_index[function.db_id] = function
-    def db_change_function(self, function):
+        self._db_connections.append(connection)
+        self.db_connections_id_index[connection.db_id] = connection
+    def db_change_connection(self, connection):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == function.db_id:
-                self._db_functions[i] = function
+        for i in xrange(len(self._db_connections)):
+            if self._db_connections[i].db_id == connection.db_id:
+                self._db_connections[i] = connection
                 found = True
                 break
         if not found:
-            self._db_functions.append(function)
-        self.db_functions_id_index[function.db_id] = function
-    def db_delete_function(self, function):
+            self._db_connections.append(connection)
+        self.db_connections_id_index[connection.db_id] = connection
+    def db_delete_connection(self, connection):
         self.is_dirty = True
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == function.db_id:
-                if not self._db_functions[i].is_new:
-                    self.db_deleted_functions.append(self._db_functions[i])
-                del self._db_functions[i]
+        for i in xrange(len(self._db_connections)):
+            if self._db_connections[i].db_id == connection.db_id:
+                if not self._db_connections[i].is_new:
+                    self.db_deleted_connections.append(self._db_connections[i])
+                del self._db_connections[i]
                 break
-        del self.db_functions_id_index[function.db_id]
-    def db_get_function(self, key):
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == key:
-                return self._db_functions[i]
+        del self.db_connections_id_index[connection.db_id]
+    def db_get_connection(self, key):
+        for i in xrange(len(self._db_connections)):
+            if self._db_connections[i].db_id == key:
+                return self._db_connections[i]
         return None
-    def db_get_function_by_id(self, key):
-        return self.db_functions_id_index[key]
-    def db_has_function_with_id(self, key):
-        return key in self.db_functions_id_index
+    def db_get_connection_by_id(self, key):
+        return self.db_connections_id_index[key]
+    def db_has_connection_with_id(self, key):
+        return key in self.db_connections_id_index
     
     def __get_db_annotations(self):
         return self._db_annotations
@@ -3863,7 +5653,6 @@ class DBGroup(object):
         self.is_dirty = True
         self._db_annotations.append(annotation)
         self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
     def db_change_annotation(self, annotation):
         self.is_dirty = True
         found = False
@@ -3875,7 +5664,6 @@ class DBGroup(object):
         if not found:
             self._db_annotations.append(annotation)
         self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
     def db_delete_annotation(self, annotation):
         self.is_dirty = True
         for i in xrange(len(self._db_annotations)):
@@ -3885,7 +5673,6 @@ class DBGroup(object):
                 del self._db_annotations[i]
                 break
         del self.db_annotations_id_index[annotation.db_id]
-        del self.db_annotations_key_index[annotation.db_key]
     def db_get_annotation(self, key):
         for i in xrange(len(self._db_annotations)):
             if self._db_annotations[i].db_id == key:
@@ -3895,62 +5682,131 @@ class DBGroup(object):
         return self.db_annotations_id_index[key]
     def db_has_annotation_with_id(self, key):
         return key in self.db_annotations_id_index
-    def db_get_annotation_by_key(self, key):
-        return self.db_annotations_key_index[key]
-    def db_has_annotation_with_key(self, key):
-        return key in self.db_annotations_key_index
+    
+    def __get_db_plugin_datas(self):
+        return self._db_plugin_datas
+    def __set_db_plugin_datas(self, plugin_datas):
+        self._db_plugin_datas = plugin_datas
+        self.is_dirty = True
+    db_plugin_datas = property(__get_db_plugin_datas, __set_db_plugin_datas)
+    def db_get_plugin_datas(self):
+        return self._db_plugin_datas
+    def db_add_plugin_data(self, plugin_data):
+        self.is_dirty = True
+        self._db_plugin_datas.append(plugin_data)
+        self.db_plugin_datas_id_index[plugin_data.db_id] = plugin_data
+    def db_change_plugin_data(self, plugin_data):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_plugin_datas)):
+            if self._db_plugin_datas[i].db_id == plugin_data.db_id:
+                self._db_plugin_datas[i] = plugin_data
+                found = True
+                break
+        if not found:
+            self._db_plugin_datas.append(plugin_data)
+        self.db_plugin_datas_id_index[plugin_data.db_id] = plugin_data
+    def db_delete_plugin_data(self, plugin_data):
+        self.is_dirty = True
+        for i in xrange(len(self._db_plugin_datas)):
+            if self._db_plugin_datas[i].db_id == plugin_data.db_id:
+                if not self._db_plugin_datas[i].is_new:
+                    self.db_deleted_plugin_datas.append(self._db_plugin_datas[i])
+                del self._db_plugin_datas[i]
+                break
+        del self.db_plugin_datas_id_index[plugin_data.db_id]
+    def db_get_plugin_data(self, key):
+        for i in xrange(len(self._db_plugin_datas)):
+            if self._db_plugin_datas[i].db_id == key:
+                return self._db_plugin_datas[i]
+        return None
+    def db_get_plugin_data_by_id(self, key):
+        return self.db_plugin_datas_id_index[key]
+    def db_has_plugin_data_with_id(self, key):
+        return key in self.db_plugin_datas_id_index
+    
+    def __get_db_others(self):
+        return self._db_others
+    def __set_db_others(self, others):
+        self._db_others = others
+        self.is_dirty = True
+    db_others = property(__get_db_others, __set_db_others)
+    def db_get_others(self):
+        return self._db_others
+    def db_add_other(self, other):
+        self.is_dirty = True
+        self._db_others.append(other)
+        self.db_others_id_index[other.db_id] = other
+    def db_change_other(self, other):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_others)):
+            if self._db_others[i].db_id == other.db_id:
+                self._db_others[i] = other
+                found = True
+                break
+        if not found:
+            self._db_others.append(other)
+        self.db_others_id_index[other.db_id] = other
+    def db_delete_other(self, other):
+        self.is_dirty = True
+        for i in xrange(len(self._db_others)):
+            if self._db_others[i].db_id == other.db_id:
+                if not self._db_others[i].is_new:
+                    self.db_deleted_others.append(self._db_others[i])
+                del self._db_others[i]
+                break
+        del self.db_others_id_index[other.db_id]
+    def db_get_other(self, key):
+        for i in xrange(len(self._db_others)):
+            if self._db_others[i].db_id == key:
+                return self._db_others[i]
+        return None
+    def db_get_other_by_id(self, key):
+        return self.db_others_id_index[key]
+    def db_has_other_with_id(self, key):
+        return key in self.db_others_id_index
+    
+    def __get_db_vistrail_id(self):
+        return self._db_vistrail_id
+    def __set_db_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+        self.is_dirty = True
+    db_vistrail_id = property(__get_db_vistrail_id, __set_db_vistrail_id)
+    def db_add_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_change_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_delete_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBLog(object):
+class DBMashupAction(object):
 
-    vtType = 'log'
+    vtType = 'mashup_action'
 
-    def __init__(self, id=None, entity_type=None, version=None, name=None, last_modified=None, workflow_execs=None, machines=None, vistrail_id=None):
+    def __init__(self, id=None, prevId=None, date=None, user=None, mashup=None):
         self._db_id = id
-        self._db_entity_type = entity_type
-        self._db_version = version
-        self._db_name = name
-        self._db_last_modified = last_modified
-        self.db_deleted_workflow_execs = []
-        self.db_workflow_execs_id_index = {}
-        if workflow_execs is None:
-            self._db_workflow_execs = []
-        else:
-            self._db_workflow_execs = workflow_execs
-            for v in self._db_workflow_execs:
-                self.db_workflow_execs_id_index[v.db_id] = v
-        self.db_deleted_machines = []
-        self.db_machines_id_index = {}
-        if machines is None:
-            self._db_machines = []
-        else:
-            self._db_machines = machines
-            for v in self._db_machines:
-                self.db_machines_id_index[v.db_id] = v
-        self._db_vistrail_id = vistrail_id
-        self.is_dirty = True
-        self.is_new = True
-    
-    def __copy__(self):
-        return DBLog.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBLog(id=self._db_id,
-                   entity_type=self._db_entity_type,
-                   version=self._db_version,
-                   name=self._db_name,
-                   last_modified=self._db_last_modified,
-                   vistrail_id=self._db_vistrail_id)
-        if self._db_workflow_execs is None:
-            cp._db_workflow_execs = []
-        else:
-            cp._db_workflow_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_workflow_execs]
-        if self._db_machines is None:
-            cp._db_machines = []
-        else:
-            cp._db_machines = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_machines]
+        self._db_prevId = prevId
+        self._db_date = date
+        self._db_user = user
+        self.db_deleted_mashup = []
+        self._db_mashup = mashup
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashupAction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashupAction(id=self._db_id,
+                            prevId=self._db_prevId,
+                            date=self._db_date,
+                            user=self._db_user)
+        if self._db_mashup is not None:
+            cp._db_mashup = self._db_mashup.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -3960,12 +5816,10 @@ class DBLog(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_vistrail_id') and ('vistrail', self._db_vistrail_id) in id_remap:
-                cp._db_vistrail_id = id_remap[('vistrail', self._db_vistrail_id)]
+            if hasattr(self, 'db_prevId') and ('mashup_action', self._db_prevId) in id_remap:
+                cp._db_prevId = id_remap[('mashup_action', self._db_prevId)]
         
         # recreate indices and set flags
-        cp.db_workflow_execs_id_index = dict((v.db_id, v) for v in cp._db_workflow_execs)
-        cp.db_machines_id_index = dict((v.db_id, v) for v in cp._db_machines)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -3974,7 +5828,7 @@ class DBLog(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBLog()
+            new_obj = DBMashupAction()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -3983,92 +5837,54 @@ class DBLog(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'entity_type' in class_dict:
-            res = class_dict['entity_type'](old_obj, trans_dict)
-            new_obj.db_entity_type = res
-        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
-            new_obj.db_entity_type = old_obj.db_entity_type
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'last_modified' in class_dict:
-            res = class_dict['last_modified'](old_obj, trans_dict)
-            new_obj.db_last_modified = res
-        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
-            new_obj.db_last_modified = old_obj.db_last_modified
-        if 'workflow_execs' in class_dict:
-            res = class_dict['workflow_execs'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_workflow_exec(obj)
-        elif hasattr(old_obj, 'db_workflow_execs') and old_obj.db_workflow_execs is not None:
-            for obj in old_obj.db_workflow_execs:
-                new_obj.db_add_workflow_exec(DBWorkflowExec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_workflow_execs') and hasattr(new_obj, 'db_deleted_workflow_execs'):
-            for obj in old_obj.db_deleted_workflow_execs:
-                n_obj = DBWorkflowExec.update_version(obj, trans_dict)
-                new_obj.db_deleted_workflow_execs.append(n_obj)
-        if 'machines' in class_dict:
-            res = class_dict['machines'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_machine(obj)
-        elif hasattr(old_obj, 'db_machines') and old_obj.db_machines is not None:
-            for obj in old_obj.db_machines:
-                new_obj.db_add_machine(DBMachine.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_machines') and hasattr(new_obj, 'db_deleted_machines'):
-            for obj in old_obj.db_deleted_machines:
-                n_obj = DBMachine.update_version(obj, trans_dict)
-                new_obj.db_deleted_machines.append(n_obj)
-        if 'vistrail_id' in class_dict:
-            res = class_dict['vistrail_id'](old_obj, trans_dict)
-            new_obj.db_vistrail_id = res
-        elif hasattr(old_obj, 'db_vistrail_id') and old_obj.db_vistrail_id is not None:
-            new_obj.db_vistrail_id = old_obj.db_vistrail_id
+        if 'prevId' in class_dict:
+            res = class_dict['prevId'](old_obj, trans_dict)
+            new_obj.db_prevId = res
+        elif hasattr(old_obj, 'db_prevId') and old_obj.db_prevId is not None:
+            new_obj.db_prevId = old_obj.db_prevId
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'mashup' in class_dict:
+            res = class_dict['mashup'](old_obj, trans_dict)
+            new_obj.db_mashup = res
+        elif hasattr(old_obj, 'db_mashup') and old_obj.db_mashup is not None:
+            obj = old_obj.db_mashup
+            new_obj.db_add_mashup(DBMashup.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_mashup') and hasattr(new_obj, 'db_deleted_mashup'):
+            for obj in old_obj.db_deleted_mashup:
+                n_obj = DBMashup.update_version(obj, trans_dict)
+                new_obj.db_deleted_mashup.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        to_del = []
-        for child in self.db_workflow_execs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_workflow_exec(child)
-        to_del = []
-        for child in self.db_machines:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_mashup is not None:
+            children.extend(self._db_mashup.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_machine(child)
+                self._db_mashup = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_workflow_execs)
-        children.extend(self.db_deleted_machines)
+        children.extend(self.db_deleted_mashup)
         if remove:
-            self.db_deleted_workflow_execs = []
-            self.db_deleted_machines = []
+            self.db_deleted_mashup = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_workflow_execs:
-            if child.has_changes():
-                return True
-        for child in self._db_machines:
-            if child.has_changes():
-                return True
+        if self._db_mashup is not None and self._db_mashup.has_changes():
+            return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -4083,178 +5899,88 @@ class DBLog(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_entity_type(self):
-        return self._db_entity_type
-    def __set_db_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-        self.is_dirty = True
-    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
-    def db_add_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_change_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_delete_entity_type(self, entity_type):
-        self._db_entity_type = None
-    
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
-        self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_last_modified(self):
-        return self._db_last_modified
-    def __set_db_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-        self.is_dirty = True
-    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
-    def db_add_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_change_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_delete_last_modified(self, last_modified):
-        self._db_last_modified = None
-    
-    def __get_db_workflow_execs(self):
-        return self._db_workflow_execs
-    def __set_db_workflow_execs(self, workflow_execs):
-        self._db_workflow_execs = workflow_execs
-        self.is_dirty = True
-    db_workflow_execs = property(__get_db_workflow_execs, __set_db_workflow_execs)
-    def db_get_workflow_execs(self):
-        return self._db_workflow_execs
-    def db_add_workflow_exec(self, workflow_exec):
-        self.is_dirty = True
-        self._db_workflow_execs.append(workflow_exec)
-        self.db_workflow_execs_id_index[workflow_exec.db_id] = workflow_exec
-    def db_change_workflow_exec(self, workflow_exec):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_workflow_execs)):
-            if self._db_workflow_execs[i].db_id == workflow_exec.db_id:
-                self._db_workflow_execs[i] = workflow_exec
-                found = True
-                break
-        if not found:
-            self._db_workflow_execs.append(workflow_exec)
-        self.db_workflow_execs_id_index[workflow_exec.db_id] = workflow_exec
-    def db_delete_workflow_exec(self, workflow_exec):
+    def __get_db_prevId(self):
+        return self._db_prevId
+    def __set_db_prevId(self, prevId):
+        self._db_prevId = prevId
         self.is_dirty = True
-        for i in xrange(len(self._db_workflow_execs)):
-            if self._db_workflow_execs[i].db_id == workflow_exec.db_id:
-                if not self._db_workflow_execs[i].is_new:
-                    self.db_deleted_workflow_execs.append(self._db_workflow_execs[i])
-                del self._db_workflow_execs[i]
-                break
-        del self.db_workflow_execs_id_index[workflow_exec.db_id]
-    def db_get_workflow_exec(self, key):
-        for i in xrange(len(self._db_workflow_execs)):
-            if self._db_workflow_execs[i].db_id == key:
-                return self._db_workflow_execs[i]
-        return None
-    def db_get_workflow_exec_by_id(self, key):
-        return self.db_workflow_execs_id_index[key]
-    def db_has_workflow_exec_with_id(self, key):
-        return key in self.db_workflow_execs_id_index
+    db_prevId = property(__get_db_prevId, __set_db_prevId)
+    def db_add_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_change_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_delete_prevId(self, prevId):
+        self._db_prevId = None
     
-    def __get_db_machines(self):
-        return self._db_machines
-    def __set_db_machines(self, machines):
-        self._db_machines = machines
-        self.is_dirty = True
-    db_machines = property(__get_db_machines, __set_db_machines)
-    def db_get_machines(self):
-        return self._db_machines
-    def db_add_machine(self, machine):
-        self.is_dirty = True
-        self._db_machines.append(machine)
-        self.db_machines_id_index[machine.db_id] = machine
-    def db_change_machine(self, machine):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_machines)):
-            if self._db_machines[i].db_id == machine.db_id:
-                self._db_machines[i] = machine
-                found = True
-                break
-        if not found:
-            self._db_machines.append(machine)
-        self.db_machines_id_index[machine.db_id] = machine
-    def db_delete_machine(self, machine):
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
         self.is_dirty = True
-        for i in xrange(len(self._db_machines)):
-            if self._db_machines[i].db_id == machine.db_id:
-                if not self._db_machines[i].is_new:
-                    self.db_deleted_machines.append(self._db_machines[i])
-                del self._db_machines[i]
-                break
-        del self.db_machines_id_index[machine.db_id]
-    def db_get_machine(self, key):
-        for i in xrange(len(self._db_machines)):
-            if self._db_machines[i].db_id == key:
-                return self._db_machines[i]
-        return None
-    def db_get_machine_by_id(self, key):
-        return self.db_machines_id_index[key]
-    def db_has_machine_with_id(self, key):
-        return key in self.db_machines_id_index
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
     
-    def __get_db_vistrail_id(self):
-        return self._db_vistrail_id
-    def __set_db_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = vistrail_id
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
         self.is_dirty = True
-    db_vistrail_id = property(__get_db_vistrail_id, __set_db_vistrail_id)
-    def db_add_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = vistrail_id
-    def db_change_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = vistrail_id
-    def db_delete_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = None
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def __get_db_mashup(self):
+        return self._db_mashup
+    def __set_db_mashup(self, mashup):
+        self._db_mashup = mashup
+        self.is_dirty = True
+    db_mashup = property(__get_db_mashup, __set_db_mashup)
+    def db_add_mashup(self, mashup):
+        self._db_mashup = mashup
+    def db_change_mashup(self, mashup):
+        self._db_mashup = mashup
+    def db_delete_mashup(self, mashup):
+        if not self.is_new:
+            self.db_deleted_mashup.append(self._db_mashup)
+        self._db_mashup = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBMashupAlias(object):
+class DBConfiguration(object):
 
-    vtType = 'mashup_alias'
+    vtType = 'configuration'
 
-    def __init__(self, id=None, name=None, component=None):
-        self._db_id = id
-        self._db_name = name
-        self.db_deleted_component = []
-        self._db_component = component
+    def __init__(self, config_keys=None):
+        self.db_deleted_config_keys = []
+        self.db_config_keys_name_index = {}
+        if config_keys is None:
+            self._db_config_keys = []
+        else:
+            self._db_config_keys = config_keys
+            for v in self._db_config_keys:
+                self.db_config_keys_name_index[v.db_name] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMashupAlias.do_copy(self)
+        return DBConfiguration.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMashupAlias(id=self._db_id,
-                           name=self._db_name)
-        if self._db_component is not None:
-            cp._db_component = self._db_component.do_copy(new_ids, id_scope, id_remap)
+        cp = DBConfiguration()
+        if self._db_config_keys is None:
+            cp._db_config_keys = []
+        else:
+            cp._db_config_keys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_config_keys]
         
         # set new ids
         if new_ids:
@@ -4266,6 +5992,7 @@ class DBMashupAlias(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_config_keys_name_index = dict((v.db_name, v) for v in cp._db_config_keys)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -4274,123 +6001,105 @@ class DBMashupAlias(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBMashupAlias()
+            new_obj = DBConfiguration()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'component' in class_dict:
-            res = class_dict['component'](old_obj, trans_dict)
-            new_obj.db_component = res
-        elif hasattr(old_obj, 'db_component') and old_obj.db_component is not None:
-            obj = old_obj.db_component
-            new_obj.db_add_component(DBMashupComponent.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_component') and hasattr(new_obj, 'db_deleted_component'):
-            for obj in old_obj.db_deleted_component:
-                n_obj = DBMashupComponent.update_version(obj, trans_dict)
-                new_obj.db_deleted_component.append(n_obj)
+        if 'config_keys' in class_dict:
+            res = class_dict['config_keys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_config_key(obj)
+        elif hasattr(old_obj, 'db_config_keys') and old_obj.db_config_keys is not None:
+            for obj in old_obj.db_config_keys:
+                new_obj.db_add_config_key(DBConfigKey.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_config_keys') and hasattr(new_obj, 'db_deleted_config_keys'):
+            for obj in old_obj.db_deleted_config_keys:
+                n_obj = DBConfigKey.update_version(obj, trans_dict)
+                new_obj.db_deleted_config_keys.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_component is not None:
-            children.extend(self._db_component.db_children((self.vtType, self.db_id), orphan, for_action))
+        to_del = []
+        for child in self.db_config_keys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_component = None
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_config_key(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_component)
+        children.extend(self.db_deleted_config_keys)
         if remove:
-            self.db_deleted_component = []
+            self.db_deleted_config_keys = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_component is not None and self._db_component.has_changes():
-            return True
+        for child in self._db_config_keys:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_config_keys(self):
+        return self._db_config_keys
+    def __set_db_config_keys(self, config_keys):
+        self._db_config_keys = config_keys
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
+    db_config_keys = property(__get_db_config_keys, __set_db_config_keys)
+    def db_get_config_keys(self):
+        return self._db_config_keys
+    def db_add_config_key(self, config_key):
         self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_component(self):
-        return self._db_component
-    def __set_db_component(self, component):
-        self._db_component = component
+        self._db_config_keys.append(config_key)
+        self.db_config_keys_name_index[config_key.db_name] = config_key
+    def db_change_config_key(self, config_key):
         self.is_dirty = True
-    db_component = property(__get_db_component, __set_db_component)
-    def db_add_component(self, component):
-        self._db_component = component
-    def db_change_component(self, component):
-        self._db_component = component
-    def db_delete_component(self, component):
-        if not self.is_new:
-            self.db_deleted_component.append(self._db_component)
-        self._db_component = None
+        self._db_config_keys.append(config_key)
+        self.db_config_keys_name_index[config_key.db_name] = config_key
+    def db_delete_config_key(self, config_key):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_config_key(self, key):
+        return None
+    def db_get_config_key_by_name(self, key):
+        return self.db_config_keys_name_index[key]
+    def db_has_config_key_with_name(self, key):
+        return key in self.db_config_keys_name_index
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBOpmAgents(object):
 
-    vtType = 'opm_agents'
+class DBChange(object):
 
-    def __init__(self, agents=None):
-        self.db_deleted_agents = []
-        self.db_agents_id_index = {}
-        if agents is None:
-            self._db_agents = []
-        else:
-            self._db_agents = agents
-            for v in self._db_agents:
-                self.db_agents_id_index[v.db_id] = v
+    vtType = 'change'
+
+    def __init__(self, data=None, id=None, what=None, oldObjId=None, newObjId=None, parentObjId=None, parentObjType=None):
+        self.db_deleted_data = []
+        self._db_data = data
+        self._db_id = id
+        self._db_what = what
+        self._db_oldObjId = oldObjId
+        self._db_newObjId = newObjId
+        self._db_parentObjId = parentObjId
+        self._db_parentObjType = parentObjType
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmAgents.do_copy(self)
+        return DBChange.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmAgents()
-        if self._db_agents is None:
-            cp._db_agents = []
-        else:
-            cp._db_agents = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_agents]
+        cp = DBChange(id=self._db_id,
+                      what=self._db_what,
+                      oldObjId=self._db_oldObjId,
+                      newObjId=self._db_newObjId,
+                      parentObjId=self._db_parentObjId,
+                      parentObjType=self._db_parentObjType)
+        if self._db_data is not None:
+            cp._db_data = self._db_data.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -4400,9 +6109,14 @@ class DBOpmAgents(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_oldObjId') and (self._db_what, self._db_oldObjId) in id_remap:
+                cp._db_oldObjId = id_remap[(self._db_what, self._db_oldObjId)]
+            if hasattr(self, 'db_newObjId') and (self._db_what, self._db_newObjId) in id_remap:
+                cp._db_newObjId = id_remap[(self._db_what, self._db_newObjId)]
+            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
+                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
         
         # recreate indices and set flags
-        cp.db_agents_id_index = dict((v.db_id, v) for v in cp._db_agents)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -4411,133 +6125,267 @@ class DBOpmAgents(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmAgents()
+            new_obj = DBChange()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'agents' in class_dict:
-            res = class_dict['agents'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_agent(obj)
-        elif hasattr(old_obj, 'db_agents') and old_obj.db_agents is not None:
-            for obj in old_obj.db_agents:
-                new_obj.db_add_agent(DBOpmAgent.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_agents') and hasattr(new_obj, 'db_deleted_agents'):
-            for obj in old_obj.db_deleted_agents:
-                n_obj = DBOpmAgent.update_version(obj, trans_dict)
-                new_obj.db_deleted_agents.append(n_obj)
+        if 'data' in class_dict:
+            res = class_dict['data'](old_obj, trans_dict)
+            new_obj.db_data = res
+        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
+            obj = old_obj.db_data
+            if obj.vtType == 'module':
+                new_obj.db_add_data(DBModule.update_version(obj, trans_dict))
+            elif obj.vtType == 'location':
+                new_obj.db_add_data(DBLocation.update_version(obj, trans_dict))
+            elif obj.vtType == 'annotation':
+                new_obj.db_add_data(DBAnnotation.update_version(obj, trans_dict))
+            elif obj.vtType == 'function':
+                new_obj.db_add_data(DBFunction.update_version(obj, trans_dict))
+            elif obj.vtType == 'connection':
+                new_obj.db_add_data(DBConnection.update_version(obj, trans_dict))
+            elif obj.vtType == 'port':
+                new_obj.db_add_data(DBPort.update_version(obj, trans_dict))
+            elif obj.vtType == 'parameter':
+                new_obj.db_add_data(DBParameter.update_version(obj, trans_dict))
+            elif obj.vtType == 'portSpec':
+                new_obj.db_add_data(DBPortSpec.update_version(obj, trans_dict))
+            elif obj.vtType == 'abstraction':
+                new_obj.db_add_data(DBAbstraction.update_version(obj, trans_dict))
+            elif obj.vtType == 'group':
+                new_obj.db_add_data(DBGroup.update_version(obj, trans_dict))
+            elif obj.vtType == 'other':
+                new_obj.db_add_data(DBOther.update_version(obj, trans_dict))
+            elif obj.vtType == 'plugin_data':
+                new_obj.db_add_data(DBPluginData.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_data') and hasattr(new_obj, 'db_deleted_data'):
+            for obj in old_obj.db_deleted_data:
+                if obj.vtType == 'module':
+                    n_obj = DBModule.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'location':
+                    n_obj = DBLocation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'annotation':
+                    n_obj = DBAnnotation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'function':
+                    n_obj = DBFunction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'connection':
+                    n_obj = DBConnection.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'port':
+                    n_obj = DBPort.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'parameter':
+                    n_obj = DBParameter.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'portSpec':
+                    n_obj = DBPortSpec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'abstraction':
+                    n_obj = DBAbstraction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'group':
+                    n_obj = DBGroup.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'other':
+                    n_obj = DBOther.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'plugin_data':
+                    n_obj = DBPluginData.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'what' in class_dict:
+            res = class_dict['what'](old_obj, trans_dict)
+            new_obj.db_what = res
+        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
+            new_obj.db_what = old_obj.db_what
+        if 'oldObjId' in class_dict:
+            res = class_dict['oldObjId'](old_obj, trans_dict)
+            new_obj.db_oldObjId = res
+        elif hasattr(old_obj, 'db_oldObjId') and old_obj.db_oldObjId is not None:
+            new_obj.db_oldObjId = old_obj.db_oldObjId
+        if 'newObjId' in class_dict:
+            res = class_dict['newObjId'](old_obj, trans_dict)
+            new_obj.db_newObjId = res
+        elif hasattr(old_obj, 'db_newObjId') and old_obj.db_newObjId is not None:
+            new_obj.db_newObjId = old_obj.db_newObjId
+        if 'parentObjId' in class_dict:
+            res = class_dict['parentObjId'](old_obj, trans_dict)
+            new_obj.db_parentObjId = res
+        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
+            new_obj.db_parentObjId = old_obj.db_parentObjId
+        if 'parentObjType' in class_dict:
+            res = class_dict['parentObjType'](old_obj, trans_dict)
+            new_obj.db_parentObjType = res
+        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
+            new_obj.db_parentObjType = old_obj.db_parentObjType
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        to_del = []
-        for child in self.db_agents:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_data is not None:
+            children.extend(self._db_data.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_agent(child)
+                self._db_data = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_agents)
+        children.extend(self.db_deleted_data)
         if remove:
-            self.db_deleted_agents = []
+            self.db_deleted_data = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_agents:
-            if child.has_changes():
-                return True
+        if self._db_data is not None and self._db_data.has_changes():
+            return True
         return False
-    def __get_db_agents(self):
-        return self._db_agents
-    def __set_db_agents(self, agents):
-        self._db_agents = agents
+    def __get_db_data(self):
+        return self._db_data
+    def __set_db_data(self, data):
+        self._db_data = data
         self.is_dirty = True
-    db_agents = property(__get_db_agents, __set_db_agents)
-    def db_get_agents(self):
-        return self._db_agents
-    def db_add_agent(self, agent):
+    db_data = property(__get_db_data, __set_db_data)
+    def db_add_data(self, data):
+        self._db_data = data
+    def db_change_data(self, data):
+        self._db_data = data
+    def db_delete_data(self, data):
+        if not self.is_new:
+            self.db_deleted_data.append(self._db_data)
+        self._db_data = None
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-        self._db_agents.append(agent)
-        self.db_agents_id_index[agent.db_id] = agent
-    def db_change_agent(self, agent):
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_what(self):
+        return self._db_what
+    def __set_db_what(self, what):
+        self._db_what = what
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_agents)):
-            if self._db_agents[i].db_id == agent.db_id:
-                self._db_agents[i] = agent
-                found = True
-                break
-        if not found:
-            self._db_agents.append(agent)
-        self.db_agents_id_index[agent.db_id] = agent
-    def db_delete_agent(self, agent):
+    db_what = property(__get_db_what, __set_db_what)
+    def db_add_what(self, what):
+        self._db_what = what
+    def db_change_what(self, what):
+        self._db_what = what
+    def db_delete_what(self, what):
+        self._db_what = None
+    
+    def __get_db_oldObjId(self):
+        return self._db_oldObjId
+    def __set_db_oldObjId(self, oldObjId):
+        self._db_oldObjId = oldObjId
         self.is_dirty = True
-        for i in xrange(len(self._db_agents)):
-            if self._db_agents[i].db_id == agent.db_id:
-                if not self._db_agents[i].is_new:
-                    self.db_deleted_agents.append(self._db_agents[i])
-                del self._db_agents[i]
-                break
-        del self.db_agents_id_index[agent.db_id]
-    def db_get_agent(self, key):
-        for i in xrange(len(self._db_agents)):
-            if self._db_agents[i].db_id == key:
-                return self._db_agents[i]
-        return None
-    def db_get_agent_by_id(self, key):
-        return self.db_agents_id_index[key]
-    def db_has_agent_with_id(self, key):
-        return key in self.db_agents_id_index
+    db_oldObjId = property(__get_db_oldObjId, __set_db_oldObjId)
+    def db_add_oldObjId(self, oldObjId):
+        self._db_oldObjId = oldObjId
+    def db_change_oldObjId(self, oldObjId):
+        self._db_oldObjId = oldObjId
+    def db_delete_oldObjId(self, oldObjId):
+        self._db_oldObjId = None
     
+    def __get_db_newObjId(self):
+        return self._db_newObjId
+    def __set_db_newObjId(self, newObjId):
+        self._db_newObjId = newObjId
+        self.is_dirty = True
+    db_newObjId = property(__get_db_newObjId, __set_db_newObjId)
+    def db_add_newObjId(self, newObjId):
+        self._db_newObjId = newObjId
+    def db_change_newObjId(self, newObjId):
+        self._db_newObjId = newObjId
+    def db_delete_newObjId(self, newObjId):
+        self._db_newObjId = None
+    
+    def __get_db_parentObjId(self):
+        return self._db_parentObjId
+    def __set_db_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+        self.is_dirty = True
+    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
+    def db_add_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_change_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_delete_parentObjId(self, parentObjId):
+        self._db_parentObjId = None
+    
+    def __get_db_parentObjType(self):
+        return self._db_parentObjType
+    def __set_db_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
+    def db_add_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_change_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_delete_parentObjType(self, parentObjType):
+        self._db_parentObjType = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBPackage(object):
 
-class DBMashup(object):
-
-    vtType = 'mashup'
+    vtType = 'package'
 
-    def __init__(self, id=None, name=None, version=None, aliases=None, type=None, vtid=None, layout=None, geometry=None, has_seq=None):
+    def __init__(self, id=None, name=None, identifier=None, codepath=None, load_configuration=None, version=None, description=None, module_descriptors=None):
         self._db_id = id
         self._db_name = name
+        self._db_identifier = identifier
+        self._db_codepath = codepath
+        self._db_load_configuration = load_configuration
         self._db_version = version
-        self.db_deleted_aliases = []
-        self.db_aliases_id_index = {}
-        if aliases is None:
-            self._db_aliases = []
+        self._db_description = description
+        self.db_deleted_module_descriptors = []
+        self.db_module_descriptors_id_index = {}
+        self.db_module_descriptors_name_index = {}
+        if module_descriptors is None:
+            self._db_module_descriptors = []
         else:
-            self._db_aliases = aliases
-            for v in self._db_aliases:
-                self.db_aliases_id_index[v.db_id] = v
-        self._db_type = type
-        self._db_vtid = vtid
-        self._db_layout = layout
-        self._db_geometry = geometry
-        self._db_has_seq = has_seq
+            self._db_module_descriptors = module_descriptors
+            for v in self._db_module_descriptors:
+                self.db_module_descriptors_id_index[v.db_id] = v
+                self.db_module_descriptors_name_index[(v.db_name,v.db_namespace,v.db_version)] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMashup.do_copy(self)
+        return DBPackage.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMashup(id=self._db_id,
-                      name=self._db_name,
-                      version=self._db_version,
-                      type=self._db_type,
-                      vtid=self._db_vtid,
-                      layout=self._db_layout,
-                      geometry=self._db_geometry,
-                      has_seq=self._db_has_seq)
-        if self._db_aliases is None:
-            cp._db_aliases = []
+        cp = DBPackage(id=self._db_id,
+                       name=self._db_name,
+                       identifier=self._db_identifier,
+                       codepath=self._db_codepath,
+                       load_configuration=self._db_load_configuration,
+                       version=self._db_version,
+                       description=self._db_description)
+        if self._db_module_descriptors is None:
+            cp._db_module_descriptors = []
         else:
-            cp._db_aliases = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_aliases]
+            cp._db_module_descriptors = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_module_descriptors]
         
         # set new ids
         if new_ids:
@@ -4547,11 +6395,10 @@ class DBMashup(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_vtid') and ('vistrail', self._db_vtid) in id_remap:
-                cp._db_vtid = id_remap[('vistrail', self._db_vtid)]
         
         # recreate indices and set flags
-        cp.db_aliases_id_index = dict((v.db_id, v) for v in cp._db_aliases)
+        cp.db_module_descriptors_id_index = dict((v.db_id, v) for v in cp._db_module_descriptors)
+        cp.db_module_descriptors_name_index = dict(((v.db_name,v.db_namespace,v.db_version), v) for v in cp._db_module_descriptors)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -4560,7 +6407,7 @@ class DBMashup(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBMashup()
+            new_obj = DBPackage()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -4574,47 +6421,42 @@ class DBMashup(object):
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
+        if 'identifier' in class_dict:
+            res = class_dict['identifier'](old_obj, trans_dict)
+            new_obj.db_identifier = res
+        elif hasattr(old_obj, 'db_identifier') and old_obj.db_identifier is not None:
+            new_obj.db_identifier = old_obj.db_identifier
+        if 'codepath' in class_dict:
+            res = class_dict['codepath'](old_obj, trans_dict)
+            new_obj.db_codepath = res
+        elif hasattr(old_obj, 'db_codepath') and old_obj.db_codepath is not None:
+            new_obj.db_codepath = old_obj.db_codepath
+        if 'load_configuration' in class_dict:
+            res = class_dict['load_configuration'](old_obj, trans_dict)
+            new_obj.db_load_configuration = res
+        elif hasattr(old_obj, 'db_load_configuration') and old_obj.db_load_configuration is not None:
+            new_obj.db_load_configuration = old_obj.db_load_configuration
         if 'version' in class_dict:
             res = class_dict['version'](old_obj, trans_dict)
             new_obj.db_version = res
         elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
             new_obj.db_version = old_obj.db_version
-        if 'aliases' in class_dict:
-            res = class_dict['aliases'](old_obj, trans_dict)
+        if 'description' in class_dict:
+            res = class_dict['description'](old_obj, trans_dict)
+            new_obj.db_description = res
+        elif hasattr(old_obj, 'db_description') and old_obj.db_description is not None:
+            new_obj.db_description = old_obj.db_description
+        if 'module_descriptors' in class_dict:
+            res = class_dict['module_descriptors'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_alias(obj)
-        elif hasattr(old_obj, 'db_aliases') and old_obj.db_aliases is not None:
-            for obj in old_obj.db_aliases:
-                new_obj.db_add_alias(DBMashupAlias.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_aliases') and hasattr(new_obj, 'db_deleted_aliases'):
-            for obj in old_obj.db_deleted_aliases:
-                n_obj = DBMashupAlias.update_version(obj, trans_dict)
-                new_obj.db_deleted_aliases.append(n_obj)
-        if 'type' in class_dict:
-            res = class_dict['type'](old_obj, trans_dict)
-            new_obj.db_type = res
-        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
-            new_obj.db_type = old_obj.db_type
-        if 'vtid' in class_dict:
-            res = class_dict['vtid'](old_obj, trans_dict)
-            new_obj.db_vtid = res
-        elif hasattr(old_obj, 'db_vtid') and old_obj.db_vtid is not None:
-            new_obj.db_vtid = old_obj.db_vtid
-        if 'layout' in class_dict:
-            res = class_dict['layout'](old_obj, trans_dict)
-            new_obj.db_layout = res
-        elif hasattr(old_obj, 'db_layout') and old_obj.db_layout is not None:
-            new_obj.db_layout = old_obj.db_layout
-        if 'geometry' in class_dict:
-            res = class_dict['geometry'](old_obj, trans_dict)
-            new_obj.db_geometry = res
-        elif hasattr(old_obj, 'db_geometry') and old_obj.db_geometry is not None:
-            new_obj.db_geometry = old_obj.db_geometry
-        if 'has_seq' in class_dict:
-            res = class_dict['has_seq'](old_obj, trans_dict)
-            new_obj.db_has_seq = res
-        elif hasattr(old_obj, 'db_has_seq') and old_obj.db_has_seq is not None:
-            new_obj.db_has_seq = old_obj.db_has_seq
+                new_obj.db_add_module_descriptor(obj)
+        elif hasattr(old_obj, 'db_module_descriptors') and old_obj.db_module_descriptors is not None:
+            for obj in old_obj.db_module_descriptors:
+                new_obj.db_add_module_descriptor(DBModuleDescriptor.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_module_descriptors') and hasattr(new_obj, 'db_deleted_module_descriptors'):
+            for obj in old_obj.db_deleted_module_descriptors:
+                n_obj = DBModuleDescriptor.update_version(obj, trans_dict)
+                new_obj.db_deleted_module_descriptors.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -4622,24 +6464,24 @@ class DBMashup(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_aliases:
+        for child in self.db_module_descriptors:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_alias(child)
+            self.db_delete_module_descriptor(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_aliases)
+        children.extend(self.db_deleted_module_descriptors)
         if remove:
-            self.db_deleted_aliases = []
+            self.db_deleted_module_descriptors = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_aliases:
+        for child in self._db_module_descriptors:
             if child.has_changes():
                 return True
         return False
@@ -4669,6 +6511,45 @@ class DBMashup(object):
     def db_delete_name(self, name):
         self._db_name = None
     
+    def __get_db_identifier(self):
+        return self._db_identifier
+    def __set_db_identifier(self, identifier):
+        self._db_identifier = identifier
+        self.is_dirty = True
+    db_identifier = property(__get_db_identifier, __set_db_identifier)
+    def db_add_identifier(self, identifier):
+        self._db_identifier = identifier
+    def db_change_identifier(self, identifier):
+        self._db_identifier = identifier
+    def db_delete_identifier(self, identifier):
+        self._db_identifier = None
+    
+    def __get_db_codepath(self):
+        return self._db_codepath
+    def __set_db_codepath(self, codepath):
+        self._db_codepath = codepath
+        self.is_dirty = True
+    db_codepath = property(__get_db_codepath, __set_db_codepath)
+    def db_add_codepath(self, codepath):
+        self._db_codepath = codepath
+    def db_change_codepath(self, codepath):
+        self._db_codepath = codepath
+    def db_delete_codepath(self, codepath):
+        self._db_codepath = None
+    
+    def __get_db_load_configuration(self):
+        return self._db_load_configuration
+    def __set_db_load_configuration(self, load_configuration):
+        self._db_load_configuration = load_configuration
+        self.is_dirty = True
+    db_load_configuration = property(__get_db_load_configuration, __set_db_load_configuration)
+    def db_add_load_configuration(self, load_configuration):
+        self._db_load_configuration = load_configuration
+    def db_change_load_configuration(self, load_configuration):
+        self._db_load_configuration = load_configuration
+    def db_delete_load_configuration(self, load_configuration):
+        self._db_load_configuration = None
+    
     def __get_db_version(self):
         return self._db_version
     def __set_db_version(self, version):
@@ -4682,130 +6563,107 @@ class DBMashup(object):
     def db_delete_version(self, version):
         self._db_version = None
     
-    def __get_db_aliases(self):
-        return self._db_aliases
-    def __set_db_aliases(self, aliases):
-        self._db_aliases = aliases
+    def __get_db_description(self):
+        return self._db_description
+    def __set_db_description(self, description):
+        self._db_description = description
         self.is_dirty = True
-    db_aliases = property(__get_db_aliases, __set_db_aliases)
-    def db_get_aliases(self):
-        return self._db_aliases
-    def db_add_alias(self, alias):
+    db_description = property(__get_db_description, __set_db_description)
+    def db_add_description(self, description):
+        self._db_description = description
+    def db_change_description(self, description):
+        self._db_description = description
+    def db_delete_description(self, description):
+        self._db_description = None
+    
+    def __get_db_module_descriptors(self):
+        return self._db_module_descriptors
+    def __set_db_module_descriptors(self, module_descriptors):
+        self._db_module_descriptors = module_descriptors
         self.is_dirty = True
-        self._db_aliases.append(alias)
-        self.db_aliases_id_index[alias.db_id] = alias
-    def db_change_alias(self, alias):
+    db_module_descriptors = property(__get_db_module_descriptors, __set_db_module_descriptors)
+    def db_get_module_descriptors(self):
+        return self._db_module_descriptors
+    def db_add_module_descriptor(self, module_descriptor):
+        self.is_dirty = True
+        self._db_module_descriptors.append(module_descriptor)
+        self.db_module_descriptors_id_index[module_descriptor.db_id] = module_descriptor
+        self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)] = module_descriptor
+    def db_change_module_descriptor(self, module_descriptor):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_aliases)):
-            if self._db_aliases[i].db_id == alias.db_id:
-                self._db_aliases[i] = alias
+        for i in xrange(len(self._db_module_descriptors)):
+            if self._db_module_descriptors[i].db_id == module_descriptor.db_id:
+                self._db_module_descriptors[i] = module_descriptor
                 found = True
                 break
         if not found:
-            self._db_aliases.append(alias)
-        self.db_aliases_id_index[alias.db_id] = alias
-    def db_delete_alias(self, alias):
+            self._db_module_descriptors.append(module_descriptor)
+        self.db_module_descriptors_id_index[module_descriptor.db_id] = module_descriptor
+        self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)] = module_descriptor
+    def db_delete_module_descriptor(self, module_descriptor):
         self.is_dirty = True
-        for i in xrange(len(self._db_aliases)):
-            if self._db_aliases[i].db_id == alias.db_id:
-                if not self._db_aliases[i].is_new:
-                    self.db_deleted_aliases.append(self._db_aliases[i])
-                del self._db_aliases[i]
+        for i in xrange(len(self._db_module_descriptors)):
+            if self._db_module_descriptors[i].db_id == module_descriptor.db_id:
+                if not self._db_module_descriptors[i].is_new:
+                    self.db_deleted_module_descriptors.append(self._db_module_descriptors[i])
+                del self._db_module_descriptors[i]
                 break
-        del self.db_aliases_id_index[alias.db_id]
-    def db_get_alias(self, key):
-        for i in xrange(len(self._db_aliases)):
-            if self._db_aliases[i].db_id == key:
-                return self._db_aliases[i]
-        return None
-    def db_get_alias_by_id(self, key):
-        return self.db_aliases_id_index[key]
-    def db_has_alias_with_id(self, key):
-        return key in self.db_aliases_id_index
-    
-    def __get_db_type(self):
-        return self._db_type
-    def __set_db_type(self, type):
-        self._db_type = type
-        self.is_dirty = True
-    db_type = property(__get_db_type, __set_db_type)
-    def db_add_type(self, type):
-        self._db_type = type
-    def db_change_type(self, type):
-        self._db_type = type
-    def db_delete_type(self, type):
-        self._db_type = None
-    
-    def __get_db_vtid(self):
-        return self._db_vtid
-    def __set_db_vtid(self, vtid):
-        self._db_vtid = vtid
-        self.is_dirty = True
-    db_vtid = property(__get_db_vtid, __set_db_vtid)
-    def db_add_vtid(self, vtid):
-        self._db_vtid = vtid
-    def db_change_vtid(self, vtid):
-        self._db_vtid = vtid
-    def db_delete_vtid(self, vtid):
-        self._db_vtid = None
-    
-    def __get_db_layout(self):
-        return self._db_layout
-    def __set_db_layout(self, layout):
-        self._db_layout = layout
-        self.is_dirty = True
-    db_layout = property(__get_db_layout, __set_db_layout)
-    def db_add_layout(self, layout):
-        self._db_layout = layout
-    def db_change_layout(self, layout):
-        self._db_layout = layout
-    def db_delete_layout(self, layout):
-        self._db_layout = None
-    
-    def __get_db_geometry(self):
-        return self._db_geometry
-    def __set_db_geometry(self, geometry):
-        self._db_geometry = geometry
-        self.is_dirty = True
-    db_geometry = property(__get_db_geometry, __set_db_geometry)
-    def db_add_geometry(self, geometry):
-        self._db_geometry = geometry
-    def db_change_geometry(self, geometry):
-        self._db_geometry = geometry
-    def db_delete_geometry(self, geometry):
-        self._db_geometry = None
-    
-    def __get_db_has_seq(self):
-        return self._db_has_seq
-    def __set_db_has_seq(self, has_seq):
-        self._db_has_seq = has_seq
-        self.is_dirty = True
-    db_has_seq = property(__get_db_has_seq, __set_db_has_seq)
-    def db_add_has_seq(self, has_seq):
-        self._db_has_seq = has_seq
-    def db_change_has_seq(self, has_seq):
-        self._db_has_seq = has_seq
-    def db_delete_has_seq(self, has_seq):
-        self._db_has_seq = None
+        del self.db_module_descriptors_id_index[module_descriptor.db_id]
+        del self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)]
+    def db_get_module_descriptor(self, key):
+        for i in xrange(len(self._db_module_descriptors)):
+            if self._db_module_descriptors[i].db_id == key:
+                return self._db_module_descriptors[i]
+        return None
+    def db_get_module_descriptor_by_id(self, key):
+        return self.db_module_descriptors_id_index[key]
+    def db_has_module_descriptor_with_id(self, key):
+        return key in self.db_module_descriptors_id_index
+    def db_get_module_descriptor_by_name(self, key):
+        return self.db_module_descriptors_name_index[key]
+    def db_has_module_descriptor_with_name(self, key):
+        return key in self.db_module_descriptors_name_index
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmProcessIdCause(object):
+class DBLoopExec(object):
 
-    vtType = 'opm_process_id_cause'
+    vtType = 'loop_exec'
 
-    def __init__(self, id=None):
+    def __init__(self, item_execs=None, id=None, ts_start=None, ts_end=None, iteration=None, completed=None, error=None):
+        self.db_deleted_item_execs = []
+        self.db_item_execs_id_index = {}
+        if item_execs is None:
+            self._db_item_execs = []
+        else:
+            self._db_item_execs = item_execs
+            for v in self._db_item_execs:
+                self.db_item_execs_id_index[v.db_id] = v
         self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_iteration = iteration
+        self._db_completed = completed
+        self._db_error = error
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmProcessIdCause.do_copy(self)
+        return DBLoopExec.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmProcessIdCause(id=self._db_id)
+        cp = DBLoopExec(id=self._db_id,
+                        ts_start=self._db_ts_start,
+                        ts_end=self._db_ts_end,
+                        iteration=self._db_iteration,
+                        completed=self._db_completed,
+                        error=self._db_error)
+        if self._db_item_execs is None:
+            cp._db_item_execs = []
+        else:
+            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
         
         # set new ids
         if new_ids:
@@ -4815,10 +6673,9 @@ class DBOpmProcessIdCause(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('opm_process', self._db_id) in id_remap:
-                cp._db_id = id_remap[('opm_process', self._db_id)]
         
         # recreate indices and set flags
+        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -4827,28 +6684,133 @@ class DBOpmProcessIdCause(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmProcessIdCause()
+            new_obj = DBLoopExec()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'item_execs' in class_dict:
+            res = class_dict['item_execs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_item_exec(obj)
+        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
+            for obj in old_obj.db_item_execs:
+                if obj.vtType == 'module_exec':
+                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'group_exec':
+                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'loop_exec':
+                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
+            for obj in old_obj.db_deleted_item_execs:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
         if 'id' in class_dict:
             res = class_dict['id'](old_obj, trans_dict)
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'iteration' in class_dict:
+            res = class_dict['iteration'](old_obj, trans_dict)
+            new_obj.db_iteration = res
+        elif hasattr(old_obj, 'db_iteration') and old_obj.db_iteration is not None:
+            new_obj.db_iteration = old_obj.db_iteration
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'error' in class_dict:
+            res = class_dict['error'](old_obj, trans_dict)
+            new_obj.db_error = res
+        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
+            new_obj.db_error = old_obj.db_error
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_item_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_item_exec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_item_execs)
+        if remove:
+            self.db_deleted_item_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_item_execs:
+            if child.has_changes():
+                return True
         return False
+    def __get_db_item_execs(self):
+        return self._db_item_execs
+    def __set_db_item_execs(self, item_execs):
+        self._db_item_execs = item_execs
+        self.is_dirty = True
+    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
+    def db_get_item_execs(self):
+        return self._db_item_execs
+    def db_add_item_exec(self, item_exec):
+        self.is_dirty = True
+        self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_change_item_exec(self, item_exec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                self._db_item_execs[i] = item_exec
+                found = True
+                break
+        if not found:
+            self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_delete_item_exec(self, item_exec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                if not self._db_item_execs[i].is_new:
+                    self.db_deleted_item_execs.append(self._db_item_execs[i])
+                del self._db_item_execs[i]
+                break
+        del self.db_item_execs_id_index[item_exec.db_id]
+    def db_get_item_exec(self, key):
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == key:
+                return self._db_item_execs[i]
+        return None
+    def db_get_item_exec_by_id(self, key):
+        return self.db_item_execs_id_index[key]
+    def db_has_item_exec_with_id(self, key):
+        return key in self.db_item_execs_id_index
+    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -4862,30 +6824,102 @@ class DBOpmProcessIdCause(object):
     def db_delete_id(self, id):
         self._db_id = None
     
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_iteration(self):
+        return self._db_iteration
+    def __set_db_iteration(self, iteration):
+        self._db_iteration = iteration
+        self.is_dirty = True
+    db_iteration = property(__get_db_iteration, __set_db_iteration)
+    def db_add_iteration(self, iteration):
+        self._db_iteration = iteration
+    def db_change_iteration(self, iteration):
+        self._db_iteration = iteration
+    def db_delete_iteration(self, iteration):
+        self._db_iteration = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_error(self):
+        return self._db_error
+    def __set_db_error(self, error):
+        self._db_error = error
+        self.is_dirty = True
+    db_error = property(__get_db_error, __set_db_error)
+    def db_add_error(self, error):
+        self._db_error = error
+    def db_change_error(self, error):
+        self._db_error = error
+    def db_delete_error(self, error):
+        self._db_error = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBConnection(object):
 
-class DBProvGeneration(object):
-
-    vtType = 'prov_generation'
+    vtType = 'connection'
 
-    def __init__(self, prov_entity=None, prov_activity=None, prov_role=None):
-        self.db_deleted_prov_entity = []
-        self._db_prov_entity = prov_entity
-        self.db_deleted_prov_activity = []
-        self._db_prov_activity = prov_activity
-        self._db_prov_role = prov_role
+    def __init__(self, id=None, ports=None):
+        self._db_id = id
+        self.db_deleted_ports = []
+        self.db_ports_id_index = {}
+        self.db_ports_type_index = {}
+        if ports is None:
+            self._db_ports = []
+        else:
+            self._db_ports = ports
+            for v in self._db_ports:
+                self.db_ports_id_index[v.db_id] = v
+                self.db_ports_type_index[v.db_type] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBProvGeneration.do_copy(self)
+        return DBConnection.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBProvGeneration(prov_role=self._db_prov_role)
-        if self._db_prov_entity is not None:
-            cp._db_prov_entity = self._db_prov_entity.do_copy(new_ids, id_scope, id_remap)
-        if self._db_prov_activity is not None:
-            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
+        cp = DBConnection(id=self._db_id)
+        if self._db_ports is None:
+            cp._db_ports = []
+        else:
+            cp._db_ports = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_ports]
         
         # set new ids
         if new_ids:
@@ -4897,6 +6931,8 @@ class DBProvGeneration(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_ports_id_index = dict((v.db_id, v) for v in cp._db_ports)
+        cp.db_ports_type_index = dict((v.db_type, v) for v in cp._db_ports)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -4905,210 +6941,161 @@ class DBProvGeneration(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBProvGeneration()
+            new_obj = DBConnection()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_entity' in class_dict:
-            res = class_dict['prov_entity'](old_obj, trans_dict)
-            new_obj.db_prov_entity = res
-        elif hasattr(old_obj, 'db_prov_entity') and old_obj.db_prov_entity is not None:
-            obj = old_obj.db_prov_entity
-            new_obj.db_add_prov_entity(DBRefProvEntity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_entity') and hasattr(new_obj, 'db_deleted_prov_entity'):
-            for obj in old_obj.db_deleted_prov_entity:
-                n_obj = DBRefProvEntity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_entity.append(n_obj)
-        if 'prov_activity' in class_dict:
-            res = class_dict['prov_activity'](old_obj, trans_dict)
-            new_obj.db_prov_activity = res
-        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
-            obj = old_obj.db_prov_activity
-            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
-            for obj in old_obj.db_deleted_prov_activity:
-                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_activity.append(n_obj)
-        if 'prov_role' in class_dict:
-            res = class_dict['prov_role'](old_obj, trans_dict)
-            new_obj.db_prov_role = res
-        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
-            new_obj.db_prov_role = old_obj.db_prov_role
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ports' in class_dict:
+            res = class_dict['ports'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_port(obj)
+        elif hasattr(old_obj, 'db_ports') and old_obj.db_ports is not None:
+            for obj in old_obj.db_ports:
+                new_obj.db_add_port(DBPort.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_ports') and hasattr(new_obj, 'db_deleted_ports'):
+            for obj in old_obj.db_deleted_ports:
+                n_obj = DBPort.update_version(obj, trans_dict)
+                new_obj.db_deleted_ports.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_prov_entity is not None:
-            children.extend(self._db_prov_entity.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_prov_entity = None
-        if self._db_prov_activity is not None:
-            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
+        to_del = []
+        for child in self.db_ports:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_prov_activity = None
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_port(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_prov_entity)
-        children.extend(self.db_deleted_prov_activity)
+        children.extend(self.db_deleted_ports)
         if remove:
-            self.db_deleted_prov_entity = []
-            self.db_deleted_prov_activity = []
+            self.db_deleted_ports = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_prov_entity is not None and self._db_prov_entity.has_changes():
-            return True
-        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
-            return True
+        for child in self._db_ports:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_prov_entity(self):
-        return self._db_prov_entity
-    def __set_db_prov_entity(self, prov_entity):
-        self._db_prov_entity = prov_entity
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_prov_entity = property(__get_db_prov_entity, __set_db_prov_entity)
-    def db_add_prov_entity(self, prov_entity):
-        self._db_prov_entity = prov_entity
-    def db_change_prov_entity(self, prov_entity):
-        self._db_prov_entity = prov_entity
-    def db_delete_prov_entity(self, prov_entity):
-        if not self.is_new:
-            self.db_deleted_prov_entity.append(self._db_prov_entity)
-        self._db_prov_entity = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_prov_activity(self):
-        return self._db_prov_activity
-    def __set_db_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
+    def __get_db_ports(self):
+        return self._db_ports
+    def __set_db_ports(self, ports):
+        self._db_ports = ports
         self.is_dirty = True
-    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
-    def db_add_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-    def db_change_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-    def db_delete_prov_activity(self, prov_activity):
-        if not self.is_new:
-            self.db_deleted_prov_activity.append(self._db_prov_activity)
-        self._db_prov_activity = None
-    
-    def __get_db_prov_role(self):
-        return self._db_prov_role
-    def __set_db_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
+    db_ports = property(__get_db_ports, __set_db_ports)
+    def db_get_ports(self):
+        return self._db_ports
+    def db_add_port(self, port):
         self.is_dirty = True
-    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
-    def db_add_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
-    def db_change_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
-    def db_delete_prov_role(self, prov_role):
-        self._db_prov_role = None
+        self._db_ports.append(port)
+        self.db_ports_id_index[port.db_id] = port
+        self.db_ports_type_index[port.db_type] = port
+    def db_change_port(self, port):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_ports)):
+            if self._db_ports[i].db_id == port.db_id:
+                self._db_ports[i] = port
+                found = True
+                break
+        if not found:
+            self._db_ports.append(port)
+        self.db_ports_id_index[port.db_id] = port
+        self.db_ports_type_index[port.db_type] = port
+    def db_delete_port(self, port):
+        self.is_dirty = True
+        for i in xrange(len(self._db_ports)):
+            if self._db_ports[i].db_id == port.db_id:
+                if not self._db_ports[i].is_new:
+                    self.db_deleted_ports.append(self._db_ports[i])
+                del self._db_ports[i]
+                break
+        del self.db_ports_id_index[port.db_id]
+        del self.db_ports_type_index[port.db_type]
+    def db_get_port(self, key):
+        for i in xrange(len(self._db_ports)):
+            if self._db_ports[i].db_id == key:
+                return self._db_ports[i]
+        return None
+    def db_get_port_by_id(self, key):
+        return self.db_ports_id_index[key]
+    def db_has_port_with_id(self, key):
+        return key in self.db_ports_id_index
+    def db_get_port_by_type(self, key):
+        return self.db_ports_type_index[key]
+    def db_has_port_with_type(self, key):
+        return key in self.db_ports_type_index
     
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBConfigBool(object):
 
-class DBPortSpecItem(object):
-
-    vtType = 'portSpecItem'
+    vtType = 'config_bool'
 
-    def __init__(self, id=None, pos=None, module=None, package=None, namespace=None, label=None, default=None, values=None, entry_type=None):
-        self._db_id = id
-        self._db_pos = pos
-        self._db_module = module
-        self._db_package = package
-        self._db_namespace = namespace
-        self._db_label = label
-        self._db_default = default
-        self._db_values = values
-        self._db_entry_type = entry_type
+    def __init__(self, value=None):
+        self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBPortSpecItem.do_copy(self)
+        return DBConfigBool.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPortSpecItem(id=self._db_id,
-                            pos=self._db_pos,
-                            module=self._db_module,
-                            package=self._db_package,
-                            namespace=self._db_namespace,
-                            label=self._db_label,
-                            default=self._db_default,
-                            values=self._db_values,
-                            entry_type=self._db_entry_type)
+        cp = DBConfigBool(value=self._db_value)
         
         # set new ids
         if new_ids:
             new_id = id_scope.getNewId(self.vtType)
             if self.vtType in id_scope.remap:
                 id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-        
-        # recreate indices and set flags
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBPortSpecItem()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'pos' in class_dict:
-            res = class_dict['pos'](old_obj, trans_dict)
-            new_obj.db_pos = res
-        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
-            new_obj.db_pos = old_obj.db_pos
-        if 'module' in class_dict:
-            res = class_dict['module'](old_obj, trans_dict)
-            new_obj.db_module = res
-        elif hasattr(old_obj, 'db_module') and old_obj.db_module is not None:
-            new_obj.db_module = old_obj.db_module
-        if 'package' in class_dict:
-            res = class_dict['package'](old_obj, trans_dict)
-            new_obj.db_package = res
-        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
-            new_obj.db_package = old_obj.db_package
-        if 'namespace' in class_dict:
-            res = class_dict['namespace'](old_obj, trans_dict)
-            new_obj.db_namespace = res
-        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
-            new_obj.db_namespace = old_obj.db_namespace
-        if 'label' in class_dict:
-            res = class_dict['label'](old_obj, trans_dict)
-            new_obj.db_label = res
-        elif hasattr(old_obj, 'db_label') and old_obj.db_label is not None:
-            new_obj.db_label = old_obj.db_label
-        if 'default' in class_dict:
-            res = class_dict['default'](old_obj, trans_dict)
-            new_obj.db_default = res
-        elif hasattr(old_obj, 'db_default') and old_obj.db_default is not None:
-            new_obj.db_default = old_obj.db_default
-        if 'values' in class_dict:
-            res = class_dict['values'](old_obj, trans_dict)
-            new_obj.db_values = res
-        elif hasattr(old_obj, 'db_values') and old_obj.db_values is not None:
-            new_obj.db_values = old_obj.db_values
-        if 'entry_type' in class_dict:
-            res = class_dict['entry_type'](old_obj, trans_dict)
-            new_obj.db_entry_type = res
-        elif hasattr(old_obj, 'db_entry_type') and old_obj.db_entry_type is not None:
-            new_obj.db_entry_type = old_obj.db_entry_type
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigBool()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -5122,150 +7109,69 @@ class DBPortSpecItem(object):
         if self.is_dirty:
             return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_pos(self):
-        return self._db_pos
-    def __set_db_pos(self, pos):
-        self._db_pos = pos
-        self.is_dirty = True
-    db_pos = property(__get_db_pos, __set_db_pos)
-    def db_add_pos(self, pos):
-        self._db_pos = pos
-    def db_change_pos(self, pos):
-        self._db_pos = pos
-    def db_delete_pos(self, pos):
-        self._db_pos = None
-    
-    def __get_db_module(self):
-        return self._db_module
-    def __set_db_module(self, module):
-        self._db_module = module
-        self.is_dirty = True
-    db_module = property(__get_db_module, __set_db_module)
-    def db_add_module(self, module):
-        self._db_module = module
-    def db_change_module(self, module):
-        self._db_module = module
-    def db_delete_module(self, module):
-        self._db_module = None
-    
-    def __get_db_package(self):
-        return self._db_package
-    def __set_db_package(self, package):
-        self._db_package = package
-        self.is_dirty = True
-    db_package = property(__get_db_package, __set_db_package)
-    def db_add_package(self, package):
-        self._db_package = package
-    def db_change_package(self, package):
-        self._db_package = package
-    def db_delete_package(self, package):
-        self._db_package = None
-    
-    def __get_db_namespace(self):
-        return self._db_namespace
-    def __set_db_namespace(self, namespace):
-        self._db_namespace = namespace
-        self.is_dirty = True
-    db_namespace = property(__get_db_namespace, __set_db_namespace)
-    def db_add_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_change_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_delete_namespace(self, namespace):
-        self._db_namespace = None
-    
-    def __get_db_label(self):
-        return self._db_label
-    def __set_db_label(self, label):
-        self._db_label = label
-        self.is_dirty = True
-    db_label = property(__get_db_label, __set_db_label)
-    def db_add_label(self, label):
-        self._db_label = label
-    def db_change_label(self, label):
-        self._db_label = label
-    def db_delete_label(self, label):
-        self._db_label = None
-    
-    def __get_db_default(self):
-        return self._db_default
-    def __set_db_default(self, default):
-        self._db_default = default
-        self.is_dirty = True
-    db_default = property(__get_db_default, __set_db_default)
-    def db_add_default(self, default):
-        self._db_default = default
-    def db_change_default(self, default):
-        self._db_default = default
-    def db_delete_default(self, default):
-        self._db_default = None
-    
-    def __get_db_values(self):
-        return self._db_values
-    def __set_db_values(self, values):
-        self._db_values = values
-        self.is_dirty = True
-    db_values = property(__get_db_values, __set_db_values)
-    def db_add_values(self, values):
-        self._db_values = values
-    def db_change_values(self, values):
-        self._db_values = values
-    def db_delete_values(self, values):
-        self._db_values = None
-    
-    def __get_db_entry_type(self):
-        return self._db_entry_type
-    def __set_db_entry_type(self, entry_type):
-        self._db_entry_type = entry_type
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-    db_entry_type = property(__get_db_entry_type, __set_db_entry_type)
-    def db_add_entry_type(self, entry_type):
-        self._db_entry_type = entry_type
-    def db_change_entry_type(self, entry_type):
-        self._db_entry_type = entry_type
-    def db_delete_entry_type(self, entry_type):
-        self._db_entry_type = None
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBMachine(object):
 
-    vtType = 'machine'
+class DBAction(object):
 
-    def __init__(self, id=None, name=None, os=None, architecture=None, processor=None, ram=None):
+    vtType = 'action'
+
+    def __init__(self, operations=None, id=None, prevId=None, date=None, session=None, user=None, annotations=None):
+        self.db_deleted_operations = []
+        self.db_operations_id_index = {}
+        if operations is None:
+            self._db_operations = []
+        else:
+            self._db_operations = operations
+            for v in self._db_operations:
+                self.db_operations_id_index[v.db_id] = v
         self._db_id = id
-        self._db_name = name
-        self._db_os = os
-        self._db_architecture = architecture
-        self._db_processor = processor
-        self._db_ram = ram
+        self._db_prevId = prevId
+        self._db_date = date
+        self._db_session = session
+        self._db_user = user
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMachine.do_copy(self)
+        return DBAction.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMachine(id=self._db_id,
-                       name=self._db_name,
-                       os=self._db_os,
-                       architecture=self._db_architecture,
-                       processor=self._db_processor,
-                       ram=self._db_ram)
+        cp = DBAction(id=self._db_id,
+                      prevId=self._db_prevId,
+                      date=self._db_date,
+                      session=self._db_session,
+                      user=self._db_user)
+        if self._db_operations is None:
+            cp._db_operations = []
+        else:
+            cp._db_operations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_operations]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
         
         # set new ids
         if new_ids:
@@ -5275,10 +7181,13 @@ class DBMachine(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_vistrailId') and ('vistrail', self._db_vistrailId) in id_remap:
-                cp._db_vistrailId = id_remap[('vistrail', self._db_vistrailId)]
+            if hasattr(self, 'db_prevId') and ('action', self._db_prevId) in id_remap:
+                cp._db_prevId = id_remap[('action', self._db_prevId)]
         
         # recreate indices and set flags
+        cp.db_operations_id_index = dict((v.db_id, v) for v in cp._db_operations)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -5287,53 +7196,151 @@ class DBMachine(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBMachine()
+            new_obj = DBAction()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'os' in class_dict:
-            res = class_dict['os'](old_obj, trans_dict)
-            new_obj.db_os = res
-        elif hasattr(old_obj, 'db_os') and old_obj.db_os is not None:
-            new_obj.db_os = old_obj.db_os
-        if 'architecture' in class_dict:
-            res = class_dict['architecture'](old_obj, trans_dict)
-            new_obj.db_architecture = res
-        elif hasattr(old_obj, 'db_architecture') and old_obj.db_architecture is not None:
-            new_obj.db_architecture = old_obj.db_architecture
-        if 'processor' in class_dict:
-            res = class_dict['processor'](old_obj, trans_dict)
-            new_obj.db_processor = res
-        elif hasattr(old_obj, 'db_processor') and old_obj.db_processor is not None:
-            new_obj.db_processor = old_obj.db_processor
-        if 'ram' in class_dict:
-            res = class_dict['ram'](old_obj, trans_dict)
-            new_obj.db_ram = res
-        elif hasattr(old_obj, 'db_ram') and old_obj.db_ram is not None:
-            new_obj.db_ram = old_obj.db_ram
+        if 'operations' in class_dict:
+            res = class_dict['operations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_operation(obj)
+        elif hasattr(old_obj, 'db_operations') and old_obj.db_operations is not None:
+            for obj in old_obj.db_operations:
+                if obj.vtType == 'add':
+                    new_obj.db_add_operation(DBAdd.update_version(obj, trans_dict))
+                elif obj.vtType == 'delete':
+                    new_obj.db_add_operation(DBDelete.update_version(obj, trans_dict))
+                elif obj.vtType == 'change':
+                    new_obj.db_add_operation(DBChange.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_operations') and hasattr(new_obj, 'db_deleted_operations'):
+            for obj in old_obj.db_deleted_operations:
+                if obj.vtType == 'add':
+                    n_obj = DBAdd.update_version(obj, trans_dict)
+                    new_obj.db_deleted_operations.append(n_obj)
+                elif obj.vtType == 'delete':
+                    n_obj = DBDelete.update_version(obj, trans_dict)
+                    new_obj.db_deleted_operations.append(n_obj)
+                elif obj.vtType == 'change':
+                    n_obj = DBChange.update_version(obj, trans_dict)
+                    new_obj.db_deleted_operations.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'prevId' in class_dict:
+            res = class_dict['prevId'](old_obj, trans_dict)
+            new_obj.db_prevId = res
+        elif hasattr(old_obj, 'db_prevId') and old_obj.db_prevId is not None:
+            new_obj.db_prevId = old_obj.db_prevId
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'session' in class_dict:
+            res = class_dict['session'](old_obj, trans_dict)
+            new_obj.db_session = res
+        elif hasattr(old_obj, 'db_session') and old_obj.db_session is not None:
+            new_obj.db_session = old_obj.db_session
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_operations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_operation(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_operations)
+        if remove:
+            self.db_deleted_annotations = []
+            self.db_deleted_operations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_operations:
+            if child.has_changes():
+                return True
         return False
+    def __get_db_operations(self):
+        return self._db_operations
+    def __set_db_operations(self, operations):
+        self._db_operations = operations
+        self.is_dirty = True
+    db_operations = property(__get_db_operations, __set_db_operations)
+    def db_get_operations(self):
+        return self._db_operations
+    def db_add_operation(self, operation):
+        self.is_dirty = True
+        self._db_operations.append(operation)
+        self.db_operations_id_index[operation.db_id] = operation
+    def db_change_operation(self, operation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_operations)):
+            if self._db_operations[i].db_id == operation.db_id:
+                self._db_operations[i] = operation
+                found = True
+                break
+        if not found:
+            self._db_operations.append(operation)
+        self.db_operations_id_index[operation.db_id] = operation
+    def db_delete_operation(self, operation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_operations)):
+            if self._db_operations[i].db_id == operation.db_id:
+                if not self._db_operations[i].is_new:
+                    self.db_deleted_operations.append(self._db_operations[i])
+                del self._db_operations[i]
+                break
+        del self.db_operations_id_index[operation.db_id]
+    def db_get_operation(self, key):
+        for i in xrange(len(self._db_operations)):
+            if self._db_operations[i].db_id == key:
+                return self._db_operations[i]
+        return None
+    def db_get_operation_by_id(self, key):
+        return self.db_operations_id_index[key]
+    def db_has_operation_with_id(self, key):
+        return key in self.db_operations_id_index
+    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -5347,100 +7354,128 @@ class DBMachine(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
+    def __get_db_prevId(self):
+        return self._db_prevId
+    def __set_db_prevId(self, prevId):
+        self._db_prevId = prevId
         self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
+    db_prevId = property(__get_db_prevId, __set_db_prevId)
+    def db_add_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_change_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_delete_prevId(self, prevId):
+        self._db_prevId = None
     
-    def __get_db_os(self):
-        return self._db_os
-    def __set_db_os(self, os):
-        self._db_os = os
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
         self.is_dirty = True
-    db_os = property(__get_db_os, __set_db_os)
-    def db_add_os(self, os):
-        self._db_os = os
-    def db_change_os(self, os):
-        self._db_os = os
-    def db_delete_os(self, os):
-        self._db_os = None
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
     
-    def __get_db_architecture(self):
-        return self._db_architecture
-    def __set_db_architecture(self, architecture):
-        self._db_architecture = architecture
+    def __get_db_session(self):
+        return self._db_session
+    def __set_db_session(self, session):
+        self._db_session = session
         self.is_dirty = True
-    db_architecture = property(__get_db_architecture, __set_db_architecture)
-    def db_add_architecture(self, architecture):
-        self._db_architecture = architecture
-    def db_change_architecture(self, architecture):
-        self._db_architecture = architecture
-    def db_delete_architecture(self, architecture):
-        self._db_architecture = None
+    db_session = property(__get_db_session, __set_db_session)
+    def db_add_session(self, session):
+        self._db_session = session
+    def db_change_session(self, session):
+        self._db_session = session
+    def db_delete_session(self, session):
+        self._db_session = None
     
-    def __get_db_processor(self):
-        return self._db_processor
-    def __set_db_processor(self, processor):
-        self._db_processor = processor
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
         self.is_dirty = True
-    db_processor = property(__get_db_processor, __set_db_processor)
-    def db_add_processor(self, processor):
-        self._db_processor = processor
-    def db_change_processor(self, processor):
-        self._db_processor = processor
-    def db_delete_processor(self, processor):
-        self._db_processor = None
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
     
-    def __get_db_ram(self):
-        return self._db_ram
-    def __set_db_ram(self, ram):
-        self._db_ram = ram
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
         self.is_dirty = True
-    db_ram = property(__get_db_ram, __set_db_ram)
-    def db_add_ram(self, ram):
-        self._db_ram = ram
-    def db_change_ram(self, ram):
-        self._db_ram = ram
-    def db_delete_ram(self, ram):
-        self._db_ram = None
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBAdd(object):
+class DBStartupPackage(object):
 
-    vtType = 'add'
+    vtType = 'startup_package'
 
-    def __init__(self, data=None, id=None, what=None, objectId=None, parentObjId=None, parentObjType=None):
-        self.db_deleted_data = []
-        self._db_data = data
-        self._db_id = id
-        self._db_what = what
-        self._db_objectId = objectId
-        self._db_parentObjId = parentObjId
-        self._db_parentObjType = parentObjType
+    def __init__(self, name=None, configuration=None):
+        self._db_name = name
+        self.db_deleted_configuration = []
+        self._db_configuration = configuration
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBAdd.do_copy(self)
+        return DBStartupPackage.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBAdd(id=self._db_id,
-                   what=self._db_what,
-                   objectId=self._db_objectId,
-                   parentObjId=self._db_parentObjId,
-                   parentObjType=self._db_parentObjType)
-        if self._db_data is not None:
-            cp._db_data = self._db_data.do_copy(new_ids, id_scope, id_remap)
+        cp = DBStartupPackage(name=self._db_name)
+        if self._db_configuration is not None:
+            cp._db_configuration = self._db_configuration.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -5450,10 +7485,6 @@ class DBAdd(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_objectId') and (self._db_what, self._db_objectId) in id_remap:
-                cp._db_objectId = id_remap[(self._db_what, self._db_objectId)]
-            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
-                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -5464,227 +7495,93 @@ class DBAdd(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBAdd()
+            new_obj = DBStartupPackage()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'data' in class_dict:
-            res = class_dict['data'](old_obj, trans_dict)
-            new_obj.db_data = res
-        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
-            obj = old_obj.db_data
-            if obj.vtType == 'module':
-                new_obj.db_add_data(DBModule.update_version(obj, trans_dict))
-            elif obj.vtType == 'location':
-                new_obj.db_add_data(DBLocation.update_version(obj, trans_dict))
-            elif obj.vtType == 'annotation':
-                new_obj.db_add_data(DBAnnotation.update_version(obj, trans_dict))
-            elif obj.vtType == 'function':
-                new_obj.db_add_data(DBFunction.update_version(obj, trans_dict))
-            elif obj.vtType == 'connection':
-                new_obj.db_add_data(DBConnection.update_version(obj, trans_dict))
-            elif obj.vtType == 'port':
-                new_obj.db_add_data(DBPort.update_version(obj, trans_dict))
-            elif obj.vtType == 'parameter':
-                new_obj.db_add_data(DBParameter.update_version(obj, trans_dict))
-            elif obj.vtType == 'portSpec':
-                new_obj.db_add_data(DBPortSpec.update_version(obj, trans_dict))
-            elif obj.vtType == 'abstraction':
-                new_obj.db_add_data(DBAbstraction.update_version(obj, trans_dict))
-            elif obj.vtType == 'group':
-                new_obj.db_add_data(DBGroup.update_version(obj, trans_dict))
-            elif obj.vtType == 'other':
-                new_obj.db_add_data(DBOther.update_version(obj, trans_dict))
-            elif obj.vtType == 'plugin_data':
-                new_obj.db_add_data(DBPluginData.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_data') and hasattr(new_obj, 'db_deleted_data'):
-            for obj in old_obj.db_deleted_data:
-                if obj.vtType == 'module':
-                    n_obj = DBModule.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'location':
-                    n_obj = DBLocation.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'annotation':
-                    n_obj = DBAnnotation.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'function':
-                    n_obj = DBFunction.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'connection':
-                    n_obj = DBConnection.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'port':
-                    n_obj = DBPort.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'parameter':
-                    n_obj = DBParameter.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'portSpec':
-                    n_obj = DBPortSpec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'abstraction':
-                    n_obj = DBAbstraction.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'group':
-                    n_obj = DBGroup.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'other':
-                    n_obj = DBOther.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'plugin_data':
-                    n_obj = DBPluginData.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'what' in class_dict:
-            res = class_dict['what'](old_obj, trans_dict)
-            new_obj.db_what = res
-        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
-            new_obj.db_what = old_obj.db_what
-        if 'objectId' in class_dict:
-            res = class_dict['objectId'](old_obj, trans_dict)
-            new_obj.db_objectId = res
-        elif hasattr(old_obj, 'db_objectId') and old_obj.db_objectId is not None:
-            new_obj.db_objectId = old_obj.db_objectId
-        if 'parentObjId' in class_dict:
-            res = class_dict['parentObjId'](old_obj, trans_dict)
-            new_obj.db_parentObjId = res
-        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
-            new_obj.db_parentObjId = old_obj.db_parentObjId
-        if 'parentObjType' in class_dict:
-            res = class_dict['parentObjType'](old_obj, trans_dict)
-            new_obj.db_parentObjType = res
-        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
-            new_obj.db_parentObjType = old_obj.db_parentObjType
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'configuration' in class_dict:
+            res = class_dict['configuration'](old_obj, trans_dict)
+            new_obj.db_configuration = res
+        elif hasattr(old_obj, 'db_configuration') and old_obj.db_configuration is not None:
+            obj = old_obj.db_configuration
+            new_obj.db_add_configuration(DBConfiguration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_configuration') and hasattr(new_obj, 'db_deleted_configuration'):
+            for obj in old_obj.db_deleted_configuration:
+                n_obj = DBConfiguration.update_version(obj, trans_dict)
+                new_obj.db_deleted_configuration.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_data is not None:
-            children.extend(self._db_data.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_configuration is not None:
+            children.extend(self._db_configuration.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_data = None
+                self._db_configuration = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_data)
+        children.extend(self.db_deleted_configuration)
         if remove:
-            self.db_deleted_data = []
+            self.db_deleted_configuration = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_data is not None and self._db_data.has_changes():
+        if self._db_configuration is not None and self._db_configuration.has_changes():
             return True
         return False
-    def __get_db_data(self):
-        return self._db_data
-    def __set_db_data(self, data):
-        self._db_data = data
-        self.is_dirty = True
-    db_data = property(__get_db_data, __set_db_data)
-    def db_add_data(self, data):
-        self._db_data = data
-    def db_change_data(self, data):
-        self._db_data = data
-    def db_delete_data(self, data):
-        if not self.is_new:
-            self.db_deleted_data.append(self._db_data)
-        self._db_data = None
-    
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_what(self):
-        return self._db_what
-    def __set_db_what(self, what):
-        self._db_what = what
-        self.is_dirty = True
-    db_what = property(__get_db_what, __set_db_what)
-    def db_add_what(self, what):
-        self._db_what = what
-    def db_change_what(self, what):
-        self._db_what = what
-    def db_delete_what(self, what):
-        self._db_what = None
-    
-    def __get_db_objectId(self):
-        return self._db_objectId
-    def __set_db_objectId(self, objectId):
-        self._db_objectId = objectId
-        self.is_dirty = True
-    db_objectId = property(__get_db_objectId, __set_db_objectId)
-    def db_add_objectId(self, objectId):
-        self._db_objectId = objectId
-    def db_change_objectId(self, objectId):
-        self._db_objectId = objectId
-    def db_delete_objectId(self, objectId):
-        self._db_objectId = None
-    
-    def __get_db_parentObjId(self):
-        return self._db_parentObjId
-    def __set_db_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
-    def db_add_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
-    def db_change_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
-    def db_delete_parentObjId(self, parentObjId):
-        self._db_parentObjId = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
-    def __get_db_parentObjType(self):
-        return self._db_parentObjType
-    def __set_db_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-        self.is_dirty = True
-    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
-    def db_add_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-    def db_change_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-    def db_delete_parentObjType(self, parentObjType):
-        self._db_parentObjType = None
+    def __get_db_configuration(self):
+        return self._db_configuration
+    def __set_db_configuration(self, configuration):
+        self._db_configuration = configuration
+        self.is_dirty = True
+    db_configuration = property(__get_db_configuration, __set_db_configuration)
+    def db_add_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_change_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_delete_configuration(self, configuration):
+        if not self.is_new:
+            self.db_deleted_configuration.append(self._db_configuration)
+        self._db_configuration = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBOther(object):
 
-    vtType = 'other'
+class DBConfigInt(object):
 
-    def __init__(self, id=None, key=None, value=None):
-        self._db_id = id
-        self._db_key = key
+    vtType = 'config_int'
+
+    def __init__(self, value=None):
         self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOther.do_copy(self)
+        return DBConfigInt.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOther(id=self._db_id,
-                     key=self._db_key,
-                     value=self._db_value)
+        cp = DBConfigInt(value=self._db_value)
         
         # set new ids
         if new_ids:
@@ -5698,26 +7595,16 @@ class DBOther(object):
         # recreate indices and set flags
         if not new_ids:
             cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBOther()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'key' in class_dict:
-            res = class_dict['key'](old_obj, trans_dict)
-            new_obj.db_key = res
-        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
-            new_obj.db_key = old_obj.db_key
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigInt()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
         if 'value' in class_dict:
             res = class_dict['value'](old_obj, trans_dict)
             new_obj.db_value = res
@@ -5736,32 +7623,6 @@ class DBOther(object):
         if self.is_dirty:
             return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_key(self):
-        return self._db_key
-    def __set_db_key(self, key):
-        self._db_key = key
-        self.is_dirty = True
-    db_key = property(__get_db_key, __set_db_key)
-    def db_add_key(self, key):
-        self._db_key = key
-    def db_change_key(self, key):
-        self._db_key = key
-    def db_delete_key(self, key):
-        self._db_key = None
-    
     def __get_db_value(self):
         return self._db_value
     def __set_db_value(self, value):
@@ -5775,27 +7636,22 @@ class DBOther(object):
     def db_delete_value(self, value):
         self._db_value = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBLocation(object):
 
-    vtType = 'location'
+class DBOpmProcessIdEffect(object):
 
-    def __init__(self, id=None, x=None, y=None):
+    vtType = 'opm_process_id_effect'
+
+    def __init__(self, id=None):
         self._db_id = id
-        self._db_x = x
-        self._db_y = y
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBLocation.do_copy(self)
+        return DBOpmProcessIdEffect.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBLocation(id=self._db_id,
-                        x=self._db_x,
-                        y=self._db_y)
+        cp = DBOpmProcessIdEffect(id=self._db_id)
         
         # set new ids
         if new_ids:
@@ -5805,6 +7661,8 @@ class DBLocation(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_process', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_process', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -5815,7 +7673,7 @@ class DBLocation(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBLocation()
+            new_obj = DBOpmProcessIdEffect()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -5824,16 +7682,6 @@ class DBLocation(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'x' in class_dict:
-            res = class_dict['x'](old_obj, trans_dict)
-            new_obj.db_x = res
-        elif hasattr(old_obj, 'db_x') and old_obj.db_x is not None:
-            new_obj.db_x = old_obj.db_x
-        if 'y' in class_dict:
-            res = class_dict['y'](old_obj, trans_dict)
-            new_obj.db_y = res
-        elif hasattr(old_obj, 'db_y') and old_obj.db_y is not None:
-            new_obj.db_y = old_obj.db_y
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -5860,57 +7708,22 @@ class DBLocation(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_x(self):
-        return self._db_x
-    def __set_db_x(self, x):
-        self._db_x = x
-        self.is_dirty = True
-    db_x = property(__get_db_x, __set_db_x)
-    def db_add_x(self, x):
-        self._db_x = x
-    def db_change_x(self, x):
-        self._db_x = x
-    def db_delete_x(self, x):
-        self._db_x = None
-    
-    def __get_db_y(self):
-        return self._db_y
-    def __set_db_y(self, y):
-        self._db_y = y
-        self.is_dirty = True
-    db_y = property(__get_db_y, __set_db_y)
-    def db_add_y(self, y):
-        self._db_y = y
-    def db_change_y(self, y):
-        self._db_y = y
-    def db_delete_y(self, y):
-        self._db_y = None
-    
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBOpmOverlaps(object):
 
-    vtType = 'opm_overlaps'
+class DBRefProvPlan(object):
 
-    def __init__(self, opm_account_ids=None):
-        self.db_deleted_opm_account_ids = []
-        if opm_account_ids is None:
-            self._db_opm_account_ids = []
-        else:
-            self._db_opm_account_ids = opm_account_ids
+    vtType = 'ref_prov_plan'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmOverlaps.do_copy(self)
+        return DBRefProvPlan.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmOverlaps()
-        if self._db_opm_account_ids is None:
-            cp._db_opm_account_ids = []
-        else:
-            cp._db_opm_account_ids = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_account_ids]
+        cp = DBRefProvPlan(prov_ref=self._db_prov_ref)
         
         # set new ids
         if new_ids:
@@ -5920,6 +7733,8 @@ class DBOpmOverlaps(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_entity', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_entity', self._db_prov_ref)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -5930,93 +7745,77 @@ class DBOpmOverlaps(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmOverlaps()
+            new_obj = DBRefProvPlan()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'opm_account_ids' in class_dict:
-            res = class_dict['opm_account_ids'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_opm_account_id(obj)
-        elif hasattr(old_obj, 'db_opm_account_ids') and old_obj.db_opm_account_ids is not None:
-            for obj in old_obj.db_opm_account_ids:
-                new_obj.db_add_opm_account_id(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_opm_account_ids') and hasattr(new_obj, 'db_deleted_opm_account_ids'):
-            for obj in old_obj.db_deleted_opm_account_ids:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_opm_account_ids.append(n_obj)
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_opm_account_ids:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_opm_account_id(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_opm_account_ids)
-        if remove:
-            self.db_deleted_opm_account_ids = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_opm_account_ids:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_opm_account_ids(self):
-        return self._db_opm_account_ids
-    def __set_db_opm_account_ids(self, opm_account_ids):
-        self._db_opm_account_ids = opm_account_ids
-        self.is_dirty = True
-    db_opm_account_ids = property(__get_db_opm_account_ids, __set_db_opm_account_ids)
-    def db_get_opm_account_ids(self):
-        return self._db_opm_account_ids
-    def db_add_opm_account_id(self, opm_account_id):
-        self.is_dirty = True
-        self._db_opm_account_ids.append(opm_account_id)
-    def db_change_opm_account_id(self, opm_account_id):
-        self.is_dirty = True
-        self._db_opm_account_ids.append(opm_account_id)
-    def db_delete_opm_account_id(self, opm_account_id):
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_opm_account_id(self, key):
-        return None
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
     
 
 
-class DBPEParameter(object):
+class DBOpmAccounts(object):
 
-    vtType = 'pe_parameter'
+    vtType = 'opm_accounts'
 
-    def __init__(self, id=None, pos=None, interpolator=None, value=None, dimension=None):
-        self._db_id = id
-        self._db_pos = pos
-        self._db_interpolator = interpolator
-        self._db_value = value
-        self._db_dimension = dimension
+    def __init__(self, accounts=None, opm_overlapss=None):
+        self.db_deleted_accounts = []
+        self.db_accounts_id_index = {}
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+            for v in self._db_accounts:
+                self.db_accounts_id_index[v.db_id] = v
+        self.db_deleted_opm_overlapss = []
+        if opm_overlapss is None:
+            self._db_opm_overlapss = []
+        else:
+            self._db_opm_overlapss = opm_overlapss
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBPEParameter.do_copy(self)
+        return DBOpmAccounts.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPEParameter(id=self._db_id,
-                           pos=self._db_pos,
-                           interpolator=self._db_interpolator,
-                           value=self._db_value,
-                           dimension=self._db_dimension)
+        cp = DBOpmAccounts()
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_overlapss is None:
+            cp._db_opm_overlapss = []
+        else:
+            cp._db_opm_overlapss = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_overlapss]
         
         # set new ids
         if new_ids:
@@ -6028,6 +7827,7 @@ class DBPEParameter(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_accounts_id_index = dict((v.db_id, v) for v in cp._db_accounts)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -6036,138 +7836,150 @@ class DBPEParameter(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBPEParameter()
+            new_obj = DBOpmAccounts()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'pos' in class_dict:
-            res = class_dict['pos'](old_obj, trans_dict)
-            new_obj.db_pos = res
-        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
-            new_obj.db_pos = old_obj.db_pos
-        if 'interpolator' in class_dict:
-            res = class_dict['interpolator'](old_obj, trans_dict)
-            new_obj.db_interpolator = res
-        elif hasattr(old_obj, 'db_interpolator') and old_obj.db_interpolator is not None:
-            new_obj.db_interpolator = old_obj.db_interpolator
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            new_obj.db_value = old_obj.db_value
-        if 'dimension' in class_dict:
-            res = class_dict['dimension'](old_obj, trans_dict)
-            new_obj.db_dimension = res
-        elif hasattr(old_obj, 'db_dimension') and old_obj.db_dimension is not None:
-            new_obj.db_dimension = old_obj.db_dimension
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccount.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccount.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_overlapss' in class_dict:
+            res = class_dict['opm_overlapss'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_overlaps(obj)
+        elif hasattr(old_obj, 'db_opm_overlapss') and old_obj.db_opm_overlapss is not None:
+            for obj in old_obj.db_opm_overlapss:
+                new_obj.db_add_opm_overlaps(DBOpmOverlaps.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_overlapss') and hasattr(new_obj, 'db_deleted_opm_overlapss'):
+            for obj in old_obj.db_deleted_opm_overlapss:
+                n_obj = DBOpmOverlaps.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_overlapss.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_overlapss:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_overlaps(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_overlapss)
+        if remove:
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_overlapss = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_overlapss:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_pos(self):
-        return self._db_pos
-    def __set_db_pos(self, pos):
-        self._db_pos = pos
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
         self.is_dirty = True
-    db_pos = property(__get_db_pos, __set_db_pos)
-    def db_add_pos(self, pos):
-        self._db_pos = pos
-    def db_change_pos(self, pos):
-        self._db_pos = pos
-    def db_delete_pos(self, pos):
-        self._db_pos = None
-    
-    def __get_db_interpolator(self):
-        return self._db_interpolator
-    def __set_db_interpolator(self, interpolator):
-        self._db_interpolator = interpolator
+        self._db_accounts.append(account)
+        self.db_accounts_id_index[account.db_id] = account
+    def db_change_account(self, account):
         self.is_dirty = True
-    db_interpolator = property(__get_db_interpolator, __set_db_interpolator)
-    def db_add_interpolator(self, interpolator):
-        self._db_interpolator = interpolator
-    def db_change_interpolator(self, interpolator):
-        self._db_interpolator = interpolator
-    def db_delete_interpolator(self, interpolator):
-        self._db_interpolator = None
-    
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+        found = False
+        for i in xrange(len(self._db_accounts)):
+            if self._db_accounts[i].db_id == account.db_id:
+                self._db_accounts[i] = account
+                found = True
+                break
+        if not found:
+            self._db_accounts.append(account)
+        self.db_accounts_id_index[account.db_id] = account
+    def db_delete_account(self, account):
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
-        self._db_value = None
+        for i in xrange(len(self._db_accounts)):
+            if self._db_accounts[i].db_id == account.db_id:
+                if not self._db_accounts[i].is_new:
+                    self.db_deleted_accounts.append(self._db_accounts[i])
+                del self._db_accounts[i]
+                break
+        del self.db_accounts_id_index[account.db_id]
+    def db_get_account(self, key):
+        for i in xrange(len(self._db_accounts)):
+            if self._db_accounts[i].db_id == key:
+                return self._db_accounts[i]
+        return None
+    def db_get_account_by_id(self, key):
+        return self.db_accounts_id_index[key]
+    def db_has_account_with_id(self, key):
+        return key in self.db_accounts_id_index
     
-    def __get_db_dimension(self):
-        return self._db_dimension
-    def __set_db_dimension(self, dimension):
-        self._db_dimension = dimension
+    def __get_db_opm_overlapss(self):
+        return self._db_opm_overlapss
+    def __set_db_opm_overlapss(self, opm_overlapss):
+        self._db_opm_overlapss = opm_overlapss
         self.is_dirty = True
-    db_dimension = property(__get_db_dimension, __set_db_dimension)
-    def db_add_dimension(self, dimension):
-        self._db_dimension = dimension
-    def db_change_dimension(self, dimension):
-        self._db_dimension = dimension
-    def db_delete_dimension(self, dimension):
-        self._db_dimension = None
+    db_opm_overlapss = property(__get_db_opm_overlapss, __set_db_opm_overlapss)
+    def db_get_opm_overlapss(self):
+        return self._db_opm_overlapss
+    def db_add_opm_overlaps(self, opm_overlaps):
+        self.is_dirty = True
+        self._db_opm_overlapss.append(opm_overlaps)
+    def db_change_opm_overlaps(self, opm_overlaps):
+        self.is_dirty = True
+        self._db_opm_overlapss.append(opm_overlaps)
+    def db_delete_opm_overlaps(self, opm_overlaps):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_overlaps(self, key):
+        return None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBOpmDependencies(object):
 
-    vtType = 'opm_dependencies'
+class DBRefProvAgent(object):
 
-    def __init__(self, dependencys=None):
-        self.db_deleted_dependencys = []
-        if dependencys is None:
-            self._db_dependencys = []
-        else:
-            self._db_dependencys = dependencys
+    vtType = 'ref_prov_agent'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmDependencies.do_copy(self)
+        return DBRefProvAgent.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmDependencies()
-        if self._db_dependencys is None:
-            cp._db_dependencys = []
-        else:
-            cp._db_dependencys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_dependencys]
+        cp = DBRefProvAgent(prov_ref=self._db_prov_ref)
         
         # set new ids
         if new_ids:
@@ -6177,6 +7989,8 @@ class DBOpmDependencies(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_agent', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_agent', self._db_prov_ref)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -6187,117 +8001,81 @@ class DBOpmDependencies(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmDependencies()
+            new_obj = DBRefProvAgent()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'dependencys' in class_dict:
-            res = class_dict['dependencys'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_dependency(obj)
-        elif hasattr(old_obj, 'db_dependencys') and old_obj.db_dependencys is not None:
-            for obj in old_obj.db_dependencys:
-                if obj.vtType == 'opm_used':
-                    new_obj.db_add_dependency(DBOpmUsed.update_version(obj, trans_dict))
-                elif obj.vtType == 'opm_was_generated_by':
-                    new_obj.db_add_dependency(DBOpmWasGeneratedBy.update_version(obj, trans_dict))
-                elif obj.vtType == 'opm_was_triggered_by':
-                    new_obj.db_add_dependency(DBOpmWasTriggeredBy.update_version(obj, trans_dict))
-                elif obj.vtType == 'opm_was_derived_from':
-                    new_obj.db_add_dependency(DBOpmWasDerivedFrom.update_version(obj, trans_dict))
-                elif obj.vtType == 'opm_was_controlled_by':
-                    new_obj.db_add_dependency(DBOpmWasControlledBy.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_dependencys') and hasattr(new_obj, 'db_deleted_dependencys'):
-            for obj in old_obj.db_deleted_dependencys:
-                if obj.vtType == 'opm_used':
-                    n_obj = DBOpmUsed.update_version(obj, trans_dict)
-                    new_obj.db_deleted_dependencys.append(n_obj)
-                elif obj.vtType == 'opm_was_generated_by':
-                    n_obj = DBOpmWasGeneratedBy.update_version(obj, trans_dict)
-                    new_obj.db_deleted_dependencys.append(n_obj)
-                elif obj.vtType == 'opm_was_triggered_by':
-                    n_obj = DBOpmWasTriggeredBy.update_version(obj, trans_dict)
-                    new_obj.db_deleted_dependencys.append(n_obj)
-                elif obj.vtType == 'opm_was_derived_from':
-                    n_obj = DBOpmWasDerivedFrom.update_version(obj, trans_dict)
-                    new_obj.db_deleted_dependencys.append(n_obj)
-                elif obj.vtType == 'opm_was_controlled_by':
-                    n_obj = DBOpmWasControlledBy.update_version(obj, trans_dict)
-                    new_obj.db_deleted_dependencys.append(n_obj)
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_dependencys:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_dependency(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_dependencys)
-        if remove:
-            self.db_deleted_dependencys = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_dependencys:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_dependencys(self):
-        return self._db_dependencys
-    def __set_db_dependencys(self, dependencys):
-        self._db_dependencys = dependencys
-        self.is_dirty = True
-    db_dependencys = property(__get_db_dependencys, __set_db_dependencys)
-    def db_get_dependencys(self):
-        return self._db_dependencys
-    def db_add_dependency(self, dependency):
-        self.is_dirty = True
-        self._db_dependencys.append(dependency)
-    def db_change_dependency(self, dependency):
-        self.is_dirty = True
-        self._db_dependencys.append(dependency)
-    def db_delete_dependency(self, dependency):
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_dependency(self, key):
-        return None
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
     
 
 
-class DBParameter(object):
+class DBPortSpec(object):
 
-    vtType = 'parameter'
+    vtType = 'portSpec'
 
-    def __init__(self, id=None, pos=None, name=None, type=None, val=None, alias=None):
+    def __init__(self, id=None, name=None, type=None, optional=None, sort_key=None, portSpecItems=None, min_conns=None, max_conns=None):
         self._db_id = id
-        self._db_pos = pos
         self._db_name = name
         self._db_type = type
-        self._db_val = val
-        self._db_alias = alias
+        self._db_optional = optional
+        self._db_sort_key = sort_key
+        self.db_deleted_portSpecItems = []
+        self.db_portSpecItems_id_index = {}
+        if portSpecItems is None:
+            self._db_portSpecItems = []
+        else:
+            self._db_portSpecItems = portSpecItems
+            for v in self._db_portSpecItems:
+                self.db_portSpecItems_id_index[v.db_id] = v
+        self._db_min_conns = min_conns
+        self._db_max_conns = max_conns
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBParameter.do_copy(self)
+        return DBPortSpec.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBParameter(id=self._db_id,
-                         pos=self._db_pos,
-                         name=self._db_name,
-                         type=self._db_type,
-                         val=self._db_val,
-                         alias=self._db_alias)
+        cp = DBPortSpec(id=self._db_id,
+                        name=self._db_name,
+                        type=self._db_type,
+                        optional=self._db_optional,
+                        sort_key=self._db_sort_key,
+                        min_conns=self._db_min_conns,
+                        max_conns=self._db_max_conns)
+        if self._db_portSpecItems is None:
+            cp._db_portSpecItems = []
+        else:
+            cp._db_portSpecItems = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecItems]
         
         # set new ids
         if new_ids:
@@ -6309,6 +8087,7 @@ class DBParameter(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_portSpecItems_id_index = dict((v.db_id, v) for v in cp._db_portSpecItems)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -6317,7 +8096,7 @@ class DBParameter(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBParameter()
+            new_obj = DBPortSpec()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -6326,11 +8105,6 @@ class DBParameter(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'pos' in class_dict:
-            res = class_dict['pos'](old_obj, trans_dict)
-            new_obj.db_pos = res
-        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
-            new_obj.db_pos = old_obj.db_pos
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
@@ -6341,28 +8115,60 @@ class DBParameter(object):
             new_obj.db_type = res
         elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
             new_obj.db_type = old_obj.db_type
-        if 'val' in class_dict:
-            res = class_dict['val'](old_obj, trans_dict)
-            new_obj.db_val = res
-        elif hasattr(old_obj, 'db_val') and old_obj.db_val is not None:
-            new_obj.db_val = old_obj.db_val
-        if 'alias' in class_dict:
-            res = class_dict['alias'](old_obj, trans_dict)
-            new_obj.db_alias = res
-        elif hasattr(old_obj, 'db_alias') and old_obj.db_alias is not None:
-            new_obj.db_alias = old_obj.db_alias
+        if 'optional' in class_dict:
+            res = class_dict['optional'](old_obj, trans_dict)
+            new_obj.db_optional = res
+        elif hasattr(old_obj, 'db_optional') and old_obj.db_optional is not None:
+            new_obj.db_optional = old_obj.db_optional
+        if 'sort_key' in class_dict:
+            res = class_dict['sort_key'](old_obj, trans_dict)
+            new_obj.db_sort_key = res
+        elif hasattr(old_obj, 'db_sort_key') and old_obj.db_sort_key is not None:
+            new_obj.db_sort_key = old_obj.db_sort_key
+        if 'portSpecItems' in class_dict:
+            res = class_dict['portSpecItems'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_portSpecItem(obj)
+        elif hasattr(old_obj, 'db_portSpecItems') and old_obj.db_portSpecItems is not None:
+            for obj in old_obj.db_portSpecItems:
+                new_obj.db_add_portSpecItem(DBPortSpecItem.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_portSpecItems') and hasattr(new_obj, 'db_deleted_portSpecItems'):
+            for obj in old_obj.db_deleted_portSpecItems:
+                n_obj = DBPortSpecItem.update_version(obj, trans_dict)
+                new_obj.db_deleted_portSpecItems.append(n_obj)
+        if 'min_conns' in class_dict:
+            res = class_dict['min_conns'](old_obj, trans_dict)
+            new_obj.db_min_conns = res
+        elif hasattr(old_obj, 'db_min_conns') and old_obj.db_min_conns is not None:
+            new_obj.db_min_conns = old_obj.db_min_conns
+        if 'max_conns' in class_dict:
+            res = class_dict['max_conns'](old_obj, trans_dict)
+            new_obj.db_max_conns = res
+        elif hasattr(old_obj, 'db_max_conns') and old_obj.db_max_conns is not None:
+            new_obj.db_max_conns = old_obj.db_max_conns
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if not for_action:
+            for child in self.db_portSpecItems:
+                children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_portSpecItems)
+        if remove:
+            self.db_deleted_portSpecItems = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_portSpecItems:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -6377,19 +8183,6 @@ class DBParameter(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_pos(self):
-        return self._db_pos
-    def __set_db_pos(self, pos):
-        self._db_pos = pos
-        self.is_dirty = True
-    db_pos = property(__get_db_pos, __set_db_pos)
-    def db_add_pos(self, pos):
-        self._db_pos = pos
-    def db_change_pos(self, pos):
-        self._db_pos = pos
-    def db_delete_pos(self, pos):
-        self._db_pos = None
-    
     def __get_db_name(self):
         return self._db_name
     def __set_db_name(self, name):
@@ -6416,78 +8209,128 @@ class DBParameter(object):
     def db_delete_type(self, type):
         self._db_type = None
     
-    def __get_db_val(self):
-        return self._db_val
-    def __set_db_val(self, val):
-        self._db_val = val
+    def __get_db_optional(self):
+        return self._db_optional
+    def __set_db_optional(self, optional):
+        self._db_optional = optional
         self.is_dirty = True
-    db_val = property(__get_db_val, __set_db_val)
-    def db_add_val(self, val):
-        self._db_val = val
-    def db_change_val(self, val):
-        self._db_val = val
-    def db_delete_val(self, val):
-        self._db_val = None
+    db_optional = property(__get_db_optional, __set_db_optional)
+    def db_add_optional(self, optional):
+        self._db_optional = optional
+    def db_change_optional(self, optional):
+        self._db_optional = optional
+    def db_delete_optional(self, optional):
+        self._db_optional = None
     
-    def __get_db_alias(self):
-        return self._db_alias
-    def __set_db_alias(self, alias):
-        self._db_alias = alias
+    def __get_db_sort_key(self):
+        return self._db_sort_key
+    def __set_db_sort_key(self, sort_key):
+        self._db_sort_key = sort_key
         self.is_dirty = True
-    db_alias = property(__get_db_alias, __set_db_alias)
-    def db_add_alias(self, alias):
-        self._db_alias = alias
-    def db_change_alias(self, alias):
-        self._db_alias = alias
-    def db_delete_alias(self, alias):
-        self._db_alias = None
+    db_sort_key = property(__get_db_sort_key, __set_db_sort_key)
+    def db_add_sort_key(self, sort_key):
+        self._db_sort_key = sort_key
+    def db_change_sort_key(self, sort_key):
+        self._db_sort_key = sort_key
+    def db_delete_sort_key(self, sort_key):
+        self._db_sort_key = None
+    
+    def __get_db_portSpecItems(self):
+        return self._db_portSpecItems
+    def __set_db_portSpecItems(self, portSpecItems):
+        self._db_portSpecItems = portSpecItems
+        self.is_dirty = True
+    db_portSpecItems = property(__get_db_portSpecItems, __set_db_portSpecItems)
+    def db_get_portSpecItems(self):
+        return self._db_portSpecItems
+    def db_add_portSpecItem(self, portSpecItem):
+        self.is_dirty = True
+        self._db_portSpecItems.append(portSpecItem)
+        self.db_portSpecItems_id_index[portSpecItem.db_id] = portSpecItem
+    def db_change_portSpecItem(self, portSpecItem):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_portSpecItems)):
+            if self._db_portSpecItems[i].db_id == portSpecItem.db_id:
+                self._db_portSpecItems[i] = portSpecItem
+                found = True
+                break
+        if not found:
+            self._db_portSpecItems.append(portSpecItem)
+        self.db_portSpecItems_id_index[portSpecItem.db_id] = portSpecItem
+    def db_delete_portSpecItem(self, portSpecItem):
+        self.is_dirty = True
+        for i in xrange(len(self._db_portSpecItems)):
+            if self._db_portSpecItems[i].db_id == portSpecItem.db_id:
+                if not self._db_portSpecItems[i].is_new:
+                    self.db_deleted_portSpecItems.append(self._db_portSpecItems[i])
+                del self._db_portSpecItems[i]
+                break
+        del self.db_portSpecItems_id_index[portSpecItem.db_id]
+    def db_get_portSpecItem(self, key):
+        for i in xrange(len(self._db_portSpecItems)):
+            if self._db_portSpecItems[i].db_id == key:
+                return self._db_portSpecItems[i]
+        return None
+    def db_get_portSpecItem_by_id(self, key):
+        return self.db_portSpecItems_id_index[key]
+    def db_has_portSpecItem_with_id(self, key):
+        return key in self.db_portSpecItems_id_index
+    
+    def __get_db_min_conns(self):
+        return self._db_min_conns
+    def __set_db_min_conns(self, min_conns):
+        self._db_min_conns = min_conns
+        self.is_dirty = True
+    db_min_conns = property(__get_db_min_conns, __set_db_min_conns)
+    def db_add_min_conns(self, min_conns):
+        self._db_min_conns = min_conns
+    def db_change_min_conns(self, min_conns):
+        self._db_min_conns = min_conns
+    def db_delete_min_conns(self, min_conns):
+        self._db_min_conns = None
+    
+    def __get_db_max_conns(self):
+        return self._db_max_conns
+    def __set_db_max_conns(self, max_conns):
+        self._db_max_conns = max_conns
+        self.is_dirty = True
+    db_max_conns = property(__get_db_max_conns, __set_db_max_conns)
+    def db_add_max_conns(self, max_conns):
+        self._db_max_conns = max_conns
+    def db_change_max_conns(self, max_conns):
+        self._db_max_conns = max_conns
+    def db_delete_max_conns(self, max_conns):
+        self._db_max_conns = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmUsed(object):
+class DBEnabledPackages(object):
 
-    vtType = 'opm_used'
+    vtType = 'enabled_packages'
 
-    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
-        self.db_deleted_effect = []
-        self._db_effect = effect
-        self.db_deleted_role = []
-        self._db_role = role
-        self.db_deleted_cause = []
-        self._db_cause = cause
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
-        else:
-            self._db_accounts = accounts
-        self.db_deleted_opm_times = []
-        if opm_times is None:
-            self._db_opm_times = []
+    def __init__(self, packages=None):
+        self.db_deleted_packages = []
+        self.db_packages_name_index = {}
+        if packages is None:
+            self._db_packages = []
         else:
-            self._db_opm_times = opm_times
+            self._db_packages = packages
+            for v in self._db_packages:
+                self.db_packages_name_index[v.db_name] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmUsed.do_copy(self)
+        return DBEnabledPackages.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmUsed()
-        if self._db_effect is not None:
-            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
-        if self._db_role is not None:
-            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
-        if self._db_cause is not None:
-            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
-        else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        if self._db_opm_times is None:
-            cp._db_opm_times = []
+        cp = DBEnabledPackages()
+        if self._db_packages is None:
+            cp._db_packages = []
         else:
-            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
         
         # set new ids
         if new_ids:
@@ -6499,6 +8342,7 @@ class DBOpmUsed(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_packages_name_index = dict((v.db_name, v) for v in cp._db_packages)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -6507,229 +8351,104 @@ class DBOpmUsed(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmUsed()
+            new_obj = DBEnabledPackages()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'effect' in class_dict:
-            res = class_dict['effect'](old_obj, trans_dict)
-            new_obj.db_effect = res
-        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
-            obj = old_obj.db_effect
-            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
-            for obj in old_obj.db_deleted_effect:
-                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
-                new_obj.db_deleted_effect.append(n_obj)
-        if 'role' in class_dict:
-            res = class_dict['role'](old_obj, trans_dict)
-            new_obj.db_role = res
-        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
-            obj = old_obj.db_role
-            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
-            for obj in old_obj.db_deleted_role:
-                n_obj = DBOpmRole.update_version(obj, trans_dict)
-                new_obj.db_deleted_role.append(n_obj)
-        if 'cause' in class_dict:
-            res = class_dict['cause'](old_obj, trans_dict)
-            new_obj.db_cause = res
-        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
-            obj = old_obj.db_cause
-            new_obj.db_add_cause(DBOpmArtifactIdCause.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
-            for obj in old_obj.db_deleted_cause:
-                n_obj = DBOpmArtifactIdCause.update_version(obj, trans_dict)
-                new_obj.db_deleted_cause.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
-        if 'opm_times' in class_dict:
-            res = class_dict['opm_times'](old_obj, trans_dict)
+        if 'packages' in class_dict:
+            res = class_dict['packages'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_opm_time(obj)
-        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
-            for obj in old_obj.db_opm_times:
-                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
-            for obj in old_obj.db_deleted_opm_times:
-                n_obj = DBOpmTime.update_version(obj, trans_dict)
-                new_obj.db_deleted_opm_times.append(n_obj)
+                new_obj.db_add_package(obj)
+        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
+            for obj in old_obj.db_packages:
+                new_obj.db_add_package(DBStartupPackage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
+            for obj in old_obj.db_deleted_packages:
+                n_obj = DBStartupPackage.update_version(obj, trans_dict)
+                new_obj.db_deleted_packages.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_effect is not None:
-            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_effect = None
-        if self._db_role is not None:
-            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_role = None
-        if self._db_cause is not None:
-            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_cause = None
         to_del = []
-        for child in self.db_accounts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_account(child)
-        to_del = []
-        for child in self.db_opm_times:
+        for child in self.db_packages:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_opm_time(child)
+            self.db_delete_package(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_effect)
-        children.extend(self.db_deleted_role)
-        children.extend(self.db_deleted_cause)
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_opm_times)
+        children.extend(self.db_deleted_packages)
         if remove:
-            self.db_deleted_effect = []
-            self.db_deleted_role = []
-            self.db_deleted_cause = []
-            self.db_deleted_accounts = []
-            self.db_deleted_opm_times = []
+            self.db_deleted_packages = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_effect is not None and self._db_effect.has_changes():
-            return True
-        if self._db_role is not None and self._db_role.has_changes():
-            return True
-        if self._db_cause is not None and self._db_cause.has_changes():
-            return True
-        for child in self._db_accounts:
-            if child.has_changes():
-                return True
-        for child in self._db_opm_times:
+        for child in self._db_packages:
             if child.has_changes():
                 return True
         return False
-    def __get_db_effect(self):
-        return self._db_effect
-    def __set_db_effect(self, effect):
-        self._db_effect = effect
-        self.is_dirty = True
-    db_effect = property(__get_db_effect, __set_db_effect)
-    def db_add_effect(self, effect):
-        self._db_effect = effect
-    def db_change_effect(self, effect):
-        self._db_effect = effect
-    def db_delete_effect(self, effect):
-        if not self.is_new:
-            self.db_deleted_effect.append(self._db_effect)
-        self._db_effect = None
-    
-    def __get_db_role(self):
-        return self._db_role
-    def __set_db_role(self, role):
-        self._db_role = role
-        self.is_dirty = True
-    db_role = property(__get_db_role, __set_db_role)
-    def db_add_role(self, role):
-        self._db_role = role
-    def db_change_role(self, role):
-        self._db_role = role
-    def db_delete_role(self, role):
-        if not self.is_new:
-            self.db_deleted_role.append(self._db_role)
-        self._db_role = None
-    
-    def __get_db_cause(self):
-        return self._db_cause
-    def __set_db_cause(self, cause):
-        self._db_cause = cause
-        self.is_dirty = True
-    db_cause = property(__get_db_cause, __set_db_cause)
-    def db_add_cause(self, cause):
-        self._db_cause = cause
-    def db_change_cause(self, cause):
-        self._db_cause = cause
-    def db_delete_cause(self, cause):
-        if not self.is_new:
-            self.db_deleted_cause.append(self._db_cause)
-        self._db_cause = None
-    
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
-        self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
-        self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
-        self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
-        self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
-        return None
-    
-    def __get_db_opm_times(self):
-        return self._db_opm_times
-    def __set_db_opm_times(self, opm_times):
-        self._db_opm_times = opm_times
+    def __get_db_packages(self):
+        return self._db_packages
+    def __set_db_packages(self, packages):
+        self._db_packages = packages
         self.is_dirty = True
-    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
-    def db_get_opm_times(self):
-        return self._db_opm_times
-    def db_add_opm_time(self, opm_time):
+    db_packages = property(__get_db_packages, __set_db_packages)
+    def db_get_packages(self):
+        return self._db_packages
+    def db_add_package(self, package):
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_change_opm_time(self, opm_time):
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_change_package(self, package):
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_delete_opm_time(self, opm_time):
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_delete_package(self, package):
         self.is_dirty = True
         raise Exception('Cannot delete a non-keyed object')
-    def db_get_opm_time(self, key):
+    def db_get_package(self, key):
         return None
+    def db_get_package_by_name(self, key):
+        return self.db_packages_name_index[key]
+    def db_has_package_with_name(self, key):
+        return key in self.db_packages_name_index
     
 
 
-class DBPluginData(object):
+class DBOpmArtifact(object):
 
-    vtType = 'plugin_data'
+    vtType = 'opm_artifact'
 
-    def __init__(self, id=None, data=None):
+    def __init__(self, id=None, value=None, accounts=None):
         self._db_id = id
-        self._db_data = data
+        self.db_deleted_value = []
+        self._db_value = value
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBPluginData.do_copy(self)
+        return DBOpmArtifact.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPluginData(id=self._db_id,
-                          data=self._db_data)
+        cp = DBOpmArtifact(id=self._db_id)
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
         
         # set new ids
         if new_ids:
@@ -6749,7 +8468,7 @@ class DBPluginData(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBPluginData()
+            new_obj = DBOpmArtifact()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -6758,23 +8477,62 @@ class DBPluginData(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'data' in class_dict:
-            res = class_dict['data'](old_obj, trans_dict)
-            new_obj.db_data = res
-        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
-            new_obj.db_data = old_obj.db_data
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            new_obj.db_add_value(DBOpmArtifactValue.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                n_obj = DBOpmArtifactValue.update_version(obj, trans_dict)
+                new_obj.db_deleted_value.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_value)
+        children.extend(self.db_deleted_accounts)
+        if remove:
+            self.db_deleted_value = []
+            self.db_deleted_accounts = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -6789,52 +8547,92 @@ class DBPluginData(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_data(self):
-        return self._db_data
-    def __set_db_data(self, data):
-        self._db_data = data
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-    db_data = property(__get_db_data, __set_db_data)
-    def db_add_data(self, data):
-        self._db_data = data
-    def db_change_data(self, data):
-        self._db_data = data
-    def db_delete_data(self, data):
-        self._db_data = None
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBFunction(object):
+class DBLog(object):
 
-    vtType = 'function'
+    vtType = 'log'
 
-    def __init__(self, id=None, pos=None, name=None, parameters=None):
+    def __init__(self, id=None, entity_type=None, version=None, name=None, last_modified=None, workflow_execs=None, machines=None, vistrail_id=None):
         self._db_id = id
-        self._db_pos = pos
+        self._db_entity_type = entity_type
+        self._db_version = version
         self._db_name = name
-        self.db_deleted_parameters = []
-        self.db_parameters_id_index = {}
-        if parameters is None:
-            self._db_parameters = []
+        self._db_last_modified = last_modified
+        self.db_deleted_workflow_execs = []
+        self.db_workflow_execs_id_index = {}
+        if workflow_execs is None:
+            self._db_workflow_execs = []
         else:
-            self._db_parameters = parameters
-            for v in self._db_parameters:
-                self.db_parameters_id_index[v.db_id] = v
+            self._db_workflow_execs = workflow_execs
+            for v in self._db_workflow_execs:
+                self.db_workflow_execs_id_index[v.db_id] = v
+        self.db_deleted_machines = []
+        self.db_machines_id_index = {}
+        if machines is None:
+            self._db_machines = []
+        else:
+            self._db_machines = machines
+            for v in self._db_machines:
+                self.db_machines_id_index[v.db_id] = v
+        self._db_vistrail_id = vistrail_id
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBFunction.do_copy(self)
+        return DBLog.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBFunction(id=self._db_id,
-                        pos=self._db_pos,
-                        name=self._db_name)
-        if self._db_parameters is None:
-            cp._db_parameters = []
+        cp = DBLog(id=self._db_id,
+                   entity_type=self._db_entity_type,
+                   version=self._db_version,
+                   name=self._db_name,
+                   last_modified=self._db_last_modified,
+                   vistrail_id=self._db_vistrail_id)
+        if self._db_workflow_execs is None:
+            cp._db_workflow_execs = []
         else:
-            cp._db_parameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameters]
+            cp._db_workflow_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_workflow_execs]
+        if self._db_machines is None:
+            cp._db_machines = []
+        else:
+            cp._db_machines = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_machines]
         
         # set new ids
         if new_ids:
@@ -6844,9 +8642,12 @@ class DBFunction(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_vistrail_id') and ('vistrail', self._db_vistrail_id) in id_remap:
+                cp._db_vistrail_id = id_remap[('vistrail', self._db_vistrail_id)]
         
         # recreate indices and set flags
-        cp.db_parameters_id_index = dict((v.db_id, v) for v in cp._db_parameters)
+        cp.db_workflow_execs_id_index = dict((v.db_id, v) for v in cp._db_workflow_execs)
+        cp.db_machines_id_index = dict((v.db_id, v) for v in cp._db_machines)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -6855,7 +8656,7 @@ class DBFunction(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBFunction()
+            new_obj = DBLog()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -6864,27 +8665,53 @@ class DBFunction(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'pos' in class_dict:
-            res = class_dict['pos'](old_obj, trans_dict)
-            new_obj.db_pos = res
-        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
-            new_obj.db_pos = old_obj.db_pos
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'parameters' in class_dict:
-            res = class_dict['parameters'](old_obj, trans_dict)
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'workflow_execs' in class_dict:
+            res = class_dict['workflow_execs'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_parameter(obj)
-        elif hasattr(old_obj, 'db_parameters') and old_obj.db_parameters is not None:
-            for obj in old_obj.db_parameters:
-                new_obj.db_add_parameter(DBParameter.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_parameters') and hasattr(new_obj, 'db_deleted_parameters'):
-            for obj in old_obj.db_deleted_parameters:
-                n_obj = DBParameter.update_version(obj, trans_dict)
-                new_obj.db_deleted_parameters.append(n_obj)
+                new_obj.db_add_workflow_exec(obj)
+        elif hasattr(old_obj, 'db_workflow_execs') and old_obj.db_workflow_execs is not None:
+            for obj in old_obj.db_workflow_execs:
+                new_obj.db_add_workflow_exec(DBWorkflowExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_workflow_execs') and hasattr(new_obj, 'db_deleted_workflow_execs'):
+            for obj in old_obj.db_deleted_workflow_execs:
+                n_obj = DBWorkflowExec.update_version(obj, trans_dict)
+                new_obj.db_deleted_workflow_execs.append(n_obj)
+        if 'machines' in class_dict:
+            res = class_dict['machines'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_machine(obj)
+        elif hasattr(old_obj, 'db_machines') and old_obj.db_machines is not None:
+            for obj in old_obj.db_machines:
+                new_obj.db_add_machine(DBMachine.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_machines') and hasattr(new_obj, 'db_deleted_machines'):
+            for obj in old_obj.db_deleted_machines:
+                n_obj = DBMachine.update_version(obj, trans_dict)
+                new_obj.db_deleted_machines.append(n_obj)
+        if 'vistrail_id' in class_dict:
+            res = class_dict['vistrail_id'](old_obj, trans_dict)
+            new_obj.db_vistrail_id = res
+        elif hasattr(old_obj, 'db_vistrail_id') and old_obj.db_vistrail_id is not None:
+            new_obj.db_vistrail_id = old_obj.db_vistrail_id
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -6892,24 +8719,36 @@ class DBFunction(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_parameters:
+        for child in self.db_workflow_execs:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_parameter(child)
+            self.db_delete_workflow_exec(child)
+        to_del = []
+        for child in self.db_machines:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_machine(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_parameters)
+        children.extend(self.db_deleted_workflow_execs)
+        children.extend(self.db_deleted_machines)
         if remove:
-            self.db_deleted_parameters = []
+            self.db_deleted_workflow_execs = []
+            self.db_deleted_machines = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_parameters:
+        for child in self._db_workflow_execs:
+            if child.has_changes():
+                return True
+        for child in self._db_machines:
             if child.has_changes():
                 return True
         return False
@@ -6926,18 +8765,31 @@ class DBFunction(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_pos(self):
-        return self._db_pos
-    def __set_db_pos(self, pos):
-        self._db_pos = pos
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
         self.is_dirty = True
-    db_pos = property(__get_db_pos, __set_db_pos)
-    def db_add_pos(self, pos):
-        self._db_pos = pos
-    def db_change_pos(self, pos):
-        self._db_pos = pos
-    def db_delete_pos(self, pos):
-        self._db_pos = None
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
     
     def __get_db_name(self):
         return self._db_name
@@ -6952,75 +8804,133 @@ class DBFunction(object):
     def db_delete_name(self, name):
         self._db_name = None
     
-    def __get_db_parameters(self):
-        return self._db_parameters
-    def __set_db_parameters(self, parameters):
-        self._db_parameters = parameters
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
         self.is_dirty = True
-    db_parameters = property(__get_db_parameters, __set_db_parameters)
-    def db_get_parameters(self):
-        return self._db_parameters
-    def db_add_parameter(self, parameter):
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_workflow_execs(self):
+        return self._db_workflow_execs
+    def __set_db_workflow_execs(self, workflow_execs):
+        self._db_workflow_execs = workflow_execs
         self.is_dirty = True
-        self._db_parameters.append(parameter)
-        self.db_parameters_id_index[parameter.db_id] = parameter
-    def db_change_parameter(self, parameter):
+    db_workflow_execs = property(__get_db_workflow_execs, __set_db_workflow_execs)
+    def db_get_workflow_execs(self):
+        return self._db_workflow_execs
+    def db_add_workflow_exec(self, workflow_exec):
+        self.is_dirty = True
+        self._db_workflow_execs.append(workflow_exec)
+        self.db_workflow_execs_id_index[workflow_exec.db_id] = workflow_exec
+    def db_change_workflow_exec(self, workflow_exec):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_parameters)):
-            if self._db_parameters[i].db_id == parameter.db_id:
-                self._db_parameters[i] = parameter
+        for i in xrange(len(self._db_workflow_execs)):
+            if self._db_workflow_execs[i].db_id == workflow_exec.db_id:
+                self._db_workflow_execs[i] = workflow_exec
                 found = True
                 break
         if not found:
-            self._db_parameters.append(parameter)
-        self.db_parameters_id_index[parameter.db_id] = parameter
-    def db_delete_parameter(self, parameter):
+            self._db_workflow_execs.append(workflow_exec)
+        self.db_workflow_execs_id_index[workflow_exec.db_id] = workflow_exec
+    def db_delete_workflow_exec(self, workflow_exec):
         self.is_dirty = True
-        for i in xrange(len(self._db_parameters)):
-            if self._db_parameters[i].db_id == parameter.db_id:
-                if not self._db_parameters[i].is_new:
-                    self.db_deleted_parameters.append(self._db_parameters[i])
-                del self._db_parameters[i]
+        for i in xrange(len(self._db_workflow_execs)):
+            if self._db_workflow_execs[i].db_id == workflow_exec.db_id:
+                if not self._db_workflow_execs[i].is_new:
+                    self.db_deleted_workflow_execs.append(self._db_workflow_execs[i])
+                del self._db_workflow_execs[i]
                 break
-        del self.db_parameters_id_index[parameter.db_id]
-    def db_get_parameter(self, key):
-        for i in xrange(len(self._db_parameters)):
-            if self._db_parameters[i].db_id == key:
-                return self._db_parameters[i]
+        del self.db_workflow_execs_id_index[workflow_exec.db_id]
+    def db_get_workflow_exec(self, key):
+        for i in xrange(len(self._db_workflow_execs)):
+            if self._db_workflow_execs[i].db_id == key:
+                return self._db_workflow_execs[i]
         return None
-    def db_get_parameter_by_id(self, key):
-        return self.db_parameters_id_index[key]
-    def db_has_parameter_with_id(self, key):
-        return key in self.db_parameters_id_index
+    def db_get_workflow_exec_by_id(self, key):
+        return self.db_workflow_execs_id_index[key]
+    def db_has_workflow_exec_with_id(self, key):
+        return key in self.db_workflow_execs_id_index
+    
+    def __get_db_machines(self):
+        return self._db_machines
+    def __set_db_machines(self, machines):
+        self._db_machines = machines
+        self.is_dirty = True
+    db_machines = property(__get_db_machines, __set_db_machines)
+    def db_get_machines(self):
+        return self._db_machines
+    def db_add_machine(self, machine):
+        self.is_dirty = True
+        self._db_machines.append(machine)
+        self.db_machines_id_index[machine.db_id] = machine
+    def db_change_machine(self, machine):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_machines)):
+            if self._db_machines[i].db_id == machine.db_id:
+                self._db_machines[i] = machine
+                found = True
+                break
+        if not found:
+            self._db_machines.append(machine)
+        self.db_machines_id_index[machine.db_id] = machine
+    def db_delete_machine(self, machine):
+        self.is_dirty = True
+        for i in xrange(len(self._db_machines)):
+            if self._db_machines[i].db_id == machine.db_id:
+                if not self._db_machines[i].is_new:
+                    self.db_deleted_machines.append(self._db_machines[i])
+                del self._db_machines[i]
+                break
+        del self.db_machines_id_index[machine.db_id]
+    def db_get_machine(self, key):
+        for i in xrange(len(self._db_machines)):
+            if self._db_machines[i].db_id == key:
+                return self._db_machines[i]
+        return None
+    def db_get_machine_by_id(self, key):
+        return self.db_machines_id_index[key]
+    def db_has_machine_with_id(self, key):
+        return key in self.db_machines_id_index
+    
+    def __get_db_vistrail_id(self):
+        return self._db_vistrail_id
+    def __set_db_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+        self.is_dirty = True
+    db_vistrail_id = property(__get_db_vistrail_id, __set_db_vistrail_id)
+    def db_add_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_change_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_delete_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBActionAnnotation(object):
+class DBOpmProcessIdCause(object):
 
-    vtType = 'actionAnnotation'
+    vtType = 'opm_process_id_cause'
 
-    def __init__(self, id=None, key=None, value=None, action_id=None, date=None, user=None):
+    def __init__(self, id=None):
         self._db_id = id
-        self._db_key = key
-        self._db_value = value
-        self._db_action_id = action_id
-        self._db_date = date
-        self._db_user = user
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBActionAnnotation.do_copy(self)
+        return DBOpmProcessIdCause.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBActionAnnotation(id=self._db_id,
-                                key=self._db_key,
-                                value=self._db_value,
-                                action_id=self._db_action_id,
-                                date=self._db_date,
-                                user=self._db_user)
+        cp = DBOpmProcessIdCause(id=self._db_id)
         
         # set new ids
         if new_ids:
@@ -7030,8 +8940,8 @@ class DBActionAnnotation(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_action_id') and ('action', self._db_action_id) in id_remap:
-                cp._db_action_id = id_remap[('action', self._db_action_id)]
+            if hasattr(self, 'db_id') and ('opm_process', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_process', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -7042,7 +8952,7 @@ class DBActionAnnotation(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBActionAnnotation()
+            new_obj = DBOpmProcessIdCause()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -7051,31 +8961,6 @@ class DBActionAnnotation(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'key' in class_dict:
-            res = class_dict['key'](old_obj, trans_dict)
-            new_obj.db_key = res
-        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
-            new_obj.db_key = old_obj.db_key
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            new_obj.db_value = old_obj.db_value
-        if 'action_id' in class_dict:
-            res = class_dict['action_id'](old_obj, trans_dict)
-            new_obj.db_action_id = res
-        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
-            new_obj.db_action_id = old_obj.db_action_id
-        if 'date' in class_dict:
-            res = class_dict['date'](old_obj, trans_dict)
-            new_obj.db_date = res
-        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
-            new_obj.db_date = old_obj.db_date
-        if 'user' in class_dict:
-            res = class_dict['user'](old_obj, trans_dict)
-            new_obj.db_user = res
-        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
-            new_obj.db_user = old_obj.db_user
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -7088,144 +8973,47 @@ class DBActionAnnotation(object):
     def has_changes(self):
         if self.is_dirty:
             return True
-        return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_key(self):
-        return self._db_key
-    def __set_db_key(self, key):
-        self._db_key = key
-        self.is_dirty = True
-    db_key = property(__get_db_key, __set_db_key)
-    def db_add_key(self, key):
-        self._db_key = key
-    def db_change_key(self, key):
-        self._db_key = key
-    def db_delete_key(self, key):
-        self._db_key = None
-    
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
-        self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
-        self._db_value = None
-    
-    def __get_db_action_id(self):
-        return self._db_action_id
-    def __set_db_action_id(self, action_id):
-        self._db_action_id = action_id
-        self.is_dirty = True
-    db_action_id = property(__get_db_action_id, __set_db_action_id)
-    def db_add_action_id(self, action_id):
-        self._db_action_id = action_id
-    def db_change_action_id(self, action_id):
-        self._db_action_id = action_id
-    def db_delete_action_id(self, action_id):
-        self._db_action_id = None
-    
-    def __get_db_date(self):
-        return self._db_date
-    def __set_db_date(self, date):
-        self._db_date = date
-        self.is_dirty = True
-    db_date = property(__get_db_date, __set_db_date)
-    def db_add_date(self, date):
-        self._db_date = date
-    def db_change_date(self, date):
-        self._db_date = date
-    def db_delete_date(self, date):
-        self._db_date = None
-    
-    def __get_db_user(self):
-        return self._db_user
-    def __set_db_user(self, user):
-        self._db_user = user
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_user = property(__get_db_user, __set_db_user)
-    def db_add_user(self, user):
-        self._db_user = user
-    def db_change_user(self, user):
-        self._db_user = user
-    def db_delete_user(self, user):
-        self._db_user = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBAbstraction(object):
 
-    vtType = 'abstraction'
+class DBOpmArtifacts(object):
 
-    def __init__(self, id=None, cache=None, name=None, namespace=None, package=None, version=None, internal_version=None, location=None, functions=None, annotations=None):
-        self._db_id = id
-        self._db_cache = cache
-        self._db_name = name
-        self._db_namespace = namespace
-        self._db_package = package
-        self._db_version = version
-        self._db_internal_version = internal_version
-        self.db_deleted_location = []
-        self._db_location = location
-        self.db_deleted_functions = []
-        self.db_functions_id_index = {}
-        if functions is None:
-            self._db_functions = []
-        else:
-            self._db_functions = functions
-            for v in self._db_functions:
-                self.db_functions_id_index[v.db_id] = v
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        self.db_annotations_key_index = {}
-        if annotations is None:
-            self._db_annotations = []
+    vtType = 'opm_artifacts'
+
+    def __init__(self, artifacts=None):
+        self.db_deleted_artifacts = []
+        self.db_artifacts_id_index = {}
+        if artifacts is None:
+            self._db_artifacts = []
         else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
-                self.db_annotations_key_index[v.db_key] = v
+            self._db_artifacts = artifacts
+            for v in self._db_artifacts:
+                self.db_artifacts_id_index[v.db_id] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBAbstraction.do_copy(self)
+        return DBOpmArtifacts.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBAbstraction(id=self._db_id,
-                           cache=self._db_cache,
-                           name=self._db_name,
-                           namespace=self._db_namespace,
-                           package=self._db_package,
-                           version=self._db_version,
-                           internal_version=self._db_internal_version)
-        if self._db_location is not None:
-            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
-        if self._db_functions is None:
-            cp._db_functions = []
-        else:
-            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
-        if self._db_annotations is None:
-            cp._db_annotations = []
+        cp = DBOpmArtifacts()
+        if self._db_artifacts is None:
+            cp._db_artifacts = []
         else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+            cp._db_artifacts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_artifacts]
         
         # set new ids
         if new_ids:
@@ -7237,9 +9025,7 @@ class DBAbstraction(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_artifacts_id_index = dict((v.db_id, v) for v in cp._db_artifacts)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -7248,124 +9034,175 @@ class DBAbstraction(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBAbstraction()
+            new_obj = DBOpmArtifacts()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'cache' in class_dict:
-            res = class_dict['cache'](old_obj, trans_dict)
-            new_obj.db_cache = res
-        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
-            new_obj.db_cache = old_obj.db_cache
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'namespace' in class_dict:
-            res = class_dict['namespace'](old_obj, trans_dict)
-            new_obj.db_namespace = res
-        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
-            new_obj.db_namespace = old_obj.db_namespace
-        if 'package' in class_dict:
-            res = class_dict['package'](old_obj, trans_dict)
-            new_obj.db_package = res
-        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
-            new_obj.db_package = old_obj.db_package
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'internal_version' in class_dict:
-            res = class_dict['internal_version'](old_obj, trans_dict)
-            new_obj.db_internal_version = res
-        elif hasattr(old_obj, 'db_internal_version') and old_obj.db_internal_version is not None:
-            new_obj.db_internal_version = old_obj.db_internal_version
-        if 'location' in class_dict:
-            res = class_dict['location'](old_obj, trans_dict)
-            new_obj.db_location = res
-        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
-            obj = old_obj.db_location
-            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
-            for obj in old_obj.db_deleted_location:
-                n_obj = DBLocation.update_version(obj, trans_dict)
-                new_obj.db_deleted_location.append(n_obj)
-        if 'functions' in class_dict:
-            res = class_dict['functions'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_function(obj)
-        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
-            for obj in old_obj.db_functions:
-                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
-            for obj in old_obj.db_deleted_functions:
-                n_obj = DBFunction.update_version(obj, trans_dict)
-                new_obj.db_deleted_functions.append(n_obj)
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
+        if 'artifacts' in class_dict:
+            res = class_dict['artifacts'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
+                new_obj.db_add_artifact(obj)
+        elif hasattr(old_obj, 'db_artifacts') and old_obj.db_artifacts is not None:
+            for obj in old_obj.db_artifacts:
+                new_obj.db_add_artifact(DBOpmArtifact.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_artifacts') and hasattr(new_obj, 'db_deleted_artifacts'):
+            for obj in old_obj.db_deleted_artifacts:
+                n_obj = DBOpmArtifact.update_version(obj, trans_dict)
+                new_obj.db_deleted_artifacts.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_artifacts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_artifact(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_artifacts)
+        if remove:
+            self.db_deleted_artifacts = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_artifacts:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_artifacts(self):
+        return self._db_artifacts
+    def __set_db_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+        self.is_dirty = True
+    db_artifacts = property(__get_db_artifacts, __set_db_artifacts)
+    def db_get_artifacts(self):
+        return self._db_artifacts
+    def db_add_artifact(self, artifact):
+        self.is_dirty = True
+        self._db_artifacts.append(artifact)
+        self.db_artifacts_id_index[artifact.db_id] = artifact
+    def db_change_artifact(self, artifact):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_artifacts)):
+            if self._db_artifacts[i].db_id == artifact.db_id:
+                self._db_artifacts[i] = artifact
+                found = True
+                break
+        if not found:
+            self._db_artifacts.append(artifact)
+        self.db_artifacts_id_index[artifact.db_id] = artifact
+    def db_delete_artifact(self, artifact):
+        self.is_dirty = True
+        for i in xrange(len(self._db_artifacts)):
+            if self._db_artifacts[i].db_id == artifact.db_id:
+                if not self._db_artifacts[i].is_new:
+                    self.db_deleted_artifacts.append(self._db_artifacts[i])
+                del self._db_artifacts[i]
+                break
+        del self.db_artifacts_id_index[artifact.db_id]
+    def db_get_artifact(self, key):
+        for i in xrange(len(self._db_artifacts)):
+            if self._db_artifacts[i].db_id == key:
+                return self._db_artifacts[i]
+        return None
+    def db_get_artifact_by_id(self, key):
+        return self.db_artifacts_id_index[key]
+    def db_has_artifact_with_id(self, key):
+        return key in self.db_artifacts_id_index
+    
+
+
+class DBPEParameter(object):
+
+    vtType = 'pe_parameter'
+
+    def __init__(self, id=None, pos=None, interpolator=None, value=None, dimension=None):
+        self._db_id = id
+        self._db_pos = pos
+        self._db_interpolator = interpolator
+        self._db_value = value
+        self._db_dimension = dimension
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPEParameter.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPEParameter(id=self._db_id,
+                           pos=self._db_pos,
+                           interpolator=self._db_interpolator,
+                           value=self._db_value,
+                           dimension=self._db_dimension)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPEParameter()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'interpolator' in class_dict:
+            res = class_dict['interpolator'](old_obj, trans_dict)
+            new_obj.db_interpolator = res
+        elif hasattr(old_obj, 'db_interpolator') and old_obj.db_interpolator is not None:
+            new_obj.db_interpolator = old_obj.db_interpolator
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'dimension' in class_dict:
+            res = class_dict['dimension'](old_obj, trans_dict)
+            new_obj.db_dimension = res
+        elif hasattr(old_obj, 'db_dimension') and old_obj.db_dimension is not None:
+            new_obj.db_dimension = old_obj.db_dimension
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_location is not None:
-            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_location = None
-        to_del = []
-        for child in self.db_functions:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_function(child)
-        to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_location)
-        children.extend(self.db_deleted_functions)
-        children.extend(self.db_deleted_annotations)
-        if remove:
-            self.db_deleted_location = []
-            self.db_deleted_functions = []
-            self.db_deleted_annotations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_location is not None and self._db_location.has_changes():
-            return True
-        for child in self._db_functions:
-            if child.has_changes():
-                return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -7380,219 +9217,86 @@ class DBAbstraction(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_cache(self):
-        return self._db_cache
-    def __set_db_cache(self, cache):
-        self._db_cache = cache
-        self.is_dirty = True
-    db_cache = property(__get_db_cache, __set_db_cache)
-    def db_add_cache(self, cache):
-        self._db_cache = cache
-    def db_change_cache(self, cache):
-        self._db_cache = cache
-    def db_delete_cache(self, cache):
-        self._db_cache = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_namespace(self):
-        return self._db_namespace
-    def __set_db_namespace(self, namespace):
-        self._db_namespace = namespace
-        self.is_dirty = True
-    db_namespace = property(__get_db_namespace, __set_db_namespace)
-    def db_add_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_change_namespace(self, namespace):
-        self._db_namespace = namespace
-    def db_delete_namespace(self, namespace):
-        self._db_namespace = None
-    
-    def __get_db_package(self):
-        return self._db_package
-    def __set_db_package(self, package):
-        self._db_package = package
-        self.is_dirty = True
-    db_package = property(__get_db_package, __set_db_package)
-    def db_add_package(self, package):
-        self._db_package = package
-    def db_change_package(self, package):
-        self._db_package = package
-    def db_delete_package(self, package):
-        self._db_package = None
-    
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
-        self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
-    
-    def __get_db_internal_version(self):
-        return self._db_internal_version
-    def __set_db_internal_version(self, internal_version):
-        self._db_internal_version = internal_version
-        self.is_dirty = True
-    db_internal_version = property(__get_db_internal_version, __set_db_internal_version)
-    def db_add_internal_version(self, internal_version):
-        self._db_internal_version = internal_version
-    def db_change_internal_version(self, internal_version):
-        self._db_internal_version = internal_version
-    def db_delete_internal_version(self, internal_version):
-        self._db_internal_version = None
-    
-    def __get_db_location(self):
-        return self._db_location
-    def __set_db_location(self, location):
-        self._db_location = location
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
         self.is_dirty = True
-    db_location = property(__get_db_location, __set_db_location)
-    def db_add_location(self, location):
-        self._db_location = location
-    def db_change_location(self, location):
-        self._db_location = location
-    def db_delete_location(self, location):
-        if not self.is_new:
-            self.db_deleted_location.append(self._db_location)
-        self._db_location = None
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
     
-    def __get_db_functions(self):
-        return self._db_functions
-    def __set_db_functions(self, functions):
-        self._db_functions = functions
-        self.is_dirty = True
-    db_functions = property(__get_db_functions, __set_db_functions)
-    def db_get_functions(self):
-        return self._db_functions
-    def db_add_function(self, function):
-        self.is_dirty = True
-        self._db_functions.append(function)
-        self.db_functions_id_index[function.db_id] = function
-    def db_change_function(self, function):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == function.db_id:
-                self._db_functions[i] = function
-                found = True
-                break
-        if not found:
-            self._db_functions.append(function)
-        self.db_functions_id_index[function.db_id] = function
-    def db_delete_function(self, function):
+    def __get_db_interpolator(self):
+        return self._db_interpolator
+    def __set_db_interpolator(self, interpolator):
+        self._db_interpolator = interpolator
         self.is_dirty = True
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == function.db_id:
-                if not self._db_functions[i].is_new:
-                    self.db_deleted_functions.append(self._db_functions[i])
-                del self._db_functions[i]
-                break
-        del self.db_functions_id_index[function.db_id]
-    def db_get_function(self, key):
-        for i in xrange(len(self._db_functions)):
-            if self._db_functions[i].db_id == key:
-                return self._db_functions[i]
-        return None
-    def db_get_function_by_id(self, key):
-        return self.db_functions_id_index[key]
-    def db_has_function_with_id(self, key):
-        return key in self.db_functions_id_index
+    db_interpolator = property(__get_db_interpolator, __set_db_interpolator)
+    def db_add_interpolator(self, interpolator):
+        self._db_interpolator = interpolator
+    def db_change_interpolator(self, interpolator):
+        self._db_interpolator = interpolator
+    def db_delete_interpolator(self, interpolator):
+        self._db_interpolator = None
     
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
-        self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
-        self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_change_annotation(self, annotation):
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
-                found = True
-                break
-        if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_delete_annotation(self, annotation):
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_dimension(self):
+        return self._db_dimension
+    def __set_db_dimension(self, dimension):
+        self._db_dimension = dimension
         self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
-                break
-        del self.db_annotations_id_index[annotation.db_id]
-        del self.db_annotations_key_index[annotation.db_key]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
-        return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
-    def db_get_annotation_by_key(self, key):
-        return self.db_annotations_key_index[key]
-    def db_has_annotation_with_key(self, key):
-        return key in self.db_annotations_key_index
+    db_dimension = property(__get_db_dimension, __set_db_dimension)
+    def db_add_dimension(self, dimension):
+        self._db_dimension = dimension
+    def db_change_dimension(self, dimension):
+        self._db_dimension = dimension
+    def db_delete_dimension(self, dimension):
+        self._db_dimension = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBWorkflow(object):
+class DBWorkflowExec(object):
 
-    vtType = 'workflow'
+    vtType = 'workflow_exec'
 
-    def __init__(self, modules=None, id=None, entity_type=None, name=None, version=None, last_modified=None, connections=None, annotations=None, plugin_datas=None, others=None, vistrail_id=None):
-        self.db_deleted_modules = []
-        self.db_modules_id_index = {}
-        if modules is None:
-            self._db_modules = []
+    def __init__(self, item_execs=None, id=None, user=None, ip=None, session=None, vt_version=None, ts_start=None, ts_end=None, parent_id=None, parent_type=None, parent_version=None, completed=None, name=None, annotations=None):
+        self.db_deleted_item_execs = []
+        self.db_item_execs_id_index = {}
+        if item_execs is None:
+            self._db_item_execs = []
         else:
-            self._db_modules = modules
-            for v in self._db_modules:
-                self.db_modules_id_index[v.db_id] = v
+            self._db_item_execs = item_execs
+            for v in self._db_item_execs:
+                self.db_item_execs_id_index[v.db_id] = v
         self._db_id = id
-        self._db_entity_type = entity_type
+        self._db_user = user
+        self._db_ip = ip
+        self._db_session = session
+        self._db_vt_version = vt_version
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_parent_id = parent_id
+        self._db_parent_type = parent_type
+        self._db_parent_version = parent_version
+        self._db_completed = completed
         self._db_name = name
-        self._db_version = version
-        self._db_last_modified = last_modified
-        self.db_deleted_connections = []
-        self.db_connections_id_index = {}
-        if connections is None:
-            self._db_connections = []
-        else:
-            self._db_connections = connections
-            for v in self._db_connections:
-                self.db_connections_id_index[v.db_id] = v
         self.db_deleted_annotations = []
         self.db_annotations_id_index = {}
         if annotations is None:
@@ -7601,56 +9305,33 @@ class DBWorkflow(object):
             self._db_annotations = annotations
             for v in self._db_annotations:
                 self.db_annotations_id_index[v.db_id] = v
-        self.db_deleted_plugin_datas = []
-        self.db_plugin_datas_id_index = {}
-        if plugin_datas is None:
-            self._db_plugin_datas = []
-        else:
-            self._db_plugin_datas = plugin_datas
-            for v in self._db_plugin_datas:
-                self.db_plugin_datas_id_index[v.db_id] = v
-        self.db_deleted_others = []
-        self.db_others_id_index = {}
-        if others is None:
-            self._db_others = []
-        else:
-            self._db_others = others
-            for v in self._db_others:
-                self.db_others_id_index[v.db_id] = v
-        self._db_vistrail_id = vistrail_id
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBWorkflow.do_copy(self)
+        return DBWorkflowExec.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBWorkflow(id=self._db_id,
-                        entity_type=self._db_entity_type,
-                        name=self._db_name,
-                        version=self._db_version,
-                        last_modified=self._db_last_modified,
-                        vistrail_id=self._db_vistrail_id)
-        if self._db_modules is None:
-            cp._db_modules = []
-        else:
-            cp._db_modules = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_modules]
-        if self._db_connections is None:
-            cp._db_connections = []
+        cp = DBWorkflowExec(id=self._db_id,
+                            user=self._db_user,
+                            ip=self._db_ip,
+                            session=self._db_session,
+                            vt_version=self._db_vt_version,
+                            ts_start=self._db_ts_start,
+                            ts_end=self._db_ts_end,
+                            parent_id=self._db_parent_id,
+                            parent_type=self._db_parent_type,
+                            parent_version=self._db_parent_version,
+                            completed=self._db_completed,
+                            name=self._db_name)
+        if self._db_item_execs is None:
+            cp._db_item_execs = []
         else:
-            cp._db_connections = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_connections]
+            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
         if self._db_annotations is None:
             cp._db_annotations = []
         else:
             cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
-        if self._db_plugin_datas is None:
-            cp._db_plugin_datas = []
-        else:
-            cp._db_plugin_datas = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_plugin_datas]
-        if self._db_others is None:
-            cp._db_others = []
-        else:
-            cp._db_others = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_others]
         
         # set new ids
         if new_ids:
@@ -7660,15 +9341,10 @@ class DBWorkflow(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_vistrail_id') and ('vistrail', self._db_vistrail_id) in id_remap:
-                cp._db_vistrail_id = id_remap[('vistrail', self._db_vistrail_id)]
         
         # recreate indices and set flags
-        cp.db_modules_id_index = dict((v.db_id, v) for v in cp._db_modules)
-        cp.db_connections_id_index = dict((v.db_id, v) for v in cp._db_connections)
+        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
         cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_plugin_datas_id_index = dict((v.db_id, v) for v in cp._db_plugin_datas)
-        cp.db_others_id_index = dict((v.db_id, v) for v in cp._db_others)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -7677,69 +9353,93 @@ class DBWorkflow(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBWorkflow()
+            new_obj = DBWorkflowExec()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'modules' in class_dict:
-            res = class_dict['modules'](old_obj, trans_dict)
+        if 'item_execs' in class_dict:
+            res = class_dict['item_execs'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_module(obj)
-        elif hasattr(old_obj, 'db_modules') and old_obj.db_modules is not None:
-            for obj in old_obj.db_modules:
-                if obj.vtType == 'module':
-                    new_obj.db_add_module(DBModule.update_version(obj, trans_dict))
-                elif obj.vtType == 'abstraction':
-                    new_obj.db_add_module(DBAbstraction.update_version(obj, trans_dict))
-                elif obj.vtType == 'group':
-                    new_obj.db_add_module(DBGroup.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_modules') and hasattr(new_obj, 'db_deleted_modules'):
-            for obj in old_obj.db_deleted_modules:
-                if obj.vtType == 'module':
-                    n_obj = DBModule.update_version(obj, trans_dict)
-                    new_obj.db_deleted_modules.append(n_obj)
-                elif obj.vtType == 'abstraction':
-                    n_obj = DBAbstraction.update_version(obj, trans_dict)
-                    new_obj.db_deleted_modules.append(n_obj)
-                elif obj.vtType == 'group':
-                    n_obj = DBGroup.update_version(obj, trans_dict)
-                    new_obj.db_deleted_modules.append(n_obj)
+                new_obj.db_add_item_exec(obj)
+        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
+            for obj in old_obj.db_item_execs:
+                if obj.vtType == 'module_exec':
+                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'group_exec':
+                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'loop_exec':
+                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
+            for obj in old_obj.db_deleted_item_execs:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
         if 'id' in class_dict:
             res = class_dict['id'](old_obj, trans_dict)
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'entity_type' in class_dict:
-            res = class_dict['entity_type'](old_obj, trans_dict)
-            new_obj.db_entity_type = res
-        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
-            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'ip' in class_dict:
+            res = class_dict['ip'](old_obj, trans_dict)
+            new_obj.db_ip = res
+        elif hasattr(old_obj, 'db_ip') and old_obj.db_ip is not None:
+            new_obj.db_ip = old_obj.db_ip
+        if 'session' in class_dict:
+            res = class_dict['session'](old_obj, trans_dict)
+            new_obj.db_session = res
+        elif hasattr(old_obj, 'db_session') and old_obj.db_session is not None:
+            new_obj.db_session = old_obj.db_session
+        if 'vt_version' in class_dict:
+            res = class_dict['vt_version'](old_obj, trans_dict)
+            new_obj.db_vt_version = res
+        elif hasattr(old_obj, 'db_vt_version') and old_obj.db_vt_version is not None:
+            new_obj.db_vt_version = old_obj.db_vt_version
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'parent_id' in class_dict:
+            res = class_dict['parent_id'](old_obj, trans_dict)
+            new_obj.db_parent_id = res
+        elif hasattr(old_obj, 'db_parent_id') and old_obj.db_parent_id is not None:
+            new_obj.db_parent_id = old_obj.db_parent_id
+        if 'parent_type' in class_dict:
+            res = class_dict['parent_type'](old_obj, trans_dict)
+            new_obj.db_parent_type = res
+        elif hasattr(old_obj, 'db_parent_type') and old_obj.db_parent_type is not None:
+            new_obj.db_parent_type = old_obj.db_parent_type
+        if 'parent_version' in class_dict:
+            res = class_dict['parent_version'](old_obj, trans_dict)
+            new_obj.db_parent_version = res
+        elif hasattr(old_obj, 'db_parent_version') and old_obj.db_parent_version is not None:
+            new_obj.db_parent_version = old_obj.db_parent_version
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'last_modified' in class_dict:
-            res = class_dict['last_modified'](old_obj, trans_dict)
-            new_obj.db_last_modified = res
-        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
-            new_obj.db_last_modified = old_obj.db_last_modified
-        if 'connections' in class_dict:
-            res = class_dict['connections'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_connection(obj)
-        elif hasattr(old_obj, 'db_connections') and old_obj.db_connections is not None:
-            for obj in old_obj.db_connections:
-                new_obj.db_add_connection(DBConnection.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_connections') and hasattr(new_obj, 'db_deleted_connections'):
-            for obj in old_obj.db_deleted_connections:
-                n_obj = DBConnection.update_version(obj, trans_dict)
-                new_obj.db_deleted_connections.append(n_obj)
         if 'annotations' in class_dict:
             res = class_dict['annotations'](old_obj, trans_dict)
             for obj in res:
@@ -7751,33 +9451,6 @@ class DBWorkflow(object):
             for obj in old_obj.db_deleted_annotations:
                 n_obj = DBAnnotation.update_version(obj, trans_dict)
                 new_obj.db_deleted_annotations.append(n_obj)
-        if 'plugin_datas' in class_dict:
-            res = class_dict['plugin_datas'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_plugin_data(obj)
-        elif hasattr(old_obj, 'db_plugin_datas') and old_obj.db_plugin_datas is not None:
-            for obj in old_obj.db_plugin_datas:
-                new_obj.db_add_plugin_data(DBPluginData.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_plugin_datas') and hasattr(new_obj, 'db_deleted_plugin_datas'):
-            for obj in old_obj.db_deleted_plugin_datas:
-                n_obj = DBPluginData.update_version(obj, trans_dict)
-                new_obj.db_deleted_plugin_datas.append(n_obj)
-        if 'others' in class_dict:
-            res = class_dict['others'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_other(obj)
-        elif hasattr(old_obj, 'db_others') and old_obj.db_others is not None:
-            for obj in old_obj.db_others:
-                new_obj.db_add_other(DBOther.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_others') and hasattr(new_obj, 'db_deleted_others'):
-            for obj in old_obj.db_deleted_others:
-                n_obj = DBOther.update_version(obj, trans_dict)
-                new_obj.db_deleted_others.append(n_obj)
-        if 'vistrail_id' in class_dict:
-            res = class_dict['vistrail_id'](old_obj, trans_dict)
-            new_obj.db_vistrail_id = res
-        elif hasattr(old_obj, 'db_vistrail_id') and old_obj.db_vistrail_id is not None:
-            new_obj.db_vistrail_id = old_obj.db_vistrail_id
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -7785,13 +9458,6 @@ class DBWorkflow(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_connections:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_connection(child)
-        to_del = []
         for child in self.db_annotations:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
@@ -7799,128 +9465,216 @@ class DBWorkflow(object):
         for child in to_del:
             self.db_delete_annotation(child)
         to_del = []
-        for child in self.db_plugin_datas:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_plugin_data(child)
-        to_del = []
-        for child in self.db_others:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_other(child)
-        to_del = []
-        for child in self.db_modules:
+        for child in self.db_item_execs:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_module(child)
+            self.db_delete_item_exec(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_connections)
         children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_plugin_datas)
-        children.extend(self.db_deleted_others)
-        children.extend(self.db_deleted_modules)
+        children.extend(self.db_deleted_item_execs)
         if remove:
-            self.db_deleted_connections = []
             self.db_deleted_annotations = []
-            self.db_deleted_plugin_datas = []
-            self.db_deleted_others = []
-            self.db_deleted_modules = []
+            self.db_deleted_item_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_connections:
-            if child.has_changes():
-                return True
         for child in self._db_annotations:
             if child.has_changes():
                 return True
-        for child in self._db_plugin_datas:
-            if child.has_changes():
-                return True
-        for child in self._db_others:
-            if child.has_changes():
-                return True
-        for child in self._db_modules:
+        for child in self._db_item_execs:
             if child.has_changes():
                 return True
         return False
-    def __get_db_modules(self):
-        return self._db_modules
-    def __set_db_modules(self, modules):
-        self._db_modules = modules
+    def __get_db_item_execs(self):
+        return self._db_item_execs
+    def __set_db_item_execs(self, item_execs):
+        self._db_item_execs = item_execs
         self.is_dirty = True
-    db_modules = property(__get_db_modules, __set_db_modules)
-    def db_get_modules(self):
-        return self._db_modules
-    def db_add_module(self, module):
+    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
+    def db_get_item_execs(self):
+        return self._db_item_execs
+    def db_add_item_exec(self, item_exec):
         self.is_dirty = True
-        self._db_modules.append(module)
-        self.db_modules_id_index[module.db_id] = module
-    def db_change_module(self, module):
+        self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_change_item_exec(self, item_exec):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_modules)):
-            if self._db_modules[i].db_id == module.db_id:
-                self._db_modules[i] = module
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                self._db_item_execs[i] = item_exec
                 found = True
                 break
         if not found:
-            self._db_modules.append(module)
-        self.db_modules_id_index[module.db_id] = module
-    def db_delete_module(self, module):
+            self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_delete_item_exec(self, item_exec):
         self.is_dirty = True
-        for i in xrange(len(self._db_modules)):
-            if self._db_modules[i].db_id == module.db_id:
-                if not self._db_modules[i].is_new:
-                    self.db_deleted_modules.append(self._db_modules[i])
-                del self._db_modules[i]
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                if not self._db_item_execs[i].is_new:
+                    self.db_deleted_item_execs.append(self._db_item_execs[i])
+                del self._db_item_execs[i]
                 break
-        del self.db_modules_id_index[module.db_id]
-    def db_get_module(self, key):
-        for i in xrange(len(self._db_modules)):
-            if self._db_modules[i].db_id == key:
-                return self._db_modules[i]
+        del self.db_item_execs_id_index[item_exec.db_id]
+    def db_get_item_exec(self, key):
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == key:
+                return self._db_item_execs[i]
         return None
-    def db_get_module_by_id(self, key):
-        return self.db_modules_id_index[key]
-    def db_has_module_with_id(self, key):
-        return key in self.db_modules_id_index
+    def db_get_item_exec_by_id(self, key):
+        return self.db_item_execs_id_index[key]
+    def db_has_item_exec_with_id(self, key):
+        return key in self.db_item_execs_id_index
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def __get_db_ip(self):
+        return self._db_ip
+    def __set_db_ip(self, ip):
+        self._db_ip = ip
+        self.is_dirty = True
+    db_ip = property(__get_db_ip, __set_db_ip)
+    def db_add_ip(self, ip):
+        self._db_ip = ip
+    def db_change_ip(self, ip):
+        self._db_ip = ip
+    def db_delete_ip(self, ip):
+        self._db_ip = None
+    
+    def __get_db_session(self):
+        return self._db_session
+    def __set_db_session(self, session):
+        self._db_session = session
+        self.is_dirty = True
+    db_session = property(__get_db_session, __set_db_session)
+    def db_add_session(self, session):
+        self._db_session = session
+    def db_change_session(self, session):
+        self._db_session = session
+    def db_delete_session(self, session):
+        self._db_session = None
+    
+    def __get_db_vt_version(self):
+        return self._db_vt_version
+    def __set_db_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+        self.is_dirty = True
+    db_vt_version = property(__get_db_vt_version, __set_db_vt_version)
+    def db_add_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_change_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_delete_vt_version(self, vt_version):
+        self._db_vt_version = None
+    
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_parent_id(self):
+        return self._db_parent_id
+    def __set_db_parent_id(self, parent_id):
+        self._db_parent_id = parent_id
+        self.is_dirty = True
+    db_parent_id = property(__get_db_parent_id, __set_db_parent_id)
+    def db_add_parent_id(self, parent_id):
+        self._db_parent_id = parent_id
+    def db_change_parent_id(self, parent_id):
+        self._db_parent_id = parent_id
+    def db_delete_parent_id(self, parent_id):
+        self._db_parent_id = None
     
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_parent_type(self):
+        return self._db_parent_type
+    def __set_db_parent_type(self, parent_type):
+        self._db_parent_type = parent_type
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
+    db_parent_type = property(__get_db_parent_type, __set_db_parent_type)
+    def db_add_parent_type(self, parent_type):
+        self._db_parent_type = parent_type
+    def db_change_parent_type(self, parent_type):
+        self._db_parent_type = parent_type
+    def db_delete_parent_type(self, parent_type):
+        self._db_parent_type = None
     
-    def __get_db_entity_type(self):
-        return self._db_entity_type
-    def __set_db_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
+    def __get_db_parent_version(self):
+        return self._db_parent_version
+    def __set_db_parent_version(self, parent_version):
+        self._db_parent_version = parent_version
         self.is_dirty = True
-    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
-    def db_add_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_change_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_delete_entity_type(self, entity_type):
-        self._db_entity_type = None
+    db_parent_version = property(__get_db_parent_version, __set_db_parent_version)
+    def db_add_parent_version(self, parent_version):
+        self._db_parent_version = parent_version
+    def db_change_parent_version(self, parent_version):
+        self._db_parent_version = parent_version
+    def db_delete_parent_version(self, parent_version):
+        self._db_parent_version = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
     
     def __get_db_name(self):
         return self._db_name
@@ -7935,74 +9689,6 @@ class DBWorkflow(object):
     def db_delete_name(self, name):
         self._db_name = None
     
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
-        self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
-    
-    def __get_db_last_modified(self):
-        return self._db_last_modified
-    def __set_db_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-        self.is_dirty = True
-    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
-    def db_add_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_change_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_delete_last_modified(self, last_modified):
-        self._db_last_modified = None
-    
-    def __get_db_connections(self):
-        return self._db_connections
-    def __set_db_connections(self, connections):
-        self._db_connections = connections
-        self.is_dirty = True
-    db_connections = property(__get_db_connections, __set_db_connections)
-    def db_get_connections(self):
-        return self._db_connections
-    def db_add_connection(self, connection):
-        self.is_dirty = True
-        self._db_connections.append(connection)
-        self.db_connections_id_index[connection.db_id] = connection
-    def db_change_connection(self, connection):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_connections)):
-            if self._db_connections[i].db_id == connection.db_id:
-                self._db_connections[i] = connection
-                found = True
-                break
-        if not found:
-            self._db_connections.append(connection)
-        self.db_connections_id_index[connection.db_id] = connection
-    def db_delete_connection(self, connection):
-        self.is_dirty = True
-        for i in xrange(len(self._db_connections)):
-            if self._db_connections[i].db_id == connection.db_id:
-                if not self._db_connections[i].is_new:
-                    self.db_deleted_connections.append(self._db_connections[i])
-                del self._db_connections[i]
-                break
-        del self.db_connections_id_index[connection.db_id]
-    def db_get_connection(self, key):
-        for i in xrange(len(self._db_connections)):
-            if self._db_connections[i].db_id == key:
-                return self._db_connections[i]
-        return None
-    def db_get_connection_by_id(self, key):
-        return self.db_connections_id_index[key]
-    def db_has_connection_with_id(self, key):
-        return key in self.db_connections_id_index
-    
     def __get_db_annotations(self):
         return self._db_annotations
     def __set_db_annotations(self, annotations):
@@ -8045,120 +9731,150 @@ class DBWorkflow(object):
     def db_has_annotation_with_id(self, key):
         return key in self.db_annotations_id_index
     
-    def __get_db_plugin_datas(self):
-        return self._db_plugin_datas
-    def __set_db_plugin_datas(self, plugin_datas):
-        self._db_plugin_datas = plugin_datas
-        self.is_dirty = True
-    db_plugin_datas = property(__get_db_plugin_datas, __set_db_plugin_datas)
-    def db_get_plugin_datas(self):
-        return self._db_plugin_datas
-    def db_add_plugin_data(self, plugin_data):
-        self.is_dirty = True
-        self._db_plugin_datas.append(plugin_data)
-        self.db_plugin_datas_id_index[plugin_data.db_id] = plugin_data
-    def db_change_plugin_data(self, plugin_data):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_plugin_datas)):
-            if self._db_plugin_datas[i].db_id == plugin_data.db_id:
-                self._db_plugin_datas[i] = plugin_data
-                found = True
-                break
-        if not found:
-            self._db_plugin_datas.append(plugin_data)
-        self.db_plugin_datas_id_index[plugin_data.db_id] = plugin_data
-    def db_delete_plugin_data(self, plugin_data):
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBLocation(object):
+
+    vtType = 'location'
+
+    def __init__(self, id=None, x=None, y=None):
+        self._db_id = id
+        self._db_x = x
+        self._db_y = y
         self.is_dirty = True
-        for i in xrange(len(self._db_plugin_datas)):
-            if self._db_plugin_datas[i].db_id == plugin_data.db_id:
-                if not self._db_plugin_datas[i].is_new:
-                    self.db_deleted_plugin_datas.append(self._db_plugin_datas[i])
-                del self._db_plugin_datas[i]
-                break
-        del self.db_plugin_datas_id_index[plugin_data.db_id]
-    def db_get_plugin_data(self, key):
-        for i in xrange(len(self._db_plugin_datas)):
-            if self._db_plugin_datas[i].db_id == key:
-                return self._db_plugin_datas[i]
-        return None
-    def db_get_plugin_data_by_id(self, key):
-        return self.db_plugin_datas_id_index[key]
-    def db_has_plugin_data_with_id(self, key):
-        return key in self.db_plugin_datas_id_index
+        self.is_new = True
     
-    def __get_db_others(self):
-        return self._db_others
-    def __set_db_others(self, others):
-        self._db_others = others
-        self.is_dirty = True
-    db_others = property(__get_db_others, __set_db_others)
-    def db_get_others(self):
-        return self._db_others
-    def db_add_other(self, other):
-        self.is_dirty = True
-        self._db_others.append(other)
-        self.db_others_id_index[other.db_id] = other
-    def db_change_other(self, other):
+    def __copy__(self):
+        return DBLocation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBLocation(id=self._db_id,
+                        x=self._db_x,
+                        y=self._db_y)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBLocation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'x' in class_dict:
+            res = class_dict['x'](old_obj, trans_dict)
+            new_obj.db_x = res
+        elif hasattr(old_obj, 'db_x') and old_obj.db_x is not None:
+            new_obj.db_x = old_obj.db_x
+        if 'y' in class_dict:
+            res = class_dict['y'](old_obj, trans_dict)
+            new_obj.db_y = res
+        elif hasattr(old_obj, 'db_y') and old_obj.db_y is not None:
+            new_obj.db_y = old_obj.db_y
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_others)):
-            if self._db_others[i].db_id == other.db_id:
-                self._db_others[i] = other
-                found = True
-                break
-        if not found:
-            self._db_others.append(other)
-        self.db_others_id_index[other.db_id] = other
-    def db_delete_other(self, other):
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_x(self):
+        return self._db_x
+    def __set_db_x(self, x):
+        self._db_x = x
         self.is_dirty = True
-        for i in xrange(len(self._db_others)):
-            if self._db_others[i].db_id == other.db_id:
-                if not self._db_others[i].is_new:
-                    self.db_deleted_others.append(self._db_others[i])
-                del self._db_others[i]
-                break
-        del self.db_others_id_index[other.db_id]
-    def db_get_other(self, key):
-        for i in xrange(len(self._db_others)):
-            if self._db_others[i].db_id == key:
-                return self._db_others[i]
-        return None
-    def db_get_other_by_id(self, key):
-        return self.db_others_id_index[key]
-    def db_has_other_with_id(self, key):
-        return key in self.db_others_id_index
+    db_x = property(__get_db_x, __set_db_x)
+    def db_add_x(self, x):
+        self._db_x = x
+    def db_change_x(self, x):
+        self._db_x = x
+    def db_delete_x(self, x):
+        self._db_x = None
     
-    def __get_db_vistrail_id(self):
-        return self._db_vistrail_id
-    def __set_db_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = vistrail_id
+    def __get_db_y(self):
+        return self._db_y
+    def __set_db_y(self, y):
+        self._db_y = y
         self.is_dirty = True
-    db_vistrail_id = property(__get_db_vistrail_id, __set_db_vistrail_id)
-    def db_add_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = vistrail_id
-    def db_change_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = vistrail_id
-    def db_delete_vistrail_id(self, vistrail_id):
-        self._db_vistrail_id = None
+    db_y = property(__get_db_y, __set_db_y)
+    def db_add_y(self, y):
+        self._db_y = y
+    def db_change_y(self, y):
+        self._db_y = y
+    def db_delete_y(self, y):
+        self._db_y = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmArtifactIdCause(object):
+class DBFunction(object):
 
-    vtType = 'opm_artifact_id_cause'
+    vtType = 'function'
 
-    def __init__(self, id=None):
+    def __init__(self, id=None, pos=None, name=None, parameters=None):
         self._db_id = id
+        self._db_pos = pos
+        self._db_name = name
+        self.db_deleted_parameters = []
+        self.db_parameters_id_index = {}
+        if parameters is None:
+            self._db_parameters = []
+        else:
+            self._db_parameters = parameters
+            for v in self._db_parameters:
+                self.db_parameters_id_index[v.db_id] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmArtifactIdCause.do_copy(self)
+        return DBFunction.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmArtifactIdCause(id=self._db_id)
+        cp = DBFunction(id=self._db_id,
+                        pos=self._db_pos,
+                        name=self._db_name)
+        if self._db_parameters is None:
+            cp._db_parameters = []
+        else:
+            cp._db_parameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameters]
         
         # set new ids
         if new_ids:
@@ -8168,10 +9884,9 @@ class DBOpmArtifactIdCause(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('opm_artifact', self._db_id) in id_remap:
-                cp._db_id = id_remap[('opm_artifact', self._db_id)]
         
         # recreate indices and set flags
+        cp.db_parameters_id_index = dict((v.db_id, v) for v in cp._db_parameters)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -8180,7 +9895,7 @@ class DBOpmArtifactIdCause(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmArtifactIdCause()
+            new_obj = DBFunction()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -8189,18 +9904,54 @@ class DBOpmArtifactIdCause(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'parameters' in class_dict:
+            res = class_dict['parameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_parameter(obj)
+        elif hasattr(old_obj, 'db_parameters') and old_obj.db_parameters is not None:
+            for obj in old_obj.db_parameters:
+                new_obj.db_add_parameter(DBParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_parameters') and hasattr(new_obj, 'db_deleted_parameters'):
+            for obj in old_obj.db_deleted_parameters:
+                n_obj = DBParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_parameters.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_parameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_parameter(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_parameters)
+        if remove:
+            self.db_deleted_parameters = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_parameters:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -8215,22 +9966,101 @@ class DBOpmArtifactIdCause(object):
     def db_delete_id(self, id):
         self._db_id = None
     
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
+        self.is_dirty = True
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_parameters(self):
+        return self._db_parameters
+    def __set_db_parameters(self, parameters):
+        self._db_parameters = parameters
+        self.is_dirty = True
+    db_parameters = property(__get_db_parameters, __set_db_parameters)
+    def db_get_parameters(self):
+        return self._db_parameters
+    def db_add_parameter(self, parameter):
+        self.is_dirty = True
+        self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_change_parameter(self, parameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                self._db_parameters[i] = parameter
+                found = True
+                break
+        if not found:
+            self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_delete_parameter(self, parameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                if not self._db_parameters[i].is_new:
+                    self.db_deleted_parameters.append(self._db_parameters[i])
+                del self._db_parameters[i]
+                break
+        del self.db_parameters_id_index[parameter.db_id]
+    def db_get_parameter(self, key):
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == key:
+                return self._db_parameters[i]
+        return None
+    def db_get_parameter_by_id(self, key):
+        return self.db_parameters_id_index[key]
+    def db_has_parameter_with_id(self, key):
+        return key in self.db_parameters_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBActionAnnotation(object):
 
-class DBRefProvEntity(object):
-
-    vtType = 'ref_prov_entity'
+    vtType = 'actionAnnotation'
 
-    def __init__(self, prov_ref=None):
-        self._db_prov_ref = prov_ref
+    def __init__(self, id=None, key=None, value=None, action_id=None, date=None, user=None):
+        self._db_id = id
+        self._db_key = key
+        self._db_value = value
+        self._db_action_id = action_id
+        self._db_date = date
+        self._db_user = user
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBRefProvEntity.do_copy(self)
+        return DBActionAnnotation.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBRefProvEntity(prov_ref=self._db_prov_ref)
+        cp = DBActionAnnotation(id=self._db_id,
+                                key=self._db_key,
+                                value=self._db_value,
+                                action_id=self._db_action_id,
+                                date=self._db_date,
+                                user=self._db_user)
         
         # set new ids
         if new_ids:
@@ -8240,8 +10070,8 @@ class DBRefProvEntity(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_prov_ref') and ('prov_entity', self._db_prov_ref) in id_remap:
-                cp._db_prov_ref = id_remap[('prov_entity', self._db_prov_ref)]
+            if hasattr(self, 'db_action_id') and ('action', self._db_action_id) in id_remap:
+                cp._db_action_id = id_remap[('action', self._db_action_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -8252,15 +10082,40 @@ class DBRefProvEntity(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBRefProvEntity()
+            new_obj = DBActionAnnotation()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_ref' in class_dict:
-            res = class_dict['prov_ref'](old_obj, trans_dict)
-            new_obj.db_prov_ref = res
-        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
-            new_obj.db_prov_ref = old_obj.db_prov_ref
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'action_id' in class_dict:
+            res = class_dict['action_id'](old_obj, trans_dict)
+            new_obj.db_action_id = res
+        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
+            new_obj.db_action_id = old_obj.db_action_id
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -8274,20 +10129,86 @@ class DBRefProvEntity(object):
         if self.is_dirty:
             return True
         return False
-    def __get_db_prov_ref(self):
-        return self._db_prov_ref
-    def __set_db_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
-    def db_add_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_change_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_delete_prov_ref(self, prov_ref):
-        self._db_prov_ref = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
+        self.is_dirty = True
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_action_id(self):
+        return self._db_action_id
+    def __set_db_action_id(self, action_id):
+        self._db_action_id = action_id
+        self.is_dirty = True
+    db_action_id = property(__get_db_action_id, __set_db_action_id)
+    def db_add_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_change_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_delete_action_id(self, action_id):
+        self._db_action_id = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
+        self.is_dirty = True
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
 class DBProvActivity(object):
 
@@ -8542,48 +10463,185 @@ class DBProvActivity(object):
     def db_delete_vt_error(self, vt_error):
         self._db_vt_error = None
     
-    def __get_db_is_part_of(self):
-        return self._db_is_part_of
-    def __set_db_is_part_of(self, is_part_of):
-        self._db_is_part_of = is_part_of
+    def __get_db_is_part_of(self):
+        return self._db_is_part_of
+    def __set_db_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+        self.is_dirty = True
+    db_is_part_of = property(__get_db_is_part_of, __set_db_is_part_of)
+    def db_add_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_change_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_delete_is_part_of(self, is_part_of):
+        if not self.is_new:
+            self.db_deleted_is_part_of.append(self._db_is_part_of)
+        self._db_is_part_of = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvUsage(object):
+
+    vtType = 'prov_usage'
+
+    def __init__(self, prov_activity=None, prov_entity=None, prov_role=None):
+        self.db_deleted_prov_activity = []
+        self._db_prov_activity = prov_activity
+        self.db_deleted_prov_entity = []
+        self._db_prov_entity = prov_entity
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvUsage.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvUsage(prov_role=self._db_prov_role)
+        if self._db_prov_activity is not None:
+            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_entity is not None:
+            cp._db_prov_entity = self._db_prov_entity.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvUsage()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_activity' in class_dict:
+            res = class_dict['prov_activity'](old_obj, trans_dict)
+            new_obj.db_prov_activity = res
+        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
+            obj = old_obj.db_prov_activity
+            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
+            for obj in old_obj.db_deleted_prov_activity:
+                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activity.append(n_obj)
+        if 'prov_entity' in class_dict:
+            res = class_dict['prov_entity'](old_obj, trans_dict)
+            new_obj.db_prov_entity = res
+        elif hasattr(old_obj, 'db_prov_entity') and old_obj.db_prov_entity is not None:
+            obj = old_obj.db_prov_entity
+            new_obj.db_add_prov_entity(DBRefProvEntity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_entity') and hasattr(new_obj, 'db_deleted_prov_entity'):
+            for obj in old_obj.db_deleted_prov_entity:
+                n_obj = DBRefProvEntity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_entity.append(n_obj)
+        if 'prov_role' in class_dict:
+            res = class_dict['prov_role'](old_obj, trans_dict)
+            new_obj.db_prov_role = res
+        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
+            new_obj.db_prov_role = old_obj.db_prov_role
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_prov_activity is not None:
+            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_activity = None
+        if self._db_prov_entity is not None:
+            children.extend(self._db_prov_entity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_entity = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_prov_activity)
+        children.extend(self.db_deleted_prov_entity)
+        if remove:
+            self.db_deleted_prov_activity = []
+            self.db_deleted_prov_entity = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
+            return True
+        if self._db_prov_entity is not None and self._db_prov_entity.has_changes():
+            return True
+        return False
+    def __get_db_prov_activity(self):
+        return self._db_prov_activity
+    def __set_db_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+        self.is_dirty = True
+    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
+    def db_add_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        if not self.is_new:
+            self.db_deleted_prov_activity.append(self._db_prov_activity)
+        self._db_prov_activity = None
+    
+    def __get_db_prov_entity(self):
+        return self._db_prov_entity
+    def __set_db_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+        self.is_dirty = True
+    db_prov_entity = property(__get_db_prov_entity, __set_db_prov_entity)
+    def db_add_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_change_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_delete_prov_entity(self, prov_entity):
+        if not self.is_new:
+            self.db_deleted_prov_entity.append(self._db_prov_entity)
+        self._db_prov_entity = None
+    
+    def __get_db_prov_role(self):
+        return self._db_prov_role
+    def __set_db_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
         self.is_dirty = True
-    db_is_part_of = property(__get_db_is_part_of, __set_db_is_part_of)
-    def db_add_is_part_of(self, is_part_of):
-        self._db_is_part_of = is_part_of
-    def db_change_is_part_of(self, is_part_of):
-        self._db_is_part_of = is_part_of
-    def db_delete_is_part_of(self, is_part_of):
-        if not self.is_new:
-            self.db_deleted_is_part_of.append(self._db_is_part_of)
-        self._db_is_part_of = None
+    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
+    def db_add_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_change_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_delete_prov_role(self, prov_role):
+        self._db_prov_role = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBMashupAction(object):
 
-    vtType = 'mashup_action'
+class DBOpmArtifactIdEffect(object):
 
-    def __init__(self, id=None, prevId=None, date=None, user=None, mashup=None):
+    vtType = 'opm_artifact_id_effect'
+
+    def __init__(self, id=None):
         self._db_id = id
-        self._db_prevId = prevId
-        self._db_date = date
-        self._db_user = user
-        self.db_deleted_mashup = []
-        self._db_mashup = mashup
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMashupAction.do_copy(self)
+        return DBOpmArtifactIdEffect.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMashupAction(id=self._db_id,
-                            prevId=self._db_prevId,
-                            date=self._db_date,
-                            user=self._db_user)
-        if self._db_mashup is not None:
-            cp._db_mashup = self._db_mashup.do_copy(new_ids, id_scope, id_remap)
+        cp = DBOpmArtifactIdEffect(id=self._db_id)
         
         # set new ids
         if new_ids:
@@ -8593,8 +10651,8 @@ class DBMashupAction(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_prevId') and ('mashup_action', self._db_prevId) in id_remap:
-                cp._db_prevId = id_remap[('mashup_action', self._db_prevId)]
+            if hasattr(self, 'db_id') and ('opm_artifact', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_artifact', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -8605,7 +10663,7 @@ class DBMashupAction(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBMashupAction()
+            new_obj = DBOpmArtifactIdEffect()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -8614,147 +10672,287 @@ class DBMashupAction(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'prevId' in class_dict:
-            res = class_dict['prevId'](old_obj, trans_dict)
-            new_obj.db_prevId = res
-        elif hasattr(old_obj, 'db_prevId') and old_obj.db_prevId is not None:
-            new_obj.db_prevId = old_obj.db_prevId
-        if 'date' in class_dict:
-            res = class_dict['date'](old_obj, trans_dict)
-            new_obj.db_date = res
-        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
-            new_obj.db_date = old_obj.db_date
-        if 'user' in class_dict:
-            res = class_dict['user'](old_obj, trans_dict)
-            new_obj.db_user = res
-        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
-            new_obj.db_user = old_obj.db_user
-        if 'mashup' in class_dict:
-            res = class_dict['mashup'](old_obj, trans_dict)
-            new_obj.db_mashup = res
-        elif hasattr(old_obj, 'db_mashup') and old_obj.db_mashup is not None:
-            obj = old_obj.db_mashup
-            new_obj.db_add_mashup(DBMashup.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_mashup') and hasattr(new_obj, 'db_deleted_mashup'):
-            for obj in old_obj.db_deleted_mashup:
-                n_obj = DBMashup.update_version(obj, trans_dict)
-                new_obj.db_deleted_mashup.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
         children = []
-        if self._db_mashup is not None:
-            children.extend(self._db_mashup.db_children((self.vtType, self.db_id), orphan, for_action))
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBOpmGraph(object):
+
+    vtType = 'opm_graph'
+
+    def __init__(self, accounts=None, processes=None, artifacts=None, agents=None, dependencies=None):
+        self.db_deleted_accounts = []
+        self._db_accounts = accounts
+        self.db_deleted_processes = []
+        self._db_processes = processes
+        self.db_deleted_artifacts = []
+        self._db_artifacts = artifacts
+        self.db_deleted_agents = []
+        self._db_agents = agents
+        self.db_deleted_dependencies = []
+        self._db_dependencies = dependencies
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmGraph.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmGraph()
+        if self._db_accounts is not None:
+            cp._db_accounts = self._db_accounts.do_copy(new_ids, id_scope, id_remap)
+        if self._db_processes is not None:
+            cp._db_processes = self._db_processes.do_copy(new_ids, id_scope, id_remap)
+        if self._db_artifacts is not None:
+            cp._db_artifacts = self._db_artifacts.do_copy(new_ids, id_scope, id_remap)
+        if self._db_agents is not None:
+            cp._db_agents = self._db_agents.do_copy(new_ids, id_scope, id_remap)
+        if self._db_dependencies is not None:
+            cp._db_dependencies = self._db_dependencies.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmGraph()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            new_obj.db_accounts = res
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            obj = old_obj.db_accounts
+            new_obj.db_add_accounts(DBOpmAccounts.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccounts.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'processes' in class_dict:
+            res = class_dict['processes'](old_obj, trans_dict)
+            new_obj.db_processes = res
+        elif hasattr(old_obj, 'db_processes') and old_obj.db_processes is not None:
+            obj = old_obj.db_processes
+            new_obj.db_add_processes(DBOpmProcesses.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_processes') and hasattr(new_obj, 'db_deleted_processes'):
+            for obj in old_obj.db_deleted_processes:
+                n_obj = DBOpmProcesses.update_version(obj, trans_dict)
+                new_obj.db_deleted_processes.append(n_obj)
+        if 'artifacts' in class_dict:
+            res = class_dict['artifacts'](old_obj, trans_dict)
+            new_obj.db_artifacts = res
+        elif hasattr(old_obj, 'db_artifacts') and old_obj.db_artifacts is not None:
+            obj = old_obj.db_artifacts
+            new_obj.db_add_artifacts(DBOpmArtifacts.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_artifacts') and hasattr(new_obj, 'db_deleted_artifacts'):
+            for obj in old_obj.db_deleted_artifacts:
+                n_obj = DBOpmArtifacts.update_version(obj, trans_dict)
+                new_obj.db_deleted_artifacts.append(n_obj)
+        if 'agents' in class_dict:
+            res = class_dict['agents'](old_obj, trans_dict)
+            new_obj.db_agents = res
+        elif hasattr(old_obj, 'db_agents') and old_obj.db_agents is not None:
+            obj = old_obj.db_agents
+            new_obj.db_add_agents(DBOpmAgents.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_agents') and hasattr(new_obj, 'db_deleted_agents'):
+            for obj in old_obj.db_deleted_agents:
+                n_obj = DBOpmAgents.update_version(obj, trans_dict)
+                new_obj.db_deleted_agents.append(n_obj)
+        if 'dependencies' in class_dict:
+            res = class_dict['dependencies'](old_obj, trans_dict)
+            new_obj.db_dependencies = res
+        elif hasattr(old_obj, 'db_dependencies') and old_obj.db_dependencies is not None:
+            obj = old_obj.db_dependencies
+            new_obj.db_add_dependencies(DBOpmDependencies.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_dependencies') and hasattr(new_obj, 'db_deleted_dependencies'):
+            for obj in old_obj.db_deleted_dependencies:
+                n_obj = DBOpmDependencies.update_version(obj, trans_dict)
+                new_obj.db_deleted_dependencies.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_accounts is not None:
+            children.extend(self._db_accounts.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_mashup = None
+                self._db_accounts = None
+        if self._db_processes is not None:
+            children.extend(self._db_processes.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_processes = None
+        if self._db_artifacts is not None:
+            children.extend(self._db_artifacts.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_artifacts = None
+        if self._db_agents is not None:
+            children.extend(self._db_agents.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_agents = None
+        if self._db_dependencies is not None:
+            children.extend(self._db_dependencies.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_dependencies = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_mashup)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_processes)
+        children.extend(self.db_deleted_artifacts)
+        children.extend(self.db_deleted_agents)
+        children.extend(self.db_deleted_dependencies)
         if remove:
-            self.db_deleted_mashup = []
+            self.db_deleted_accounts = []
+            self.db_deleted_processes = []
+            self.db_deleted_artifacts = []
+            self.db_deleted_agents = []
+            self.db_deleted_dependencies = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_mashup is not None and self._db_mashup.has_changes():
+        if self._db_accounts is not None and self._db_accounts.has_changes():
+            return True
+        if self._db_processes is not None and self._db_processes.has_changes():
+            return True
+        if self._db_artifacts is not None and self._db_artifacts.has_changes():
+            return True
+        if self._db_agents is not None and self._db_agents.has_changes():
+            return True
+        if self._db_dependencies is not None and self._db_dependencies.has_changes():
             return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_add_accounts(self, accounts):
+        self._db_accounts = accounts
+    def db_change_accounts(self, accounts):
+        self._db_accounts = accounts
+    def db_delete_accounts(self, accounts):
+        if not self.is_new:
+            self.db_deleted_accounts.append(self._db_accounts)
+        self._db_accounts = None
     
-    def __get_db_prevId(self):
-        return self._db_prevId
-    def __set_db_prevId(self, prevId):
-        self._db_prevId = prevId
+    def __get_db_processes(self):
+        return self._db_processes
+    def __set_db_processes(self, processes):
+        self._db_processes = processes
         self.is_dirty = True
-    db_prevId = property(__get_db_prevId, __set_db_prevId)
-    def db_add_prevId(self, prevId):
-        self._db_prevId = prevId
-    def db_change_prevId(self, prevId):
-        self._db_prevId = prevId
-    def db_delete_prevId(self, prevId):
-        self._db_prevId = None
+    db_processes = property(__get_db_processes, __set_db_processes)
+    def db_add_processes(self, processes):
+        self._db_processes = processes
+    def db_change_processes(self, processes):
+        self._db_processes = processes
+    def db_delete_processes(self, processes):
+        if not self.is_new:
+            self.db_deleted_processes.append(self._db_processes)
+        self._db_processes = None
     
-    def __get_db_date(self):
-        return self._db_date
-    def __set_db_date(self, date):
-        self._db_date = date
+    def __get_db_artifacts(self):
+        return self._db_artifacts
+    def __set_db_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
         self.is_dirty = True
-    db_date = property(__get_db_date, __set_db_date)
-    def db_add_date(self, date):
-        self._db_date = date
-    def db_change_date(self, date):
-        self._db_date = date
-    def db_delete_date(self, date):
-        self._db_date = None
+    db_artifacts = property(__get_db_artifacts, __set_db_artifacts)
+    def db_add_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+    def db_change_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+    def db_delete_artifacts(self, artifacts):
+        if not self.is_new:
+            self.db_deleted_artifacts.append(self._db_artifacts)
+        self._db_artifacts = None
     
-    def __get_db_user(self):
-        return self._db_user
-    def __set_db_user(self, user):
-        self._db_user = user
+    def __get_db_agents(self):
+        return self._db_agents
+    def __set_db_agents(self, agents):
+        self._db_agents = agents
         self.is_dirty = True
-    db_user = property(__get_db_user, __set_db_user)
-    def db_add_user(self, user):
-        self._db_user = user
-    def db_change_user(self, user):
-        self._db_user = user
-    def db_delete_user(self, user):
-        self._db_user = None
+    db_agents = property(__get_db_agents, __set_db_agents)
+    def db_add_agents(self, agents):
+        self._db_agents = agents
+    def db_change_agents(self, agents):
+        self._db_agents = agents
+    def db_delete_agents(self, agents):
+        if not self.is_new:
+            self.db_deleted_agents.append(self._db_agents)
+        self._db_agents = None
     
-    def __get_db_mashup(self):
-        return self._db_mashup
-    def __set_db_mashup(self, mashup):
-        self._db_mashup = mashup
+    def __get_db_dependencies(self):
+        return self._db_dependencies
+    def __set_db_dependencies(self, dependencies):
+        self._db_dependencies = dependencies
         self.is_dirty = True
-    db_mashup = property(__get_db_mashup, __set_db_mashup)
-    def db_add_mashup(self, mashup):
-        self._db_mashup = mashup
-    def db_change_mashup(self, mashup):
-        self._db_mashup = mashup
-    def db_delete_mashup(self, mashup):
+    db_dependencies = property(__get_db_dependencies, __set_db_dependencies)
+    def db_add_dependencies(self, dependencies):
+        self._db_dependencies = dependencies
+    def db_change_dependencies(self, dependencies):
+        self._db_dependencies = dependencies
+    def db_delete_dependencies(self, dependencies):
         if not self.is_new:
-            self.db_deleted_mashup.append(self._db_mashup)
-        self._db_mashup = None
+            self.db_deleted_dependencies.append(self._db_dependencies)
+        self._db_dependencies = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBProvUsage(object):
 
-    vtType = 'prov_usage'
+class DBIsPartOf(object):
 
-    def __init__(self, prov_activity=None, prov_entity=None, prov_role=None):
-        self.db_deleted_prov_activity = []
-        self._db_prov_activity = prov_activity
-        self.db_deleted_prov_entity = []
-        self._db_prov_entity = prov_entity
-        self._db_prov_role = prov_role
+    vtType = 'is_part_of'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBProvUsage.do_copy(self)
+        return DBIsPartOf.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBProvUsage(prov_role=self._db_prov_role)
-        if self._db_prov_activity is not None:
-            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
-        if self._db_prov_entity is not None:
-            cp._db_prov_entity = self._db_prov_entity.do_copy(new_ids, id_scope, id_remap)
+        cp = DBIsPartOf(prov_ref=self._db_prov_ref)
         
         # set new ids
         if new_ids:
@@ -8774,129 +10972,86 @@ class DBProvUsage(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBProvUsage()
+            new_obj = DBIsPartOf()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_activity' in class_dict:
-            res = class_dict['prov_activity'](old_obj, trans_dict)
-            new_obj.db_prov_activity = res
-        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
-            obj = old_obj.db_prov_activity
-            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
-            for obj in old_obj.db_deleted_prov_activity:
-                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_activity.append(n_obj)
-        if 'prov_entity' in class_dict:
-            res = class_dict['prov_entity'](old_obj, trans_dict)
-            new_obj.db_prov_entity = res
-        elif hasattr(old_obj, 'db_prov_entity') and old_obj.db_prov_entity is not None:
-            obj = old_obj.db_prov_entity
-            new_obj.db_add_prov_entity(DBRefProvEntity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_entity') and hasattr(new_obj, 'db_deleted_prov_entity'):
-            for obj in old_obj.db_deleted_prov_entity:
-                n_obj = DBRefProvEntity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_entity.append(n_obj)
-        if 'prov_role' in class_dict:
-            res = class_dict['prov_role'](old_obj, trans_dict)
-            new_obj.db_prov_role = res
-        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
-            new_obj.db_prov_role = old_obj.db_prov_role
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_prov_activity is not None:
-            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_prov_activity = None
-        if self._db_prov_entity is not None:
-            children.extend(self._db_prov_entity.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_prov_entity = None
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_prov_activity)
-        children.extend(self.db_deleted_prov_entity)
-        if remove:
-            self.db_deleted_prov_activity = []
-            self.db_deleted_prov_entity = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
-            return True
-        if self._db_prov_entity is not None and self._db_prov_entity.has_changes():
-            return True
         return False
-    def __get_db_prov_activity(self):
-        return self._db_prov_activity
-    def __set_db_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-        self.is_dirty = True
-    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
-    def db_add_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-    def db_change_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-    def db_delete_prov_activity(self, prov_activity):
-        if not self.is_new:
-            self.db_deleted_prov_activity.append(self._db_prov_activity)
-        self._db_prov_activity = None
-    
-    def __get_db_prov_entity(self):
-        return self._db_prov_entity
-    def __set_db_prov_entity(self, prov_entity):
-        self._db_prov_entity = prov_entity
-        self.is_dirty = True
-    db_prov_entity = property(__get_db_prov_entity, __set_db_prov_entity)
-    def db_add_prov_entity(self, prov_entity):
-        self._db_prov_entity = prov_entity
-    def db_change_prov_entity(self, prov_entity):
-        self._db_prov_entity = prov_entity
-    def db_delete_prov_entity(self, prov_entity):
-        if not self.is_new:
-            self.db_deleted_prov_entity.append(self._db_prov_entity)
-        self._db_prov_entity = None
-    
-    def __get_db_prov_role(self):
-        return self._db_prov_role
-    def __set_db_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
         self.is_dirty = True
-    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
-    def db_add_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
-    def db_change_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
-    def db_delete_prov_role(self, prov_role):
-        self._db_prov_role = None
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
     
 
 
-class DBOpmArtifactValue(object):
-
-    vtType = 'opm_artifact_value'
+class DBOpmWasDerivedFrom(object):
 
-    def __init__(self, value=None):
-        self.db_deleted_value = []
-        self._db_value = value
+    vtType = 'opm_was_derived_from'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmArtifactValue.do_copy(self)
+        return DBOpmWasDerivedFrom.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmArtifactValue()
-        if self._db_value is not None:
-            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        cp = DBOpmWasDerivedFrom()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
         
         # set new ids
         if new_ids:
@@ -8916,82 +11071,229 @@ class DBOpmArtifactValue(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmArtifactValue()
+            new_obj = DBOpmWasDerivedFrom()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            obj = old_obj.db_value
-            if obj.vtType == 'portSpec':
-                new_obj.db_add_value(DBPortSpec.update_version(obj, trans_dict))
-            elif obj.vtType == 'function':
-                new_obj.db_add_value(DBFunction.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
-            for obj in old_obj.db_deleted_value:
-                if obj.vtType == 'portSpec':
-                    n_obj = DBPortSpec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_value.append(n_obj)
-                elif obj.vtType == 'function':
-                    n_obj = DBFunction.update_version(obj, trans_dict)
-                    new_obj.db_deleted_value.append(n_obj)
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmArtifactIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmArtifactIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmArtifactIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmArtifactIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_value is not None:
-            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_value = None
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_value)
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
         if remove:
-            self.db_deleted_value = []
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_value is not None and self._db_value.has_changes():
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
             return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
         if not self.is_new:
-            self.db_deleted_value.append(self._db_value)
-        self._db_value = None
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
+        self.is_dirty = True
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
     
 
 
-class DBOpmArtifactIdEffect(object):
+class DBPluginData(object):
 
-    vtType = 'opm_artifact_id_effect'
+    vtType = 'plugin_data'
 
-    def __init__(self, id=None):
+    def __init__(self, id=None, data=None):
         self._db_id = id
+        self._db_data = data
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmArtifactIdEffect.do_copy(self)
+        return DBPluginData.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmArtifactIdEffect(id=self._db_id)
+        cp = DBPluginData(id=self._db_id,
+                          data=self._db_data)
         
         # set new ids
         if new_ids:
@@ -9001,8 +11303,6 @@ class DBOpmArtifactIdEffect(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('opm_artifact', self._db_id) in id_remap:
-                cp._db_id = id_remap[('opm_artifact', self._db_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -9013,7 +11313,7 @@ class DBOpmArtifactIdEffect(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmArtifactIdEffect()
+            new_obj = DBPluginData()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -9022,6 +11322,11 @@ class DBOpmArtifactIdEffect(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
+        if 'data' in class_dict:
+            res = class_dict['data'](old_obj, trans_dict)
+            new_obj.db_data = res
+        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
+            new_obj.db_data = old_obj.db_data
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -9048,41 +11353,44 @@ class DBOpmArtifactIdEffect(object):
     def db_delete_id(self, id):
         self._db_id = None
     
+    def __get_db_data(self):
+        return self._db_data
+    def __set_db_data(self, data):
+        self._db_data = data
+        self.is_dirty = True
+    db_data = property(__get_db_data, __set_db_data)
+    def db_add_data(self, data):
+        self._db_data = data
+    def db_change_data(self, data):
+        self._db_data = data
+    def db_delete_data(self, data):
+        self._db_data = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBDelete(object):
 
-class DBOpmGraph(object):
-
-    vtType = 'opm_graph'
+    vtType = 'delete'
 
-    def __init__(self, accounts=None, processes=None, artifacts=None, agents=None, dependencies=None):
-        self.db_deleted_accounts = []
-        self._db_accounts = accounts
-        self.db_deleted_processes = []
-        self._db_processes = processes
-        self.db_deleted_artifacts = []
-        self._db_artifacts = artifacts
-        self.db_deleted_agents = []
-        self._db_agents = agents
-        self.db_deleted_dependencies = []
-        self._db_dependencies = dependencies
+    def __init__(self, id=None, what=None, objectId=None, parentObjId=None, parentObjType=None):
+        self._db_id = id
+        self._db_what = what
+        self._db_objectId = objectId
+        self._db_parentObjId = parentObjId
+        self._db_parentObjType = parentObjType
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmGraph.do_copy(self)
+        return DBDelete.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmGraph()
-        if self._db_accounts is not None:
-            cp._db_accounts = self._db_accounts.do_copy(new_ids, id_scope, id_remap)
-        if self._db_processes is not None:
-            cp._db_processes = self._db_processes.do_copy(new_ids, id_scope, id_remap)
-        if self._db_artifacts is not None:
-            cp._db_artifacts = self._db_artifacts.do_copy(new_ids, id_scope, id_remap)
-        if self._db_agents is not None:
-            cp._db_agents = self._db_agents.do_copy(new_ids, id_scope, id_remap)
-        if self._db_dependencies is not None:
-            cp._db_dependencies = self._db_dependencies.do_copy(new_ids, id_scope, id_remap)
+        cp = DBDelete(id=self._db_id,
+                      what=self._db_what,
+                      objectId=self._db_objectId,
+                      parentObjId=self._db_parentObjId,
+                      parentObjType=self._db_parentObjType)
         
         # set new ids
         if new_ids:
@@ -9092,6 +11400,10 @@ class DBOpmGraph(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_objectId') and (self._db_what, self._db_objectId) in id_remap:
+                cp._db_objectId = id_remap[(self._db_what, self._db_objectId)]
+            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
+                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -9102,257 +11414,140 @@ class DBOpmGraph(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmGraph()
+            new_obj = DBDelete()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            new_obj.db_accounts = res
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            obj = old_obj.db_accounts
-            new_obj.db_add_accounts(DBOpmAccounts.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccounts.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
-        if 'processes' in class_dict:
-            res = class_dict['processes'](old_obj, trans_dict)
-            new_obj.db_processes = res
-        elif hasattr(old_obj, 'db_processes') and old_obj.db_processes is not None:
-            obj = old_obj.db_processes
-            new_obj.db_add_processes(DBOpmProcesses.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_processes') and hasattr(new_obj, 'db_deleted_processes'):
-            for obj in old_obj.db_deleted_processes:
-                n_obj = DBOpmProcesses.update_version(obj, trans_dict)
-                new_obj.db_deleted_processes.append(n_obj)
-        if 'artifacts' in class_dict:
-            res = class_dict['artifacts'](old_obj, trans_dict)
-            new_obj.db_artifacts = res
-        elif hasattr(old_obj, 'db_artifacts') and old_obj.db_artifacts is not None:
-            obj = old_obj.db_artifacts
-            new_obj.db_add_artifacts(DBOpmArtifacts.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_artifacts') and hasattr(new_obj, 'db_deleted_artifacts'):
-            for obj in old_obj.db_deleted_artifacts:
-                n_obj = DBOpmArtifacts.update_version(obj, trans_dict)
-                new_obj.db_deleted_artifacts.append(n_obj)
-        if 'agents' in class_dict:
-            res = class_dict['agents'](old_obj, trans_dict)
-            new_obj.db_agents = res
-        elif hasattr(old_obj, 'db_agents') and old_obj.db_agents is not None:
-            obj = old_obj.db_agents
-            new_obj.db_add_agents(DBOpmAgents.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_agents') and hasattr(new_obj, 'db_deleted_agents'):
-            for obj in old_obj.db_deleted_agents:
-                n_obj = DBOpmAgents.update_version(obj, trans_dict)
-                new_obj.db_deleted_agents.append(n_obj)
-        if 'dependencies' in class_dict:
-            res = class_dict['dependencies'](old_obj, trans_dict)
-            new_obj.db_dependencies = res
-        elif hasattr(old_obj, 'db_dependencies') and old_obj.db_dependencies is not None:
-            obj = old_obj.db_dependencies
-            new_obj.db_add_dependencies(DBOpmDependencies.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_dependencies') and hasattr(new_obj, 'db_deleted_dependencies'):
-            for obj in old_obj.db_deleted_dependencies:
-                n_obj = DBOpmDependencies.update_version(obj, trans_dict)
-                new_obj.db_deleted_dependencies.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'what' in class_dict:
+            res = class_dict['what'](old_obj, trans_dict)
+            new_obj.db_what = res
+        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
+            new_obj.db_what = old_obj.db_what
+        if 'objectId' in class_dict:
+            res = class_dict['objectId'](old_obj, trans_dict)
+            new_obj.db_objectId = res
+        elif hasattr(old_obj, 'db_objectId') and old_obj.db_objectId is not None:
+            new_obj.db_objectId = old_obj.db_objectId
+        if 'parentObjId' in class_dict:
+            res = class_dict['parentObjId'](old_obj, trans_dict)
+            new_obj.db_parentObjId = res
+        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
+            new_obj.db_parentObjId = old_obj.db_parentObjId
+        if 'parentObjType' in class_dict:
+            res = class_dict['parentObjType'](old_obj, trans_dict)
+            new_obj.db_parentObjType = res
+        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
+            new_obj.db_parentObjType = old_obj.db_parentObjType
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_accounts is not None:
-            children.extend(self._db_accounts.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_accounts = None
-        if self._db_processes is not None:
-            children.extend(self._db_processes.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_processes = None
-        if self._db_artifacts is not None:
-            children.extend(self._db_artifacts.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_artifacts = None
-        if self._db_agents is not None:
-            children.extend(self._db_agents.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_agents = None
-        if self._db_dependencies is not None:
-            children.extend(self._db_dependencies.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_dependencies = None
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_processes)
-        children.extend(self.db_deleted_artifacts)
-        children.extend(self.db_deleted_agents)
-        children.extend(self.db_deleted_dependencies)
-        if remove:
-            self.db_deleted_accounts = []
-            self.db_deleted_processes = []
-            self.db_deleted_artifacts = []
-            self.db_deleted_agents = []
-            self.db_deleted_dependencies = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_accounts is not None and self._db_accounts.has_changes():
-            return True
-        if self._db_processes is not None and self._db_processes.has_changes():
-            return True
-        if self._db_artifacts is not None and self._db_artifacts.has_changes():
-            return True
-        if self._db_agents is not None and self._db_agents.has_changes():
-            return True
-        if self._db_dependencies is not None and self._db_dependencies.has_changes():
-            return True
         return False
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_add_accounts(self, accounts):
-        self._db_accounts = accounts
-    def db_change_accounts(self, accounts):
-        self._db_accounts = accounts
-    def db_delete_accounts(self, accounts):
-        if not self.is_new:
-            self.db_deleted_accounts.append(self._db_accounts)
-        self._db_accounts = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_processes(self):
-        return self._db_processes
-    def __set_db_processes(self, processes):
-        self._db_processes = processes
+    def __get_db_what(self):
+        return self._db_what
+    def __set_db_what(self, what):
+        self._db_what = what
         self.is_dirty = True
-    db_processes = property(__get_db_processes, __set_db_processes)
-    def db_add_processes(self, processes):
-        self._db_processes = processes
-    def db_change_processes(self, processes):
-        self._db_processes = processes
-    def db_delete_processes(self, processes):
-        if not self.is_new:
-            self.db_deleted_processes.append(self._db_processes)
-        self._db_processes = None
+    db_what = property(__get_db_what, __set_db_what)
+    def db_add_what(self, what):
+        self._db_what = what
+    def db_change_what(self, what):
+        self._db_what = what
+    def db_delete_what(self, what):
+        self._db_what = None
     
-    def __get_db_artifacts(self):
-        return self._db_artifacts
-    def __set_db_artifacts(self, artifacts):
-        self._db_artifacts = artifacts
+    def __get_db_objectId(self):
+        return self._db_objectId
+    def __set_db_objectId(self, objectId):
+        self._db_objectId = objectId
         self.is_dirty = True
-    db_artifacts = property(__get_db_artifacts, __set_db_artifacts)
-    def db_add_artifacts(self, artifacts):
-        self._db_artifacts = artifacts
-    def db_change_artifacts(self, artifacts):
-        self._db_artifacts = artifacts
-    def db_delete_artifacts(self, artifacts):
-        if not self.is_new:
-            self.db_deleted_artifacts.append(self._db_artifacts)
-        self._db_artifacts = None
+    db_objectId = property(__get_db_objectId, __set_db_objectId)
+    def db_add_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_change_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_delete_objectId(self, objectId):
+        self._db_objectId = None
     
-    def __get_db_agents(self):
-        return self._db_agents
-    def __set_db_agents(self, agents):
-        self._db_agents = agents
+    def __get_db_parentObjId(self):
+        return self._db_parentObjId
+    def __set_db_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
         self.is_dirty = True
-    db_agents = property(__get_db_agents, __set_db_agents)
-    def db_add_agents(self, agents):
-        self._db_agents = agents
-    def db_change_agents(self, agents):
-        self._db_agents = agents
-    def db_delete_agents(self, agents):
-        if not self.is_new:
-            self.db_deleted_agents.append(self._db_agents)
-        self._db_agents = None
+    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
+    def db_add_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_change_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_delete_parentObjId(self, parentObjId):
+        self._db_parentObjId = None
     
-    def __get_db_dependencies(self):
-        return self._db_dependencies
-    def __set_db_dependencies(self, dependencies):
-        self._db_dependencies = dependencies
+    def __get_db_parentObjType(self):
+        return self._db_parentObjType
+    def __set_db_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
         self.is_dirty = True
-    db_dependencies = property(__get_db_dependencies, __set_db_dependencies)
-    def db_add_dependencies(self, dependencies):
-        self._db_dependencies = dependencies
-    def db_change_dependencies(self, dependencies):
-        self._db_dependencies = dependencies
-    def db_delete_dependencies(self, dependencies):
-        if not self.is_new:
-            self.db_deleted_dependencies.append(self._db_dependencies)
-        self._db_dependencies = None
+    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
+    def db_add_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_change_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_delete_parentObjType(self, parentObjType):
+        self._db_parentObjType = None
     
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBVistrailVariable(object):
 
-class DBMashuptrail(object):
-
-    vtType = 'mashuptrail'
+    vtType = 'vistrailVariable'
 
-    def __init__(self, id=None, name=None, version=None, vtVersion=None, last_modified=None, actions=None, annotations=None, actionAnnotations=None):
-        self._db_id = id
+    def __init__(self, name=None, uuid=None, package=None, module=None, namespace=None, value=None):
         self._db_name = name
-        self._db_version = version
-        self._db_vtVersion = vtVersion
-        self._db_last_modified = last_modified
-        self.db_deleted_actions = []
-        self.db_actions_id_index = {}
-        if actions is None:
-            self._db_actions = []
-        else:
-            self._db_actions = actions
-            for v in self._db_actions:
-                self.db_actions_id_index[v.db_id] = v
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        self.db_annotations_key_index = {}
-        if annotations is None:
-            self._db_annotations = []
-        else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
-                self.db_annotations_key_index[v.db_key] = v
-        self.db_deleted_actionAnnotations = []
-        self.db_actionAnnotations_id_index = {}
-        self.db_actionAnnotations_action_id_index = {}
-        self.db_actionAnnotations_key_index = {}
-        if actionAnnotations is None:
-            self._db_actionAnnotations = []
-        else:
-            self._db_actionAnnotations = actionAnnotations
-            for v in self._db_actionAnnotations:
-                self.db_actionAnnotations_id_index[v.db_id] = v
-                self.db_actionAnnotations_action_id_index[(v.db_action_id,v.db_key)] = v
-                self.db_actionAnnotations_key_index[(v.db_key,v.db_value)] = v
+        self._db_uuid = uuid
+        self._db_package = package
+        self._db_module = module
+        self._db_namespace = namespace
+        self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMashuptrail.do_copy(self)
+        return DBVistrailVariable.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMashuptrail(id=self._db_id,
-                           name=self._db_name,
-                           version=self._db_version,
-                           vtVersion=self._db_vtVersion,
-                           last_modified=self._db_last_modified)
-        if self._db_actions is None:
-            cp._db_actions = []
-        else:
-            cp._db_actions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actions]
-        if self._db_annotations is None:
-            cp._db_annotations = []
-        else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
-        if self._db_actionAnnotations is None:
-            cp._db_actionAnnotations = []
-        else:
-            cp._db_actionAnnotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actionAnnotations]
+        cp = DBVistrailVariable(name=self._db_name,
+                                uuid=self._db_uuid,
+                                package=self._db_package,
+                                module=self._db_module,
+                                namespace=self._db_namespace,
+                                value=self._db_value)
         
         # set new ids
         if new_ids:
@@ -9364,12 +11559,6 @@ class DBMashuptrail(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_actions_id_index = dict((v.db_id, v) for v in cp._db_actions)
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
-        cp.db_actionAnnotations_id_index = dict((v.db_id, v) for v in cp._db_actionAnnotations)
-        cp.db_actionAnnotations_action_id_index = dict(((v.db_action_id,v.db_key), v) for v in cp._db_actionAnnotations)
-        cp.db_actionAnnotations_key_index = dict(((v.db_key,v.db_value), v) for v in cp._db_actionAnnotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -9378,133 +11567,53 @@ class DBMashuptrail(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBMashuptrail()
+            new_obj = DBVistrailVariable()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'vtVersion' in class_dict:
-            res = class_dict['vtVersion'](old_obj, trans_dict)
-            new_obj.db_vtVersion = res
-        elif hasattr(old_obj, 'db_vtVersion') and old_obj.db_vtVersion is not None:
-            new_obj.db_vtVersion = old_obj.db_vtVersion
-        if 'last_modified' in class_dict:
-            res = class_dict['last_modified'](old_obj, trans_dict)
-            new_obj.db_last_modified = res
-        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
-            new_obj.db_last_modified = old_obj.db_last_modified
-        if 'actions' in class_dict:
-            res = class_dict['actions'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_action(obj)
-        elif hasattr(old_obj, 'db_actions') and old_obj.db_actions is not None:
-            for obj in old_obj.db_actions:
-                new_obj.db_add_action(DBMashupAction.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_actions') and hasattr(new_obj, 'db_deleted_actions'):
-            for obj in old_obj.db_deleted_actions:
-                n_obj = DBMashupAction.update_version(obj, trans_dict)
-                new_obj.db_deleted_actions.append(n_obj)
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
-        if 'actionAnnotations' in class_dict:
-            res = class_dict['actionAnnotations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_actionAnnotation(obj)
-        elif hasattr(old_obj, 'db_actionAnnotations') and old_obj.db_actionAnnotations is not None:
-            for obj in old_obj.db_actionAnnotations:
-                new_obj.db_add_actionAnnotation(DBMashupActionAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_actionAnnotations') and hasattr(new_obj, 'db_deleted_actionAnnotations'):
-            for obj in old_obj.db_deleted_actionAnnotations:
-                n_obj = DBMashupActionAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_actionAnnotations.append(n_obj)
+        if 'uuid' in class_dict:
+            res = class_dict['uuid'](old_obj, trans_dict)
+            new_obj.db_uuid = res
+        elif hasattr(old_obj, 'db_uuid') and old_obj.db_uuid is not None:
+            new_obj.db_uuid = old_obj.db_uuid
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'module' in class_dict:
+            res = class_dict['module'](old_obj, trans_dict)
+            new_obj.db_module = res
+        elif hasattr(old_obj, 'db_module') and old_obj.db_module is not None:
+            new_obj.db_module = old_obj.db_module
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_actions:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_action(child)
-        to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        to_del = []
-        for child in self.db_actionAnnotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_actionAnnotation(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_actions)
-        children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_actionAnnotations)
-        if remove:
-            self.db_deleted_actions = []
-            self.db_deleted_annotations = []
-            self.db_deleted_actionAnnotations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_actions:
-            if child.has_changes():
-                return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
-        for child in self._db_actionAnnotations:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
     def __get_db_name(self):
         return self._db_name
     def __set_db_name(self, name):
@@ -9518,236 +11627,96 @@ class DBMashuptrail(object):
     def db_delete_name(self, name):
         self._db_name = None
     
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
-        self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
-    
-    def __get_db_vtVersion(self):
-        return self._db_vtVersion
-    def __set_db_vtVersion(self, vtVersion):
-        self._db_vtVersion = vtVersion
+    def __get_db_uuid(self):
+        return self._db_uuid
+    def __set_db_uuid(self, uuid):
+        self._db_uuid = uuid
         self.is_dirty = True
-    db_vtVersion = property(__get_db_vtVersion, __set_db_vtVersion)
-    def db_add_vtVersion(self, vtVersion):
-        self._db_vtVersion = vtVersion
-    def db_change_vtVersion(self, vtVersion):
-        self._db_vtVersion = vtVersion
-    def db_delete_vtVersion(self, vtVersion):
-        self._db_vtVersion = None
+    db_uuid = property(__get_db_uuid, __set_db_uuid)
+    def db_add_uuid(self, uuid):
+        self._db_uuid = uuid
+    def db_change_uuid(self, uuid):
+        self._db_uuid = uuid
+    def db_delete_uuid(self, uuid):
+        self._db_uuid = None
     
-    def __get_db_last_modified(self):
-        return self._db_last_modified
-    def __set_db_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
         self.is_dirty = True
-    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
-    def db_add_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_change_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_delete_last_modified(self, last_modified):
-        self._db_last_modified = None
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
     
-    def __get_db_actions(self):
-        return self._db_actions
-    def __set_db_actions(self, actions):
-        self._db_actions = actions
-        self.is_dirty = True
-    db_actions = property(__get_db_actions, __set_db_actions)
-    def db_get_actions(self):
-        return self._db_actions
-    def db_add_action(self, action):
-        self.is_dirty = True
-        self._db_actions.append(action)
-        self.db_actions_id_index[action.db_id] = action
-    def db_change_action(self, action):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_actions)):
-            if self._db_actions[i].db_id == action.db_id:
-                self._db_actions[i] = action
-                found = True
-                break
-        if not found:
-            self._db_actions.append(action)
-        self.db_actions_id_index[action.db_id] = action
-    def db_delete_action(self, action):
+    def __get_db_module(self):
+        return self._db_module
+    def __set_db_module(self, module):
+        self._db_module = module
         self.is_dirty = True
-        for i in xrange(len(self._db_actions)):
-            if self._db_actions[i].db_id == action.db_id:
-                if not self._db_actions[i].is_new:
-                    self.db_deleted_actions.append(self._db_actions[i])
-                del self._db_actions[i]
-                break
-        del self.db_actions_id_index[action.db_id]
-    def db_get_action(self, key):
-        for i in xrange(len(self._db_actions)):
-            if self._db_actions[i].db_id == key:
-                return self._db_actions[i]
-        return None
-    def db_get_action_by_id(self, key):
-        return self.db_actions_id_index[key]
-    def db_has_action_with_id(self, key):
-        return key in self.db_actions_id_index
+    db_module = property(__get_db_module, __set_db_module)
+    def db_add_module(self, module):
+        self._db_module = module
+    def db_change_module(self, module):
+        self._db_module = module
+    def db_delete_module(self, module):
+        self._db_module = None
     
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
-        self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
-        self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_change_annotation(self, annotation):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
-                found = True
-                break
-        if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_delete_annotation(self, annotation):
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
         self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
-                break
-        del self.db_annotations_id_index[annotation.db_id]
-        del self.db_annotations_key_index[annotation.db_key]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
-        return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
-    def db_get_annotation_by_key(self, key):
-        return self.db_annotations_key_index[key]
-    def db_has_annotation_with_key(self, key):
-        return key in self.db_annotations_key_index
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
     
-    def __get_db_actionAnnotations(self):
-        return self._db_actionAnnotations
-    def __set_db_actionAnnotations(self, actionAnnotations):
-        self._db_actionAnnotations = actionAnnotations
-        self.is_dirty = True
-    db_actionAnnotations = property(__get_db_actionAnnotations, __set_db_actionAnnotations)
-    def db_get_actionAnnotations(self):
-        return self._db_actionAnnotations
-    def db_add_actionAnnotation(self, actionAnnotation):
-        self.is_dirty = True
-        self._db_actionAnnotations.append(actionAnnotation)
-        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
-        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
-        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
-    def db_change_actionAnnotation(self, actionAnnotation):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_actionAnnotations)):
-            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
-                self._db_actionAnnotations[i] = actionAnnotation
-                found = True
-                break
-        if not found:
-            self._db_actionAnnotations.append(actionAnnotation)
-        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
-        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
-        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
-    def db_delete_actionAnnotation(self, actionAnnotation):
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-        for i in xrange(len(self._db_actionAnnotations)):
-            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
-                if not self._db_actionAnnotations[i].is_new:
-                    self.db_deleted_actionAnnotations.append(self._db_actionAnnotations[i])
-                del self._db_actionAnnotations[i]
-                break
-        del self.db_actionAnnotations_id_index[actionAnnotation.db_id]
-        del self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)]
-        try:
-            del self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)]
-        except KeyError:
-            pass
-    def db_get_actionAnnotation(self, key):
-        for i in xrange(len(self._db_actionAnnotations)):
-            if self._db_actionAnnotations[i].db_id == key:
-                return self._db_actionAnnotations[i]
-        return None
-    def db_get_actionAnnotation_by_id(self, key):
-        return self.db_actionAnnotations_id_index[key]
-    def db_has_actionAnnotation_with_id(self, key):
-        return key in self.db_actionAnnotations_id_index
-    def db_get_actionAnnotation_by_action_id(self, key):
-        return self.db_actionAnnotations_action_id_index[key]
-    def db_has_actionAnnotation_with_action_id(self, key):
-        return key in self.db_actionAnnotations_action_id_index
-    def db_get_actionAnnotation_by_key(self, key):
-        return self.db_actionAnnotations_key_index[key]
-    def db_has_actionAnnotation_with_key(self, key):
-        return key in self.db_actionAnnotations_key_index
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
     
     def getPrimaryKey(self):
-        return self._db_id
+        return self._db_name
 
-class DBRegistry(object):
+class DBOpmOverlaps(object):
 
-    vtType = 'registry'
+    vtType = 'opm_overlaps'
 
-    def __init__(self, id=None, entity_type=None, version=None, root_descriptor_id=None, name=None, last_modified=None, packages=None):
-        self._db_id = id
-        self._db_entity_type = entity_type
-        self._db_version = version
-        self._db_root_descriptor_id = root_descriptor_id
-        self._db_name = name
-        self._db_last_modified = last_modified
-        self.db_deleted_packages = []
-        self.db_packages_id_index = {}
-        self.db_packages_identifier_index = {}
-        if packages is None:
-            self._db_packages = []
+    def __init__(self, opm_account_ids=None):
+        self.db_deleted_opm_account_ids = []
+        if opm_account_ids is None:
+            self._db_opm_account_ids = []
         else:
-            self._db_packages = packages
-            for v in self._db_packages:
-                self.db_packages_id_index[v.db_id] = v
-                self.db_packages_identifier_index[(v.db_identifier,v.db_version)] = v
+            self._db_opm_account_ids = opm_account_ids
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBRegistry.do_copy(self)
+        return DBOpmOverlaps.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBRegistry(id=self._db_id,
-                        entity_type=self._db_entity_type,
-                        version=self._db_version,
-                        root_descriptor_id=self._db_root_descriptor_id,
-                        name=self._db_name,
-                        last_modified=self._db_last_modified)
-        if self._db_packages is None:
-            cp._db_packages = []
+        cp = DBOpmOverlaps()
+        if self._db_opm_account_ids is None:
+            cp._db_opm_account_ids = []
         else:
-            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
+            cp._db_opm_account_ids = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_account_ids]
         
         # set new ids
         if new_ids:
@@ -9757,12 +11726,8 @@ class DBRegistry(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_root_descriptor_id') and ('module_descriptor', self._db_root_descriptor_id) in id_remap:
-                cp._db_root_descriptor_id = id_remap[('module_descriptor', self._db_root_descriptor_id)]
         
         # recreate indices and set flags
-        cp.db_packages_id_index = dict((v.db_id, v) for v in cp._db_packages)
-        cp.db_packages_identifier_index = dict(((v.db_identifier,v.db_version), v) for v in cp._db_packages)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -9771,51 +11736,21 @@ class DBRegistry(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBRegistry()
+            new_obj = DBOpmOverlaps()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'entity_type' in class_dict:
-            res = class_dict['entity_type'](old_obj, trans_dict)
-            new_obj.db_entity_type = res
-        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
-            new_obj.db_entity_type = old_obj.db_entity_type
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'root_descriptor_id' in class_dict:
-            res = class_dict['root_descriptor_id'](old_obj, trans_dict)
-            new_obj.db_root_descriptor_id = res
-        elif hasattr(old_obj, 'db_root_descriptor_id') and old_obj.db_root_descriptor_id is not None:
-            new_obj.db_root_descriptor_id = old_obj.db_root_descriptor_id
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'last_modified' in class_dict:
-            res = class_dict['last_modified'](old_obj, trans_dict)
-            new_obj.db_last_modified = res
-        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
-            new_obj.db_last_modified = old_obj.db_last_modified
-        if 'packages' in class_dict:
-            res = class_dict['packages'](old_obj, trans_dict)
+        if 'opm_account_ids' in class_dict:
+            res = class_dict['opm_account_ids'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_package(obj)
-        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
-            for obj in old_obj.db_packages:
-                new_obj.db_add_package(DBPackage.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
-            for obj in old_obj.db_deleted_packages:
-                n_obj = DBPackage.update_version(obj, trans_dict)
-                new_obj.db_deleted_packages.append(n_obj)
+                new_obj.db_add_opm_account_id(obj)
+        elif hasattr(old_obj, 'db_opm_account_ids') and old_obj.db_opm_account_ids is not None:
+            for obj in old_obj.db_opm_account_ids:
+                new_obj.db_add_opm_account_id(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_account_ids') and hasattr(new_obj, 'db_deleted_opm_account_ids'):
+            for obj in old_obj.db_deleted_opm_account_ids:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_account_ids.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -9823,183 +11758,92 @@ class DBRegistry(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_packages:
+        for child in self.db_opm_account_ids:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_package(child)
+            self.db_delete_opm_account_id(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_packages)
+        children.extend(self.db_deleted_opm_account_ids)
         if remove:
-            self.db_deleted_packages = []
+            self.db_deleted_opm_account_ids = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_packages:
+        for child in self._db_opm_account_ids:
             if child.has_changes():
                 return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_entity_type(self):
-        return self._db_entity_type
-    def __set_db_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-        self.is_dirty = True
-    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
-    def db_add_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_change_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_delete_entity_type(self, entity_type):
-        self._db_entity_type = None
-    
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
-        self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
-    
-    def __get_db_root_descriptor_id(self):
-        return self._db_root_descriptor_id
-    def __set_db_root_descriptor_id(self, root_descriptor_id):
-        self._db_root_descriptor_id = root_descriptor_id
-        self.is_dirty = True
-    db_root_descriptor_id = property(__get_db_root_descriptor_id, __set_db_root_descriptor_id)
-    def db_add_root_descriptor_id(self, root_descriptor_id):
-        self._db_root_descriptor_id = root_descriptor_id
-    def db_change_root_descriptor_id(self, root_descriptor_id):
-        self._db_root_descriptor_id = root_descriptor_id
-    def db_delete_root_descriptor_id(self, root_descriptor_id):
-        self._db_root_descriptor_id = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_last_modified(self):
-        return self._db_last_modified
-    def __set_db_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-        self.is_dirty = True
-    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
-    def db_add_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_change_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_delete_last_modified(self, last_modified):
-        self._db_last_modified = None
-    
-    def __get_db_packages(self):
-        return self._db_packages
-    def __set_db_packages(self, packages):
-        self._db_packages = packages
+    def __get_db_opm_account_ids(self):
+        return self._db_opm_account_ids
+    def __set_db_opm_account_ids(self, opm_account_ids):
+        self._db_opm_account_ids = opm_account_ids
         self.is_dirty = True
-    db_packages = property(__get_db_packages, __set_db_packages)
-    def db_get_packages(self):
-        return self._db_packages
-    def db_add_package(self, package):
+    db_opm_account_ids = property(__get_db_opm_account_ids, __set_db_opm_account_ids)
+    def db_get_opm_account_ids(self):
+        return self._db_opm_account_ids
+    def db_add_opm_account_id(self, opm_account_id):
         self.is_dirty = True
-        self._db_packages.append(package)
-        self.db_packages_id_index[package.db_id] = package
-        self.db_packages_identifier_index[(package.db_identifier,package.db_version)] = package
-    def db_change_package(self, package):
+        self._db_opm_account_ids.append(opm_account_id)
+    def db_change_opm_account_id(self, opm_account_id):
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_packages)):
-            if self._db_packages[i].db_id == package.db_id:
-                self._db_packages[i] = package
-                found = True
-                break
-        if not found:
-            self._db_packages.append(package)
-        self.db_packages_id_index[package.db_id] = package
-        self.db_packages_identifier_index[(package.db_identifier,package.db_version)] = package
-    def db_delete_package(self, package):
+        self._db_opm_account_ids.append(opm_account_id)
+    def db_delete_opm_account_id(self, opm_account_id):
         self.is_dirty = True
-        for i in xrange(len(self._db_packages)):
-            if self._db_packages[i].db_id == package.db_id:
-                if not self._db_packages[i].is_new:
-                    self.db_deleted_packages.append(self._db_packages[i])
-                del self._db_packages[i]
-                break
-        del self.db_packages_id_index[package.db_id]
-        del self.db_packages_identifier_index[(package.db_identifier,package.db_version)]
-    def db_get_package(self, key):
-        for i in xrange(len(self._db_packages)):
-            if self._db_packages[i].db_id == key:
-                return self._db_packages[i]
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_account_id(self, key):
         return None
-    def db_get_package_by_id(self, key):
-        return self.db_packages_id_index[key]
-    def db_has_package_with_id(self, key):
-        return key in self.db_packages_id_index
-    def db_get_package_by_identifier(self, key):
-        return self.db_packages_identifier_index[key]
-    def db_has_package_with_identifier(self, key):
-        return key in self.db_packages_identifier_index
     
-    def getPrimaryKey(self):
-        return self._db_id
-
-class DBVtConnection(object):
 
-    vtType = 'vt_connection'
 
-    def __init__(self, id=None, vt_source=None, vt_dest=None, vt_source_port=None, vt_dest_port=None, vt_source_signature=None, vt_dest_signature=None):
-        self._db_id = id
-        self._db_vt_source = vt_source
-        self._db_vt_dest = vt_dest
-        self._db_vt_source_port = vt_source_port
-        self._db_vt_dest_port = vt_dest_port
-        self._db_vt_source_signature = vt_source_signature
-        self._db_vt_dest_signature = vt_dest_signature
+class DBOpmWasTriggeredBy(object):
+
+    vtType = 'opm_was_triggered_by'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBVtConnection.do_copy(self)
+        return DBOpmWasTriggeredBy.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBVtConnection(id=self._db_id,
-                            vt_source=self._db_vt_source,
-                            vt_dest=self._db_vt_dest,
-                            vt_source_port=self._db_vt_source_port,
-                            vt_dest_port=self._db_vt_dest_port,
-                            vt_source_signature=self._db_vt_source_signature,
-                            vt_dest_signature=self._db_vt_dest_signature)
+        cp = DBOpmWasTriggeredBy()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
         
         # set new ids
         if new_ids:
@@ -10019,198 +11863,253 @@ class DBVtConnection(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBVtConnection()
+            new_obj = DBOpmWasTriggeredBy()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'vt_source' in class_dict:
-            res = class_dict['vt_source'](old_obj, trans_dict)
-            new_obj.db_vt_source = res
-        elif hasattr(old_obj, 'db_vt_source') and old_obj.db_vt_source is not None:
-            new_obj.db_vt_source = old_obj.db_vt_source
-        if 'vt_dest' in class_dict:
-            res = class_dict['vt_dest'](old_obj, trans_dict)
-            new_obj.db_vt_dest = res
-        elif hasattr(old_obj, 'db_vt_dest') and old_obj.db_vt_dest is not None:
-            new_obj.db_vt_dest = old_obj.db_vt_dest
-        if 'vt_source_port' in class_dict:
-            res = class_dict['vt_source_port'](old_obj, trans_dict)
-            new_obj.db_vt_source_port = res
-        elif hasattr(old_obj, 'db_vt_source_port') and old_obj.db_vt_source_port is not None:
-            new_obj.db_vt_source_port = old_obj.db_vt_source_port
-        if 'vt_dest_port' in class_dict:
-            res = class_dict['vt_dest_port'](old_obj, trans_dict)
-            new_obj.db_vt_dest_port = res
-        elif hasattr(old_obj, 'db_vt_dest_port') and old_obj.db_vt_dest_port is not None:
-            new_obj.db_vt_dest_port = old_obj.db_vt_dest_port
-        if 'vt_source_signature' in class_dict:
-            res = class_dict['vt_source_signature'](old_obj, trans_dict)
-            new_obj.db_vt_source_signature = res
-        elif hasattr(old_obj, 'db_vt_source_signature') and old_obj.db_vt_source_signature is not None:
-            new_obj.db_vt_source_signature = old_obj.db_vt_source_signature
-        if 'vt_dest_signature' in class_dict:
-            res = class_dict['vt_dest_signature'](old_obj, trans_dict)
-            new_obj.db_vt_dest_signature = res
-        elif hasattr(old_obj, 'db_vt_dest_signature') and old_obj.db_vt_dest_signature is not None:
-            new_obj.db_vt_dest_signature = old_obj.db_vt_dest_signature
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmProcessIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmProcessIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
     
-    def __get_db_vt_source(self):
-        return self._db_vt_source
-    def __set_db_vt_source(self, vt_source):
-        self._db_vt_source = vt_source
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
         self.is_dirty = True
-    db_vt_source = property(__get_db_vt_source, __set_db_vt_source)
-    def db_add_vt_source(self, vt_source):
-        self._db_vt_source = vt_source
-    def db_change_vt_source(self, vt_source):
-        self._db_vt_source = vt_source
-    def db_delete_vt_source(self, vt_source):
-        self._db_vt_source = None
-    
-    def __get_db_vt_dest(self):
-        return self._db_vt_dest
-    def __set_db_vt_dest(self, vt_dest):
-        self._db_vt_dest = vt_dest
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
         self.is_dirty = True
-    db_vt_dest = property(__get_db_vt_dest, __set_db_vt_dest)
-    def db_add_vt_dest(self, vt_dest):
-        self._db_vt_dest = vt_dest
-    def db_change_vt_dest(self, vt_dest):
-        self._db_vt_dest = vt_dest
-    def db_delete_vt_dest(self, vt_dest):
-        self._db_vt_dest = None
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
     
-    def __get_db_vt_source_port(self):
-        return self._db_vt_source_port
-    def __set_db_vt_source_port(self, vt_source_port):
-        self._db_vt_source_port = vt_source_port
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
         self.is_dirty = True
-    db_vt_source_port = property(__get_db_vt_source_port, __set_db_vt_source_port)
-    def db_add_vt_source_port(self, vt_source_port):
-        self._db_vt_source_port = vt_source_port
-    def db_change_vt_source_port(self, vt_source_port):
-        self._db_vt_source_port = vt_source_port
-    def db_delete_vt_source_port(self, vt_source_port):
-        self._db_vt_source_port = None
-    
-    def __get_db_vt_dest_port(self):
-        return self._db_vt_dest_port
-    def __set_db_vt_dest_port(self, vt_dest_port):
-        self._db_vt_dest_port = vt_dest_port
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
         self.is_dirty = True
-    db_vt_dest_port = property(__get_db_vt_dest_port, __set_db_vt_dest_port)
-    def db_add_vt_dest_port(self, vt_dest_port):
-        self._db_vt_dest_port = vt_dest_port
-    def db_change_vt_dest_port(self, vt_dest_port):
-        self._db_vt_dest_port = vt_dest_port
-    def db_delete_vt_dest_port(self, vt_dest_port):
-        self._db_vt_dest_port = None
-    
-    def __get_db_vt_source_signature(self):
-        return self._db_vt_source_signature
-    def __set_db_vt_source_signature(self, vt_source_signature):
-        self._db_vt_source_signature = vt_source_signature
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
         self.is_dirty = True
-    db_vt_source_signature = property(__get_db_vt_source_signature, __set_db_vt_source_signature)
-    def db_add_vt_source_signature(self, vt_source_signature):
-        self._db_vt_source_signature = vt_source_signature
-    def db_change_vt_source_signature(self, vt_source_signature):
-        self._db_vt_source_signature = vt_source_signature
-    def db_delete_vt_source_signature(self, vt_source_signature):
-        self._db_vt_source_signature = None
-    
-    def __get_db_vt_dest_signature(self):
-        return self._db_vt_dest_signature
-    def __set_db_vt_dest_signature(self, vt_dest_signature):
-        self._db_vt_dest_signature = vt_dest_signature
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
         self.is_dirty = True
-    db_vt_dest_signature = property(__get_db_vt_dest_signature, __set_db_vt_dest_signature)
-    def db_add_vt_dest_signature(self, vt_dest_signature):
-        self._db_vt_dest_signature = vt_dest_signature
-    def db_change_vt_dest_signature(self, vt_dest_signature):
-        self._db_vt_dest_signature = vt_dest_signature
-    def db_delete_vt_dest_signature(self, vt_dest_signature):
-        self._db_vt_dest_signature = None
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBMashupComponent(object):
 
-    vtType = 'mashup_component'
+class DBModuleDescriptor(object):
 
-    def __init__(self, id=None, vtid=None, vttype=None, vtparent_type=None, vtparent_id=None, vtpos=None, vtmid=None, pos=None, type=None, val=None, minVal=None, maxVal=None, stepSize=None, strvaluelist=None, widget=None, seq=None, parent=None):
+    vtType = 'module_descriptor'
+
+    def __init__(self, id=None, name=None, package=None, namespace=None, package_version=None, version=None, base_descriptor_id=None, portSpecs=None):
         self._db_id = id
-        self._db_vtid = vtid
-        self._db_vttype = vttype
-        self._db_vtparent_type = vtparent_type
-        self._db_vtparent_id = vtparent_id
-        self._db_vtpos = vtpos
-        self._db_vtmid = vtmid
-        self._db_pos = pos
-        self._db_type = type
-        self._db_val = val
-        self._db_minVal = minVal
-        self._db_maxVal = maxVal
-        self._db_stepSize = stepSize
-        self._db_strvaluelist = strvaluelist
-        self._db_widget = widget
-        self._db_seq = seq
-        self._db_parent = parent
+        self._db_name = name
+        self._db_package = package
+        self._db_namespace = namespace
+        self._db_package_version = package_version
+        self._db_version = version
+        self._db_base_descriptor_id = base_descriptor_id
+        self.db_deleted_portSpecs = []
+        self.db_portSpecs_id_index = {}
+        self.db_portSpecs_name_index = {}
+        if portSpecs is None:
+            self._db_portSpecs = []
+        else:
+            self._db_portSpecs = portSpecs
+            for v in self._db_portSpecs:
+                self.db_portSpecs_id_index[v.db_id] = v
+                self.db_portSpecs_name_index[(v.db_name,v.db_type)] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMashupComponent.do_copy(self)
+        return DBModuleDescriptor.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMashupComponent(id=self._db_id,
-                               vtid=self._db_vtid,
-                               vttype=self._db_vttype,
-                               vtparent_type=self._db_vtparent_type,
-                               vtparent_id=self._db_vtparent_id,
-                               vtpos=self._db_vtpos,
-                               vtmid=self._db_vtmid,
-                               pos=self._db_pos,
-                               type=self._db_type,
-                               val=self._db_val,
-                               minVal=self._db_minVal,
-                               maxVal=self._db_maxVal,
-                               stepSize=self._db_stepSize,
-                               strvaluelist=self._db_strvaluelist,
-                               widget=self._db_widget,
-                               seq=self._db_seq,
-                               parent=self._db_parent)
+        cp = DBModuleDescriptor(id=self._db_id,
+                                name=self._db_name,
+                                package=self._db_package,
+                                namespace=self._db_namespace,
+                                package_version=self._db_package_version,
+                                version=self._db_version,
+                                base_descriptor_id=self._db_base_descriptor_id)
+        if self._db_portSpecs is None:
+            cp._db_portSpecs = []
+        else:
+            cp._db_portSpecs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecs]
         
         # set new ids
         if new_ids:
@@ -10220,117 +12119,97 @@ class DBMashupComponent(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_base_descriptor_id') and ('module_descriptor', self._db_base_descriptor_id) in id_remap:
+                cp._db_base_descriptor_id = id_remap[('module_descriptor', self._db_base_descriptor_id)]
         
         # recreate indices and set flags
+        cp.db_portSpecs_id_index = dict((v.db_id, v) for v in cp._db_portSpecs)
+        cp.db_portSpecs_name_index = dict(((v.db_name,v.db_type), v) for v in cp._db_portSpecs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBMashupComponent()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'vtid' in class_dict:
-            res = class_dict['vtid'](old_obj, trans_dict)
-            new_obj.db_vtid = res
-        elif hasattr(old_obj, 'db_vtid') and old_obj.db_vtid is not None:
-            new_obj.db_vtid = old_obj.db_vtid
-        if 'vttype' in class_dict:
-            res = class_dict['vttype'](old_obj, trans_dict)
-            new_obj.db_vttype = res
-        elif hasattr(old_obj, 'db_vttype') and old_obj.db_vttype is not None:
-            new_obj.db_vttype = old_obj.db_vttype
-        if 'vtparent_type' in class_dict:
-            res = class_dict['vtparent_type'](old_obj, trans_dict)
-            new_obj.db_vtparent_type = res
-        elif hasattr(old_obj, 'db_vtparent_type') and old_obj.db_vtparent_type is not None:
-            new_obj.db_vtparent_type = old_obj.db_vtparent_type
-        if 'vtparent_id' in class_dict:
-            res = class_dict['vtparent_id'](old_obj, trans_dict)
-            new_obj.db_vtparent_id = res
-        elif hasattr(old_obj, 'db_vtparent_id') and old_obj.db_vtparent_id is not None:
-            new_obj.db_vtparent_id = old_obj.db_vtparent_id
-        if 'vtpos' in class_dict:
-            res = class_dict['vtpos'](old_obj, trans_dict)
-            new_obj.db_vtpos = res
-        elif hasattr(old_obj, 'db_vtpos') and old_obj.db_vtpos is not None:
-            new_obj.db_vtpos = old_obj.db_vtpos
-        if 'vtmid' in class_dict:
-            res = class_dict['vtmid'](old_obj, trans_dict)
-            new_obj.db_vtmid = res
-        elif hasattr(old_obj, 'db_vtmid') and old_obj.db_vtmid is not None:
-            new_obj.db_vtmid = old_obj.db_vtmid
-        if 'pos' in class_dict:
-            res = class_dict['pos'](old_obj, trans_dict)
-            new_obj.db_pos = res
-        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
-            new_obj.db_pos = old_obj.db_pos
-        if 'type' in class_dict:
-            res = class_dict['type'](old_obj, trans_dict)
-            new_obj.db_type = res
-        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
-            new_obj.db_type = old_obj.db_type
-        if 'val' in class_dict:
-            res = class_dict['val'](old_obj, trans_dict)
-            new_obj.db_val = res
-        elif hasattr(old_obj, 'db_val') and old_obj.db_val is not None:
-            new_obj.db_val = old_obj.db_val
-        if 'minVal' in class_dict:
-            res = class_dict['minVal'](old_obj, trans_dict)
-            new_obj.db_minVal = res
-        elif hasattr(old_obj, 'db_minVal') and old_obj.db_minVal is not None:
-            new_obj.db_minVal = old_obj.db_minVal
-        if 'maxVal' in class_dict:
-            res = class_dict['maxVal'](old_obj, trans_dict)
-            new_obj.db_maxVal = res
-        elif hasattr(old_obj, 'db_maxVal') and old_obj.db_maxVal is not None:
-            new_obj.db_maxVal = old_obj.db_maxVal
-        if 'stepSize' in class_dict:
-            res = class_dict['stepSize'](old_obj, trans_dict)
-            new_obj.db_stepSize = res
-        elif hasattr(old_obj, 'db_stepSize') and old_obj.db_stepSize is not None:
-            new_obj.db_stepSize = old_obj.db_stepSize
-        if 'strvaluelist' in class_dict:
-            res = class_dict['strvaluelist'](old_obj, trans_dict)
-            new_obj.db_strvaluelist = res
-        elif hasattr(old_obj, 'db_strvaluelist') and old_obj.db_strvaluelist is not None:
-            new_obj.db_strvaluelist = old_obj.db_strvaluelist
-        if 'widget' in class_dict:
-            res = class_dict['widget'](old_obj, trans_dict)
-            new_obj.db_widget = res
-        elif hasattr(old_obj, 'db_widget') and old_obj.db_widget is not None:
-            new_obj.db_widget = old_obj.db_widget
-        if 'seq' in class_dict:
-            res = class_dict['seq'](old_obj, trans_dict)
-            new_obj.db_seq = res
-        elif hasattr(old_obj, 'db_seq') and old_obj.db_seq is not None:
-            new_obj.db_seq = old_obj.db_seq
-        if 'parent' in class_dict:
-            res = class_dict['parent'](old_obj, trans_dict)
-            new_obj.db_parent = res
-        elif hasattr(old_obj, 'db_parent') and old_obj.db_parent is not None:
-            new_obj.db_parent = old_obj.db_parent
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBModuleDescriptor()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package_version' in class_dict:
+            res = class_dict['package_version'](old_obj, trans_dict)
+            new_obj.db_package_version = res
+        elif hasattr(old_obj, 'db_package_version') and old_obj.db_package_version is not None:
+            new_obj.db_package_version = old_obj.db_package_version
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'base_descriptor_id' in class_dict:
+            res = class_dict['base_descriptor_id'](old_obj, trans_dict)
+            new_obj.db_base_descriptor_id = res
+        elif hasattr(old_obj, 'db_base_descriptor_id') and old_obj.db_base_descriptor_id is not None:
+            new_obj.db_base_descriptor_id = old_obj.db_base_descriptor_id
+        if 'portSpecs' in class_dict:
+            res = class_dict['portSpecs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_portSpec(obj)
+        elif hasattr(old_obj, 'db_portSpecs') and old_obj.db_portSpecs is not None:
+            for obj in old_obj.db_portSpecs:
+                new_obj.db_add_portSpec(DBPortSpec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_portSpecs') and hasattr(new_obj, 'db_deleted_portSpecs'):
+            for obj in old_obj.db_deleted_portSpecs:
+                n_obj = DBPortSpec.update_version(obj, trans_dict)
+                new_obj.db_deleted_portSpecs.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_portSpecs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_portSpec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_portSpecs)
+        if remove:
+            self.db_deleted_portSpecs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_portSpecs:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -10345,373 +12224,199 @@ class DBMashupComponent(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_vtid(self):
-        return self._db_vtid
-    def __set_db_vtid(self, vtid):
-        self._db_vtid = vtid
-        self.is_dirty = True
-    db_vtid = property(__get_db_vtid, __set_db_vtid)
-    def db_add_vtid(self, vtid):
-        self._db_vtid = vtid
-    def db_change_vtid(self, vtid):
-        self._db_vtid = vtid
-    def db_delete_vtid(self, vtid):
-        self._db_vtid = None
-    
-    def __get_db_vttype(self):
-        return self._db_vttype
-    def __set_db_vttype(self, vttype):
-        self._db_vttype = vttype
-        self.is_dirty = True
-    db_vttype = property(__get_db_vttype, __set_db_vttype)
-    def db_add_vttype(self, vttype):
-        self._db_vttype = vttype
-    def db_change_vttype(self, vttype):
-        self._db_vttype = vttype
-    def db_delete_vttype(self, vttype):
-        self._db_vttype = None
-    
-    def __get_db_vtparent_type(self):
-        return self._db_vtparent_type
-    def __set_db_vtparent_type(self, vtparent_type):
-        self._db_vtparent_type = vtparent_type
-        self.is_dirty = True
-    db_vtparent_type = property(__get_db_vtparent_type, __set_db_vtparent_type)
-    def db_add_vtparent_type(self, vtparent_type):
-        self._db_vtparent_type = vtparent_type
-    def db_change_vtparent_type(self, vtparent_type):
-        self._db_vtparent_type = vtparent_type
-    def db_delete_vtparent_type(self, vtparent_type):
-        self._db_vtparent_type = None
-    
-    def __get_db_vtparent_id(self):
-        return self._db_vtparent_id
-    def __set_db_vtparent_id(self, vtparent_id):
-        self._db_vtparent_id = vtparent_id
-        self.is_dirty = True
-    db_vtparent_id = property(__get_db_vtparent_id, __set_db_vtparent_id)
-    def db_add_vtparent_id(self, vtparent_id):
-        self._db_vtparent_id = vtparent_id
-    def db_change_vtparent_id(self, vtparent_id):
-        self._db_vtparent_id = vtparent_id
-    def db_delete_vtparent_id(self, vtparent_id):
-        self._db_vtparent_id = None
-    
-    def __get_db_vtpos(self):
-        return self._db_vtpos
-    def __set_db_vtpos(self, vtpos):
-        self._db_vtpos = vtpos
-        self.is_dirty = True
-    db_vtpos = property(__get_db_vtpos, __set_db_vtpos)
-    def db_add_vtpos(self, vtpos):
-        self._db_vtpos = vtpos
-    def db_change_vtpos(self, vtpos):
-        self._db_vtpos = vtpos
-    def db_delete_vtpos(self, vtpos):
-        self._db_vtpos = None
-    
-    def __get_db_vtmid(self):
-        return self._db_vtmid
-    def __set_db_vtmid(self, vtmid):
-        self._db_vtmid = vtmid
-        self.is_dirty = True
-    db_vtmid = property(__get_db_vtmid, __set_db_vtmid)
-    def db_add_vtmid(self, vtmid):
-        self._db_vtmid = vtmid
-    def db_change_vtmid(self, vtmid):
-        self._db_vtmid = vtmid
-    def db_delete_vtmid(self, vtmid):
-        self._db_vtmid = None
-    
-    def __get_db_pos(self):
-        return self._db_pos
-    def __set_db_pos(self, pos):
-        self._db_pos = pos
-        self.is_dirty = True
-    db_pos = property(__get_db_pos, __set_db_pos)
-    def db_add_pos(self, pos):
-        self._db_pos = pos
-    def db_change_pos(self, pos):
-        self._db_pos = pos
-    def db_delete_pos(self, pos):
-        self._db_pos = None
-    
-    def __get_db_type(self):
-        return self._db_type
-    def __set_db_type(self, type):
-        self._db_type = type
-        self.is_dirty = True
-    db_type = property(__get_db_type, __set_db_type)
-    def db_add_type(self, type):
-        self._db_type = type
-    def db_change_type(self, type):
-        self._db_type = type
-    def db_delete_type(self, type):
-        self._db_type = None
-    
-    def __get_db_val(self):
-        return self._db_val
-    def __set_db_val(self, val):
-        self._db_val = val
-        self.is_dirty = True
-    db_val = property(__get_db_val, __set_db_val)
-    def db_add_val(self, val):
-        self._db_val = val
-    def db_change_val(self, val):
-        self._db_val = val
-    def db_delete_val(self, val):
-        self._db_val = None
-    
-    def __get_db_minVal(self):
-        return self._db_minVal
-    def __set_db_minVal(self, minVal):
-        self._db_minVal = minVal
-        self.is_dirty = True
-    db_minVal = property(__get_db_minVal, __set_db_minVal)
-    def db_add_minVal(self, minVal):
-        self._db_minVal = minVal
-    def db_change_minVal(self, minVal):
-        self._db_minVal = minVal
-    def db_delete_minVal(self, minVal):
-        self._db_minVal = None
-    
-    def __get_db_maxVal(self):
-        return self._db_maxVal
-    def __set_db_maxVal(self, maxVal):
-        self._db_maxVal = maxVal
-        self.is_dirty = True
-    db_maxVal = property(__get_db_maxVal, __set_db_maxVal)
-    def db_add_maxVal(self, maxVal):
-        self._db_maxVal = maxVal
-    def db_change_maxVal(self, maxVal):
-        self._db_maxVal = maxVal
-    def db_delete_maxVal(self, maxVal):
-        self._db_maxVal = None
-    
-    def __get_db_stepSize(self):
-        return self._db_stepSize
-    def __set_db_stepSize(self, stepSize):
-        self._db_stepSize = stepSize
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_stepSize = property(__get_db_stepSize, __set_db_stepSize)
-    def db_add_stepSize(self, stepSize):
-        self._db_stepSize = stepSize
-    def db_change_stepSize(self, stepSize):
-        self._db_stepSize = stepSize
-    def db_delete_stepSize(self, stepSize):
-        self._db_stepSize = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
-    def __get_db_strvaluelist(self):
-        return self._db_strvaluelist
-    def __set_db_strvaluelist(self, strvaluelist):
-        self._db_strvaluelist = strvaluelist
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
         self.is_dirty = True
-    db_strvaluelist = property(__get_db_strvaluelist, __set_db_strvaluelist)
-    def db_add_strvaluelist(self, strvaluelist):
-        self._db_strvaluelist = strvaluelist
-    def db_change_strvaluelist(self, strvaluelist):
-        self._db_strvaluelist = strvaluelist
-    def db_delete_strvaluelist(self, strvaluelist):
-        self._db_strvaluelist = None
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
     
-    def __get_db_widget(self):
-        return self._db_widget
-    def __set_db_widget(self, widget):
-        self._db_widget = widget
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
         self.is_dirty = True
-    db_widget = property(__get_db_widget, __set_db_widget)
-    def db_add_widget(self, widget):
-        self._db_widget = widget
-    def db_change_widget(self, widget):
-        self._db_widget = widget
-    def db_delete_widget(self, widget):
-        self._db_widget = None
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
     
-    def __get_db_seq(self):
-        return self._db_seq
-    def __set_db_seq(self, seq):
-        self._db_seq = seq
+    def __get_db_package_version(self):
+        return self._db_package_version
+    def __set_db_package_version(self, package_version):
+        self._db_package_version = package_version
         self.is_dirty = True
-    db_seq = property(__get_db_seq, __set_db_seq)
-    def db_add_seq(self, seq):
-        self._db_seq = seq
-    def db_change_seq(self, seq):
-        self._db_seq = seq
-    def db_delete_seq(self, seq):
-        self._db_seq = None
+    db_package_version = property(__get_db_package_version, __set_db_package_version)
+    def db_add_package_version(self, package_version):
+        self._db_package_version = package_version
+    def db_change_package_version(self, package_version):
+        self._db_package_version = package_version
+    def db_delete_package_version(self, package_version):
+        self._db_package_version = None
     
-    def __get_db_parent(self):
-        return self._db_parent
-    def __set_db_parent(self, parent):
-        self._db_parent = parent
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
         self.is_dirty = True
-    db_parent = property(__get_db_parent, __set_db_parent)
-    def db_add_parent(self, parent):
-        self._db_parent = parent
-    def db_change_parent(self, parent):
-        self._db_parent = parent
-    def db_delete_parent(self, parent):
-        self._db_parent = None
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
     
-    def getPrimaryKey(self):
-        return self._db_id
-
-class DBProvEntity(object):
-
-    vtType = 'prov_entity'
-
-    def __init__(self, id=None, prov_type=None, prov_label=None, prov_value=None, vt_id=None, vt_type=None, vt_desc=None, vt_package=None, vt_version=None, vt_cache=None, vt_location_x=None, vt_location_y=None, is_part_of=None):
-        self._db_id = id
-        self._db_prov_type = prov_type
-        self._db_prov_label = prov_label
-        self._db_prov_value = prov_value
-        self._db_vt_id = vt_id
-        self._db_vt_type = vt_type
-        self._db_vt_desc = vt_desc
-        self._db_vt_package = vt_package
-        self._db_vt_version = vt_version
-        self._db_vt_cache = vt_cache
-        self._db_vt_location_x = vt_location_x
-        self._db_vt_location_y = vt_location_y
-        self.db_deleted_is_part_of = []
-        self._db_is_part_of = is_part_of
+    def __get_db_base_descriptor_id(self):
+        return self._db_base_descriptor_id
+    def __set_db_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = base_descriptor_id
         self.is_dirty = True
-        self.is_new = True
+    db_base_descriptor_id = property(__get_db_base_descriptor_id, __set_db_base_descriptor_id)
+    def db_add_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = base_descriptor_id
+    def db_change_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = base_descriptor_id
+    def db_delete_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = None
     
-    def __copy__(self):
-        return DBProvEntity.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBProvEntity(id=self._db_id,
-                          prov_type=self._db_prov_type,
-                          prov_label=self._db_prov_label,
-                          prov_value=self._db_prov_value,
-                          vt_id=self._db_vt_id,
-                          vt_type=self._db_vt_type,
-                          vt_desc=self._db_vt_desc,
-                          vt_package=self._db_vt_package,
-                          vt_version=self._db_vt_version,
-                          vt_cache=self._db_vt_cache,
-                          vt_location_x=self._db_vt_location_x,
-                          vt_location_y=self._db_vt_location_y)
-        if self._db_is_part_of is not None:
-            cp._db_is_part_of = self._db_is_part_of.do_copy(new_ids, id_scope, id_remap)
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
-            if self.vtType in id_scope.remap:
-                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-        
-        # recreate indices and set flags
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBProvEntity()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'prov_type' in class_dict:
-            res = class_dict['prov_type'](old_obj, trans_dict)
-            new_obj.db_prov_type = res
-        elif hasattr(old_obj, 'db_prov_type') and old_obj.db_prov_type is not None:
-            new_obj.db_prov_type = old_obj.db_prov_type
-        if 'prov_label' in class_dict:
-            res = class_dict['prov_label'](old_obj, trans_dict)
-            new_obj.db_prov_label = res
-        elif hasattr(old_obj, 'db_prov_label') and old_obj.db_prov_label is not None:
-            new_obj.db_prov_label = old_obj.db_prov_label
-        if 'prov_value' in class_dict:
-            res = class_dict['prov_value'](old_obj, trans_dict)
-            new_obj.db_prov_value = res
-        elif hasattr(old_obj, 'db_prov_value') and old_obj.db_prov_value is not None:
-            new_obj.db_prov_value = old_obj.db_prov_value
-        if 'vt_id' in class_dict:
-            res = class_dict['vt_id'](old_obj, trans_dict)
-            new_obj.db_vt_id = res
-        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
-            new_obj.db_vt_id = old_obj.db_vt_id
-        if 'vt_type' in class_dict:
-            res = class_dict['vt_type'](old_obj, trans_dict)
-            new_obj.db_vt_type = res
-        elif hasattr(old_obj, 'db_vt_type') and old_obj.db_vt_type is not None:
-            new_obj.db_vt_type = old_obj.db_vt_type
-        if 'vt_desc' in class_dict:
-            res = class_dict['vt_desc'](old_obj, trans_dict)
-            new_obj.db_vt_desc = res
-        elif hasattr(old_obj, 'db_vt_desc') and old_obj.db_vt_desc is not None:
-            new_obj.db_vt_desc = old_obj.db_vt_desc
-        if 'vt_package' in class_dict:
-            res = class_dict['vt_package'](old_obj, trans_dict)
-            new_obj.db_vt_package = res
-        elif hasattr(old_obj, 'db_vt_package') and old_obj.db_vt_package is not None:
-            new_obj.db_vt_package = old_obj.db_vt_package
-        if 'vt_version' in class_dict:
-            res = class_dict['vt_version'](old_obj, trans_dict)
-            new_obj.db_vt_version = res
-        elif hasattr(old_obj, 'db_vt_version') and old_obj.db_vt_version is not None:
-            new_obj.db_vt_version = old_obj.db_vt_version
-        if 'vt_cache' in class_dict:
-            res = class_dict['vt_cache'](old_obj, trans_dict)
-            new_obj.db_vt_cache = res
-        elif hasattr(old_obj, 'db_vt_cache') and old_obj.db_vt_cache is not None:
-            new_obj.db_vt_cache = old_obj.db_vt_cache
-        if 'vt_location_x' in class_dict:
-            res = class_dict['vt_location_x'](old_obj, trans_dict)
-            new_obj.db_vt_location_x = res
-        elif hasattr(old_obj, 'db_vt_location_x') and old_obj.db_vt_location_x is not None:
-            new_obj.db_vt_location_x = old_obj.db_vt_location_x
-        if 'vt_location_y' in class_dict:
-            res = class_dict['vt_location_y'](old_obj, trans_dict)
-            new_obj.db_vt_location_y = res
-        elif hasattr(old_obj, 'db_vt_location_y') and old_obj.db_vt_location_y is not None:
-            new_obj.db_vt_location_y = old_obj.db_vt_location_y
-        if 'is_part_of' in class_dict:
-            res = class_dict['is_part_of'](old_obj, trans_dict)
-            new_obj.db_is_part_of = res
-        elif hasattr(old_obj, 'db_is_part_of') and old_obj.db_is_part_of is not None:
-            obj = old_obj.db_is_part_of
-            new_obj.db_add_is_part_of(DBIsPartOf.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_is_part_of') and hasattr(new_obj, 'db_deleted_is_part_of'):
-            for obj in old_obj.db_deleted_is_part_of:
-                n_obj = DBIsPartOf.update_version(obj, trans_dict)
-                new_obj.db_deleted_is_part_of.append(n_obj)
+    def __get_db_portSpecs(self):
+        return self._db_portSpecs
+    def __set_db_portSpecs(self, portSpecs):
+        self._db_portSpecs = portSpecs
+        self.is_dirty = True
+    db_portSpecs = property(__get_db_portSpecs, __set_db_portSpecs)
+    def db_get_portSpecs(self):
+        return self._db_portSpecs
+    def db_add_portSpec(self, portSpec):
+        self.is_dirty = True
+        self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_change_portSpec(self, portSpec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                self._db_portSpecs[i] = portSpec
+                found = True
+                break
+        if not found:
+            self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_delete_portSpec(self, portSpec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                if not self._db_portSpecs[i].is_new:
+                    self.db_deleted_portSpecs.append(self._db_portSpecs[i])
+                del self._db_portSpecs[i]
+                break
+        del self.db_portSpecs_id_index[portSpec.db_id]
+        del self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)]
+    def db_get_portSpec(self, key):
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == key:
+                return self._db_portSpecs[i]
+        return None
+    def db_get_portSpec_by_id(self, key):
+        return self.db_portSpecs_id_index[key]
+    def db_has_portSpec_with_id(self, key):
+        return key in self.db_portSpecs_id_index
+    def db_get_portSpec_by_name(self, key):
+        return self.db_portSpecs_name_index[key]
+    def db_has_portSpec_with_name(self, key):
+        return key in self.db_portSpecs_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBTag(object):
+
+    vtType = 'tag'
+
+    def __init__(self, id=None, name=None):
+        self._db_id = id
+        self._db_name = name
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBTag.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBTag(id=self._db_id,
+                   name=self._db_name)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('action', self._db_id) in id_remap:
+                cp._db_id = id_remap[('action', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBTag()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_is_part_of is not None:
-            children.extend(self._db_is_part_of.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_is_part_of = None
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_is_part_of)
-        if remove:
-            self.db_deleted_is_part_of = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_is_part_of is not None and self._db_is_part_of.has_changes():
-            return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -10726,185 +12431,36 @@ class DBProvEntity(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_prov_type(self):
-        return self._db_prov_type
-    def __set_db_prov_type(self, prov_type):
-        self._db_prov_type = prov_type
-        self.is_dirty = True
-    db_prov_type = property(__get_db_prov_type, __set_db_prov_type)
-    def db_add_prov_type(self, prov_type):
-        self._db_prov_type = prov_type
-    def db_change_prov_type(self, prov_type):
-        self._db_prov_type = prov_type
-    def db_delete_prov_type(self, prov_type):
-        self._db_prov_type = None
-    
-    def __get_db_prov_label(self):
-        return self._db_prov_label
-    def __set_db_prov_label(self, prov_label):
-        self._db_prov_label = prov_label
-        self.is_dirty = True
-    db_prov_label = property(__get_db_prov_label, __set_db_prov_label)
-    def db_add_prov_label(self, prov_label):
-        self._db_prov_label = prov_label
-    def db_change_prov_label(self, prov_label):
-        self._db_prov_label = prov_label
-    def db_delete_prov_label(self, prov_label):
-        self._db_prov_label = None
-    
-    def __get_db_prov_value(self):
-        return self._db_prov_value
-    def __set_db_prov_value(self, prov_value):
-        self._db_prov_value = prov_value
-        self.is_dirty = True
-    db_prov_value = property(__get_db_prov_value, __set_db_prov_value)
-    def db_add_prov_value(self, prov_value):
-        self._db_prov_value = prov_value
-    def db_change_prov_value(self, prov_value):
-        self._db_prov_value = prov_value
-    def db_delete_prov_value(self, prov_value):
-        self._db_prov_value = None
-    
-    def __get_db_vt_id(self):
-        return self._db_vt_id
-    def __set_db_vt_id(self, vt_id):
-        self._db_vt_id = vt_id
-        self.is_dirty = True
-    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
-    def db_add_vt_id(self, vt_id):
-        self._db_vt_id = vt_id
-    def db_change_vt_id(self, vt_id):
-        self._db_vt_id = vt_id
-    def db_delete_vt_id(self, vt_id):
-        self._db_vt_id = None
-    
-    def __get_db_vt_type(self):
-        return self._db_vt_type
-    def __set_db_vt_type(self, vt_type):
-        self._db_vt_type = vt_type
-        self.is_dirty = True
-    db_vt_type = property(__get_db_vt_type, __set_db_vt_type)
-    def db_add_vt_type(self, vt_type):
-        self._db_vt_type = vt_type
-    def db_change_vt_type(self, vt_type):
-        self._db_vt_type = vt_type
-    def db_delete_vt_type(self, vt_type):
-        self._db_vt_type = None
-    
-    def __get_db_vt_desc(self):
-        return self._db_vt_desc
-    def __set_db_vt_desc(self, vt_desc):
-        self._db_vt_desc = vt_desc
-        self.is_dirty = True
-    db_vt_desc = property(__get_db_vt_desc, __set_db_vt_desc)
-    def db_add_vt_desc(self, vt_desc):
-        self._db_vt_desc = vt_desc
-    def db_change_vt_desc(self, vt_desc):
-        self._db_vt_desc = vt_desc
-    def db_delete_vt_desc(self, vt_desc):
-        self._db_vt_desc = None
-    
-    def __get_db_vt_package(self):
-        return self._db_vt_package
-    def __set_db_vt_package(self, vt_package):
-        self._db_vt_package = vt_package
-        self.is_dirty = True
-    db_vt_package = property(__get_db_vt_package, __set_db_vt_package)
-    def db_add_vt_package(self, vt_package):
-        self._db_vt_package = vt_package
-    def db_change_vt_package(self, vt_package):
-        self._db_vt_package = vt_package
-    def db_delete_vt_package(self, vt_package):
-        self._db_vt_package = None
-    
-    def __get_db_vt_version(self):
-        return self._db_vt_version
-    def __set_db_vt_version(self, vt_version):
-        self._db_vt_version = vt_version
-        self.is_dirty = True
-    db_vt_version = property(__get_db_vt_version, __set_db_vt_version)
-    def db_add_vt_version(self, vt_version):
-        self._db_vt_version = vt_version
-    def db_change_vt_version(self, vt_version):
-        self._db_vt_version = vt_version
-    def db_delete_vt_version(self, vt_version):
-        self._db_vt_version = None
-    
-    def __get_db_vt_cache(self):
-        return self._db_vt_cache
-    def __set_db_vt_cache(self, vt_cache):
-        self._db_vt_cache = vt_cache
-        self.is_dirty = True
-    db_vt_cache = property(__get_db_vt_cache, __set_db_vt_cache)
-    def db_add_vt_cache(self, vt_cache):
-        self._db_vt_cache = vt_cache
-    def db_change_vt_cache(self, vt_cache):
-        self._db_vt_cache = vt_cache
-    def db_delete_vt_cache(self, vt_cache):
-        self._db_vt_cache = None
-    
-    def __get_db_vt_location_x(self):
-        return self._db_vt_location_x
-    def __set_db_vt_location_x(self, vt_location_x):
-        self._db_vt_location_x = vt_location_x
-        self.is_dirty = True
-    db_vt_location_x = property(__get_db_vt_location_x, __set_db_vt_location_x)
-    def db_add_vt_location_x(self, vt_location_x):
-        self._db_vt_location_x = vt_location_x
-    def db_change_vt_location_x(self, vt_location_x):
-        self._db_vt_location_x = vt_location_x
-    def db_delete_vt_location_x(self, vt_location_x):
-        self._db_vt_location_x = None
-    
-    def __get_db_vt_location_y(self):
-        return self._db_vt_location_y
-    def __set_db_vt_location_y(self, vt_location_y):
-        self._db_vt_location_y = vt_location_y
-        self.is_dirty = True
-    db_vt_location_y = property(__get_db_vt_location_y, __set_db_vt_location_y)
-    def db_add_vt_location_y(self, vt_location_y):
-        self._db_vt_location_y = vt_location_y
-    def db_change_vt_location_y(self, vt_location_y):
-        self._db_vt_location_y = vt_location_y
-    def db_delete_vt_location_y(self, vt_location_y):
-        self._db_vt_location_y = None
-    
-    def __get_db_is_part_of(self):
-        return self._db_is_part_of
-    def __set_db_is_part_of(self, is_part_of):
-        self._db_is_part_of = is_part_of
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_is_part_of = property(__get_db_is_part_of, __set_db_is_part_of)
-    def db_add_is_part_of(self, is_part_of):
-        self._db_is_part_of = is_part_of
-    def db_change_is_part_of(self, is_part_of):
-        self._db_is_part_of = is_part_of
-    def db_delete_is_part_of(self, is_part_of):
-        if not self.is_new:
-            self.db_deleted_is_part_of.append(self._db_is_part_of)
-        self._db_is_part_of = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBAnnotation(object):
+class DBOpmRole(object):
 
-    vtType = 'annotation'
+    vtType = 'opm_role'
 
-    def __init__(self, id=None, key=None, value=None):
-        self._db_id = id
-        self._db_key = key
+    def __init__(self, value=None):
         self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBAnnotation.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBAnnotation(id=self._db_id,
-                          key=self._db_key,
-                          value=self._db_value)
+        return DBOpmRole.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmRole(value=self._db_value)
         
         # set new ids
         if new_ids:
@@ -10924,20 +12480,10 @@ class DBAnnotation(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBAnnotation()
+            new_obj = DBOpmRole()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'key' in class_dict:
-            res = class_dict['key'](old_obj, trans_dict)
-            new_obj.db_key = res
-        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
-            new_obj.db_key = old_obj.db_key
         if 'value' in class_dict:
             res = class_dict['value'](old_obj, trans_dict)
             new_obj.db_value = res
@@ -10956,32 +12502,6 @@ class DBAnnotation(object):
         if self.is_dirty:
             return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_key(self):
-        return self._db_key
-    def __set_db_key(self, key):
-        self._db_key = key
-        self.is_dirty = True
-    db_key = property(__get_db_key, __set_db_key)
-    def db_add_key(self, key):
-        self._db_key = key
-    def db_change_key(self, key):
-        self._db_key = key
-    def db_delete_key(self, key):
-        self._db_key = None
-    
     def __get_db_value(self):
         return self._db_value
     def __set_db_value(self, value):
@@ -10995,37 +12515,96 @@ class DBAnnotation(object):
     def db_delete_value(self, value):
         self._db_value = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBChange(object):
 
-    vtType = 'change'
+class DBProvDocument(object):
 
-    def __init__(self, data=None, id=None, what=None, oldObjId=None, newObjId=None, parentObjId=None, parentObjType=None):
-        self.db_deleted_data = []
-        self._db_data = data
-        self._db_id = id
-        self._db_what = what
-        self._db_oldObjId = oldObjId
-        self._db_newObjId = newObjId
-        self._db_parentObjId = parentObjId
-        self._db_parentObjType = parentObjType
+    vtType = 'prov_document'
+
+    def __init__(self, prov_entitys=None, prov_activitys=None, prov_agents=None, vt_connections=None, prov_usages=None, prov_generations=None, prov_associations=None):
+        self.db_deleted_prov_entitys = []
+        self.db_prov_entitys_id_index = {}
+        if prov_entitys is None:
+            self._db_prov_entitys = []
+        else:
+            self._db_prov_entitys = prov_entitys
+            for v in self._db_prov_entitys:
+                self.db_prov_entitys_id_index[v.db_id] = v
+        self.db_deleted_prov_activitys = []
+        self.db_prov_activitys_id_index = {}
+        if prov_activitys is None:
+            self._db_prov_activitys = []
+        else:
+            self._db_prov_activitys = prov_activitys
+            for v in self._db_prov_activitys:
+                self.db_prov_activitys_id_index[v.db_id] = v
+        self.db_deleted_prov_agents = []
+        self.db_prov_agents_id_index = {}
+        if prov_agents is None:
+            self._db_prov_agents = []
+        else:
+            self._db_prov_agents = prov_agents
+            for v in self._db_prov_agents:
+                self.db_prov_agents_id_index[v.db_id] = v
+        self.db_deleted_vt_connections = []
+        self.db_vt_connections_id_index = {}
+        if vt_connections is None:
+            self._db_vt_connections = []
+        else:
+            self._db_vt_connections = vt_connections
+            for v in self._db_vt_connections:
+                self.db_vt_connections_id_index[v.db_id] = v
+        self.db_deleted_prov_usages = []
+        if prov_usages is None:
+            self._db_prov_usages = []
+        else:
+            self._db_prov_usages = prov_usages
+        self.db_deleted_prov_generations = []
+        if prov_generations is None:
+            self._db_prov_generations = []
+        else:
+            self._db_prov_generations = prov_generations
+        self.db_deleted_prov_associations = []
+        if prov_associations is None:
+            self._db_prov_associations = []
+        else:
+            self._db_prov_associations = prov_associations
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBChange.do_copy(self)
+        return DBProvDocument.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBChange(id=self._db_id,
-                      what=self._db_what,
-                      oldObjId=self._db_oldObjId,
-                      newObjId=self._db_newObjId,
-                      parentObjId=self._db_parentObjId,
-                      parentObjType=self._db_parentObjType)
-        if self._db_data is not None:
-            cp._db_data = self._db_data.do_copy(new_ids, id_scope, id_remap)
+        cp = DBProvDocument()
+        if self._db_prov_entitys is None:
+            cp._db_prov_entitys = []
+        else:
+            cp._db_prov_entitys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_entitys]
+        if self._db_prov_activitys is None:
+            cp._db_prov_activitys = []
+        else:
+            cp._db_prov_activitys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_activitys]
+        if self._db_prov_agents is None:
+            cp._db_prov_agents = []
+        else:
+            cp._db_prov_agents = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_agents]
+        if self._db_vt_connections is None:
+            cp._db_vt_connections = []
+        else:
+            cp._db_vt_connections = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_vt_connections]
+        if self._db_prov_usages is None:
+            cp._db_prov_usages = []
+        else:
+            cp._db_prov_usages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_usages]
+        if self._db_prov_generations is None:
+            cp._db_prov_generations = []
+        else:
+            cp._db_prov_generations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_generations]
+        if self._db_prov_associations is None:
+            cp._db_prov_associations = []
+        else:
+            cp._db_prov_associations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_associations]
         
         # set new ids
         if new_ids:
@@ -11035,14 +12614,12 @@ class DBChange(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_oldObjId') and (self._db_what, self._db_oldObjId) in id_remap:
-                cp._db_oldObjId = id_remap[(self._db_what, self._db_oldObjId)]
-            if hasattr(self, 'db_newObjId') and (self._db_what, self._db_newObjId) in id_remap:
-                cp._db_newObjId = id_remap[(self._db_what, self._db_newObjId)]
-            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
-                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
         
         # recreate indices and set flags
+        cp.db_prov_entitys_id_index = dict((v.db_id, v) for v in cp._db_prov_entitys)
+        cp.db_prov_activitys_id_index = dict((v.db_id, v) for v in cp._db_prov_activitys)
+        cp.db_prov_agents_id_index = dict((v.db_id, v) for v in cp._db_prov_agents)
+        cp.db_vt_connections_id_index = dict((v.db_id, v) for v in cp._db_vt_connections)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -11051,270 +12628,442 @@ class DBChange(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBChange()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'data' in class_dict:
-            res = class_dict['data'](old_obj, trans_dict)
-            new_obj.db_data = res
-        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
-            obj = old_obj.db_data
-            if obj.vtType == 'module':
-                new_obj.db_add_data(DBModule.update_version(obj, trans_dict))
-            elif obj.vtType == 'location':
-                new_obj.db_add_data(DBLocation.update_version(obj, trans_dict))
-            elif obj.vtType == 'annotation':
-                new_obj.db_add_data(DBAnnotation.update_version(obj, trans_dict))
-            elif obj.vtType == 'function':
-                new_obj.db_add_data(DBFunction.update_version(obj, trans_dict))
-            elif obj.vtType == 'connection':
-                new_obj.db_add_data(DBConnection.update_version(obj, trans_dict))
-            elif obj.vtType == 'port':
-                new_obj.db_add_data(DBPort.update_version(obj, trans_dict))
-            elif obj.vtType == 'parameter':
-                new_obj.db_add_data(DBParameter.update_version(obj, trans_dict))
-            elif obj.vtType == 'portSpec':
-                new_obj.db_add_data(DBPortSpec.update_version(obj, trans_dict))
-            elif obj.vtType == 'abstraction':
-                new_obj.db_add_data(DBAbstraction.update_version(obj, trans_dict))
-            elif obj.vtType == 'group':
-                new_obj.db_add_data(DBGroup.update_version(obj, trans_dict))
-            elif obj.vtType == 'other':
-                new_obj.db_add_data(DBOther.update_version(obj, trans_dict))
-            elif obj.vtType == 'plugin_data':
-                new_obj.db_add_data(DBPluginData.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_data') and hasattr(new_obj, 'db_deleted_data'):
-            for obj in old_obj.db_deleted_data:
-                if obj.vtType == 'module':
-                    n_obj = DBModule.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'location':
-                    n_obj = DBLocation.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'annotation':
-                    n_obj = DBAnnotation.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'function':
-                    n_obj = DBFunction.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'connection':
-                    n_obj = DBConnection.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'port':
-                    n_obj = DBPort.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'parameter':
-                    n_obj = DBParameter.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'portSpec':
-                    n_obj = DBPortSpec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'abstraction':
-                    n_obj = DBAbstraction.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'group':
-                    n_obj = DBGroup.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'other':
-                    n_obj = DBOther.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-                elif obj.vtType == 'plugin_data':
-                    n_obj = DBPluginData.update_version(obj, trans_dict)
-                    new_obj.db_deleted_data.append(n_obj)
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'what' in class_dict:
-            res = class_dict['what'](old_obj, trans_dict)
-            new_obj.db_what = res
-        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
-            new_obj.db_what = old_obj.db_what
-        if 'oldObjId' in class_dict:
-            res = class_dict['oldObjId'](old_obj, trans_dict)
-            new_obj.db_oldObjId = res
-        elif hasattr(old_obj, 'db_oldObjId') and old_obj.db_oldObjId is not None:
-            new_obj.db_oldObjId = old_obj.db_oldObjId
-        if 'newObjId' in class_dict:
-            res = class_dict['newObjId'](old_obj, trans_dict)
-            new_obj.db_newObjId = res
-        elif hasattr(old_obj, 'db_newObjId') and old_obj.db_newObjId is not None:
-            new_obj.db_newObjId = old_obj.db_newObjId
-        if 'parentObjId' in class_dict:
-            res = class_dict['parentObjId'](old_obj, trans_dict)
-            new_obj.db_parentObjId = res
-        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
-            new_obj.db_parentObjId = old_obj.db_parentObjId
-        if 'parentObjType' in class_dict:
-            res = class_dict['parentObjType'](old_obj, trans_dict)
-            new_obj.db_parentObjType = res
-        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
-            new_obj.db_parentObjType = old_obj.db_parentObjType
+            new_obj = DBProvDocument()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_entitys' in class_dict:
+            res = class_dict['prov_entitys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_entity(obj)
+        elif hasattr(old_obj, 'db_prov_entitys') and old_obj.db_prov_entitys is not None:
+            for obj in old_obj.db_prov_entitys:
+                new_obj.db_add_prov_entity(DBProvEntity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_entitys') and hasattr(new_obj, 'db_deleted_prov_entitys'):
+            for obj in old_obj.db_deleted_prov_entitys:
+                n_obj = DBProvEntity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_entitys.append(n_obj)
+        if 'prov_activitys' in class_dict:
+            res = class_dict['prov_activitys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_activity(obj)
+        elif hasattr(old_obj, 'db_prov_activitys') and old_obj.db_prov_activitys is not None:
+            for obj in old_obj.db_prov_activitys:
+                new_obj.db_add_prov_activity(DBProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activitys') and hasattr(new_obj, 'db_deleted_prov_activitys'):
+            for obj in old_obj.db_deleted_prov_activitys:
+                n_obj = DBProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activitys.append(n_obj)
+        if 'prov_agents' in class_dict:
+            res = class_dict['prov_agents'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_agent(obj)
+        elif hasattr(old_obj, 'db_prov_agents') and old_obj.db_prov_agents is not None:
+            for obj in old_obj.db_prov_agents:
+                new_obj.db_add_prov_agent(DBProvAgent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_agents') and hasattr(new_obj, 'db_deleted_prov_agents'):
+            for obj in old_obj.db_deleted_prov_agents:
+                n_obj = DBProvAgent.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_agents.append(n_obj)
+        if 'vt_connections' in class_dict:
+            res = class_dict['vt_connections'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_vt_connection(obj)
+        elif hasattr(old_obj, 'db_vt_connections') and old_obj.db_vt_connections is not None:
+            for obj in old_obj.db_vt_connections:
+                new_obj.db_add_vt_connection(DBVtConnection.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_vt_connections') and hasattr(new_obj, 'db_deleted_vt_connections'):
+            for obj in old_obj.db_deleted_vt_connections:
+                n_obj = DBVtConnection.update_version(obj, trans_dict)
+                new_obj.db_deleted_vt_connections.append(n_obj)
+        if 'prov_usages' in class_dict:
+            res = class_dict['prov_usages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_usage(obj)
+        elif hasattr(old_obj, 'db_prov_usages') and old_obj.db_prov_usages is not None:
+            for obj in old_obj.db_prov_usages:
+                new_obj.db_add_prov_usage(DBProvUsage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_usages') and hasattr(new_obj, 'db_deleted_prov_usages'):
+            for obj in old_obj.db_deleted_prov_usages:
+                n_obj = DBProvUsage.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_usages.append(n_obj)
+        if 'prov_generations' in class_dict:
+            res = class_dict['prov_generations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_generation(obj)
+        elif hasattr(old_obj, 'db_prov_generations') and old_obj.db_prov_generations is not None:
+            for obj in old_obj.db_prov_generations:
+                new_obj.db_add_prov_generation(DBProvGeneration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_generations') and hasattr(new_obj, 'db_deleted_prov_generations'):
+            for obj in old_obj.db_deleted_prov_generations:
+                n_obj = DBProvGeneration.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_generations.append(n_obj)
+        if 'prov_associations' in class_dict:
+            res = class_dict['prov_associations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_association(obj)
+        elif hasattr(old_obj, 'db_prov_associations') and old_obj.db_prov_associations is not None:
+            for obj in old_obj.db_prov_associations:
+                new_obj.db_add_prov_association(DBProvAssociation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_associations') and hasattr(new_obj, 'db_deleted_prov_associations'):
+            for obj in old_obj.db_deleted_prov_associations:
+                n_obj = DBProvAssociation.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_associations.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_data is not None:
-            children.extend(self._db_data.db_children((self.vtType, self.db_id), orphan, for_action))
+        to_del = []
+        for child in self.db_prov_entitys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_data = None
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_entity(child)
+        to_del = []
+        for child in self.db_prov_activitys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_activity(child)
+        to_del = []
+        for child in self.db_prov_agents:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_agent(child)
+        to_del = []
+        for child in self.db_vt_connections:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_vt_connection(child)
+        to_del = []
+        for child in self.db_prov_usages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_usage(child)
+        to_del = []
+        for child in self.db_prov_generations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_generation(child)
+        to_del = []
+        for child in self.db_prov_associations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_association(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_data)
+        children.extend(self.db_deleted_prov_entitys)
+        children.extend(self.db_deleted_prov_activitys)
+        children.extend(self.db_deleted_prov_agents)
+        children.extend(self.db_deleted_vt_connections)
+        children.extend(self.db_deleted_prov_usages)
+        children.extend(self.db_deleted_prov_generations)
+        children.extend(self.db_deleted_prov_associations)
         if remove:
-            self.db_deleted_data = []
+            self.db_deleted_prov_entitys = []
+            self.db_deleted_prov_activitys = []
+            self.db_deleted_prov_agents = []
+            self.db_deleted_vt_connections = []
+            self.db_deleted_prov_usages = []
+            self.db_deleted_prov_generations = []
+            self.db_deleted_prov_associations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_data is not None and self._db_data.has_changes():
-            return True
+        for child in self._db_prov_entitys:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_activitys:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_agents:
+            if child.has_changes():
+                return True
+        for child in self._db_vt_connections:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_usages:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_generations:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_associations:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_data(self):
-        return self._db_data
-    def __set_db_data(self, data):
-        self._db_data = data
+    def __get_db_prov_entitys(self):
+        return self._db_prov_entitys
+    def __set_db_prov_entitys(self, prov_entitys):
+        self._db_prov_entitys = prov_entitys
         self.is_dirty = True
-    db_data = property(__get_db_data, __set_db_data)
-    def db_add_data(self, data):
-        self._db_data = data
-    def db_change_data(self, data):
-        self._db_data = data
-    def db_delete_data(self, data):
-        if not self.is_new:
-            self.db_deleted_data.append(self._db_data)
-        self._db_data = None
+    db_prov_entitys = property(__get_db_prov_entitys, __set_db_prov_entitys)
+    def db_get_prov_entitys(self):
+        return self._db_prov_entitys
+    def db_add_prov_entity(self, prov_entity):
+        self.is_dirty = True
+        self._db_prov_entitys.append(prov_entity)
+        self.db_prov_entitys_id_index[prov_entity.db_id] = prov_entity
+    def db_change_prov_entity(self, prov_entity):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_prov_entitys)):
+            if self._db_prov_entitys[i].db_id == prov_entity.db_id:
+                self._db_prov_entitys[i] = prov_entity
+                found = True
+                break
+        if not found:
+            self._db_prov_entitys.append(prov_entity)
+        self.db_prov_entitys_id_index[prov_entity.db_id] = prov_entity
+    def db_delete_prov_entity(self, prov_entity):
+        self.is_dirty = True
+        for i in xrange(len(self._db_prov_entitys)):
+            if self._db_prov_entitys[i].db_id == prov_entity.db_id:
+                if not self._db_prov_entitys[i].is_new:
+                    self.db_deleted_prov_entitys.append(self._db_prov_entitys[i])
+                del self._db_prov_entitys[i]
+                break
+        del self.db_prov_entitys_id_index[prov_entity.db_id]
+    def db_get_prov_entity(self, key):
+        for i in xrange(len(self._db_prov_entitys)):
+            if self._db_prov_entitys[i].db_id == key:
+                return self._db_prov_entitys[i]
+        return None
+    def db_get_prov_entity_by_id(self, key):
+        return self.db_prov_entitys_id_index[key]
+    def db_has_prov_entity_with_id(self, key):
+        return key in self.db_prov_entitys_id_index
+    
+    def __get_db_prov_activitys(self):
+        return self._db_prov_activitys
+    def __set_db_prov_activitys(self, prov_activitys):
+        self._db_prov_activitys = prov_activitys
+        self.is_dirty = True
+    db_prov_activitys = property(__get_db_prov_activitys, __set_db_prov_activitys)
+    def db_get_prov_activitys(self):
+        return self._db_prov_activitys
+    def db_add_prov_activity(self, prov_activity):
+        self.is_dirty = True
+        self._db_prov_activitys.append(prov_activity)
+        self.db_prov_activitys_id_index[prov_activity.db_id] = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_prov_activitys)):
+            if self._db_prov_activitys[i].db_id == prov_activity.db_id:
+                self._db_prov_activitys[i] = prov_activity
+                found = True
+                break
+        if not found:
+            self._db_prov_activitys.append(prov_activity)
+        self.db_prov_activitys_id_index[prov_activity.db_id] = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        self.is_dirty = True
+        for i in xrange(len(self._db_prov_activitys)):
+            if self._db_prov_activitys[i].db_id == prov_activity.db_id:
+                if not self._db_prov_activitys[i].is_new:
+                    self.db_deleted_prov_activitys.append(self._db_prov_activitys[i])
+                del self._db_prov_activitys[i]
+                break
+        del self.db_prov_activitys_id_index[prov_activity.db_id]
+    def db_get_prov_activity(self, key):
+        for i in xrange(len(self._db_prov_activitys)):
+            if self._db_prov_activitys[i].db_id == key:
+                return self._db_prov_activitys[i]
+        return None
+    def db_get_prov_activity_by_id(self, key):
+        return self.db_prov_activitys_id_index[key]
+    def db_has_prov_activity_with_id(self, key):
+        return key in self.db_prov_activitys_id_index
     
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_prov_agents(self):
+        return self._db_prov_agents
+    def __set_db_prov_agents(self, prov_agents):
+        self._db_prov_agents = prov_agents
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_what(self):
-        return self._db_what
-    def __set_db_what(self, what):
-        self._db_what = what
+    db_prov_agents = property(__get_db_prov_agents, __set_db_prov_agents)
+    def db_get_prov_agents(self):
+        return self._db_prov_agents
+    def db_add_prov_agent(self, prov_agent):
         self.is_dirty = True
-    db_what = property(__get_db_what, __set_db_what)
-    def db_add_what(self, what):
-        self._db_what = what
-    def db_change_what(self, what):
-        self._db_what = what
-    def db_delete_what(self, what):
-        self._db_what = None
+        self._db_prov_agents.append(prov_agent)
+        self.db_prov_agents_id_index[prov_agent.db_id] = prov_agent
+    def db_change_prov_agent(self, prov_agent):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_prov_agents)):
+            if self._db_prov_agents[i].db_id == prov_agent.db_id:
+                self._db_prov_agents[i] = prov_agent
+                found = True
+                break
+        if not found:
+            self._db_prov_agents.append(prov_agent)
+        self.db_prov_agents_id_index[prov_agent.db_id] = prov_agent
+    def db_delete_prov_agent(self, prov_agent):
+        self.is_dirty = True
+        for i in xrange(len(self._db_prov_agents)):
+            if self._db_prov_agents[i].db_id == prov_agent.db_id:
+                if not self._db_prov_agents[i].is_new:
+                    self.db_deleted_prov_agents.append(self._db_prov_agents[i])
+                del self._db_prov_agents[i]
+                break
+        del self.db_prov_agents_id_index[prov_agent.db_id]
+    def db_get_prov_agent(self, key):
+        for i in xrange(len(self._db_prov_agents)):
+            if self._db_prov_agents[i].db_id == key:
+                return self._db_prov_agents[i]
+        return None
+    def db_get_prov_agent_by_id(self, key):
+        return self.db_prov_agents_id_index[key]
+    def db_has_prov_agent_with_id(self, key):
+        return key in self.db_prov_agents_id_index
     
-    def __get_db_oldObjId(self):
-        return self._db_oldObjId
-    def __set_db_oldObjId(self, oldObjId):
-        self._db_oldObjId = oldObjId
+    def __get_db_vt_connections(self):
+        return self._db_vt_connections
+    def __set_db_vt_connections(self, vt_connections):
+        self._db_vt_connections = vt_connections
         self.is_dirty = True
-    db_oldObjId = property(__get_db_oldObjId, __set_db_oldObjId)
-    def db_add_oldObjId(self, oldObjId):
-        self._db_oldObjId = oldObjId
-    def db_change_oldObjId(self, oldObjId):
-        self._db_oldObjId = oldObjId
-    def db_delete_oldObjId(self, oldObjId):
-        self._db_oldObjId = None
+    db_vt_connections = property(__get_db_vt_connections, __set_db_vt_connections)
+    def db_get_vt_connections(self):
+        return self._db_vt_connections
+    def db_add_vt_connection(self, vt_connection):
+        self.is_dirty = True
+        self._db_vt_connections.append(vt_connection)
+        self.db_vt_connections_id_index[vt_connection.db_id] = vt_connection
+    def db_change_vt_connection(self, vt_connection):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_vt_connections)):
+            if self._db_vt_connections[i].db_id == vt_connection.db_id:
+                self._db_vt_connections[i] = vt_connection
+                found = True
+                break
+        if not found:
+            self._db_vt_connections.append(vt_connection)
+        self.db_vt_connections_id_index[vt_connection.db_id] = vt_connection
+    def db_delete_vt_connection(self, vt_connection):
+        self.is_dirty = True
+        for i in xrange(len(self._db_vt_connections)):
+            if self._db_vt_connections[i].db_id == vt_connection.db_id:
+                if not self._db_vt_connections[i].is_new:
+                    self.db_deleted_vt_connections.append(self._db_vt_connections[i])
+                del self._db_vt_connections[i]
+                break
+        del self.db_vt_connections_id_index[vt_connection.db_id]
+    def db_get_vt_connection(self, key):
+        for i in xrange(len(self._db_vt_connections)):
+            if self._db_vt_connections[i].db_id == key:
+                return self._db_vt_connections[i]
+        return None
+    def db_get_vt_connection_by_id(self, key):
+        return self.db_vt_connections_id_index[key]
+    def db_has_vt_connection_with_id(self, key):
+        return key in self.db_vt_connections_id_index
     
-    def __get_db_newObjId(self):
-        return self._db_newObjId
-    def __set_db_newObjId(self, newObjId):
-        self._db_newObjId = newObjId
+    def __get_db_prov_usages(self):
+        return self._db_prov_usages
+    def __set_db_prov_usages(self, prov_usages):
+        self._db_prov_usages = prov_usages
         self.is_dirty = True
-    db_newObjId = property(__get_db_newObjId, __set_db_newObjId)
-    def db_add_newObjId(self, newObjId):
-        self._db_newObjId = newObjId
-    def db_change_newObjId(self, newObjId):
-        self._db_newObjId = newObjId
-    def db_delete_newObjId(self, newObjId):
-        self._db_newObjId = None
+    db_prov_usages = property(__get_db_prov_usages, __set_db_prov_usages)
+    def db_get_prov_usages(self):
+        return self._db_prov_usages
+    def db_add_prov_usage(self, prov_usage):
+        self.is_dirty = True
+        self._db_prov_usages.append(prov_usage)
+    def db_change_prov_usage(self, prov_usage):
+        self.is_dirty = True
+        self._db_prov_usages.append(prov_usage)
+    def db_delete_prov_usage(self, prov_usage):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_prov_usage(self, key):
+        return None
     
-    def __get_db_parentObjId(self):
-        return self._db_parentObjId
-    def __set_db_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
+    def __get_db_prov_generations(self):
+        return self._db_prov_generations
+    def __set_db_prov_generations(self, prov_generations):
+        self._db_prov_generations = prov_generations
         self.is_dirty = True
-    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
-    def db_add_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
-    def db_change_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
-    def db_delete_parentObjId(self, parentObjId):
-        self._db_parentObjId = None
+    db_prov_generations = property(__get_db_prov_generations, __set_db_prov_generations)
+    def db_get_prov_generations(self):
+        return self._db_prov_generations
+    def db_add_prov_generation(self, prov_generation):
+        self.is_dirty = True
+        self._db_prov_generations.append(prov_generation)
+    def db_change_prov_generation(self, prov_generation):
+        self.is_dirty = True
+        self._db_prov_generations.append(prov_generation)
+    def db_delete_prov_generation(self, prov_generation):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_prov_generation(self, key):
+        return None
     
-    def __get_db_parentObjType(self):
-        return self._db_parentObjType
-    def __set_db_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
+    def __get_db_prov_associations(self):
+        return self._db_prov_associations
+    def __set_db_prov_associations(self, prov_associations):
+        self._db_prov_associations = prov_associations
         self.is_dirty = True
-    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
-    def db_add_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-    def db_change_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-    def db_delete_parentObjType(self, parentObjType):
-        self._db_parentObjType = None
+    db_prov_associations = property(__get_db_prov_associations, __set_db_prov_associations)
+    def db_get_prov_associations(self):
+        return self._db_prov_associations
+    def db_add_prov_association(self, prov_association):
+        self.is_dirty = True
+        self._db_prov_associations.append(prov_association)
+    def db_change_prov_association(self, prov_association):
+        self.is_dirty = True
+        self._db_prov_associations.append(prov_association)
+    def db_delete_prov_association(self, prov_association):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_prov_association(self, key):
+        return None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBOpmWasDerivedFrom(object):
 
-    vtType = 'opm_was_derived_from'
+class DBOpmProcesses(object):
 
-    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
-        self.db_deleted_effect = []
-        self._db_effect = effect
-        self.db_deleted_role = []
-        self._db_role = role
-        self.db_deleted_cause = []
-        self._db_cause = cause
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
-        else:
-            self._db_accounts = accounts
-        self.db_deleted_opm_times = []
-        if opm_times is None:
-            self._db_opm_times = []
+    vtType = 'opm_processes'
+
+    def __init__(self, processs=None):
+        self.db_deleted_processs = []
+        self.db_processs_id_index = {}
+        if processs is None:
+            self._db_processs = []
         else:
-            self._db_opm_times = opm_times
+            self._db_processs = processs
+            for v in self._db_processs:
+                self.db_processs_id_index[v.db_id] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmWasDerivedFrom.do_copy(self)
+        return DBOpmProcesses.do_copy(self)
 
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmWasDerivedFrom()
-        if self._db_effect is not None:
-            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
-        if self._db_role is not None:
-            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
-        if self._db_cause is not None:
-            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
-        else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        if self._db_opm_times is None:
-            cp._db_opm_times = []
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmProcesses()
+        if self._db_processs is None:
+            cp._db_processs = []
         else:
-            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+            cp._db_processs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_processs]
         
         # set new ids
         if new_ids:
@@ -11326,6 +13075,7 @@ class DBOpmWasDerivedFrom(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_processs_id_index = dict((v.db_id, v) for v in cp._db_processs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -11334,238 +13084,107 @@ class DBOpmWasDerivedFrom(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmWasDerivedFrom()
+            new_obj = DBOpmProcesses()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'effect' in class_dict:
-            res = class_dict['effect'](old_obj, trans_dict)
-            new_obj.db_effect = res
-        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
-            obj = old_obj.db_effect
-            new_obj.db_add_effect(DBOpmArtifactIdEffect.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
-            for obj in old_obj.db_deleted_effect:
-                n_obj = DBOpmArtifactIdEffect.update_version(obj, trans_dict)
-                new_obj.db_deleted_effect.append(n_obj)
-        if 'role' in class_dict:
-            res = class_dict['role'](old_obj, trans_dict)
-            new_obj.db_role = res
-        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
-            obj = old_obj.db_role
-            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
-            for obj in old_obj.db_deleted_role:
-                n_obj = DBOpmRole.update_version(obj, trans_dict)
-                new_obj.db_deleted_role.append(n_obj)
-        if 'cause' in class_dict:
-            res = class_dict['cause'](old_obj, trans_dict)
-            new_obj.db_cause = res
-        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
-            obj = old_obj.db_cause
-            new_obj.db_add_cause(DBOpmArtifactIdCause.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
-            for obj in old_obj.db_deleted_cause:
-                n_obj = DBOpmArtifactIdCause.update_version(obj, trans_dict)
-                new_obj.db_deleted_cause.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
-        if 'opm_times' in class_dict:
-            res = class_dict['opm_times'](old_obj, trans_dict)
+        if 'processs' in class_dict:
+            res = class_dict['processs'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_opm_time(obj)
-        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
-            for obj in old_obj.db_opm_times:
-                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
-            for obj in old_obj.db_deleted_opm_times:
-                n_obj = DBOpmTime.update_version(obj, trans_dict)
-                new_obj.db_deleted_opm_times.append(n_obj)
+                new_obj.db_add_process(obj)
+        elif hasattr(old_obj, 'db_processs') and old_obj.db_processs is not None:
+            for obj in old_obj.db_processs:
+                new_obj.db_add_process(DBOpmProcess.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_processs') and hasattr(new_obj, 'db_deleted_processs'):
+            for obj in old_obj.db_deleted_processs:
+                n_obj = DBOpmProcess.update_version(obj, trans_dict)
+                new_obj.db_deleted_processs.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_effect is not None:
-            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_effect = None
-        if self._db_role is not None:
-            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_role = None
-        if self._db_cause is not None:
-            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_cause = None
-        to_del = []
-        for child in self.db_accounts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_account(child)
         to_del = []
-        for child in self.db_opm_times:
+        for child in self.db_processs:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_opm_time(child)
+            self.db_delete_process(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_effect)
-        children.extend(self.db_deleted_role)
-        children.extend(self.db_deleted_cause)
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_opm_times)
+        children.extend(self.db_deleted_processs)
         if remove:
-            self.db_deleted_effect = []
-            self.db_deleted_role = []
-            self.db_deleted_cause = []
-            self.db_deleted_accounts = []
-            self.db_deleted_opm_times = []
+            self.db_deleted_processs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_effect is not None and self._db_effect.has_changes():
-            return True
-        if self._db_role is not None and self._db_role.has_changes():
-            return True
-        if self._db_cause is not None and self._db_cause.has_changes():
-            return True
-        for child in self._db_accounts:
-            if child.has_changes():
-                return True
-        for child in self._db_opm_times:
+        for child in self._db_processs:
             if child.has_changes():
                 return True
         return False
-    def __get_db_effect(self):
-        return self._db_effect
-    def __set_db_effect(self, effect):
-        self._db_effect = effect
-        self.is_dirty = True
-    db_effect = property(__get_db_effect, __set_db_effect)
-    def db_add_effect(self, effect):
-        self._db_effect = effect
-    def db_change_effect(self, effect):
-        self._db_effect = effect
-    def db_delete_effect(self, effect):
-        if not self.is_new:
-            self.db_deleted_effect.append(self._db_effect)
-        self._db_effect = None
-    
-    def __get_db_role(self):
-        return self._db_role
-    def __set_db_role(self, role):
-        self._db_role = role
-        self.is_dirty = True
-    db_role = property(__get_db_role, __set_db_role)
-    def db_add_role(self, role):
-        self._db_role = role
-    def db_change_role(self, role):
-        self._db_role = role
-    def db_delete_role(self, role):
-        if not self.is_new:
-            self.db_deleted_role.append(self._db_role)
-        self._db_role = None
-    
-    def __get_db_cause(self):
-        return self._db_cause
-    def __set_db_cause(self, cause):
-        self._db_cause = cause
-        self.is_dirty = True
-    db_cause = property(__get_db_cause, __set_db_cause)
-    def db_add_cause(self, cause):
-        self._db_cause = cause
-    def db_change_cause(self, cause):
-        self._db_cause = cause
-    def db_delete_cause(self, cause):
-        if not self.is_new:
-            self.db_deleted_cause.append(self._db_cause)
-        self._db_cause = None
-    
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
-        self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
-        self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
-        self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
-        self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
-        return None
-    
-    def __get_db_opm_times(self):
-        return self._db_opm_times
-    def __set_db_opm_times(self, opm_times):
-        self._db_opm_times = opm_times
+    def __get_db_processs(self):
+        return self._db_processs
+    def __set_db_processs(self, processs):
+        self._db_processs = processs
         self.is_dirty = True
-    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
-    def db_get_opm_times(self):
-        return self._db_opm_times
-    def db_add_opm_time(self, opm_time):
+    db_processs = property(__get_db_processs, __set_db_processs)
+    def db_get_processs(self):
+        return self._db_processs
+    def db_add_process(self, process):
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_change_opm_time(self, opm_time):
+        self._db_processs.append(process)
+        self.db_processs_id_index[process.db_id] = process
+    def db_change_process(self, process):
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_delete_opm_time(self, opm_time):
+        found = False
+        for i in xrange(len(self._db_processs)):
+            if self._db_processs[i].db_id == process.db_id:
+                self._db_processs[i] = process
+                found = True
+                break
+        if not found:
+            self._db_processs.append(process)
+        self.db_processs_id_index[process.db_id] = process
+    def db_delete_process(self, process):
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_opm_time(self, key):
+        for i in xrange(len(self._db_processs)):
+            if self._db_processs[i].db_id == process.db_id:
+                if not self._db_processs[i].is_new:
+                    self.db_deleted_processs.append(self._db_processs[i])
+                del self._db_processs[i]
+                break
+        del self.db_processs_id_index[process.db_id]
+    def db_get_process(self, key):
+        for i in xrange(len(self._db_processs)):
+            if self._db_processs[i].db_id == key:
+                return self._db_processs[i]
         return None
+    def db_get_process_by_id(self, key):
+        return self.db_processs_id_index[key]
+    def db_has_process_with_id(self, key):
+        return key in self.db_processs_id_index
     
 
 
-class DBOpmArtifacts(object):
+class DBOpmAccountId(object):
 
-    vtType = 'opm_artifacts'
+    vtType = 'opm_account_id'
 
-    def __init__(self, artifacts=None):
-        self.db_deleted_artifacts = []
-        self.db_artifacts_id_index = {}
-        if artifacts is None:
-            self._db_artifacts = []
-        else:
-            self._db_artifacts = artifacts
-            for v in self._db_artifacts:
-                self.db_artifacts_id_index[v.db_id] = v
+    def __init__(self, id=None):
+        self._db_id = id
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmArtifacts.do_copy(self)
+        return DBOpmAccountId.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmArtifacts()
-        if self._db_artifacts is None:
-            cp._db_artifacts = []
-        else:
-            cp._db_artifacts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_artifacts]
+        cp = DBOpmAccountId(id=self._db_id)
         
         # set new ids
         if new_ids:
@@ -11575,9 +13194,10 @@ class DBOpmArtifacts(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_account', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_account', self._db_id)]
         
         # recreate indices and set flags
-        cp.db_artifacts_id_index = dict((v.db_id, v) for v in cp._db_artifacts)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -11586,145 +13206,73 @@ class DBOpmArtifacts(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmArtifacts()
+            new_obj = DBOpmAccountId()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'artifacts' in class_dict:
-            res = class_dict['artifacts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_artifact(obj)
-        elif hasattr(old_obj, 'db_artifacts') and old_obj.db_artifacts is not None:
-            for obj in old_obj.db_artifacts:
-                new_obj.db_add_artifact(DBOpmArtifact.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_artifacts') and hasattr(new_obj, 'db_deleted_artifacts'):
-            for obj in old_obj.db_deleted_artifacts:
-                n_obj = DBOpmArtifact.update_version(obj, trans_dict)
-                new_obj.db_deleted_artifacts.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_artifacts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_artifact(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_artifacts)
-        if remove:
-            self.db_deleted_artifacts = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_artifacts:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_artifacts(self):
-        return self._db_artifacts
-    def __set_db_artifacts(self, artifacts):
-        self._db_artifacts = artifacts
-        self.is_dirty = True
-    db_artifacts = property(__get_db_artifacts, __set_db_artifacts)
-    def db_get_artifacts(self):
-        return self._db_artifacts
-    def db_add_artifact(self, artifact):
-        self.is_dirty = True
-        self._db_artifacts.append(artifact)
-        self.db_artifacts_id_index[artifact.db_id] = artifact
-    def db_change_artifact(self, artifact):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_artifacts)):
-            if self._db_artifacts[i].db_id == artifact.db_id:
-                self._db_artifacts[i] = artifact
-                found = True
-                break
-        if not found:
-            self._db_artifacts.append(artifact)
-        self.db_artifacts_id_index[artifact.db_id] = artifact
-    def db_delete_artifact(self, artifact):
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-        for i in xrange(len(self._db_artifacts)):
-            if self._db_artifacts[i].db_id == artifact.db_id:
-                if not self._db_artifacts[i].is_new:
-                    self.db_deleted_artifacts.append(self._db_artifacts[i])
-                del self._db_artifacts[i]
-                break
-        del self.db_artifacts_id_index[artifact.db_id]
-    def db_get_artifact(self, key):
-        for i in xrange(len(self._db_artifacts)):
-            if self._db_artifacts[i].db_id == key:
-                return self._db_artifacts[i]
-        return None
-    def db_get_artifact_by_id(self, key):
-        return self.db_artifacts_id_index[key]
-    def db_has_artifact_with_id(self, key):
-        return key in self.db_artifacts_id_index
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
 
 
-class DBOpmWasControlledBy(object):
+class DBPortSpecItem(object):
 
-    vtType = 'opm_was_controlled_by'
+    vtType = 'portSpecItem'
 
-    def __init__(self, effect=None, role=None, cause=None, accounts=None, starts=None, ends=None):
-        self.db_deleted_effect = []
-        self._db_effect = effect
-        self.db_deleted_role = []
-        self._db_role = role
-        self.db_deleted_cause = []
-        self._db_cause = cause
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
-        else:
-            self._db_accounts = accounts
-        self.db_deleted_starts = []
-        if starts is None:
-            self._db_starts = []
-        else:
-            self._db_starts = starts
-        self.db_deleted_ends = []
-        if ends is None:
-            self._db_ends = []
-        else:
-            self._db_ends = ends
+    def __init__(self, id=None, pos=None, module=None, package=None, namespace=None, label=None, default=None, values=None, entry_type=None):
+        self._db_id = id
+        self._db_pos = pos
+        self._db_module = module
+        self._db_package = package
+        self._db_namespace = namespace
+        self._db_label = label
+        self._db_default = default
+        self._db_values = values
+        self._db_entry_type = entry_type
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmWasControlledBy.do_copy(self)
+        return DBPortSpecItem.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmWasControlledBy()
-        if self._db_effect is not None:
-            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
-        if self._db_role is not None:
-            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
-        if self._db_cause is not None:
-            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
-        else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        if self._db_starts is None:
-            cp._db_starts = []
-        else:
-            cp._db_starts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_starts]
-        if self._db_ends is None:
-            cp._db_ends = []
-        else:
-            cp._db_ends = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_ends]
+        cp = DBPortSpecItem(id=self._db_id,
+                            pos=self._db_pos,
+                            module=self._db_module,
+                            package=self._db_package,
+                            namespace=self._db_namespace,
+                            label=self._db_label,
+                            default=self._db_default,
+                            values=self._db_values,
+                            entry_type=self._db_entry_type)
         
         # set new ids
         if new_ids:
@@ -11744,384 +13292,234 @@ class DBOpmWasControlledBy(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmWasControlledBy()
+            new_obj = DBPortSpecItem()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'effect' in class_dict:
-            res = class_dict['effect'](old_obj, trans_dict)
-            new_obj.db_effect = res
-        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
-            obj = old_obj.db_effect
-            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
-            for obj in old_obj.db_deleted_effect:
-                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
-                new_obj.db_deleted_effect.append(n_obj)
-        if 'role' in class_dict:
-            res = class_dict['role'](old_obj, trans_dict)
-            new_obj.db_role = res
-        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
-            obj = old_obj.db_role
-            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
-            for obj in old_obj.db_deleted_role:
-                n_obj = DBOpmRole.update_version(obj, trans_dict)
-                new_obj.db_deleted_role.append(n_obj)
-        if 'cause' in class_dict:
-            res = class_dict['cause'](old_obj, trans_dict)
-            new_obj.db_cause = res
-        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
-            obj = old_obj.db_cause
-            new_obj.db_add_cause(DBOpmAgentId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
-            for obj in old_obj.db_deleted_cause:
-                n_obj = DBOpmAgentId.update_version(obj, trans_dict)
-                new_obj.db_deleted_cause.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
-        if 'starts' in class_dict:
-            res = class_dict['starts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_start(obj)
-        elif hasattr(old_obj, 'db_starts') and old_obj.db_starts is not None:
-            for obj in old_obj.db_starts:
-                new_obj.db_add_start(DBOpmTime.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_starts') and hasattr(new_obj, 'db_deleted_starts'):
-            for obj in old_obj.db_deleted_starts:
-                n_obj = DBOpmTime.update_version(obj, trans_dict)
-                new_obj.db_deleted_starts.append(n_obj)
-        if 'ends' in class_dict:
-            res = class_dict['ends'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_end(obj)
-        elif hasattr(old_obj, 'db_ends') and old_obj.db_ends is not None:
-            for obj in old_obj.db_ends:
-                new_obj.db_add_end(DBOpmTime.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_ends') and hasattr(new_obj, 'db_deleted_ends'):
-            for obj in old_obj.db_deleted_ends:
-                n_obj = DBOpmTime.update_version(obj, trans_dict)
-                new_obj.db_deleted_ends.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'module' in class_dict:
+            res = class_dict['module'](old_obj, trans_dict)
+            new_obj.db_module = res
+        elif hasattr(old_obj, 'db_module') and old_obj.db_module is not None:
+            new_obj.db_module = old_obj.db_module
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'label' in class_dict:
+            res = class_dict['label'](old_obj, trans_dict)
+            new_obj.db_label = res
+        elif hasattr(old_obj, 'db_label') and old_obj.db_label is not None:
+            new_obj.db_label = old_obj.db_label
+        if 'default' in class_dict:
+            res = class_dict['default'](old_obj, trans_dict)
+            new_obj.db_default = res
+        elif hasattr(old_obj, 'db_default') and old_obj.db_default is not None:
+            new_obj.db_default = old_obj.db_default
+        if 'values' in class_dict:
+            res = class_dict['values'](old_obj, trans_dict)
+            new_obj.db_values = res
+        elif hasattr(old_obj, 'db_values') and old_obj.db_values is not None:
+            new_obj.db_values = old_obj.db_values
+        if 'entry_type' in class_dict:
+            res = class_dict['entry_type'](old_obj, trans_dict)
+            new_obj.db_entry_type = res
+        elif hasattr(old_obj, 'db_entry_type') and old_obj.db_entry_type is not None:
+            new_obj.db_entry_type = old_obj.db_entry_type
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_effect is not None:
-            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_effect = None
-        if self._db_role is not None:
-            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_role = None
-        if self._db_cause is not None:
-            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_cause = None
-        to_del = []
-        for child in self.db_accounts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_account(child)
-        to_del = []
-        for child in self.db_starts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_start(child)
-        to_del = []
-        for child in self.db_ends:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_end(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_effect)
-        children.extend(self.db_deleted_role)
-        children.extend(self.db_deleted_cause)
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_starts)
-        children.extend(self.db_deleted_ends)
-        if remove:
-            self.db_deleted_effect = []
-            self.db_deleted_role = []
-            self.db_deleted_cause = []
-            self.db_deleted_accounts = []
-            self.db_deleted_starts = []
-            self.db_deleted_ends = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_effect is not None and self._db_effect.has_changes():
-            return True
-        if self._db_role is not None and self._db_role.has_changes():
-            return True
-        if self._db_cause is not None and self._db_cause.has_changes():
-            return True
-        for child in self._db_accounts:
-            if child.has_changes():
-                return True
-        for child in self._db_starts:
-            if child.has_changes():
-                return True
-        for child in self._db_ends:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_effect(self):
-        return self._db_effect
-    def __set_db_effect(self, effect):
-        self._db_effect = effect
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_effect = property(__get_db_effect, __set_db_effect)
-    def db_add_effect(self, effect):
-        self._db_effect = effect
-    def db_change_effect(self, effect):
-        self._db_effect = effect
-    def db_delete_effect(self, effect):
-        if not self.is_new:
-            self.db_deleted_effect.append(self._db_effect)
-        self._db_effect = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_role(self):
-        return self._db_role
-    def __set_db_role(self, role):
-        self._db_role = role
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
         self.is_dirty = True
-    db_role = property(__get_db_role, __set_db_role)
-    def db_add_role(self, role):
-        self._db_role = role
-    def db_change_role(self, role):
-        self._db_role = role
-    def db_delete_role(self, role):
-        if not self.is_new:
-            self.db_deleted_role.append(self._db_role)
-        self._db_role = None
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
     
-    def __get_db_cause(self):
-        return self._db_cause
-    def __set_db_cause(self, cause):
-        self._db_cause = cause
+    def __get_db_module(self):
+        return self._db_module
+    def __set_db_module(self, module):
+        self._db_module = module
         self.is_dirty = True
-    db_cause = property(__get_db_cause, __set_db_cause)
-    def db_add_cause(self, cause):
-        self._db_cause = cause
-    def db_change_cause(self, cause):
-        self._db_cause = cause
-    def db_delete_cause(self, cause):
-        if not self.is_new:
-            self.db_deleted_cause.append(self._db_cause)
-        self._db_cause = None
+    db_module = property(__get_db_module, __set_db_module)
+    def db_add_module(self, module):
+        self._db_module = module
+    def db_change_module(self, module):
+        self._db_module = module
+    def db_delete_module(self, module):
+        self._db_module = None
     
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
-        self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
-        self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
-        self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
-        return None
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
     
-    def __get_db_starts(self):
-        return self._db_starts
-    def __set_db_starts(self, starts):
-        self._db_starts = starts
-        self.is_dirty = True
-    db_starts = property(__get_db_starts, __set_db_starts)
-    def db_get_starts(self):
-        return self._db_starts
-    def db_add_start(self, start):
-        self.is_dirty = True
-        self._db_starts.append(start)
-    def db_change_start(self, start):
-        self.is_dirty = True
-        self._db_starts.append(start)
-    def db_delete_start(self, start):
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_start(self, key):
-        return None
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
     
-    def __get_db_ends(self):
-        return self._db_ends
-    def __set_db_ends(self, ends):
-        self._db_ends = ends
-        self.is_dirty = True
-    db_ends = property(__get_db_ends, __set_db_ends)
-    def db_get_ends(self):
-        return self._db_ends
-    def db_add_end(self, end):
-        self.is_dirty = True
-        self._db_ends.append(end)
-    def db_change_end(self, end):
+    def __get_db_label(self):
+        return self._db_label
+    def __set_db_label(self, label):
+        self._db_label = label
         self.is_dirty = True
-        self._db_ends.append(end)
-    def db_delete_end(self, end):
+    db_label = property(__get_db_label, __set_db_label)
+    def db_add_label(self, label):
+        self._db_label = label
+    def db_change_label(self, label):
+        self._db_label = label
+    def db_delete_label(self, label):
+        self._db_label = None
+    
+    def __get_db_default(self):
+        return self._db_default
+    def __set_db_default(self, default):
+        self._db_default = default
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_end(self, key):
-        return None
+    db_default = property(__get_db_default, __set_db_default)
+    def db_add_default(self, default):
+        self._db_default = default
+    def db_change_default(self, default):
+        self._db_default = default
+    def db_delete_default(self, default):
+        self._db_default = None
     
-
-
-class DBOpmAgentId(object):
-
-    vtType = 'opm_agent_id'
-
-    def __init__(self, id=None):
-        self._db_id = id
+    def __get_db_values(self):
+        return self._db_values
+    def __set_db_values(self, values):
+        self._db_values = values
         self.is_dirty = True
-        self.is_new = True
+    db_values = property(__get_db_values, __set_db_values)
+    def db_add_values(self, values):
+        self._db_values = values
+    def db_change_values(self, values):
+        self._db_values = values
+    def db_delete_values(self, values):
+        self._db_values = None
     
-    def __copy__(self):
-        return DBOpmAgentId.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmAgentId(id=self._db_id)
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
-            if self.vtType in id_scope.remap:
-                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-            if hasattr(self, 'db_id') and ('opm_agent', self._db_id) in id_remap:
-                cp._db_id = id_remap[('opm_agent', self._db_id)]
-        
-        # recreate indices and set flags
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBOpmAgentId()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
-    def db_deleted_children(self, remove=False):
-        children = []
-        return children
-    def has_changes(self):
-        if self.is_dirty:
-            return True
-        return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
+    def __get_db_entry_type(self):
+        return self._db_entry_type
+    def __set_db_entry_type(self, entry_type):
+        self._db_entry_type = entry_type
         self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
+    db_entry_type = property(__get_db_entry_type, __set_db_entry_type)
+    def db_add_entry_type(self, entry_type):
+        self._db_entry_type = entry_type
+    def db_change_entry_type(self, entry_type):
+        self._db_entry_type = entry_type
+    def db_delete_entry_type(self, entry_type):
+        self._db_entry_type = None
     
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBMashupComponent(object):
 
-class DBGroupExec(object):
-
-    vtType = 'group_exec'
+    vtType = 'mashup_component'
 
-    def __init__(self, item_execs=None, id=None, ts_start=None, ts_end=None, cached=None, module_id=None, group_name=None, group_type=None, completed=None, error=None, machine_id=None, annotations=None):
-        self.db_deleted_item_execs = []
-        self.db_item_execs_id_index = {}
-        if item_execs is None:
-            self._db_item_execs = []
-        else:
-            self._db_item_execs = item_execs
-            for v in self._db_item_execs:
-                self.db_item_execs_id_index[v.db_id] = v
+    def __init__(self, id=None, vtid=None, vttype=None, vtparent_type=None, vtparent_id=None, vtpos=None, vtmid=None, pos=None, type=None, val=None, minVal=None, maxVal=None, stepSize=None, strvaluelist=None, widget=None, seq=None, parent=None):
         self._db_id = id
-        self._db_ts_start = ts_start
-        self._db_ts_end = ts_end
-        self._db_cached = cached
-        self._db_module_id = module_id
-        self._db_group_name = group_name
-        self._db_group_type = group_type
-        self._db_completed = completed
-        self._db_error = error
-        self._db_machine_id = machine_id
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        if annotations is None:
-            self._db_annotations = []
-        else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
+        self._db_vtid = vtid
+        self._db_vttype = vttype
+        self._db_vtparent_type = vtparent_type
+        self._db_vtparent_id = vtparent_id
+        self._db_vtpos = vtpos
+        self._db_vtmid = vtmid
+        self._db_pos = pos
+        self._db_type = type
+        self._db_val = val
+        self._db_minVal = minVal
+        self._db_maxVal = maxVal
+        self._db_stepSize = stepSize
+        self._db_strvaluelist = strvaluelist
+        self._db_widget = widget
+        self._db_seq = seq
+        self._db_parent = parent
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBGroupExec.do_copy(self)
+        return DBMashupComponent.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBGroupExec(id=self._db_id,
-                         ts_start=self._db_ts_start,
-                         ts_end=self._db_ts_end,
-                         cached=self._db_cached,
-                         module_id=self._db_module_id,
-                         group_name=self._db_group_name,
-                         group_type=self._db_group_type,
-                         completed=self._db_completed,
-                         error=self._db_error,
-                         machine_id=self._db_machine_id)
-        if self._db_item_execs is None:
-            cp._db_item_execs = []
-        else:
-            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
-        if self._db_annotations is None:
-            cp._db_annotations = []
-        else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        cp = DBMashupComponent(id=self._db_id,
+                               vtid=self._db_vtid,
+                               vttype=self._db_vttype,
+                               vtparent_type=self._db_vtparent_type,
+                               vtparent_id=self._db_vtparent_id,
+                               vtpos=self._db_vtpos,
+                               vtmid=self._db_vtmid,
+                               pos=self._db_pos,
+                               type=self._db_type,
+                               val=self._db_val,
+                               minVal=self._db_minVal,
+                               maxVal=self._db_maxVal,
+                               stepSize=self._db_stepSize,
+                               strvaluelist=self._db_strvaluelist,
+                               widget=self._db_widget,
+                               seq=self._db_seq,
+                               parent=self._db_parent)
         
         # set new ids
         if new_ids:
@@ -12131,14 +13529,8 @@ class DBGroupExec(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
-                cp._db_module_id = id_remap[('module', self._db_module_id)]
-            if hasattr(self, 'db_machine_id') and ('machine', self._db_machine_id) in id_remap:
-                cp._db_machine_id = id_remap[('machine', self._db_machine_id)]
         
         # recreate indices and set flags
-        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -12147,176 +13539,108 @@ class DBGroupExec(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBGroupExec()
+            new_obj = DBMashupComponent()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'item_execs' in class_dict:
-            res = class_dict['item_execs'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_item_exec(obj)
-        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
-            for obj in old_obj.db_item_execs:
-                if obj.vtType == 'module_exec':
-                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
-                elif obj.vtType == 'group_exec':
-                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
-                elif obj.vtType == 'loop_exec':
-                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
-            for obj in old_obj.db_deleted_item_execs:
-                if obj.vtType == 'module_exec':
-                    n_obj = DBModuleExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-                elif obj.vtType == 'group_exec':
-                    n_obj = DBGroupExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-                elif obj.vtType == 'loop_exec':
-                    n_obj = DBLoopExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'ts_start' in class_dict:
-            res = class_dict['ts_start'](old_obj, trans_dict)
-            new_obj.db_ts_start = res
-        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
-            new_obj.db_ts_start = old_obj.db_ts_start
-        if 'ts_end' in class_dict:
-            res = class_dict['ts_end'](old_obj, trans_dict)
-            new_obj.db_ts_end = res
-        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
-            new_obj.db_ts_end = old_obj.db_ts_end
-        if 'cached' in class_dict:
-            res = class_dict['cached'](old_obj, trans_dict)
-            new_obj.db_cached = res
-        elif hasattr(old_obj, 'db_cached') and old_obj.db_cached is not None:
-            new_obj.db_cached = old_obj.db_cached
-        if 'module_id' in class_dict:
-            res = class_dict['module_id'](old_obj, trans_dict)
-            new_obj.db_module_id = res
-        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
-            new_obj.db_module_id = old_obj.db_module_id
-        if 'group_name' in class_dict:
-            res = class_dict['group_name'](old_obj, trans_dict)
-            new_obj.db_group_name = res
-        elif hasattr(old_obj, 'db_group_name') and old_obj.db_group_name is not None:
-            new_obj.db_group_name = old_obj.db_group_name
-        if 'group_type' in class_dict:
-            res = class_dict['group_type'](old_obj, trans_dict)
-            new_obj.db_group_type = res
-        elif hasattr(old_obj, 'db_group_type') and old_obj.db_group_type is not None:
-            new_obj.db_group_type = old_obj.db_group_type
-        if 'completed' in class_dict:
-            res = class_dict['completed'](old_obj, trans_dict)
-            new_obj.db_completed = res
-        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
-            new_obj.db_completed = old_obj.db_completed
-        if 'error' in class_dict:
-            res = class_dict['error'](old_obj, trans_dict)
-            new_obj.db_error = res
-        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
-            new_obj.db_error = old_obj.db_error
-        if 'machine_id' in class_dict:
-            res = class_dict['machine_id'](old_obj, trans_dict)
-            new_obj.db_machine_id = res
-        elif hasattr(old_obj, 'db_machine_id') and old_obj.db_machine_id is not None:
-            new_obj.db_machine_id = old_obj.db_machine_id
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'vtid' in class_dict:
+            res = class_dict['vtid'](old_obj, trans_dict)
+            new_obj.db_vtid = res
+        elif hasattr(old_obj, 'db_vtid') and old_obj.db_vtid is not None:
+            new_obj.db_vtid = old_obj.db_vtid
+        if 'vttype' in class_dict:
+            res = class_dict['vttype'](old_obj, trans_dict)
+            new_obj.db_vttype = res
+        elif hasattr(old_obj, 'db_vttype') and old_obj.db_vttype is not None:
+            new_obj.db_vttype = old_obj.db_vttype
+        if 'vtparent_type' in class_dict:
+            res = class_dict['vtparent_type'](old_obj, trans_dict)
+            new_obj.db_vtparent_type = res
+        elif hasattr(old_obj, 'db_vtparent_type') and old_obj.db_vtparent_type is not None:
+            new_obj.db_vtparent_type = old_obj.db_vtparent_type
+        if 'vtparent_id' in class_dict:
+            res = class_dict['vtparent_id'](old_obj, trans_dict)
+            new_obj.db_vtparent_id = res
+        elif hasattr(old_obj, 'db_vtparent_id') and old_obj.db_vtparent_id is not None:
+            new_obj.db_vtparent_id = old_obj.db_vtparent_id
+        if 'vtpos' in class_dict:
+            res = class_dict['vtpos'](old_obj, trans_dict)
+            new_obj.db_vtpos = res
+        elif hasattr(old_obj, 'db_vtpos') and old_obj.db_vtpos is not None:
+            new_obj.db_vtpos = old_obj.db_vtpos
+        if 'vtmid' in class_dict:
+            res = class_dict['vtmid'](old_obj, trans_dict)
+            new_obj.db_vtmid = res
+        elif hasattr(old_obj, 'db_vtmid') and old_obj.db_vtmid is not None:
+            new_obj.db_vtmid = old_obj.db_vtmid
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'val' in class_dict:
+            res = class_dict['val'](old_obj, trans_dict)
+            new_obj.db_val = res
+        elif hasattr(old_obj, 'db_val') and old_obj.db_val is not None:
+            new_obj.db_val = old_obj.db_val
+        if 'minVal' in class_dict:
+            res = class_dict['minVal'](old_obj, trans_dict)
+            new_obj.db_minVal = res
+        elif hasattr(old_obj, 'db_minVal') and old_obj.db_minVal is not None:
+            new_obj.db_minVal = old_obj.db_minVal
+        if 'maxVal' in class_dict:
+            res = class_dict['maxVal'](old_obj, trans_dict)
+            new_obj.db_maxVal = res
+        elif hasattr(old_obj, 'db_maxVal') and old_obj.db_maxVal is not None:
+            new_obj.db_maxVal = old_obj.db_maxVal
+        if 'stepSize' in class_dict:
+            res = class_dict['stepSize'](old_obj, trans_dict)
+            new_obj.db_stepSize = res
+        elif hasattr(old_obj, 'db_stepSize') and old_obj.db_stepSize is not None:
+            new_obj.db_stepSize = old_obj.db_stepSize
+        if 'strvaluelist' in class_dict:
+            res = class_dict['strvaluelist'](old_obj, trans_dict)
+            new_obj.db_strvaluelist = res
+        elif hasattr(old_obj, 'db_strvaluelist') and old_obj.db_strvaluelist is not None:
+            new_obj.db_strvaluelist = old_obj.db_strvaluelist
+        if 'widget' in class_dict:
+            res = class_dict['widget'](old_obj, trans_dict)
+            new_obj.db_widget = res
+        elif hasattr(old_obj, 'db_widget') and old_obj.db_widget is not None:
+            new_obj.db_widget = old_obj.db_widget
+        if 'seq' in class_dict:
+            res = class_dict['seq'](old_obj, trans_dict)
+            new_obj.db_seq = res
+        elif hasattr(old_obj, 'db_seq') and old_obj.db_seq is not None:
+            new_obj.db_seq = old_obj.db_seq
+        if 'parent' in class_dict:
+            res = class_dict['parent'](old_obj, trans_dict)
+            new_obj.db_parent = res
+        elif hasattr(old_obj, 'db_parent') and old_obj.db_parent is not None:
+            new_obj.db_parent = old_obj.db_parent
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        to_del = []
-        for child in self.db_item_execs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_item_exec(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_item_execs)
-        if remove:
-            self.db_deleted_annotations = []
-            self.db_deleted_item_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
-        for child in self._db_item_execs:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_item_execs(self):
-        return self._db_item_execs
-    def __set_db_item_execs(self, item_execs):
-        self._db_item_execs = item_execs
-        self.is_dirty = True
-    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
-    def db_get_item_execs(self):
-        return self._db_item_execs
-    def db_add_item_exec(self, item_exec):
-        self.is_dirty = True
-        self._db_item_execs.append(item_exec)
-        self.db_item_execs_id_index[item_exec.db_id] = item_exec
-    def db_change_item_exec(self, item_exec):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == item_exec.db_id:
-                self._db_item_execs[i] = item_exec
-                found = True
-                break
-        if not found:
-            self._db_item_execs.append(item_exec)
-        self.db_item_execs_id_index[item_exec.db_id] = item_exec
-    def db_delete_item_exec(self, item_exec):
-        self.is_dirty = True
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == item_exec.db_id:
-                if not self._db_item_execs[i].is_new:
-                    self.db_deleted_item_execs.append(self._db_item_execs[i])
-                del self._db_item_execs[i]
-                break
-        del self.db_item_execs_id_index[item_exec.db_id]
-    def db_get_item_exec(self, key):
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == key:
-                return self._db_item_execs[i]
-        return None
-    def db_get_item_exec_by_id(self, key):
-        return self.db_item_execs_id_index[key]
-    def db_has_item_exec_with_id(self, key):
-        return key in self.db_item_execs_id_index
-    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -12330,186 +13654,257 @@ class DBGroupExec(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_ts_start(self):
-        return self._db_ts_start
-    def __set_db_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
+    def __get_db_vtid(self):
+        return self._db_vtid
+    def __set_db_vtid(self, vtid):
+        self._db_vtid = vtid
         self.is_dirty = True
-    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
-    def db_add_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_change_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_delete_ts_start(self, ts_start):
-        self._db_ts_start = None
+    db_vtid = property(__get_db_vtid, __set_db_vtid)
+    def db_add_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_change_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_delete_vtid(self, vtid):
+        self._db_vtid = None
     
-    def __get_db_ts_end(self):
-        return self._db_ts_end
-    def __set_db_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
+    def __get_db_vttype(self):
+        return self._db_vttype
+    def __set_db_vttype(self, vttype):
+        self._db_vttype = vttype
         self.is_dirty = True
-    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
-    def db_add_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_change_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_delete_ts_end(self, ts_end):
-        self._db_ts_end = None
+    db_vttype = property(__get_db_vttype, __set_db_vttype)
+    def db_add_vttype(self, vttype):
+        self._db_vttype = vttype
+    def db_change_vttype(self, vttype):
+        self._db_vttype = vttype
+    def db_delete_vttype(self, vttype):
+        self._db_vttype = None
     
-    def __get_db_cached(self):
-        return self._db_cached
-    def __set_db_cached(self, cached):
-        self._db_cached = cached
+    def __get_db_vtparent_type(self):
+        return self._db_vtparent_type
+    def __set_db_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = vtparent_type
         self.is_dirty = True
-    db_cached = property(__get_db_cached, __set_db_cached)
-    def db_add_cached(self, cached):
-        self._db_cached = cached
-    def db_change_cached(self, cached):
-        self._db_cached = cached
-    def db_delete_cached(self, cached):
-        self._db_cached = None
+    db_vtparent_type = property(__get_db_vtparent_type, __set_db_vtparent_type)
+    def db_add_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = vtparent_type
+    def db_change_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = vtparent_type
+    def db_delete_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = None
+    
+    def __get_db_vtparent_id(self):
+        return self._db_vtparent_id
+    def __set_db_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = vtparent_id
+        self.is_dirty = True
+    db_vtparent_id = property(__get_db_vtparent_id, __set_db_vtparent_id)
+    def db_add_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = vtparent_id
+    def db_change_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = vtparent_id
+    def db_delete_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = None
+    
+    def __get_db_vtpos(self):
+        return self._db_vtpos
+    def __set_db_vtpos(self, vtpos):
+        self._db_vtpos = vtpos
+        self.is_dirty = True
+    db_vtpos = property(__get_db_vtpos, __set_db_vtpos)
+    def db_add_vtpos(self, vtpos):
+        self._db_vtpos = vtpos
+    def db_change_vtpos(self, vtpos):
+        self._db_vtpos = vtpos
+    def db_delete_vtpos(self, vtpos):
+        self._db_vtpos = None
+    
+    def __get_db_vtmid(self):
+        return self._db_vtmid
+    def __set_db_vtmid(self, vtmid):
+        self._db_vtmid = vtmid
+        self.is_dirty = True
+    db_vtmid = property(__get_db_vtmid, __set_db_vtmid)
+    def db_add_vtmid(self, vtmid):
+        self._db_vtmid = vtmid
+    def db_change_vtmid(self, vtmid):
+        self._db_vtmid = vtmid
+    def db_delete_vtmid(self, vtmid):
+        self._db_vtmid = None
     
-    def __get_db_module_id(self):
-        return self._db_module_id
-    def __set_db_module_id(self, module_id):
-        self._db_module_id = module_id
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
         self.is_dirty = True
-    db_module_id = property(__get_db_module_id, __set_db_module_id)
-    def db_add_module_id(self, module_id):
-        self._db_module_id = module_id
-    def db_change_module_id(self, module_id):
-        self._db_module_id = module_id
-    def db_delete_module_id(self, module_id):
-        self._db_module_id = None
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
     
-    def __get_db_group_name(self):
-        return self._db_group_name
-    def __set_db_group_name(self, group_name):
-        self._db_group_name = group_name
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
         self.is_dirty = True
-    db_group_name = property(__get_db_group_name, __set_db_group_name)
-    def db_add_group_name(self, group_name):
-        self._db_group_name = group_name
-    def db_change_group_name(self, group_name):
-        self._db_group_name = group_name
-    def db_delete_group_name(self, group_name):
-        self._db_group_name = None
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
     
-    def __get_db_group_type(self):
-        return self._db_group_type
-    def __set_db_group_type(self, group_type):
-        self._db_group_type = group_type
+    def __get_db_val(self):
+        return self._db_val
+    def __set_db_val(self, val):
+        self._db_val = val
         self.is_dirty = True
-    db_group_type = property(__get_db_group_type, __set_db_group_type)
-    def db_add_group_type(self, group_type):
-        self._db_group_type = group_type
-    def db_change_group_type(self, group_type):
-        self._db_group_type = group_type
-    def db_delete_group_type(self, group_type):
-        self._db_group_type = None
+    db_val = property(__get_db_val, __set_db_val)
+    def db_add_val(self, val):
+        self._db_val = val
+    def db_change_val(self, val):
+        self._db_val = val
+    def db_delete_val(self, val):
+        self._db_val = None
     
-    def __get_db_completed(self):
-        return self._db_completed
-    def __set_db_completed(self, completed):
-        self._db_completed = completed
+    def __get_db_minVal(self):
+        return self._db_minVal
+    def __set_db_minVal(self, minVal):
+        self._db_minVal = minVal
         self.is_dirty = True
-    db_completed = property(__get_db_completed, __set_db_completed)
-    def db_add_completed(self, completed):
-        self._db_completed = completed
-    def db_change_completed(self, completed):
-        self._db_completed = completed
-    def db_delete_completed(self, completed):
-        self._db_completed = None
+    db_minVal = property(__get_db_minVal, __set_db_minVal)
+    def db_add_minVal(self, minVal):
+        self._db_minVal = minVal
+    def db_change_minVal(self, minVal):
+        self._db_minVal = minVal
+    def db_delete_minVal(self, minVal):
+        self._db_minVal = None
     
-    def __get_db_error(self):
-        return self._db_error
-    def __set_db_error(self, error):
-        self._db_error = error
+    def __get_db_maxVal(self):
+        return self._db_maxVal
+    def __set_db_maxVal(self, maxVal):
+        self._db_maxVal = maxVal
         self.is_dirty = True
-    db_error = property(__get_db_error, __set_db_error)
-    def db_add_error(self, error):
-        self._db_error = error
-    def db_change_error(self, error):
-        self._db_error = error
-    def db_delete_error(self, error):
-        self._db_error = None
+    db_maxVal = property(__get_db_maxVal, __set_db_maxVal)
+    def db_add_maxVal(self, maxVal):
+        self._db_maxVal = maxVal
+    def db_change_maxVal(self, maxVal):
+        self._db_maxVal = maxVal
+    def db_delete_maxVal(self, maxVal):
+        self._db_maxVal = None
     
-    def __get_db_machine_id(self):
-        return self._db_machine_id
-    def __set_db_machine_id(self, machine_id):
-        self._db_machine_id = machine_id
+    def __get_db_stepSize(self):
+        return self._db_stepSize
+    def __set_db_stepSize(self, stepSize):
+        self._db_stepSize = stepSize
         self.is_dirty = True
-    db_machine_id = property(__get_db_machine_id, __set_db_machine_id)
-    def db_add_machine_id(self, machine_id):
-        self._db_machine_id = machine_id
-    def db_change_machine_id(self, machine_id):
-        self._db_machine_id = machine_id
-    def db_delete_machine_id(self, machine_id):
-        self._db_machine_id = None
+    db_stepSize = property(__get_db_stepSize, __set_db_stepSize)
+    def db_add_stepSize(self, stepSize):
+        self._db_stepSize = stepSize
+    def db_change_stepSize(self, stepSize):
+        self._db_stepSize = stepSize
+    def db_delete_stepSize(self, stepSize):
+        self._db_stepSize = None
     
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
+    def __get_db_strvaluelist(self):
+        return self._db_strvaluelist
+    def __set_db_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = strvaluelist
         self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
+    db_strvaluelist = property(__get_db_strvaluelist, __set_db_strvaluelist)
+    def db_add_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = strvaluelist
+    def db_change_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = strvaluelist
+    def db_delete_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = None
+    
+    def __get_db_widget(self):
+        return self._db_widget
+    def __set_db_widget(self, widget):
+        self._db_widget = widget
         self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-    def db_change_annotation(self, annotation):
+    db_widget = property(__get_db_widget, __set_db_widget)
+    def db_add_widget(self, widget):
+        self._db_widget = widget
+    def db_change_widget(self, widget):
+        self._db_widget = widget
+    def db_delete_widget(self, widget):
+        self._db_widget = None
+    
+    def __get_db_seq(self):
+        return self._db_seq
+    def __set_db_seq(self, seq):
+        self._db_seq = seq
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
-                found = True
-                break
-        if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-    def db_delete_annotation(self, annotation):
+    db_seq = property(__get_db_seq, __set_db_seq)
+    def db_add_seq(self, seq):
+        self._db_seq = seq
+    def db_change_seq(self, seq):
+        self._db_seq = seq
+    def db_delete_seq(self, seq):
+        self._db_seq = None
+    
+    def __get_db_parent(self):
+        return self._db_parent
+    def __set_db_parent(self, parent):
+        self._db_parent = parent
         self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
-                break
-        del self.db_annotations_id_index[annotation.db_id]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
-        return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
+    db_parent = property(__get_db_parent, __set_db_parent)
+    def db_add_parent(self, parent):
+        self._db_parent = parent
+    def db_change_parent(self, parent):
+        self._db_parent = parent
+    def db_delete_parent(self, parent):
+        self._db_parent = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmTime(object):
+class DBMashup(object):
 
-    vtType = 'opm_time'
+    vtType = 'mashup'
 
-    def __init__(self, no_later_than=None, no_earlier_than=None, clock_id=None):
-        self._db_no_later_than = no_later_than
-        self._db_no_earlier_than = no_earlier_than
-        self._db_clock_id = clock_id
+    def __init__(self, id=None, name=None, version=None, aliases=None, type=None, vtid=None, layout=None, geometry=None, has_seq=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_version = version
+        self.db_deleted_aliases = []
+        self.db_aliases_id_index = {}
+        if aliases is None:
+            self._db_aliases = []
+        else:
+            self._db_aliases = aliases
+            for v in self._db_aliases:
+                self.db_aliases_id_index[v.db_id] = v
+        self._db_type = type
+        self._db_vtid = vtid
+        self._db_layout = layout
+        self._db_geometry = geometry
+        self._db_has_seq = has_seq
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmTime.do_copy(self)
+        return DBMashup.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmTime(no_later_than=self._db_no_later_than,
-                       no_earlier_than=self._db_no_earlier_than,
-                       clock_id=self._db_clock_id)
+        cp = DBMashup(id=self._db_id,
+                      name=self._db_name,
+                      version=self._db_version,
+                      type=self._db_type,
+                      vtid=self._db_vtid,
+                      layout=self._db_layout,
+                      geometry=self._db_geometry,
+                      has_seq=self._db_has_seq)
+        if self._db_aliases is None:
+            cp._db_aliases = []
+        else:
+            cp._db_aliases = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_aliases]
         
         # set new ids
         if new_ids:
@@ -12519,8 +13914,11 @@ class DBOpmTime(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_vtid') and ('vistrail', self._db_vtid) in id_remap:
+                cp._db_vtid = id_remap[('vistrail', self._db_vtid)]
         
         # recreate indices and set flags
+        cp.db_aliases_id_index = dict((v.db_id, v) for v in cp._db_aliases)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -12529,119 +13927,262 @@ class DBOpmTime(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmTime()
+            new_obj = DBMashup()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'no_later_than' in class_dict:
-            res = class_dict['no_later_than'](old_obj, trans_dict)
-            new_obj.db_no_later_than = res
-        elif hasattr(old_obj, 'db_no_later_than') and old_obj.db_no_later_than is not None:
-            new_obj.db_no_later_than = old_obj.db_no_later_than
-        if 'no_earlier_than' in class_dict:
-            res = class_dict['no_earlier_than'](old_obj, trans_dict)
-            new_obj.db_no_earlier_than = res
-        elif hasattr(old_obj, 'db_no_earlier_than') and old_obj.db_no_earlier_than is not None:
-            new_obj.db_no_earlier_than = old_obj.db_no_earlier_than
-        if 'clock_id' in class_dict:
-            res = class_dict['clock_id'](old_obj, trans_dict)
-            new_obj.db_clock_id = res
-        elif hasattr(old_obj, 'db_clock_id') and old_obj.db_clock_id is not None:
-            new_obj.db_clock_id = old_obj.db_clock_id
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'aliases' in class_dict:
+            res = class_dict['aliases'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_alias(obj)
+        elif hasattr(old_obj, 'db_aliases') and old_obj.db_aliases is not None:
+            for obj in old_obj.db_aliases:
+                new_obj.db_add_alias(DBMashupAlias.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_aliases') and hasattr(new_obj, 'db_deleted_aliases'):
+            for obj in old_obj.db_deleted_aliases:
+                n_obj = DBMashupAlias.update_version(obj, trans_dict)
+                new_obj.db_deleted_aliases.append(n_obj)
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'vtid' in class_dict:
+            res = class_dict['vtid'](old_obj, trans_dict)
+            new_obj.db_vtid = res
+        elif hasattr(old_obj, 'db_vtid') and old_obj.db_vtid is not None:
+            new_obj.db_vtid = old_obj.db_vtid
+        if 'layout' in class_dict:
+            res = class_dict['layout'](old_obj, trans_dict)
+            new_obj.db_layout = res
+        elif hasattr(old_obj, 'db_layout') and old_obj.db_layout is not None:
+            new_obj.db_layout = old_obj.db_layout
+        if 'geometry' in class_dict:
+            res = class_dict['geometry'](old_obj, trans_dict)
+            new_obj.db_geometry = res
+        elif hasattr(old_obj, 'db_geometry') and old_obj.db_geometry is not None:
+            new_obj.db_geometry = old_obj.db_geometry
+        if 'has_seq' in class_dict:
+            res = class_dict['has_seq'](old_obj, trans_dict)
+            new_obj.db_has_seq = res
+        elif hasattr(old_obj, 'db_has_seq') and old_obj.db_has_seq is not None:
+            new_obj.db_has_seq = old_obj.db_has_seq
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_aliases:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_alias(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_aliases)
+        if remove:
+            self.db_deleted_aliases = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_aliases:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_no_later_than(self):
-        return self._db_no_later_than
-    def __set_db_no_later_than(self, no_later_than):
-        self._db_no_later_than = no_later_than
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_no_later_than = property(__get_db_no_later_than, __set_db_no_later_than)
-    def db_add_no_later_than(self, no_later_than):
-        self._db_no_later_than = no_later_than
-    def db_change_no_later_than(self, no_later_than):
-        self._db_no_later_than = no_later_than
-    def db_delete_no_later_than(self, no_later_than):
-        self._db_no_later_than = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_no_earlier_than(self):
-        return self._db_no_earlier_than
-    def __set_db_no_earlier_than(self, no_earlier_than):
-        self._db_no_earlier_than = no_earlier_than
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_no_earlier_than = property(__get_db_no_earlier_than, __set_db_no_earlier_than)
-    def db_add_no_earlier_than(self, no_earlier_than):
-        self._db_no_earlier_than = no_earlier_than
-    def db_change_no_earlier_than(self, no_earlier_than):
-        self._db_no_earlier_than = no_earlier_than
-    def db_delete_no_earlier_than(self, no_earlier_than):
-        self._db_no_earlier_than = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
-    def __get_db_clock_id(self):
-        return self._db_clock_id
-    def __set_db_clock_id(self, clock_id):
-        self._db_clock_id = clock_id
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
         self.is_dirty = True
-    db_clock_id = property(__get_db_clock_id, __set_db_clock_id)
-    def db_add_clock_id(self, clock_id):
-        self._db_clock_id = clock_id
-    def db_change_clock_id(self, clock_id):
-        self._db_clock_id = clock_id
-    def db_delete_clock_id(self, clock_id):
-        self._db_clock_id = None
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_aliases(self):
+        return self._db_aliases
+    def __set_db_aliases(self, aliases):
+        self._db_aliases = aliases
+        self.is_dirty = True
+    db_aliases = property(__get_db_aliases, __set_db_aliases)
+    def db_get_aliases(self):
+        return self._db_aliases
+    def db_add_alias(self, alias):
+        self.is_dirty = True
+        self._db_aliases.append(alias)
+        self.db_aliases_id_index[alias.db_id] = alias
+    def db_change_alias(self, alias):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_aliases)):
+            if self._db_aliases[i].db_id == alias.db_id:
+                self._db_aliases[i] = alias
+                found = True
+                break
+        if not found:
+            self._db_aliases.append(alias)
+        self.db_aliases_id_index[alias.db_id] = alias
+    def db_delete_alias(self, alias):
+        self.is_dirty = True
+        for i in xrange(len(self._db_aliases)):
+            if self._db_aliases[i].db_id == alias.db_id:
+                if not self._db_aliases[i].is_new:
+                    self.db_deleted_aliases.append(self._db_aliases[i])
+                del self._db_aliases[i]
+                break
+        del self.db_aliases_id_index[alias.db_id]
+    def db_get_alias(self, key):
+        for i in xrange(len(self._db_aliases)):
+            if self._db_aliases[i].db_id == key:
+                return self._db_aliases[i]
+        return None
+    def db_get_alias_by_id(self, key):
+        return self.db_aliases_id_index[key]
+    def db_has_alias_with_id(self, key):
+        return key in self.db_aliases_id_index
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_vtid(self):
+        return self._db_vtid
+    def __set_db_vtid(self, vtid):
+        self._db_vtid = vtid
+        self.is_dirty = True
+    db_vtid = property(__get_db_vtid, __set_db_vtid)
+    def db_add_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_change_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_delete_vtid(self, vtid):
+        self._db_vtid = None
+    
+    def __get_db_layout(self):
+        return self._db_layout
+    def __set_db_layout(self, layout):
+        self._db_layout = layout
+        self.is_dirty = True
+    db_layout = property(__get_db_layout, __set_db_layout)
+    def db_add_layout(self, layout):
+        self._db_layout = layout
+    def db_change_layout(self, layout):
+        self._db_layout = layout
+    def db_delete_layout(self, layout):
+        self._db_layout = None
+    
+    def __get_db_geometry(self):
+        return self._db_geometry
+    def __set_db_geometry(self, geometry):
+        self._db_geometry = geometry
+        self.is_dirty = True
+    db_geometry = property(__get_db_geometry, __set_db_geometry)
+    def db_add_geometry(self, geometry):
+        self._db_geometry = geometry
+    def db_change_geometry(self, geometry):
+        self._db_geometry = geometry
+    def db_delete_geometry(self, geometry):
+        self._db_geometry = None
     
+    def __get_db_has_seq(self):
+        return self._db_has_seq
+    def __set_db_has_seq(self, has_seq):
+        self._db_has_seq = has_seq
+        self.is_dirty = True
+    db_has_seq = property(__get_db_has_seq, __set_db_has_seq)
+    def db_add_has_seq(self, has_seq):
+        self._db_has_seq = has_seq
+    def db_change_has_seq(self, has_seq):
+        self._db_has_seq = has_seq
+    def db_delete_has_seq(self, has_seq):
+        self._db_has_seq = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBMachine(object):
 
-class DBPackage(object):
-
-    vtType = 'package'
+    vtType = 'machine'
 
-    def __init__(self, id=None, name=None, identifier=None, codepath=None, load_configuration=None, version=None, description=None, module_descriptors=None):
+    def __init__(self, id=None, name=None, os=None, architecture=None, processor=None, ram=None):
         self._db_id = id
         self._db_name = name
-        self._db_identifier = identifier
-        self._db_codepath = codepath
-        self._db_load_configuration = load_configuration
-        self._db_version = version
-        self._db_description = description
-        self.db_deleted_module_descriptors = []
-        self.db_module_descriptors_id_index = {}
-        self.db_module_descriptors_name_index = {}
-        if module_descriptors is None:
-            self._db_module_descriptors = []
-        else:
-            self._db_module_descriptors = module_descriptors
-            for v in self._db_module_descriptors:
-                self.db_module_descriptors_id_index[v.db_id] = v
-                self.db_module_descriptors_name_index[(v.db_name,v.db_namespace,v.db_version)] = v
+        self._db_os = os
+        self._db_architecture = architecture
+        self._db_processor = processor
+        self._db_ram = ram
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBPackage.do_copy(self)
+        return DBMachine.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPackage(id=self._db_id,
+        cp = DBMachine(id=self._db_id,
                        name=self._db_name,
-                       identifier=self._db_identifier,
-                       codepath=self._db_codepath,
-                       load_configuration=self._db_load_configuration,
-                       version=self._db_version,
-                       description=self._db_description)
-        if self._db_module_descriptors is None:
-            cp._db_module_descriptors = []
-        else:
-            cp._db_module_descriptors = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_module_descriptors]
+                       os=self._db_os,
+                       architecture=self._db_architecture,
+                       processor=self._db_processor,
+                       ram=self._db_ram)
         
         # set new ids
         if new_ids:
@@ -12651,10 +14192,10 @@ class DBPackage(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_vistrailId') and ('vistrail', self._db_vistrailId) in id_remap:
+                cp._db_vistrailId = id_remap[('vistrail', self._db_vistrailId)]
         
         # recreate indices and set flags
-        cp.db_module_descriptors_id_index = dict((v.db_id, v) for v in cp._db_module_descriptors)
-        cp.db_module_descriptors_name_index = dict(((v.db_name,v.db_namespace,v.db_version), v) for v in cp._db_module_descriptors)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -12663,7 +14204,7 @@ class DBPackage(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBPackage()
+            new_obj = DBMachine()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -12677,69 +14218,38 @@ class DBPackage(object):
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'identifier' in class_dict:
-            res = class_dict['identifier'](old_obj, trans_dict)
-            new_obj.db_identifier = res
-        elif hasattr(old_obj, 'db_identifier') and old_obj.db_identifier is not None:
-            new_obj.db_identifier = old_obj.db_identifier
-        if 'codepath' in class_dict:
-            res = class_dict['codepath'](old_obj, trans_dict)
-            new_obj.db_codepath = res
-        elif hasattr(old_obj, 'db_codepath') and old_obj.db_codepath is not None:
-            new_obj.db_codepath = old_obj.db_codepath
-        if 'load_configuration' in class_dict:
-            res = class_dict['load_configuration'](old_obj, trans_dict)
-            new_obj.db_load_configuration = res
-        elif hasattr(old_obj, 'db_load_configuration') and old_obj.db_load_configuration is not None:
-            new_obj.db_load_configuration = old_obj.db_load_configuration
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'description' in class_dict:
-            res = class_dict['description'](old_obj, trans_dict)
-            new_obj.db_description = res
-        elif hasattr(old_obj, 'db_description') and old_obj.db_description is not None:
-            new_obj.db_description = old_obj.db_description
-        if 'module_descriptors' in class_dict:
-            res = class_dict['module_descriptors'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_module_descriptor(obj)
-        elif hasattr(old_obj, 'db_module_descriptors') and old_obj.db_module_descriptors is not None:
-            for obj in old_obj.db_module_descriptors:
-                new_obj.db_add_module_descriptor(DBModuleDescriptor.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_module_descriptors') and hasattr(new_obj, 'db_deleted_module_descriptors'):
-            for obj in old_obj.db_deleted_module_descriptors:
-                n_obj = DBModuleDescriptor.update_version(obj, trans_dict)
-                new_obj.db_deleted_module_descriptors.append(n_obj)
+        if 'os' in class_dict:
+            res = class_dict['os'](old_obj, trans_dict)
+            new_obj.db_os = res
+        elif hasattr(old_obj, 'db_os') and old_obj.db_os is not None:
+            new_obj.db_os = old_obj.db_os
+        if 'architecture' in class_dict:
+            res = class_dict['architecture'](old_obj, trans_dict)
+            new_obj.db_architecture = res
+        elif hasattr(old_obj, 'db_architecture') and old_obj.db_architecture is not None:
+            new_obj.db_architecture = old_obj.db_architecture
+        if 'processor' in class_dict:
+            res = class_dict['processor'](old_obj, trans_dict)
+            new_obj.db_processor = res
+        elif hasattr(old_obj, 'db_processor') and old_obj.db_processor is not None:
+            new_obj.db_processor = old_obj.db_processor
+        if 'ram' in class_dict:
+            res = class_dict['ram'](old_obj, trans_dict)
+            new_obj.db_ram = res
+        elif hasattr(old_obj, 'db_ram') and old_obj.db_ram is not None:
+            new_obj.db_ram = old_obj.db_ram
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_module_descriptors:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_module_descriptor(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_module_descriptors)
-        if remove:
-            self.db_deleted_module_descriptors = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_module_descriptors:
-            if child.has_changes():
-                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -12767,183 +14277,75 @@ class DBPackage(object):
     def db_delete_name(self, name):
         self._db_name = None
     
-    def __get_db_identifier(self):
-        return self._db_identifier
-    def __set_db_identifier(self, identifier):
-        self._db_identifier = identifier
-        self.is_dirty = True
-    db_identifier = property(__get_db_identifier, __set_db_identifier)
-    def db_add_identifier(self, identifier):
-        self._db_identifier = identifier
-    def db_change_identifier(self, identifier):
-        self._db_identifier = identifier
-    def db_delete_identifier(self, identifier):
-        self._db_identifier = None
-    
-    def __get_db_codepath(self):
-        return self._db_codepath
-    def __set_db_codepath(self, codepath):
-        self._db_codepath = codepath
-        self.is_dirty = True
-    db_codepath = property(__get_db_codepath, __set_db_codepath)
-    def db_add_codepath(self, codepath):
-        self._db_codepath = codepath
-    def db_change_codepath(self, codepath):
-        self._db_codepath = codepath
-    def db_delete_codepath(self, codepath):
-        self._db_codepath = None
-    
-    def __get_db_load_configuration(self):
-        return self._db_load_configuration
-    def __set_db_load_configuration(self, load_configuration):
-        self._db_load_configuration = load_configuration
-        self.is_dirty = True
-    db_load_configuration = property(__get_db_load_configuration, __set_db_load_configuration)
-    def db_add_load_configuration(self, load_configuration):
-        self._db_load_configuration = load_configuration
-    def db_change_load_configuration(self, load_configuration):
-        self._db_load_configuration = load_configuration
-    def db_delete_load_configuration(self, load_configuration):
-        self._db_load_configuration = None
-    
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
+    def __get_db_os(self):
+        return self._db_os
+    def __set_db_os(self, os):
+        self._db_os = os
         self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
+    db_os = property(__get_db_os, __set_db_os)
+    def db_add_os(self, os):
+        self._db_os = os
+    def db_change_os(self, os):
+        self._db_os = os
+    def db_delete_os(self, os):
+        self._db_os = None
     
-    def __get_db_description(self):
-        return self._db_description
-    def __set_db_description(self, description):
-        self._db_description = description
+    def __get_db_architecture(self):
+        return self._db_architecture
+    def __set_db_architecture(self, architecture):
+        self._db_architecture = architecture
         self.is_dirty = True
-    db_description = property(__get_db_description, __set_db_description)
-    def db_add_description(self, description):
-        self._db_description = description
-    def db_change_description(self, description):
-        self._db_description = description
-    def db_delete_description(self, description):
-        self._db_description = None
+    db_architecture = property(__get_db_architecture, __set_db_architecture)
+    def db_add_architecture(self, architecture):
+        self._db_architecture = architecture
+    def db_change_architecture(self, architecture):
+        self._db_architecture = architecture
+    def db_delete_architecture(self, architecture):
+        self._db_architecture = None
     
-    def __get_db_module_descriptors(self):
-        return self._db_module_descriptors
-    def __set_db_module_descriptors(self, module_descriptors):
-        self._db_module_descriptors = module_descriptors
-        self.is_dirty = True
-    db_module_descriptors = property(__get_db_module_descriptors, __set_db_module_descriptors)
-    def db_get_module_descriptors(self):
-        return self._db_module_descriptors
-    def db_add_module_descriptor(self, module_descriptor):
-        self.is_dirty = True
-        self._db_module_descriptors.append(module_descriptor)
-        self.db_module_descriptors_id_index[module_descriptor.db_id] = module_descriptor
-        self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)] = module_descriptor
-    def db_change_module_descriptor(self, module_descriptor):
+    def __get_db_processor(self):
+        return self._db_processor
+    def __set_db_processor(self, processor):
+        self._db_processor = processor
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_module_descriptors)):
-            if self._db_module_descriptors[i].db_id == module_descriptor.db_id:
-                self._db_module_descriptors[i] = module_descriptor
-                found = True
-                break
-        if not found:
-            self._db_module_descriptors.append(module_descriptor)
-        self.db_module_descriptors_id_index[module_descriptor.db_id] = module_descriptor
-        self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)] = module_descriptor
-    def db_delete_module_descriptor(self, module_descriptor):
+    db_processor = property(__get_db_processor, __set_db_processor)
+    def db_add_processor(self, processor):
+        self._db_processor = processor
+    def db_change_processor(self, processor):
+        self._db_processor = processor
+    def db_delete_processor(self, processor):
+        self._db_processor = None
+    
+    def __get_db_ram(self):
+        return self._db_ram
+    def __set_db_ram(self, ram):
+        self._db_ram = ram
         self.is_dirty = True
-        for i in xrange(len(self._db_module_descriptors)):
-            if self._db_module_descriptors[i].db_id == module_descriptor.db_id:
-                if not self._db_module_descriptors[i].is_new:
-                    self.db_deleted_module_descriptors.append(self._db_module_descriptors[i])
-                del self._db_module_descriptors[i]
-                break
-        del self.db_module_descriptors_id_index[module_descriptor.db_id]
-        del self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)]
-    def db_get_module_descriptor(self, key):
-        for i in xrange(len(self._db_module_descriptors)):
-            if self._db_module_descriptors[i].db_id == key:
-                return self._db_module_descriptors[i]
-        return None
-    def db_get_module_descriptor_by_id(self, key):
-        return self.db_module_descriptors_id_index[key]
-    def db_has_module_descriptor_with_id(self, key):
-        return key in self.db_module_descriptors_id_index
-    def db_get_module_descriptor_by_name(self, key):
-        return self.db_module_descriptors_name_index[key]
-    def db_has_module_descriptor_with_name(self, key):
-        return key in self.db_module_descriptors_name_index
+    db_ram = property(__get_db_ram, __set_db_ram)
+    def db_add_ram(self, ram):
+        self._db_ram = ram
+    def db_change_ram(self, ram):
+        self._db_ram = ram
+    def db_delete_ram(self, ram):
+        self._db_ram = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBWorkflowExec(object):
+class DBConfigFloat(object):
 
-    vtType = 'workflow_exec'
+    vtType = 'config_float'
 
-    def __init__(self, item_execs=None, id=None, user=None, ip=None, session=None, vt_version=None, ts_start=None, ts_end=None, parent_id=None, parent_type=None, parent_version=None, completed=None, name=None, annotations=None):
-        self.db_deleted_item_execs = []
-        self.db_item_execs_id_index = {}
-        if item_execs is None:
-            self._db_item_execs = []
-        else:
-            self._db_item_execs = item_execs
-            for v in self._db_item_execs:
-                self.db_item_execs_id_index[v.db_id] = v
-        self._db_id = id
-        self._db_user = user
-        self._db_ip = ip
-        self._db_session = session
-        self._db_vt_version = vt_version
-        self._db_ts_start = ts_start
-        self._db_ts_end = ts_end
-        self._db_parent_id = parent_id
-        self._db_parent_type = parent_type
-        self._db_parent_version = parent_version
-        self._db_completed = completed
-        self._db_name = name
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        if annotations is None:
-            self._db_annotations = []
-        else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
+    def __init__(self, value=None):
+        self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBWorkflowExec.do_copy(self)
+        return DBConfigFloat.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBWorkflowExec(id=self._db_id,
-                            user=self._db_user,
-                            ip=self._db_ip,
-                            session=self._db_session,
-                            vt_version=self._db_vt_version,
-                            ts_start=self._db_ts_start,
-                            ts_end=self._db_ts_end,
-                            parent_id=self._db_parent_id,
-                            parent_type=self._db_parent_type,
-                            parent_version=self._db_parent_version,
-                            completed=self._db_completed,
-                            name=self._db_name)
-        if self._db_item_execs is None:
-            cp._db_item_execs = []
-        else:
-            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
-        if self._db_annotations is None:
-            cp._db_annotations = []
-        else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        cp = DBConfigFloat(value=self._db_value)
         
         # set new ids
         if new_ids:
@@ -12955,8 +14357,6 @@ class DBWorkflowExec(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -12965,186 +14365,112 @@ class DBWorkflowExec(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBWorkflowExec()
+            new_obj = DBConfigFloat()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'item_execs' in class_dict:
-            res = class_dict['item_execs'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_item_exec(obj)
-        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
-            for obj in old_obj.db_item_execs:
-                if obj.vtType == 'module_exec':
-                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
-                elif obj.vtType == 'group_exec':
-                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
-                elif obj.vtType == 'loop_exec':
-                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
-            for obj in old_obj.db_deleted_item_execs:
-                if obj.vtType == 'module_exec':
-                    n_obj = DBModuleExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-                elif obj.vtType == 'group_exec':
-                    n_obj = DBGroupExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-                elif obj.vtType == 'loop_exec':
-                    n_obj = DBLoopExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'user' in class_dict:
-            res = class_dict['user'](old_obj, trans_dict)
-            new_obj.db_user = res
-        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
-            new_obj.db_user = old_obj.db_user
-        if 'ip' in class_dict:
-            res = class_dict['ip'](old_obj, trans_dict)
-            new_obj.db_ip = res
-        elif hasattr(old_obj, 'db_ip') and old_obj.db_ip is not None:
-            new_obj.db_ip = old_obj.db_ip
-        if 'session' in class_dict:
-            res = class_dict['session'](old_obj, trans_dict)
-            new_obj.db_session = res
-        elif hasattr(old_obj, 'db_session') and old_obj.db_session is not None:
-            new_obj.db_session = old_obj.db_session
-        if 'vt_version' in class_dict:
-            res = class_dict['vt_version'](old_obj, trans_dict)
-            new_obj.db_vt_version = res
-        elif hasattr(old_obj, 'db_vt_version') and old_obj.db_vt_version is not None:
-            new_obj.db_vt_version = old_obj.db_vt_version
-        if 'ts_start' in class_dict:
-            res = class_dict['ts_start'](old_obj, trans_dict)
-            new_obj.db_ts_start = res
-        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
-            new_obj.db_ts_start = old_obj.db_ts_start
-        if 'ts_end' in class_dict:
-            res = class_dict['ts_end'](old_obj, trans_dict)
-            new_obj.db_ts_end = res
-        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
-            new_obj.db_ts_end = old_obj.db_ts_end
-        if 'parent_id' in class_dict:
-            res = class_dict['parent_id'](old_obj, trans_dict)
-            new_obj.db_parent_id = res
-        elif hasattr(old_obj, 'db_parent_id') and old_obj.db_parent_id is not None:
-            new_obj.db_parent_id = old_obj.db_parent_id
-        if 'parent_type' in class_dict:
-            res = class_dict['parent_type'](old_obj, trans_dict)
-            new_obj.db_parent_type = res
-        elif hasattr(old_obj, 'db_parent_type') and old_obj.db_parent_type is not None:
-            new_obj.db_parent_type = old_obj.db_parent_type
-        if 'parent_version' in class_dict:
-            res = class_dict['parent_version'](old_obj, trans_dict)
-            new_obj.db_parent_version = res
-        elif hasattr(old_obj, 'db_parent_version') and old_obj.db_parent_version is not None:
-            new_obj.db_parent_version = old_obj.db_parent_version
-        if 'completed' in class_dict:
-            res = class_dict['completed'](old_obj, trans_dict)
-            new_obj.db_completed = res
-        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
-            new_obj.db_completed = old_obj.db_completed
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBOther(object):
+
+    vtType = 'other'
+
+    def __init__(self, id=None, key=None, value=None):
+        self._db_id = id
+        self._db_key = key
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOther.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOther(id=self._db_id,
+                     key=self._db_key,
+                     value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOther()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        to_del = []
-        for child in self.db_item_execs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_item_exec(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_item_execs)
-        if remove:
-            self.db_deleted_annotations = []
-            self.db_deleted_item_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
-        for child in self._db_item_execs:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_item_execs(self):
-        return self._db_item_execs
-    def __set_db_item_execs(self, item_execs):
-        self._db_item_execs = item_execs
-        self.is_dirty = True
-    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
-    def db_get_item_execs(self):
-        return self._db_item_execs
-    def db_add_item_exec(self, item_exec):
-        self.is_dirty = True
-        self._db_item_execs.append(item_exec)
-        self.db_item_execs_id_index[item_exec.db_id] = item_exec
-    def db_change_item_exec(self, item_exec):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == item_exec.db_id:
-                self._db_item_execs[i] = item_exec
-                found = True
-                break
-        if not found:
-            self._db_item_execs.append(item_exec)
-        self.db_item_execs_id_index[item_exec.db_id] = item_exec
-    def db_delete_item_exec(self, item_exec):
-        self.is_dirty = True
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == item_exec.db_id:
-                if not self._db_item_execs[i].is_new:
-                    self.db_deleted_item_execs.append(self._db_item_execs[i])
-                del self._db_item_execs[i]
-                break
-        del self.db_item_execs_id_index[item_exec.db_id]
-    def db_get_item_exec(self, key):
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == key:
-                return self._db_item_execs[i]
-        return None
-    def db_get_item_exec_by_id(self, key):
-        return self.db_item_execs_id_index[key]
-    def db_has_item_exec_with_id(self, key):
-        return key in self.db_item_execs_id_index
-    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -13158,206 +14484,121 @@ class DBWorkflowExec(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_user(self):
-        return self._db_user
-    def __set_db_user(self, user):
-        self._db_user = user
-        self.is_dirty = True
-    db_user = property(__get_db_user, __set_db_user)
-    def db_add_user(self, user):
-        self._db_user = user
-    def db_change_user(self, user):
-        self._db_user = user
-    def db_delete_user(self, user):
-        self._db_user = None
-    
-    def __get_db_ip(self):
-        return self._db_ip
-    def __set_db_ip(self, ip):
-        self._db_ip = ip
-        self.is_dirty = True
-    db_ip = property(__get_db_ip, __set_db_ip)
-    def db_add_ip(self, ip):
-        self._db_ip = ip
-    def db_change_ip(self, ip):
-        self._db_ip = ip
-    def db_delete_ip(self, ip):
-        self._db_ip = None
-    
-    def __get_db_session(self):
-        return self._db_session
-    def __set_db_session(self, session):
-        self._db_session = session
-        self.is_dirty = True
-    db_session = property(__get_db_session, __set_db_session)
-    def db_add_session(self, session):
-        self._db_session = session
-    def db_change_session(self, session):
-        self._db_session = session
-    def db_delete_session(self, session):
-        self._db_session = None
-    
-    def __get_db_vt_version(self):
-        return self._db_vt_version
-    def __set_db_vt_version(self, vt_version):
-        self._db_vt_version = vt_version
-        self.is_dirty = True
-    db_vt_version = property(__get_db_vt_version, __set_db_vt_version)
-    def db_add_vt_version(self, vt_version):
-        self._db_vt_version = vt_version
-    def db_change_vt_version(self, vt_version):
-        self._db_vt_version = vt_version
-    def db_delete_vt_version(self, vt_version):
-        self._db_vt_version = None
-    
-    def __get_db_ts_start(self):
-        return self._db_ts_start
-    def __set_db_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-        self.is_dirty = True
-    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
-    def db_add_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_change_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_delete_ts_start(self, ts_start):
-        self._db_ts_start = None
-    
-    def __get_db_ts_end(self):
-        return self._db_ts_end
-    def __set_db_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-        self.is_dirty = True
-    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
-    def db_add_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_change_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_delete_ts_end(self, ts_end):
-        self._db_ts_end = None
-    
-    def __get_db_parent_id(self):
-        return self._db_parent_id
-    def __set_db_parent_id(self, parent_id):
-        self._db_parent_id = parent_id
-        self.is_dirty = True
-    db_parent_id = property(__get_db_parent_id, __set_db_parent_id)
-    def db_add_parent_id(self, parent_id):
-        self._db_parent_id = parent_id
-    def db_change_parent_id(self, parent_id):
-        self._db_parent_id = parent_id
-    def db_delete_parent_id(self, parent_id):
-        self._db_parent_id = None
-    
-    def __get_db_parent_type(self):
-        return self._db_parent_type
-    def __set_db_parent_type(self, parent_type):
-        self._db_parent_type = parent_type
-        self.is_dirty = True
-    db_parent_type = property(__get_db_parent_type, __set_db_parent_type)
-    def db_add_parent_type(self, parent_type):
-        self._db_parent_type = parent_type
-    def db_change_parent_type(self, parent_type):
-        self._db_parent_type = parent_type
-    def db_delete_parent_type(self, parent_type):
-        self._db_parent_type = None
-    
-    def __get_db_parent_version(self):
-        return self._db_parent_version
-    def __set_db_parent_version(self, parent_version):
-        self._db_parent_version = parent_version
-        self.is_dirty = True
-    db_parent_version = property(__get_db_parent_version, __set_db_parent_version)
-    def db_add_parent_version(self, parent_version):
-        self._db_parent_version = parent_version
-    def db_change_parent_version(self, parent_version):
-        self._db_parent_version = parent_version
-    def db_delete_parent_version(self, parent_version):
-        self._db_parent_version = None
-    
-    def __get_db_completed(self):
-        return self._db_completed
-    def __set_db_completed(self, completed):
-        self._db_completed = completed
-        self.is_dirty = True
-    db_completed = property(__get_db_completed, __set_db_completed)
-    def db_add_completed(self, completed):
-        self._db_completed = completed
-    def db_change_completed(self, completed):
-        self._db_completed = completed
-    def db_delete_completed(self, completed):
-        self._db_completed = None
-    
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
-        self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
-    
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
-        self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
-        self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-    def db_change_annotation(self, annotation):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
-                found = True
-                break
-        if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-    def db_delete_annotation(self, annotation):
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
         self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
-                break
-        del self.db_annotations_id_index[annotation.db_id]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
-        return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBParameterExploration(object):
+class DBRefProvActivity(object):
 
-    vtType = 'parameter_exploration'
+    vtType = 'ref_prov_activity'
 
-    def __init__(self, id=None, action_id=None, name=None, date=None, user=None, dims=None, layout=None, functions=None):
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBRefProvActivity.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBRefProvActivity(prov_ref=self._db_prov_ref)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_activity', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_activity', self._db_prov_ref)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRefProvActivity()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
+    
+
+
+class DBAbstraction(object):
+
+    vtType = 'abstraction'
+
+    def __init__(self, id=None, cache=None, name=None, namespace=None, package=None, version=None, internal_version=None, location=None, functions=None, annotations=None):
         self._db_id = id
-        self._db_action_id = action_id
+        self._db_cache = cache
         self._db_name = name
-        self._db_date = date
-        self._db_user = user
-        self._db_dims = dims
-        self._db_layout = layout
+        self._db_namespace = namespace
+        self._db_package = package
+        self._db_version = version
+        self._db_internal_version = internal_version
+        self.db_deleted_location = []
+        self._db_location = location
         self.db_deleted_functions = []
         self.db_functions_id_index = {}
         if functions is None:
@@ -13366,24 +14607,40 @@ class DBParameterExploration(object):
             self._db_functions = functions
             for v in self._db_functions:
                 self.db_functions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBParameterExploration.do_copy(self)
+        return DBAbstraction.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBParameterExploration(id=self._db_id,
-                                    action_id=self._db_action_id,
-                                    name=self._db_name,
-                                    date=self._db_date,
-                                    user=self._db_user,
-                                    dims=self._db_dims,
-                                    layout=self._db_layout)
+        cp = DBAbstraction(id=self._db_id,
+                           cache=self._db_cache,
+                           name=self._db_name,
+                           namespace=self._db_namespace,
+                           package=self._db_package,
+                           version=self._db_version,
+                           internal_version=self._db_internal_version)
+        if self._db_location is not None:
+            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
         if self._db_functions is None:
             cp._db_functions = []
         else:
             cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
         
         # set new ids
         if new_ids:
@@ -13393,11 +14650,11 @@ class DBParameterExploration(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_action_id') and ('action', self._db_action_id) in id_remap:
-                cp._db_action_id = id_remap[('action', self._db_action_id)]
         
         # recreate indices and set flags
         cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -13406,7 +14663,7 @@ class DBParameterExploration(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBParameterExploration()
+            new_obj = DBAbstraction()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -13415,53 +14672,78 @@ class DBParameterExploration(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'action_id' in class_dict:
-            res = class_dict['action_id'](old_obj, trans_dict)
-            new_obj.db_action_id = res
-        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
-            new_obj.db_action_id = old_obj.db_action_id
+        if 'cache' in class_dict:
+            res = class_dict['cache'](old_obj, trans_dict)
+            new_obj.db_cache = res
+        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
+            new_obj.db_cache = old_obj.db_cache
         if 'name' in class_dict:
             res = class_dict['name'](old_obj, trans_dict)
             new_obj.db_name = res
         elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
             new_obj.db_name = old_obj.db_name
-        if 'date' in class_dict:
-            res = class_dict['date'](old_obj, trans_dict)
-            new_obj.db_date = res
-        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
-            new_obj.db_date = old_obj.db_date
-        if 'user' in class_dict:
-            res = class_dict['user'](old_obj, trans_dict)
-            new_obj.db_user = res
-        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
-            new_obj.db_user = old_obj.db_user
-        if 'dims' in class_dict:
-            res = class_dict['dims'](old_obj, trans_dict)
-            new_obj.db_dims = res
-        elif hasattr(old_obj, 'db_dims') and old_obj.db_dims is not None:
-            new_obj.db_dims = old_obj.db_dims
-        if 'layout' in class_dict:
-            res = class_dict['layout'](old_obj, trans_dict)
-            new_obj.db_layout = res
-        elif hasattr(old_obj, 'db_layout') and old_obj.db_layout is not None:
-            new_obj.db_layout = old_obj.db_layout
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'internal_version' in class_dict:
+            res = class_dict['internal_version'](old_obj, trans_dict)
+            new_obj.db_internal_version = res
+        elif hasattr(old_obj, 'db_internal_version') and old_obj.db_internal_version is not None:
+            new_obj.db_internal_version = old_obj.db_internal_version
+        if 'location' in class_dict:
+            res = class_dict['location'](old_obj, trans_dict)
+            new_obj.db_location = res
+        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
+            obj = old_obj.db_location
+            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
+            for obj in old_obj.db_deleted_location:
+                n_obj = DBLocation.update_version(obj, trans_dict)
+                new_obj.db_deleted_location.append(n_obj)
         if 'functions' in class_dict:
             res = class_dict['functions'](old_obj, trans_dict)
             for obj in res:
                 new_obj.db_add_function(obj)
         elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
             for obj in old_obj.db_functions:
-                new_obj.db_add_function(DBPEFunction.update_version(obj, trans_dict))
+                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
         if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
             for obj in old_obj.db_deleted_functions:
-                n_obj = DBPEFunction.update_version(obj, trans_dict)
+                n_obj = DBFunction.update_version(obj, trans_dict)
                 new_obj.db_deleted_functions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
+        if self._db_location is not None:
+            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_location = None
         to_del = []
         for child in self.db_functions:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
@@ -13469,20 +14751,36 @@ class DBParameterExploration(object):
                 to_del.append(child)
         for child in to_del:
             self.db_delete_function(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_location)
         children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_annotations)
         if remove:
+            self.db_deleted_location = []
             self.db_deleted_functions = []
+            self.db_deleted_annotations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_location is not None and self._db_location.has_changes():
+            return True
         for child in self._db_functions:
             if child.has_changes():
                 return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -13497,18 +14795,18 @@ class DBParameterExploration(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_action_id(self):
-        return self._db_action_id
-    def __set_db_action_id(self, action_id):
-        self._db_action_id = action_id
+    def __get_db_cache(self):
+        return self._db_cache
+    def __set_db_cache(self, cache):
+        self._db_cache = cache
         self.is_dirty = True
-    db_action_id = property(__get_db_action_id, __set_db_action_id)
-    def db_add_action_id(self, action_id):
-        self._db_action_id = action_id
-    def db_change_action_id(self, action_id):
-        self._db_action_id = action_id
-    def db_delete_action_id(self, action_id):
-        self._db_action_id = None
+    db_cache = property(__get_db_cache, __set_db_cache)
+    def db_add_cache(self, cache):
+        self._db_cache = cache
+    def db_change_cache(self, cache):
+        self._db_cache = cache
+    def db_delete_cache(self, cache):
+        self._db_cache = None
     
     def __get_db_name(self):
         return self._db_name
@@ -13523,57 +14821,72 @@ class DBParameterExploration(object):
     def db_delete_name(self, name):
         self._db_name = None
     
-    def __get_db_date(self):
-        return self._db_date
-    def __set_db_date(self, date):
-        self._db_date = date
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
         self.is_dirty = True
-    db_date = property(__get_db_date, __set_db_date)
-    def db_add_date(self, date):
-        self._db_date = date
-    def db_change_date(self, date):
-        self._db_date = date
-    def db_delete_date(self, date):
-        self._db_date = None
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
     
-    def __get_db_user(self):
-        return self._db_user
-    def __set_db_user(self, user):
-        self._db_user = user
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
         self.is_dirty = True
-    db_user = property(__get_db_user, __set_db_user)
-    def db_add_user(self, user):
-        self._db_user = user
-    def db_change_user(self, user):
-        self._db_user = user
-    def db_delete_user(self, user):
-        self._db_user = None
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
     
-    def __get_db_dims(self):
-        return self._db_dims
-    def __set_db_dims(self, dims):
-        self._db_dims = dims
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
         self.is_dirty = True
-    db_dims = property(__get_db_dims, __set_db_dims)
-    def db_add_dims(self, dims):
-        self._db_dims = dims
-    def db_change_dims(self, dims):
-        self._db_dims = dims
-    def db_delete_dims(self, dims):
-        self._db_dims = None
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
     
-    def __get_db_layout(self):
-        return self._db_layout
-    def __set_db_layout(self, layout):
-        self._db_layout = layout
+    def __get_db_internal_version(self):
+        return self._db_internal_version
+    def __set_db_internal_version(self, internal_version):
+        self._db_internal_version = internal_version
         self.is_dirty = True
-    db_layout = property(__get_db_layout, __set_db_layout)
-    def db_add_layout(self, layout):
-        self._db_layout = layout
-    def db_change_layout(self, layout):
-        self._db_layout = layout
-    def db_delete_layout(self, layout):
-        self._db_layout = None
+    db_internal_version = property(__get_db_internal_version, __set_db_internal_version)
+    def db_add_internal_version(self, internal_version):
+        self._db_internal_version = internal_version
+    def db_change_internal_version(self, internal_version):
+        self._db_internal_version = internal_version
+    def db_delete_internal_version(self, internal_version):
+        self._db_internal_version = None
+    
+    def __get_db_location(self):
+        return self._db_location
+    def __set_db_location(self, location):
+        self._db_location = location
+        self.is_dirty = True
+    db_location = property(__get_db_location, __set_db_location)
+    def db_add_location(self, location):
+        self._db_location = location
+    def db_change_location(self, location):
+        self._db_location = location
+    def db_delete_location(self, location):
+        if not self.is_new:
+            self.db_deleted_location.append(self._db_location)
+        self._db_location = None
     
     def __get_db_functions(self):
         return self._db_functions
@@ -13617,45 +14930,86 @@ class DBParameterExploration(object):
     def db_has_function_with_id(self, key):
         return key in self.db_functions_id_index
     
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
     def getPrimaryKey(self):
         return self._db_id
 
-class DBLoopExec(object):
+class DBProvAgent(object):
 
-    vtType = 'loop_exec'
+    vtType = 'prov_agent'
 
-    def __init__(self, item_execs=None, id=None, ts_start=None, ts_end=None, iteration=None, completed=None, error=None):
-        self.db_deleted_item_execs = []
-        self.db_item_execs_id_index = {}
-        if item_execs is None:
-            self._db_item_execs = []
-        else:
-            self._db_item_execs = item_execs
-            for v in self._db_item_execs:
-                self.db_item_execs_id_index[v.db_id] = v
+    def __init__(self, id=None, vt_id=None, prov_type=None, prov_label=None, vt_machine_os=None, vt_machine_architecture=None, vt_machine_processor=None, vt_machine_ram=None):
         self._db_id = id
-        self._db_ts_start = ts_start
-        self._db_ts_end = ts_end
-        self._db_iteration = iteration
-        self._db_completed = completed
-        self._db_error = error
+        self._db_vt_id = vt_id
+        self._db_prov_type = prov_type
+        self._db_prov_label = prov_label
+        self._db_vt_machine_os = vt_machine_os
+        self._db_vt_machine_architecture = vt_machine_architecture
+        self._db_vt_machine_processor = vt_machine_processor
+        self._db_vt_machine_ram = vt_machine_ram
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBLoopExec.do_copy(self)
+        return DBProvAgent.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBLoopExec(id=self._db_id,
-                        ts_start=self._db_ts_start,
-                        ts_end=self._db_ts_end,
-                        iteration=self._db_iteration,
-                        completed=self._db_completed,
-                        error=self._db_error)
-        if self._db_item_execs is None:
-            cp._db_item_execs = []
-        else:
-            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
+        cp = DBProvAgent(id=self._db_id,
+                         vt_id=self._db_vt_id,
+                         prov_type=self._db_prov_type,
+                         prov_label=self._db_prov_label,
+                         vt_machine_os=self._db_vt_machine_os,
+                         vt_machine_architecture=self._db_vt_machine_architecture,
+                         vt_machine_processor=self._db_vt_machine_processor,
+                         vt_machine_ram=self._db_vt_machine_ram)
         
         # set new ids
         if new_ids:
@@ -13667,142 +15021,71 @@ class DBLoopExec(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
         return cp
 
     @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBLoopExec()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'item_execs' in class_dict:
-            res = class_dict['item_execs'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_item_exec(obj)
-        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
-            for obj in old_obj.db_item_execs:
-                if obj.vtType == 'module_exec':
-                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
-                elif obj.vtType == 'group_exec':
-                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
-                elif obj.vtType == 'loop_exec':
-                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
-            for obj in old_obj.db_deleted_item_execs:
-                if obj.vtType == 'module_exec':
-                    n_obj = DBModuleExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-                elif obj.vtType == 'group_exec':
-                    n_obj = DBGroupExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
-                elif obj.vtType == 'loop_exec':
-                    n_obj = DBLoopExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_item_execs.append(n_obj)
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvAgent()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
         if 'id' in class_dict:
             res = class_dict['id'](old_obj, trans_dict)
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'ts_start' in class_dict:
-            res = class_dict['ts_start'](old_obj, trans_dict)
-            new_obj.db_ts_start = res
-        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
-            new_obj.db_ts_start = old_obj.db_ts_start
-        if 'ts_end' in class_dict:
-            res = class_dict['ts_end'](old_obj, trans_dict)
-            new_obj.db_ts_end = res
-        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
-            new_obj.db_ts_end = old_obj.db_ts_end
-        if 'iteration' in class_dict:
-            res = class_dict['iteration'](old_obj, trans_dict)
-            new_obj.db_iteration = res
-        elif hasattr(old_obj, 'db_iteration') and old_obj.db_iteration is not None:
-            new_obj.db_iteration = old_obj.db_iteration
-        if 'completed' in class_dict:
-            res = class_dict['completed'](old_obj, trans_dict)
-            new_obj.db_completed = res
-        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
-            new_obj.db_completed = old_obj.db_completed
-        if 'error' in class_dict:
-            res = class_dict['error'](old_obj, trans_dict)
-            new_obj.db_error = res
-        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
-            new_obj.db_error = old_obj.db_error
+        if 'vt_id' in class_dict:
+            res = class_dict['vt_id'](old_obj, trans_dict)
+            new_obj.db_vt_id = res
+        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
+            new_obj.db_vt_id = old_obj.db_vt_id
+        if 'prov_type' in class_dict:
+            res = class_dict['prov_type'](old_obj, trans_dict)
+            new_obj.db_prov_type = res
+        elif hasattr(old_obj, 'db_prov_type') and old_obj.db_prov_type is not None:
+            new_obj.db_prov_type = old_obj.db_prov_type
+        if 'prov_label' in class_dict:
+            res = class_dict['prov_label'](old_obj, trans_dict)
+            new_obj.db_prov_label = res
+        elif hasattr(old_obj, 'db_prov_label') and old_obj.db_prov_label is not None:
+            new_obj.db_prov_label = old_obj.db_prov_label
+        if 'vt_machine_os' in class_dict:
+            res = class_dict['vt_machine_os'](old_obj, trans_dict)
+            new_obj.db_vt_machine_os = res
+        elif hasattr(old_obj, 'db_vt_machine_os') and old_obj.db_vt_machine_os is not None:
+            new_obj.db_vt_machine_os = old_obj.db_vt_machine_os
+        if 'vt_machine_architecture' in class_dict:
+            res = class_dict['vt_machine_architecture'](old_obj, trans_dict)
+            new_obj.db_vt_machine_architecture = res
+        elif hasattr(old_obj, 'db_vt_machine_architecture') and old_obj.db_vt_machine_architecture is not None:
+            new_obj.db_vt_machine_architecture = old_obj.db_vt_machine_architecture
+        if 'vt_machine_processor' in class_dict:
+            res = class_dict['vt_machine_processor'](old_obj, trans_dict)
+            new_obj.db_vt_machine_processor = res
+        elif hasattr(old_obj, 'db_vt_machine_processor') and old_obj.db_vt_machine_processor is not None:
+            new_obj.db_vt_machine_processor = old_obj.db_vt_machine_processor
+        if 'vt_machine_ram' in class_dict:
+            res = class_dict['vt_machine_ram'](old_obj, trans_dict)
+            new_obj.db_vt_machine_ram = res
+        elif hasattr(old_obj, 'db_vt_machine_ram') and old_obj.db_vt_machine_ram is not None:
+            new_obj.db_vt_machine_ram = old_obj.db_vt_machine_ram
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_item_execs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_item_exec(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_item_execs)
-        if remove:
-            self.db_deleted_item_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_item_execs:
-            if child.has_changes():
-                return True
         return False
-    def __get_db_item_execs(self):
-        return self._db_item_execs
-    def __set_db_item_execs(self, item_execs):
-        self._db_item_execs = item_execs
-        self.is_dirty = True
-    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
-    def db_get_item_execs(self):
-        return self._db_item_execs
-    def db_add_item_exec(self, item_exec):
-        self.is_dirty = True
-        self._db_item_execs.append(item_exec)
-        self.db_item_execs_id_index[item_exec.db_id] = item_exec
-    def db_change_item_exec(self, item_exec):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == item_exec.db_id:
-                self._db_item_execs[i] = item_exec
-                found = True
-                break
-        if not found:
-            self._db_item_execs.append(item_exec)
-        self.db_item_execs_id_index[item_exec.db_id] = item_exec
-    def db_delete_item_exec(self, item_exec):
-        self.is_dirty = True
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == item_exec.db_id:
-                if not self._db_item_execs[i].is_new:
-                    self.db_deleted_item_execs.append(self._db_item_execs[i])
-                del self._db_item_execs[i]
-                break
-        del self.db_item_execs_id_index[item_exec.db_id]
-    def db_get_item_exec(self, key):
-        for i in xrange(len(self._db_item_execs)):
-            if self._db_item_execs[i].db_id == key:
-                return self._db_item_execs[i]
-        return None
-    def db_get_item_exec_by_id(self, key):
-        return self.db_item_execs_id_index[key]
-    def db_has_item_exec_with_id(self, key):
-        return key in self.db_item_execs_id_index
-    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -13816,117 +15099,164 @@ class DBLoopExec(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_ts_start(self):
-        return self._db_ts_start
-    def __set_db_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
+    def __get_db_vt_id(self):
+        return self._db_vt_id
+    def __set_db_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
         self.is_dirty = True
-    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
-    def db_add_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_change_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_delete_ts_start(self, ts_start):
-        self._db_ts_start = None
+    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
+    def db_add_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_change_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_delete_vt_id(self, vt_id):
+        self._db_vt_id = None
     
-    def __get_db_ts_end(self):
-        return self._db_ts_end
-    def __set_db_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
+    def __get_db_prov_type(self):
+        return self._db_prov_type
+    def __set_db_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
         self.is_dirty = True
-    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
-    def db_add_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_change_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_delete_ts_end(self, ts_end):
-        self._db_ts_end = None
+    db_prov_type = property(__get_db_prov_type, __set_db_prov_type)
+    def db_add_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_change_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_delete_prov_type(self, prov_type):
+        self._db_prov_type = None
     
-    def __get_db_iteration(self):
-        return self._db_iteration
-    def __set_db_iteration(self, iteration):
-        self._db_iteration = iteration
+    def __get_db_prov_label(self):
+        return self._db_prov_label
+    def __set_db_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
         self.is_dirty = True
-    db_iteration = property(__get_db_iteration, __set_db_iteration)
-    def db_add_iteration(self, iteration):
-        self._db_iteration = iteration
-    def db_change_iteration(self, iteration):
-        self._db_iteration = iteration
-    def db_delete_iteration(self, iteration):
-        self._db_iteration = None
+    db_prov_label = property(__get_db_prov_label, __set_db_prov_label)
+    def db_add_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_change_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_delete_prov_label(self, prov_label):
+        self._db_prov_label = None
     
-    def __get_db_completed(self):
-        return self._db_completed
-    def __set_db_completed(self, completed):
-        self._db_completed = completed
+    def __get_db_vt_machine_os(self):
+        return self._db_vt_machine_os
+    def __set_db_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = vt_machine_os
         self.is_dirty = True
-    db_completed = property(__get_db_completed, __set_db_completed)
-    def db_add_completed(self, completed):
-        self._db_completed = completed
-    def db_change_completed(self, completed):
-        self._db_completed = completed
-    def db_delete_completed(self, completed):
-        self._db_completed = None
+    db_vt_machine_os = property(__get_db_vt_machine_os, __set_db_vt_machine_os)
+    def db_add_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = vt_machine_os
+    def db_change_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = vt_machine_os
+    def db_delete_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = None
     
-    def __get_db_error(self):
-        return self._db_error
-    def __set_db_error(self, error):
-        self._db_error = error
+    def __get_db_vt_machine_architecture(self):
+        return self._db_vt_machine_architecture
+    def __set_db_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = vt_machine_architecture
         self.is_dirty = True
-    db_error = property(__get_db_error, __set_db_error)
-    def db_add_error(self, error):
-        self._db_error = error
-    def db_change_error(self, error):
-        self._db_error = error
-    def db_delete_error(self, error):
-        self._db_error = None
+    db_vt_machine_architecture = property(__get_db_vt_machine_architecture, __set_db_vt_machine_architecture)
+    def db_add_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = vt_machine_architecture
+    def db_change_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = vt_machine_architecture
+    def db_delete_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = None
+    
+    def __get_db_vt_machine_processor(self):
+        return self._db_vt_machine_processor
+    def __set_db_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = vt_machine_processor
+        self.is_dirty = True
+    db_vt_machine_processor = property(__get_db_vt_machine_processor, __set_db_vt_machine_processor)
+    def db_add_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = vt_machine_processor
+    def db_change_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = vt_machine_processor
+    def db_delete_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = None
+    
+    def __get_db_vt_machine_ram(self):
+        return self._db_vt_machine_ram
+    def __set_db_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = vt_machine_ram
+        self.is_dirty = True
+    db_vt_machine_ram = property(__get_db_vt_machine_ram, __set_db_vt_machine_ram)
+    def db_add_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = vt_machine_ram
+    def db_change_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = vt_machine_ram
+    def db_delete_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmWasTriggeredBy(object):
+class DBMashuptrail(object):
 
-    vtType = 'opm_was_triggered_by'
+    vtType = 'mashuptrail'
 
-    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
-        self.db_deleted_effect = []
-        self._db_effect = effect
-        self.db_deleted_role = []
-        self._db_role = role
-        self.db_deleted_cause = []
-        self._db_cause = cause
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
+    def __init__(self, id=None, name=None, version=None, vtVersion=None, last_modified=None, actions=None, annotations=None, actionAnnotations=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_version = version
+        self._db_vtVersion = vtVersion
+        self._db_last_modified = last_modified
+        self.db_deleted_actions = []
+        self.db_actions_id_index = {}
+        if actions is None:
+            self._db_actions = []
         else:
-            self._db_accounts = accounts
-        self.db_deleted_opm_times = []
-        if opm_times is None:
-            self._db_opm_times = []
+            self._db_actions = actions
+            for v in self._db_actions:
+                self.db_actions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
         else:
-            self._db_opm_times = opm_times
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_actionAnnotations = []
+        self.db_actionAnnotations_id_index = {}
+        self.db_actionAnnotations_action_id_index = {}
+        self.db_actionAnnotations_key_index = {}
+        if actionAnnotations is None:
+            self._db_actionAnnotations = []
+        else:
+            self._db_actionAnnotations = actionAnnotations
+            for v in self._db_actionAnnotations:
+                self.db_actionAnnotations_id_index[v.db_id] = v
+                self.db_actionAnnotations_action_id_index[(v.db_action_id,v.db_key)] = v
+                self.db_actionAnnotations_key_index[(v.db_key,v.db_value)] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmWasTriggeredBy.do_copy(self)
+        return DBMashuptrail.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmWasTriggeredBy()
-        if self._db_effect is not None:
-            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
-        if self._db_role is not None:
-            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
-        if self._db_cause is not None:
-            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
+        cp = DBMashuptrail(id=self._db_id,
+                           name=self._db_name,
+                           version=self._db_version,
+                           vtVersion=self._db_vtVersion,
+                           last_modified=self._db_last_modified)
+        if self._db_actions is None:
+            cp._db_actions = []
         else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
-        if self._db_opm_times is None:
-            cp._db_opm_times = []
+            cp._db_actions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
         else:
-            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_actionAnnotations is None:
+            cp._db_actionAnnotations = []
+        else:
+            cp._db_actionAnnotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actionAnnotations]
         
         # set new ids
         if new_ids:
@@ -13938,6 +15268,12 @@ class DBOpmWasTriggeredBy(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_actions_id_index = dict((v.db_id, v) for v in cp._db_actions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_actionAnnotations_id_index = dict((v.db_id, v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_action_id_index = dict(((v.db_action_id,v.db_key), v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_key_index = dict(((v.db_key,v.db_value), v) for v in cp._db_actionAnnotations)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -13946,237 +15282,376 @@ class DBOpmWasTriggeredBy(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmWasTriggeredBy()
+            new_obj = DBMashuptrail()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'effect' in class_dict:
-            res = class_dict['effect'](old_obj, trans_dict)
-            new_obj.db_effect = res
-        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
-            obj = old_obj.db_effect
-            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
-            for obj in old_obj.db_deleted_effect:
-                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
-                new_obj.db_deleted_effect.append(n_obj)
-        if 'role' in class_dict:
-            res = class_dict['role'](old_obj, trans_dict)
-            new_obj.db_role = res
-        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
-            obj = old_obj.db_role
-            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
-            for obj in old_obj.db_deleted_role:
-                n_obj = DBOpmRole.update_version(obj, trans_dict)
-                new_obj.db_deleted_role.append(n_obj)
-        if 'cause' in class_dict:
-            res = class_dict['cause'](old_obj, trans_dict)
-            new_obj.db_cause = res
-        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
-            obj = old_obj.db_cause
-            new_obj.db_add_cause(DBOpmProcessIdCause.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
-            for obj in old_obj.db_deleted_cause:
-                n_obj = DBOpmProcessIdCause.update_version(obj, trans_dict)
-                new_obj.db_deleted_cause.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'vtVersion' in class_dict:
+            res = class_dict['vtVersion'](old_obj, trans_dict)
+            new_obj.db_vtVersion = res
+        elif hasattr(old_obj, 'db_vtVersion') and old_obj.db_vtVersion is not None:
+            new_obj.db_vtVersion = old_obj.db_vtVersion
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'actions' in class_dict:
+            res = class_dict['actions'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
-        if 'opm_times' in class_dict:
-            res = class_dict['opm_times'](old_obj, trans_dict)
+                new_obj.db_add_action(obj)
+        elif hasattr(old_obj, 'db_actions') and old_obj.db_actions is not None:
+            for obj in old_obj.db_actions:
+                new_obj.db_add_action(DBMashupAction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actions') and hasattr(new_obj, 'db_deleted_actions'):
+            for obj in old_obj.db_deleted_actions:
+                n_obj = DBMashupAction.update_version(obj, trans_dict)
+                new_obj.db_deleted_actions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_opm_time(obj)
-        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
-            for obj in old_obj.db_opm_times:
-                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
-            for obj in old_obj.db_deleted_opm_times:
-                n_obj = DBOpmTime.update_version(obj, trans_dict)
-                new_obj.db_deleted_opm_times.append(n_obj)
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'actionAnnotations' in class_dict:
+            res = class_dict['actionAnnotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_actionAnnotation(obj)
+        elif hasattr(old_obj, 'db_actionAnnotations') and old_obj.db_actionAnnotations is not None:
+            for obj in old_obj.db_actionAnnotations:
+                new_obj.db_add_actionAnnotation(DBMashupActionAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actionAnnotations') and hasattr(new_obj, 'db_deleted_actionAnnotations'):
+            for obj in old_obj.db_deleted_actionAnnotations:
+                n_obj = DBMashupActionAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_actionAnnotations.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_effect is not None:
-            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_effect = None
-        if self._db_role is not None:
-            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_role = None
-        if self._db_cause is not None:
-            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+        to_del = []
+        for child in self.db_actions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_cause = None
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_action(child)
         to_del = []
-        for child in self.db_accounts:
+        for child in self.db_annotations:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_account(child)
+            self.db_delete_annotation(child)
         to_del = []
-        for child in self.db_opm_times:
+        for child in self.db_actionAnnotations:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_opm_time(child)
+            self.db_delete_actionAnnotation(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_effect)
-        children.extend(self.db_deleted_role)
-        children.extend(self.db_deleted_cause)
-        children.extend(self.db_deleted_accounts)
-        children.extend(self.db_deleted_opm_times)
+        children.extend(self.db_deleted_actions)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_actionAnnotations)
         if remove:
-            self.db_deleted_effect = []
-            self.db_deleted_role = []
-            self.db_deleted_cause = []
-            self.db_deleted_accounts = []
-            self.db_deleted_opm_times = []
+            self.db_deleted_actions = []
+            self.db_deleted_annotations = []
+            self.db_deleted_actionAnnotations = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_effect is not None and self._db_effect.has_changes():
-            return True
-        if self._db_role is not None and self._db_role.has_changes():
-            return True
-        if self._db_cause is not None and self._db_cause.has_changes():
-            return True
-        for child in self._db_accounts:
+        for child in self._db_actions:
             if child.has_changes():
                 return True
-        for child in self._db_opm_times:
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_actionAnnotations:
             if child.has_changes():
                 return True
         return False
-    def __get_db_effect(self):
-        return self._db_effect
-    def __set_db_effect(self, effect):
-        self._db_effect = effect
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
         self.is_dirty = True
-    db_effect = property(__get_db_effect, __set_db_effect)
-    def db_add_effect(self, effect):
-        self._db_effect = effect
-    def db_change_effect(self, effect):
-        self._db_effect = effect
-    def db_delete_effect(self, effect):
-        if not self.is_new:
-            self.db_deleted_effect.append(self._db_effect)
-        self._db_effect = None
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
     
-    def __get_db_role(self):
-        return self._db_role
-    def __set_db_role(self, role):
-        self._db_role = role
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_role = property(__get_db_role, __set_db_role)
-    def db_add_role(self, role):
-        self._db_role = role
-    def db_change_role(self, role):
-        self._db_role = role
-    def db_delete_role(self, role):
-        if not self.is_new:
-            self.db_deleted_role.append(self._db_role)
-        self._db_role = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
-    def __get_db_cause(self):
-        return self._db_cause
-    def __set_db_cause(self, cause):
-        self._db_cause = cause
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
         self.is_dirty = True
-    db_cause = property(__get_db_cause, __set_db_cause)
-    def db_add_cause(self, cause):
-        self._db_cause = cause
-    def db_change_cause(self, cause):
-        self._db_cause = cause
-    def db_delete_cause(self, cause):
-        if not self.is_new:
-            self.db_deleted_cause.append(self._db_cause)
-        self._db_cause = None
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
     
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
+    def __get_db_vtVersion(self):
+        return self._db_vtVersion
+    def __set_db_vtVersion(self, vtVersion):
+        self._db_vtVersion = vtVersion
         self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
+    db_vtVersion = property(__get_db_vtVersion, __set_db_vtVersion)
+    def db_add_vtVersion(self, vtVersion):
+        self._db_vtVersion = vtVersion
+    def db_change_vtVersion(self, vtVersion):
+        self._db_vtVersion = vtVersion
+    def db_delete_vtVersion(self, vtVersion):
+        self._db_vtVersion = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_actions(self):
+        return self._db_actions
+    def __set_db_actions(self, actions):
+        self._db_actions = actions
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
+    db_actions = property(__get_db_actions, __set_db_actions)
+    def db_get_actions(self):
+        return self._db_actions
+    def db_add_action(self, action):
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
+        self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_change_action(self, action):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                self._db_actions[i] = action
+                found = True
+                break
+        if not found:
+            self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_delete_action(self, action):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                if not self._db_actions[i].is_new:
+                    self.db_deleted_actions.append(self._db_actions[i])
+                del self._db_actions[i]
+                break
+        del self.db_actions_id_index[action.db_id]
+    def db_get_action(self, key):
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == key:
+                return self._db_actions[i]
         return None
+    def db_get_action_by_id(self, key):
+        return self.db_actions_id_index[key]
+    def db_has_action_with_id(self, key):
+        return key in self.db_actions_id_index
     
-    def __get_db_opm_times(self):
-        return self._db_opm_times
-    def __set_db_opm_times(self, opm_times):
-        self._db_opm_times = opm_times
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
         self.is_dirty = True
-    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
-    def db_get_opm_times(self):
-        return self._db_opm_times
-    def db_add_opm_time(self, opm_time):
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_change_opm_time(self, opm_time):
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
         self.is_dirty = True
-        self._db_opm_times.append(opm_time)
-    def db_delete_opm_time(self, opm_time):
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_opm_time(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def __set_db_actionAnnotations(self, actionAnnotations):
+        self._db_actionAnnotations = actionAnnotations
+        self.is_dirty = True
+    db_actionAnnotations = property(__get_db_actionAnnotations, __set_db_actionAnnotations)
+    def db_get_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def db_add_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_change_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                self._db_actionAnnotations[i] = actionAnnotation
+                found = True
+                break
+        if not found:
+            self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_delete_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                if not self._db_actionAnnotations[i].is_new:
+                    self.db_deleted_actionAnnotations.append(self._db_actionAnnotations[i])
+                del self._db_actionAnnotations[i]
+                break
+        del self.db_actionAnnotations_id_index[actionAnnotation.db_id]
+        del self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)]
+        try:
+            del self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)]
+        except KeyError:
+            pass
+    def db_get_actionAnnotation(self, key):
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == key:
+                return self._db_actionAnnotations[i]
         return None
+    def db_get_actionAnnotation_by_id(self, key):
+        return self.db_actionAnnotations_id_index[key]
+    def db_has_actionAnnotation_with_id(self, key):
+        return key in self.db_actionAnnotations_id_index
+    def db_get_actionAnnotation_by_action_id(self, key):
+        return self.db_actionAnnotations_action_id_index[key]
+    def db_has_actionAnnotation_with_action_id(self, key):
+        return key in self.db_actionAnnotations_action_id_index
+    def db_get_actionAnnotation_by_key(self, key):
+        return self.db_actionAnnotations_key_index[key]
+    def db_has_actionAnnotation_with_key(self, key):
+        return key in self.db_actionAnnotations_key_index
     
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBRegistry(object):
 
-class DBMashupActionAnnotation(object):
-
-    vtType = 'mashup_actionAnnotation'
+    vtType = 'registry'
 
-    def __init__(self, id=None, key=None, value=None, action_id=None, date=None, user=None):
+    def __init__(self, id=None, entity_type=None, version=None, root_descriptor_id=None, name=None, last_modified=None, packages=None):
         self._db_id = id
-        self._db_key = key
-        self._db_value = value
-        self._db_action_id = action_id
-        self._db_date = date
-        self._db_user = user
+        self._db_entity_type = entity_type
+        self._db_version = version
+        self._db_root_descriptor_id = root_descriptor_id
+        self._db_name = name
+        self._db_last_modified = last_modified
+        self.db_deleted_packages = []
+        self.db_packages_id_index = {}
+        self.db_packages_identifier_index = {}
+        if packages is None:
+            self._db_packages = []
+        else:
+            self._db_packages = packages
+            for v in self._db_packages:
+                self.db_packages_id_index[v.db_id] = v
+                self.db_packages_identifier_index[(v.db_identifier,v.db_version)] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBMashupActionAnnotation.do_copy(self)
+        return DBRegistry.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBMashupActionAnnotation(id=self._db_id,
-                                      key=self._db_key,
-                                      value=self._db_value,
-                                      action_id=self._db_action_id,
-                                      date=self._db_date,
-                                      user=self._db_user)
+        cp = DBRegistry(id=self._db_id,
+                        entity_type=self._db_entity_type,
+                        version=self._db_version,
+                        root_descriptor_id=self._db_root_descriptor_id,
+                        name=self._db_name,
+                        last_modified=self._db_last_modified)
+        if self._db_packages is None:
+            cp._db_packages = []
+        else:
+            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
         
         # set new ids
         if new_ids:
@@ -14186,10 +15661,12 @@ class DBMashupActionAnnotation(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_action_id') and ('mashup_action', self._db_action_id) in id_remap:
-                cp._db_action_id = id_remap[('mashup_action', self._db_action_id)]
+            if hasattr(self, 'db_root_descriptor_id') and ('module_descriptor', self._db_root_descriptor_id) in id_remap:
+                cp._db_root_descriptor_id = id_remap[('module_descriptor', self._db_root_descriptor_id)]
         
         # recreate indices and set flags
+        cp.db_packages_id_index = dict((v.db_id, v) for v in cp._db_packages)
+        cp.db_packages_identifier_index = dict(((v.db_identifier,v.db_version), v) for v in cp._db_packages)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -14198,7 +15675,7 @@ class DBMashupActionAnnotation(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBMashupActionAnnotation()
+            new_obj = DBRegistry()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -14207,43 +15684,69 @@ class DBMashupActionAnnotation(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'key' in class_dict:
-            res = class_dict['key'](old_obj, trans_dict)
-            new_obj.db_key = res
-        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
-            new_obj.db_key = old_obj.db_key
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            new_obj.db_value = old_obj.db_value
-        if 'action_id' in class_dict:
-            res = class_dict['action_id'](old_obj, trans_dict)
-            new_obj.db_action_id = res
-        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
-            new_obj.db_action_id = old_obj.db_action_id
-        if 'date' in class_dict:
-            res = class_dict['date'](old_obj, trans_dict)
-            new_obj.db_date = res
-        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
-            new_obj.db_date = old_obj.db_date
-        if 'user' in class_dict:
-            res = class_dict['user'](old_obj, trans_dict)
-            new_obj.db_user = res
-        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
-            new_obj.db_user = old_obj.db_user
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'root_descriptor_id' in class_dict:
+            res = class_dict['root_descriptor_id'](old_obj, trans_dict)
+            new_obj.db_root_descriptor_id = res
+        elif hasattr(old_obj, 'db_root_descriptor_id') and old_obj.db_root_descriptor_id is not None:
+            new_obj.db_root_descriptor_id = old_obj.db_root_descriptor_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'packages' in class_dict:
+            res = class_dict['packages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_package(obj)
+        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
+            for obj in old_obj.db_packages:
+                new_obj.db_add_package(DBPackage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
+            for obj in old_obj.db_deleted_packages:
+                n_obj = DBPackage.update_version(obj, trans_dict)
+                new_obj.db_deleted_packages.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        to_del = []
+        for child in self.db_packages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_package(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_packages)
+        if remove:
+            self.db_deleted_packages = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        for child in self._db_packages:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -14258,102 +15761,148 @@ class DBMashupActionAnnotation(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_key(self):
-        return self._db_key
-    def __set_db_key(self, key):
-        self._db_key = key
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
         self.is_dirty = True
-    db_key = property(__get_db_key, __set_db_key)
-    def db_add_key(self, key):
-        self._db_key = key
-    def db_change_key(self, key):
-        self._db_key = key
-    def db_delete_key(self, key):
-        self._db_key = None
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
     
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
-        self._db_value = None
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
     
-    def __get_db_action_id(self):
-        return self._db_action_id
-    def __set_db_action_id(self, action_id):
-        self._db_action_id = action_id
+    def __get_db_root_descriptor_id(self):
+        return self._db_root_descriptor_id
+    def __set_db_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = root_descriptor_id
         self.is_dirty = True
-    db_action_id = property(__get_db_action_id, __set_db_action_id)
-    def db_add_action_id(self, action_id):
-        self._db_action_id = action_id
-    def db_change_action_id(self, action_id):
-        self._db_action_id = action_id
-    def db_delete_action_id(self, action_id):
-        self._db_action_id = None
+    db_root_descriptor_id = property(__get_db_root_descriptor_id, __set_db_root_descriptor_id)
+    def db_add_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = root_descriptor_id
+    def db_change_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = root_descriptor_id
+    def db_delete_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = None
     
-    def __get_db_date(self):
-        return self._db_date
-    def __set_db_date(self, date):
-        self._db_date = date
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
         self.is_dirty = True
-    db_date = property(__get_db_date, __set_db_date)
-    def db_add_date(self, date):
-        self._db_date = date
-    def db_change_date(self, date):
-        self._db_date = date
-    def db_delete_date(self, date):
-        self._db_date = None
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
-    def __get_db_user(self):
-        return self._db_user
-    def __set_db_user(self, user):
-        self._db_user = user
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_packages(self):
+        return self._db_packages
+    def __set_db_packages(self, packages):
+        self._db_packages = packages
+        self.is_dirty = True
+    db_packages = property(__get_db_packages, __set_db_packages)
+    def db_get_packages(self):
+        return self._db_packages
+    def db_add_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_id_index[package.db_id] = package
+        self.db_packages_identifier_index[(package.db_identifier,package.db_version)] = package
+    def db_change_package(self, package):
         self.is_dirty = True
-    db_user = property(__get_db_user, __set_db_user)
-    def db_add_user(self, user):
-        self._db_user = user
-    def db_change_user(self, user):
-        self._db_user = user
-    def db_delete_user(self, user):
-        self._db_user = None
+        found = False
+        for i in xrange(len(self._db_packages)):
+            if self._db_packages[i].db_id == package.db_id:
+                self._db_packages[i] = package
+                found = True
+                break
+        if not found:
+            self._db_packages.append(package)
+        self.db_packages_id_index[package.db_id] = package
+        self.db_packages_identifier_index[(package.db_identifier,package.db_version)] = package
+    def db_delete_package(self, package):
+        self.is_dirty = True
+        for i in xrange(len(self._db_packages)):
+            if self._db_packages[i].db_id == package.db_id:
+                if not self._db_packages[i].is_new:
+                    self.db_deleted_packages.append(self._db_packages[i])
+                del self._db_packages[i]
+                break
+        del self.db_packages_id_index[package.db_id]
+        del self.db_packages_identifier_index[(package.db_identifier,package.db_version)]
+    def db_get_package(self, key):
+        for i in xrange(len(self._db_packages)):
+            if self._db_packages[i].db_id == key:
+                return self._db_packages[i]
+        return None
+    def db_get_package_by_id(self, key):
+        return self.db_packages_id_index[key]
+    def db_has_package_with_id(self, key):
+        return key in self.db_packages_id_index
+    def db_get_package_by_identifier(self, key):
+        return self.db_packages_identifier_index[key]
+    def db_has_package_with_identifier(self, key):
+        return key in self.db_packages_identifier_index
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBConnection(object):
+class DBOpmAgent(object):
 
-    vtType = 'connection'
+    vtType = 'opm_agent'
 
-    def __init__(self, id=None, ports=None):
+    def __init__(self, id=None, value=None, accounts=None):
         self._db_id = id
-        self.db_deleted_ports = []
-        self.db_ports_id_index = {}
-        self.db_ports_type_index = {}
-        if ports is None:
-            self._db_ports = []
+        self._db_value = value
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
         else:
-            self._db_ports = ports
-            for v in self._db_ports:
-                self.db_ports_id_index[v.db_id] = v
-                self.db_ports_type_index[v.db_type] = v
+            self._db_accounts = accounts
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBConnection.do_copy(self)
+        return DBOpmAgent.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBConnection(id=self._db_id)
-        if self._db_ports is None:
-            cp._db_ports = []
+        cp = DBOpmAgent(id=self._db_id,
+                        value=self._db_value)
+        if self._db_accounts is None:
+            cp._db_accounts = []
         else:
-            cp._db_ports = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_ports]
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
         
         # set new ids
         if new_ids:
@@ -14365,8 +15914,6 @@ class DBConnection(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
-        cp.db_ports_id_index = dict((v.db_id, v) for v in cp._db_ports)
-        cp.db_ports_type_index = dict((v.db_type, v) for v in cp._db_ports)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -14375,7 +15922,7 @@ class DBConnection(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBConnection()
+            new_obj = DBOpmAgent()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -14384,17 +15931,22 @@ class DBConnection(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'ports' in class_dict:
-            res = class_dict['ports'](old_obj, trans_dict)
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_port(obj)
-        elif hasattr(old_obj, 'db_ports') and old_obj.db_ports is not None:
-            for obj in old_obj.db_ports:
-                new_obj.db_add_port(DBPort.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_ports') and hasattr(new_obj, 'db_deleted_ports'):
-            for obj in old_obj.db_deleted_ports:
-                n_obj = DBPort.update_version(obj, trans_dict)
-                new_obj.db_deleted_ports.append(n_obj)
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -14402,24 +15954,24 @@ class DBConnection(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_ports:
+        for child in self.db_accounts:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_port(child)
+            self.db_delete_account(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_ports)
+        children.extend(self.db_deleted_accounts)
         if remove:
-            self.db_deleted_ports = []
+            self.db_deleted_accounts = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_ports:
+        for child in self._db_accounts:
             if child.has_changes():
                 return True
         return False
@@ -14436,85 +15988,82 @@ class DBConnection(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_ports(self):
-        return self._db_ports
-    def __set_db_ports(self, ports):
-        self._db_ports = ports
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-    db_ports = property(__get_db_ports, __set_db_ports)
-    def db_get_ports(self):
-        return self._db_ports
-    def db_add_port(self, port):
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
         self.is_dirty = True
-        self._db_ports.append(port)
-        self.db_ports_id_index[port.db_id] = port
-        self.db_ports_type_index[port.db_type] = port
-    def db_change_port(self, port):
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_ports)):
-            if self._db_ports[i].db_id == port.db_id:
-                self._db_ports[i] = port
-                found = True
-                break
-        if not found:
-            self._db_ports.append(port)
-        self.db_ports_id_index[port.db_id] = port
-        self.db_ports_type_index[port.db_type] = port
-    def db_delete_port(self, port):
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
         self.is_dirty = True
-        for i in xrange(len(self._db_ports)):
-            if self._db_ports[i].db_id == port.db_id:
-                if not self._db_ports[i].is_new:
-                    self.db_deleted_ports.append(self._db_ports[i])
-                del self._db_ports[i]
-                break
-        del self.db_ports_id_index[port.db_id]
-        del self.db_ports_type_index[port.db_type]
-    def db_get_port(self, key):
-        for i in xrange(len(self._db_ports)):
-            if self._db_ports[i].db_id == key:
-                return self._db_ports[i]
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
         return None
-    def db_get_port_by_id(self, key):
-        return self.db_ports_id_index[key]
-    def db_has_port_with_id(self, key):
-        return key in self.db_ports_id_index
-    def db_get_port_by_type(self, key):
-        return self.db_ports_type_index[key]
-    def db_has_port_with_type(self, key):
-        return key in self.db_ports_type_index
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmProcess(object):
+class DBProvEntity(object):
 
-    vtType = 'opm_process'
+    vtType = 'prov_entity'
 
-    def __init__(self, id=None, value=None, accounts=None):
+    def __init__(self, id=None, prov_type=None, prov_label=None, prov_value=None, vt_id=None, vt_type=None, vt_desc=None, vt_package=None, vt_version=None, vt_cache=None, vt_location_x=None, vt_location_y=None, is_part_of=None):
         self._db_id = id
-        self.db_deleted_value = []
-        self._db_value = value
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
-        else:
-            self._db_accounts = accounts
+        self._db_prov_type = prov_type
+        self._db_prov_label = prov_label
+        self._db_prov_value = prov_value
+        self._db_vt_id = vt_id
+        self._db_vt_type = vt_type
+        self._db_vt_desc = vt_desc
+        self._db_vt_package = vt_package
+        self._db_vt_version = vt_version
+        self._db_vt_cache = vt_cache
+        self._db_vt_location_x = vt_location_x
+        self._db_vt_location_y = vt_location_y
+        self.db_deleted_is_part_of = []
+        self._db_is_part_of = is_part_of
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmProcess.do_copy(self)
+        return DBProvEntity.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmProcess(id=self._db_id)
-        if self._db_value is not None:
-            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
-        if self._db_accounts is None:
-            cp._db_accounts = []
-        else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        cp = DBProvEntity(id=self._db_id,
+                          prov_type=self._db_prov_type,
+                          prov_label=self._db_prov_label,
+                          prov_value=self._db_prov_value,
+                          vt_id=self._db_vt_id,
+                          vt_type=self._db_vt_type,
+                          vt_desc=self._db_vt_desc,
+                          vt_package=self._db_vt_package,
+                          vt_version=self._db_vt_version,
+                          vt_cache=self._db_vt_cache,
+                          vt_location_x=self._db_vt_location_x,
+                          vt_location_y=self._db_vt_location_y)
+        if self._db_is_part_of is not None:
+            cp._db_is_part_of = self._db_is_part_of.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -14534,7 +16083,7 @@ class DBOpmProcess(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmProcess()
+            new_obj = DBProvEntity()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -14543,62 +16092,94 @@ class DBOpmProcess(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            obj = old_obj.db_value
-            new_obj.db_add_value(DBOpmProcessValue.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
-            for obj in old_obj.db_deleted_value:
-                n_obj = DBOpmProcessValue.update_version(obj, trans_dict)
-                new_obj.db_deleted_value.append(n_obj)
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
+        if 'prov_type' in class_dict:
+            res = class_dict['prov_type'](old_obj, trans_dict)
+            new_obj.db_prov_type = res
+        elif hasattr(old_obj, 'db_prov_type') and old_obj.db_prov_type is not None:
+            new_obj.db_prov_type = old_obj.db_prov_type
+        if 'prov_label' in class_dict:
+            res = class_dict['prov_label'](old_obj, trans_dict)
+            new_obj.db_prov_label = res
+        elif hasattr(old_obj, 'db_prov_label') and old_obj.db_prov_label is not None:
+            new_obj.db_prov_label = old_obj.db_prov_label
+        if 'prov_value' in class_dict:
+            res = class_dict['prov_value'](old_obj, trans_dict)
+            new_obj.db_prov_value = res
+        elif hasattr(old_obj, 'db_prov_value') and old_obj.db_prov_value is not None:
+            new_obj.db_prov_value = old_obj.db_prov_value
+        if 'vt_id' in class_dict:
+            res = class_dict['vt_id'](old_obj, trans_dict)
+            new_obj.db_vt_id = res
+        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
+            new_obj.db_vt_id = old_obj.db_vt_id
+        if 'vt_type' in class_dict:
+            res = class_dict['vt_type'](old_obj, trans_dict)
+            new_obj.db_vt_type = res
+        elif hasattr(old_obj, 'db_vt_type') and old_obj.db_vt_type is not None:
+            new_obj.db_vt_type = old_obj.db_vt_type
+        if 'vt_desc' in class_dict:
+            res = class_dict['vt_desc'](old_obj, trans_dict)
+            new_obj.db_vt_desc = res
+        elif hasattr(old_obj, 'db_vt_desc') and old_obj.db_vt_desc is not None:
+            new_obj.db_vt_desc = old_obj.db_vt_desc
+        if 'vt_package' in class_dict:
+            res = class_dict['vt_package'](old_obj, trans_dict)
+            new_obj.db_vt_package = res
+        elif hasattr(old_obj, 'db_vt_package') and old_obj.db_vt_package is not None:
+            new_obj.db_vt_package = old_obj.db_vt_package
+        if 'vt_version' in class_dict:
+            res = class_dict['vt_version'](old_obj, trans_dict)
+            new_obj.db_vt_version = res
+        elif hasattr(old_obj, 'db_vt_version') and old_obj.db_vt_version is not None:
+            new_obj.db_vt_version = old_obj.db_vt_version
+        if 'vt_cache' in class_dict:
+            res = class_dict['vt_cache'](old_obj, trans_dict)
+            new_obj.db_vt_cache = res
+        elif hasattr(old_obj, 'db_vt_cache') and old_obj.db_vt_cache is not None:
+            new_obj.db_vt_cache = old_obj.db_vt_cache
+        if 'vt_location_x' in class_dict:
+            res = class_dict['vt_location_x'](old_obj, trans_dict)
+            new_obj.db_vt_location_x = res
+        elif hasattr(old_obj, 'db_vt_location_x') and old_obj.db_vt_location_x is not None:
+            new_obj.db_vt_location_x = old_obj.db_vt_location_x
+        if 'vt_location_y' in class_dict:
+            res = class_dict['vt_location_y'](old_obj, trans_dict)
+            new_obj.db_vt_location_y = res
+        elif hasattr(old_obj, 'db_vt_location_y') and old_obj.db_vt_location_y is not None:
+            new_obj.db_vt_location_y = old_obj.db_vt_location_y
+        if 'is_part_of' in class_dict:
+            res = class_dict['is_part_of'](old_obj, trans_dict)
+            new_obj.db_is_part_of = res
+        elif hasattr(old_obj, 'db_is_part_of') and old_obj.db_is_part_of is not None:
+            obj = old_obj.db_is_part_of
+            new_obj.db_add_is_part_of(DBIsPartOf.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_is_part_of') and hasattr(new_obj, 'db_deleted_is_part_of'):
+            for obj in old_obj.db_deleted_is_part_of:
+                n_obj = DBIsPartOf.update_version(obj, trans_dict)
+                new_obj.db_deleted_is_part_of.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_value is not None:
-            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_value = None
-        to_del = []
-        for child in self.db_accounts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_is_part_of is not None:
+            children.extend(self._db_is_part_of.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_account(child)
+                self._db_is_part_of = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_value)
-        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_is_part_of)
         if remove:
-            self.db_deleted_value = []
-            self.db_deleted_accounts = []
+            self.db_deleted_is_part_of = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_value is not None and self._db_value.has_changes():
+        if self._db_is_part_of is not None and self._db_is_part_of.has_changes():
             return True
-        for child in self._db_accounts:
-            if child.has_changes():
-                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -14613,146 +16194,185 @@ class DBOpmProcess(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+    def __get_db_prov_type(self):
+        return self._db_prov_type
+    def __set_db_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
-        if not self.is_new:
-            self.db_deleted_value.append(self._db_value)
-        self._db_value = None
+    db_prov_type = property(__get_db_prov_type, __set_db_prov_type)
+    def db_add_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_change_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_delete_prov_type(self, prov_type):
+        self._db_prov_type = None
     
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
+    def __get_db_prov_label(self):
+        return self._db_prov_label
+    def __set_db_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
         self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
+    db_prov_label = property(__get_db_prov_label, __set_db_prov_label)
+    def db_add_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_change_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_delete_prov_label(self, prov_label):
+        self._db_prov_label = None
+    
+    def __get_db_prov_value(self):
+        return self._db_prov_value
+    def __set_db_prov_value(self, prov_value):
+        self._db_prov_value = prov_value
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
+    db_prov_value = property(__get_db_prov_value, __set_db_prov_value)
+    def db_add_prov_value(self, prov_value):
+        self._db_prov_value = prov_value
+    def db_change_prov_value(self, prov_value):
+        self._db_prov_value = prov_value
+    def db_delete_prov_value(self, prov_value):
+        self._db_prov_value = None
+    
+    def __get_db_vt_id(self):
+        return self._db_vt_id
+    def __set_db_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
+    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
+    def db_add_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_change_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_delete_vt_id(self, vt_id):
+        self._db_vt_id = None
+    
+    def __get_db_vt_type(self):
+        return self._db_vt_type
+    def __set_db_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
-        return None
+    db_vt_type = property(__get_db_vt_type, __set_db_vt_type)
+    def db_add_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+    def db_change_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+    def db_delete_vt_type(self, vt_type):
+        self._db_vt_type = None
     
-    def getPrimaryKey(self):
-        return self._db_id
-
-class DBIsPartOf(object):
-
-    vtType = 'is_part_of'
-
-    def __init__(self, prov_ref=None):
-        self._db_prov_ref = prov_ref
+    def __get_db_vt_desc(self):
+        return self._db_vt_desc
+    def __set_db_vt_desc(self, vt_desc):
+        self._db_vt_desc = vt_desc
         self.is_dirty = True
-        self.is_new = True
+    db_vt_desc = property(__get_db_vt_desc, __set_db_vt_desc)
+    def db_add_vt_desc(self, vt_desc):
+        self._db_vt_desc = vt_desc
+    def db_change_vt_desc(self, vt_desc):
+        self._db_vt_desc = vt_desc
+    def db_delete_vt_desc(self, vt_desc):
+        self._db_vt_desc = None
+    
+    def __get_db_vt_package(self):
+        return self._db_vt_package
+    def __set_db_vt_package(self, vt_package):
+        self._db_vt_package = vt_package
+        self.is_dirty = True
+    db_vt_package = property(__get_db_vt_package, __set_db_vt_package)
+    def db_add_vt_package(self, vt_package):
+        self._db_vt_package = vt_package
+    def db_change_vt_package(self, vt_package):
+        self._db_vt_package = vt_package
+    def db_delete_vt_package(self, vt_package):
+        self._db_vt_package = None
+    
+    def __get_db_vt_version(self):
+        return self._db_vt_version
+    def __set_db_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+        self.is_dirty = True
+    db_vt_version = property(__get_db_vt_version, __set_db_vt_version)
+    def db_add_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_change_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_delete_vt_version(self, vt_version):
+        self._db_vt_version = None
+    
+    def __get_db_vt_cache(self):
+        return self._db_vt_cache
+    def __set_db_vt_cache(self, vt_cache):
+        self._db_vt_cache = vt_cache
+        self.is_dirty = True
+    db_vt_cache = property(__get_db_vt_cache, __set_db_vt_cache)
+    def db_add_vt_cache(self, vt_cache):
+        self._db_vt_cache = vt_cache
+    def db_change_vt_cache(self, vt_cache):
+        self._db_vt_cache = vt_cache
+    def db_delete_vt_cache(self, vt_cache):
+        self._db_vt_cache = None
+    
+    def __get_db_vt_location_x(self):
+        return self._db_vt_location_x
+    def __set_db_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = vt_location_x
+        self.is_dirty = True
+    db_vt_location_x = property(__get_db_vt_location_x, __set_db_vt_location_x)
+    def db_add_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = vt_location_x
+    def db_change_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = vt_location_x
+    def db_delete_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = None
+    
+    def __get_db_vt_location_y(self):
+        return self._db_vt_location_y
+    def __set_db_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = vt_location_y
+        self.is_dirty = True
+    db_vt_location_y = property(__get_db_vt_location_y, __set_db_vt_location_y)
+    def db_add_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = vt_location_y
+    def db_change_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = vt_location_y
+    def db_delete_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = None
     
-    def __copy__(self):
-        return DBIsPartOf.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBIsPartOf(prov_ref=self._db_prov_ref)
-        
-        # set new ids
-        if new_ids:
-            new_id = id_scope.getNewId(self.vtType)
-            if self.vtType in id_scope.remap:
-                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
-            else:
-                id_remap[(self.vtType, self.db_id)] = new_id
-            cp.db_id = new_id
-        
-        # recreate indices and set flags
-        if not new_ids:
-            cp.is_dirty = self.is_dirty
-            cp.is_new = self.is_new
-        return cp
-
-    @staticmethod
-    def update_version(old_obj, trans_dict, new_obj=None):
-        if new_obj is None:
-            new_obj = DBIsPartOf()
-        class_dict = {}
-        if new_obj.__class__.__name__ in trans_dict:
-            class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_ref' in class_dict:
-            res = class_dict['prov_ref'](old_obj, trans_dict)
-            new_obj.db_prov_ref = res
-        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
-            new_obj.db_prov_ref = old_obj.db_prov_ref
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
-    def db_deleted_children(self, remove=False):
-        children = []
-        return children
-    def has_changes(self):
-        if self.is_dirty:
-            return True
-        return False
-    def __get_db_prov_ref(self):
-        return self._db_prov_ref
-    def __set_db_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
+    def __get_db_is_part_of(self):
+        return self._db_is_part_of
+    def __set_db_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
         self.is_dirty = True
-    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
-    def db_add_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_change_prov_ref(self, prov_ref):
-        self._db_prov_ref = prov_ref
-    def db_delete_prov_ref(self, prov_ref):
-        self._db_prov_ref = None
+    db_is_part_of = property(__get_db_is_part_of, __set_db_is_part_of)
+    def db_add_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_change_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_delete_is_part_of(self, is_part_of):
+        if not self.is_new:
+            self.db_deleted_is_part_of.append(self._db_is_part_of)
+        self._db_is_part_of = None
     
+    def getPrimaryKey(self):
+        return self._db_id
 
+class DBAnnotation(object):
 
-class DBPEFunction(object):
-
-    vtType = 'pe_function'
+    vtType = 'annotation'
 
-    def __init__(self, id=None, module_id=None, port_name=None, is_alias=None, parameters=None):
+    def __init__(self, id=None, key=None, value=None):
         self._db_id = id
-        self._db_module_id = module_id
-        self._db_port_name = port_name
-        self._db_is_alias = is_alias
-        self.db_deleted_parameters = []
-        self.db_parameters_id_index = {}
-        if parameters is None:
-            self._db_parameters = []
-        else:
-            self._db_parameters = parameters
-            for v in self._db_parameters:
-                self.db_parameters_id_index[v.db_id] = v
+        self._db_key = key
+        self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBPEFunction.do_copy(self)
+        return DBAnnotation.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBPEFunction(id=self._db_id,
-                          module_id=self._db_module_id,
-                          port_name=self._db_port_name,
-                          is_alias=self._db_is_alias)
-        if self._db_parameters is None:
-            cp._db_parameters = []
-        else:
-            cp._db_parameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameters]
+        cp = DBAnnotation(id=self._db_id,
+                          key=self._db_key,
+                          value=self._db_value)
         
         # set new ids
         if new_ids:
@@ -14762,11 +16382,8 @@ class DBPEFunction(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
-                cp._db_module_id = id_remap[('module', self._db_module_id)]
         
         # recreate indices and set flags
-        cp.db_parameters_id_index = dict((v.db_id, v) for v in cp._db_parameters)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -14775,7 +16392,7 @@ class DBPEFunction(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBPEFunction()
+            new_obj = DBAnnotation()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -14784,59 +16401,28 @@ class DBPEFunction(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'module_id' in class_dict:
-            res = class_dict['module_id'](old_obj, trans_dict)
-            new_obj.db_module_id = res
-        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
-            new_obj.db_module_id = old_obj.db_module_id
-        if 'port_name' in class_dict:
-            res = class_dict['port_name'](old_obj, trans_dict)
-            new_obj.db_port_name = res
-        elif hasattr(old_obj, 'db_port_name') and old_obj.db_port_name is not None:
-            new_obj.db_port_name = old_obj.db_port_name
-        if 'is_alias' in class_dict:
-            res = class_dict['is_alias'](old_obj, trans_dict)
-            new_obj.db_is_alias = res
-        elif hasattr(old_obj, 'db_is_alias') and old_obj.db_is_alias is not None:
-            new_obj.db_is_alias = old_obj.db_is_alias
-        if 'parameters' in class_dict:
-            res = class_dict['parameters'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_parameter(obj)
-        elif hasattr(old_obj, 'db_parameters') and old_obj.db_parameters is not None:
-            for obj in old_obj.db_parameters:
-                new_obj.db_add_parameter(DBPEParameter.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_parameters') and hasattr(new_obj, 'db_deleted_parameters'):
-            for obj in old_obj.db_deleted_parameters:
-                n_obj = DBPEParameter.update_version(obj, trans_dict)
-                new_obj.db_deleted_parameters.append(n_obj)
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_parameters:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_parameter(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_parameters)
-        if remove:
-            self.db_deleted_parameters = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_parameters:
-            if child.has_changes():
-                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -14851,107 +16437,53 @@ class DBPEFunction(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_module_id(self):
-        return self._db_module_id
-    def __set_db_module_id(self, module_id):
-        self._db_module_id = module_id
-        self.is_dirty = True
-    db_module_id = property(__get_db_module_id, __set_db_module_id)
-    def db_add_module_id(self, module_id):
-        self._db_module_id = module_id
-    def db_change_module_id(self, module_id):
-        self._db_module_id = module_id
-    def db_delete_module_id(self, module_id):
-        self._db_module_id = None
-    
-    def __get_db_port_name(self):
-        return self._db_port_name
-    def __set_db_port_name(self, port_name):
-        self._db_port_name = port_name
-        self.is_dirty = True
-    db_port_name = property(__get_db_port_name, __set_db_port_name)
-    def db_add_port_name(self, port_name):
-        self._db_port_name = port_name
-    def db_change_port_name(self, port_name):
-        self._db_port_name = port_name
-    def db_delete_port_name(self, port_name):
-        self._db_port_name = None
-    
-    def __get_db_is_alias(self):
-        return self._db_is_alias
-    def __set_db_is_alias(self, is_alias):
-        self._db_is_alias = is_alias
-        self.is_dirty = True
-    db_is_alias = property(__get_db_is_alias, __set_db_is_alias)
-    def db_add_is_alias(self, is_alias):
-        self._db_is_alias = is_alias
-    def db_change_is_alias(self, is_alias):
-        self._db_is_alias = is_alias
-    def db_delete_is_alias(self, is_alias):
-        self._db_is_alias = None
-    
-    def __get_db_parameters(self):
-        return self._db_parameters
-    def __set_db_parameters(self, parameters):
-        self._db_parameters = parameters
-        self.is_dirty = True
-    db_parameters = property(__get_db_parameters, __set_db_parameters)
-    def db_get_parameters(self):
-        return self._db_parameters
-    def db_add_parameter(self, parameter):
-        self.is_dirty = True
-        self._db_parameters.append(parameter)
-        self.db_parameters_id_index[parameter.db_id] = parameter
-    def db_change_parameter(self, parameter):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_parameters)):
-            if self._db_parameters[i].db_id == parameter.db_id:
-                self._db_parameters[i] = parameter
-                found = True
-                break
-        if not found:
-            self._db_parameters.append(parameter)
-        self.db_parameters_id_index[parameter.db_id] = parameter
-    def db_delete_parameter(self, parameter):
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
         self.is_dirty = True
-        for i in xrange(len(self._db_parameters)):
-            if self._db_parameters[i].db_id == parameter.db_id:
-                if not self._db_parameters[i].is_new:
-                    self.db_deleted_parameters.append(self._db_parameters[i])
-                del self._db_parameters[i]
-                break
-        del self.db_parameters_id_index[parameter.db_id]
-    def db_get_parameter(self, key):
-        for i in xrange(len(self._db_parameters)):
-            if self._db_parameters[i].db_id == key:
-                return self._db_parameters[i]
-        return None
-    def db_get_parameter_by_id(self, key):
-        return self.db_parameters_id_index[key]
-    def db_has_parameter_with_id(self, key):
-        return key in self.db_parameters_id_index
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmProcessValue(object):
+class DBOpmTime(object):
 
-    vtType = 'opm_process_value'
+    vtType = 'opm_time'
 
-    def __init__(self, value=None):
-        self.db_deleted_value = []
-        self._db_value = value
+    def __init__(self, no_later_than=None, no_earlier_than=None, clock_id=None):
+        self._db_no_later_than = no_later_than
+        self._db_no_earlier_than = no_earlier_than
+        self._db_clock_id = clock_id
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBOpmProcessValue.do_copy(self)
+        return DBOpmTime.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmProcessValue()
-        if self._db_value is not None:
-            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        cp = DBOpmTime(no_later_than=self._db_no_later_than,
+                       no_earlier_than=self._db_no_earlier_than,
+                       clock_id=self._db_clock_id)
         
         # set new ids
         if new_ids:
@@ -14971,121 +16503,117 @@ class DBOpmProcessValue(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmProcessValue()
+            new_obj = DBOpmTime()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'value' in class_dict:
-            res = class_dict['value'](old_obj, trans_dict)
-            new_obj.db_value = res
-        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
-            obj = old_obj.db_value
-            if obj.vtType == 'module_exec':
-                new_obj.db_add_value(DBModuleExec.update_version(obj, trans_dict))
-            elif obj.vtType == 'group_exec':
-                new_obj.db_add_value(DBGroupExec.update_version(obj, trans_dict))
-            elif obj.vtType == 'loop_exec':
-                new_obj.db_add_value(DBLoopExec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
-            for obj in old_obj.db_deleted_value:
-                if obj.vtType == 'module_exec':
-                    n_obj = DBModuleExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_value.append(n_obj)
-                elif obj.vtType == 'group_exec':
-                    n_obj = DBGroupExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_value.append(n_obj)
-                elif obj.vtType == 'loop_exec':
-                    n_obj = DBLoopExec.update_version(obj, trans_dict)
-                    new_obj.db_deleted_value.append(n_obj)
+        if 'no_later_than' in class_dict:
+            res = class_dict['no_later_than'](old_obj, trans_dict)
+            new_obj.db_no_later_than = res
+        elif hasattr(old_obj, 'db_no_later_than') and old_obj.db_no_later_than is not None:
+            new_obj.db_no_later_than = old_obj.db_no_later_than
+        if 'no_earlier_than' in class_dict:
+            res = class_dict['no_earlier_than'](old_obj, trans_dict)
+            new_obj.db_no_earlier_than = res
+        elif hasattr(old_obj, 'db_no_earlier_than') and old_obj.db_no_earlier_than is not None:
+            new_obj.db_no_earlier_than = old_obj.db_no_earlier_than
+        if 'clock_id' in class_dict:
+            res = class_dict['clock_id'](old_obj, trans_dict)
+            new_obj.db_clock_id = res
+        elif hasattr(old_obj, 'db_clock_id') and old_obj.db_clock_id is not None:
+            new_obj.db_clock_id = old_obj.db_clock_id
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        if self._db_value is not None:
-            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_value = None
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_value)
-        if remove:
-            self.db_deleted_value = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_value is not None and self._db_value.has_changes():
-            return True
         return False
-    def __get_db_value(self):
-        return self._db_value
-    def __set_db_value(self, value):
-        self._db_value = value
+    def __get_db_no_later_than(self):
+        return self._db_no_later_than
+    def __set_db_no_later_than(self, no_later_than):
+        self._db_no_later_than = no_later_than
         self.is_dirty = True
-    db_value = property(__get_db_value, __set_db_value)
-    def db_add_value(self, value):
-        self._db_value = value
-    def db_change_value(self, value):
-        self._db_value = value
-    def db_delete_value(self, value):
-        if not self.is_new:
-            self.db_deleted_value.append(self._db_value)
-        self._db_value = None
+    db_no_later_than = property(__get_db_no_later_than, __set_db_no_later_than)
+    def db_add_no_later_than(self, no_later_than):
+        self._db_no_later_than = no_later_than
+    def db_change_no_later_than(self, no_later_than):
+        self._db_no_later_than = no_later_than
+    def db_delete_no_later_than(self, no_later_than):
+        self._db_no_later_than = None
+    
+    def __get_db_no_earlier_than(self):
+        return self._db_no_earlier_than
+    def __set_db_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = no_earlier_than
+        self.is_dirty = True
+    db_no_earlier_than = property(__get_db_no_earlier_than, __set_db_no_earlier_than)
+    def db_add_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = no_earlier_than
+    def db_change_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = no_earlier_than
+    def db_delete_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = None
+    
+    def __get_db_clock_id(self):
+        return self._db_clock_id
+    def __set_db_clock_id(self, clock_id):
+        self._db_clock_id = clock_id
+        self.is_dirty = True
+    db_clock_id = property(__get_db_clock_id, __set_db_clock_id)
+    def db_add_clock_id(self, clock_id):
+        self._db_clock_id = clock_id
+    def db_change_clock_id(self, clock_id):
+        self._db_clock_id = clock_id
+    def db_delete_clock_id(self, clock_id):
+        self._db_clock_id = None
     
 
 
-class DBAction(object):
+class DBParameterExploration(object):
 
-    vtType = 'action'
+    vtType = 'parameter_exploration'
 
-    def __init__(self, operations=None, id=None, prevId=None, date=None, session=None, user=None, annotations=None):
-        self.db_deleted_operations = []
-        self.db_operations_id_index = {}
-        if operations is None:
-            self._db_operations = []
-        else:
-            self._db_operations = operations
-            for v in self._db_operations:
-                self.db_operations_id_index[v.db_id] = v
+    def __init__(self, id=None, action_id=None, name=None, date=None, user=None, dims=None, layout=None, functions=None):
         self._db_id = id
-        self._db_prevId = prevId
+        self._db_action_id = action_id
+        self._db_name = name
         self._db_date = date
-        self._db_session = session
         self._db_user = user
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        self.db_annotations_key_index = {}
-        if annotations is None:
-            self._db_annotations = []
+        self._db_dims = dims
+        self._db_layout = layout
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
         else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
-                self.db_annotations_key_index[v.db_key] = v
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBAction.do_copy(self)
+        return DBParameterExploration.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBAction(id=self._db_id,
-                      prevId=self._db_prevId,
-                      date=self._db_date,
-                      session=self._db_session,
-                      user=self._db_user)
-        if self._db_operations is None:
-            cp._db_operations = []
-        else:
-            cp._db_operations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_operations]
-        if self._db_annotations is None:
-            cp._db_annotations = []
+        cp = DBParameterExploration(id=self._db_id,
+                                    action_id=self._db_action_id,
+                                    name=self._db_name,
+                                    date=self._db_date,
+                                    user=self._db_user,
+                                    dims=self._db_dims,
+                                    layout=self._db_layout)
+        if self._db_functions is None:
+            cp._db_functions = []
         else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
         
         # set new ids
         if new_ids:
@@ -15095,13 +16623,11 @@ class DBAction(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_prevId') and ('action', self._db_prevId) in id_remap:
-                cp._db_prevId = id_remap[('action', self._db_prevId)]
+            if hasattr(self, 'db_action_id') and ('action', self._db_action_id) in id_remap:
+                cp._db_action_id = id_remap[('action', self._db_action_id)]
         
         # recreate indices and set flags
-        cp.db_operations_id_index = dict((v.db_id, v) for v in cp._db_operations)
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -15110,69 +16636,56 @@ class DBAction(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBAction()
+            new_obj = DBParameterExploration()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'operations' in class_dict:
-            res = class_dict['operations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_operation(obj)
-        elif hasattr(old_obj, 'db_operations') and old_obj.db_operations is not None:
-            for obj in old_obj.db_operations:
-                if obj.vtType == 'add':
-                    new_obj.db_add_operation(DBAdd.update_version(obj, trans_dict))
-                elif obj.vtType == 'delete':
-                    new_obj.db_add_operation(DBDelete.update_version(obj, trans_dict))
-                elif obj.vtType == 'change':
-                    new_obj.db_add_operation(DBChange.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_operations') and hasattr(new_obj, 'db_deleted_operations'):
-            for obj in old_obj.db_deleted_operations:
-                if obj.vtType == 'add':
-                    n_obj = DBAdd.update_version(obj, trans_dict)
-                    new_obj.db_deleted_operations.append(n_obj)
-                elif obj.vtType == 'delete':
-                    n_obj = DBDelete.update_version(obj, trans_dict)
-                    new_obj.db_deleted_operations.append(n_obj)
-                elif obj.vtType == 'change':
-                    n_obj = DBChange.update_version(obj, trans_dict)
-                    new_obj.db_deleted_operations.append(n_obj)
         if 'id' in class_dict:
             res = class_dict['id'](old_obj, trans_dict)
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'prevId' in class_dict:
-            res = class_dict['prevId'](old_obj, trans_dict)
-            new_obj.db_prevId = res
-        elif hasattr(old_obj, 'db_prevId') and old_obj.db_prevId is not None:
-            new_obj.db_prevId = old_obj.db_prevId
+        if 'action_id' in class_dict:
+            res = class_dict['action_id'](old_obj, trans_dict)
+            new_obj.db_action_id = res
+        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
+            new_obj.db_action_id = old_obj.db_action_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
         if 'date' in class_dict:
             res = class_dict['date'](old_obj, trans_dict)
             new_obj.db_date = res
         elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
             new_obj.db_date = old_obj.db_date
-        if 'session' in class_dict:
-            res = class_dict['session'](old_obj, trans_dict)
-            new_obj.db_session = res
-        elif hasattr(old_obj, 'db_session') and old_obj.db_session is not None:
-            new_obj.db_session = old_obj.db_session
         if 'user' in class_dict:
             res = class_dict['user'](old_obj, trans_dict)
             new_obj.db_user = res
         elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
             new_obj.db_user = old_obj.db_user
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
+        if 'dims' in class_dict:
+            res = class_dict['dims'](old_obj, trans_dict)
+            new_obj.db_dims = res
+        elif hasattr(old_obj, 'db_dims') and old_obj.db_dims is not None:
+            new_obj.db_dims = old_obj.db_dims
+        if 'layout' in class_dict:
+            res = class_dict['layout'](old_obj, trans_dict)
+            new_obj.db_layout = res
+        elif hasattr(old_obj, 'db_layout') and old_obj.db_layout is not None:
+            new_obj.db_layout = old_obj.db_layout
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBPEFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBPEFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
@@ -15180,81 +16693,27 @@ class DBAction(object):
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
         to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        to_del = []
-        for child in self.db_operations:
+        for child in self.db_functions:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_operation(child)
+            self.db_delete_function(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_operations)
+        children.extend(self.db_deleted_functions)
         if remove:
-            self.db_deleted_annotations = []
-            self.db_deleted_operations = []
+            self.db_deleted_functions = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
-        for child in self._db_operations:
+        for child in self._db_functions:
             if child.has_changes():
                 return True
         return False
-    def __get_db_operations(self):
-        return self._db_operations
-    def __set_db_operations(self, operations):
-        self._db_operations = operations
-        self.is_dirty = True
-    db_operations = property(__get_db_operations, __set_db_operations)
-    def db_get_operations(self):
-        return self._db_operations
-    def db_add_operation(self, operation):
-        self.is_dirty = True
-        self._db_operations.append(operation)
-        self.db_operations_id_index[operation.db_id] = operation
-    def db_change_operation(self, operation):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_operations)):
-            if self._db_operations[i].db_id == operation.db_id:
-                self._db_operations[i] = operation
-                found = True
-                break
-        if not found:
-            self._db_operations.append(operation)
-        self.db_operations_id_index[operation.db_id] = operation
-    def db_delete_operation(self, operation):
-        self.is_dirty = True
-        for i in xrange(len(self._db_operations)):
-            if self._db_operations[i].db_id == operation.db_id:
-                if not self._db_operations[i].is_new:
-                    self.db_deleted_operations.append(self._db_operations[i])
-                del self._db_operations[i]
-                break
-        del self.db_operations_id_index[operation.db_id]
-    def db_get_operation(self, key):
-        for i in xrange(len(self._db_operations)):
-            if self._db_operations[i].db_id == key:
-                return self._db_operations[i]
-        return None
-    def db_get_operation_by_id(self, key):
-        return self.db_operations_id_index[key]
-    def db_has_operation_with_id(self, key):
-        return key in self.db_operations_id_index
-    
     def __get_db_id(self):
         return self._db_id
     def __set_db_id(self, id):
@@ -15268,18 +16727,31 @@ class DBAction(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_prevId(self):
-        return self._db_prevId
-    def __set_db_prevId(self, prevId):
-        self._db_prevId = prevId
+    def __get_db_action_id(self):
+        return self._db_action_id
+    def __set_db_action_id(self, action_id):
+        self._db_action_id = action_id
         self.is_dirty = True
-    db_prevId = property(__get_db_prevId, __set_db_prevId)
-    def db_add_prevId(self, prevId):
-        self._db_prevId = prevId
-    def db_change_prevId(self, prevId):
-        self._db_prevId = prevId
-    def db_delete_prevId(self, prevId):
-        self._db_prevId = None
+    db_action_id = property(__get_db_action_id, __set_db_action_id)
+    def db_add_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_change_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_delete_action_id(self, action_id):
+        self._db_action_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
     
     def __get_db_date(self):
         return self._db_date
@@ -15294,19 +16766,6 @@ class DBAction(object):
     def db_delete_date(self, date):
         self._db_date = None
     
-    def __get_db_session(self):
-        return self._db_session
-    def __set_db_session(self, session):
-        self._db_session = session
-        self.is_dirty = True
-    db_session = property(__get_db_session, __set_db_session)
-    def db_add_session(self, session):
-        self._db_session = session
-    def db_change_session(self, session):
-        self._db_session = session
-    def db_delete_session(self, session):
-        self._db_session = None
-    
     def __get_db_user(self):
         return self._db_user
     def __set_db_user(self, user):
@@ -15320,83 +16779,101 @@ class DBAction(object):
     def db_delete_user(self, user):
         self._db_user = None
     
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
+    def __get_db_dims(self):
+        return self._db_dims
+    def __set_db_dims(self, dims):
+        self._db_dims = dims
         self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
+    db_dims = property(__get_db_dims, __set_db_dims)
+    def db_add_dims(self, dims):
+        self._db_dims = dims
+    def db_change_dims(self, dims):
+        self._db_dims = dims
+    def db_delete_dims(self, dims):
+        self._db_dims = None
+    
+    def __get_db_layout(self):
+        return self._db_layout
+    def __set_db_layout(self, layout):
+        self._db_layout = layout
         self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_change_annotation(self, annotation):
+    db_layout = property(__get_db_layout, __set_db_layout)
+    def db_add_layout(self, layout):
+        self._db_layout = layout
+    def db_change_layout(self, layout):
+        self._db_layout = layout
+    def db_delete_layout(self, layout):
+        self._db_layout = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
+        self.is_dirty = True
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
+        self.is_dirty = True
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
                 found = True
                 break
         if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
-    def db_delete_annotation(self, annotation):
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
         self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
                 break
-        del self.db_annotations_id_index[annotation.db_id]
-        del self.db_annotations_key_index[annotation.db_key]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
         return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
-    def db_get_annotation_by_key(self, key):
-        return self.db_annotations_key_index[key]
-    def db_has_annotation_with_key(self, key):
-        return key in self.db_annotations_key_index
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBOpmAgent(object):
+class DBMashupActionAnnotation(object):
 
-    vtType = 'opm_agent'
+    vtType = 'mashup_actionAnnotation'
 
-    def __init__(self, id=None, value=None, accounts=None):
+    def __init__(self, id=None, key=None, value=None, action_id=None, date=None, user=None):
         self._db_id = id
+        self._db_key = key
         self._db_value = value
-        self.db_deleted_accounts = []
-        if accounts is None:
-            self._db_accounts = []
-        else:
-            self._db_accounts = accounts
+        self._db_action_id = action_id
+        self._db_date = date
+        self._db_user = user
         self.is_dirty = True
         self.is_new = True
-    
-    def __copy__(self):
-        return DBOpmAgent.do_copy(self)
-
-    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBOpmAgent(id=self._db_id,
-                        value=self._db_value)
-        if self._db_accounts is None:
-            cp._db_accounts = []
-        else:
-            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+    
+    def __copy__(self):
+        return DBMashupActionAnnotation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashupActionAnnotation(id=self._db_id,
+                                      key=self._db_key,
+                                      value=self._db_value,
+                                      action_id=self._db_action_id,
+                                      date=self._db_date,
+                                      user=self._db_user)
         
         # set new ids
         if new_ids:
@@ -15406,6 +16883,8 @@ class DBOpmAgent(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_action_id') and ('mashup_action', self._db_action_id) in id_remap:
+                cp._db_action_id = id_remap[('mashup_action', self._db_action_id)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -15416,7 +16895,7 @@ class DBOpmAgent(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBOpmAgent()
+            new_obj = DBMashupActionAnnotation()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -15425,49 +16904,43 @@ class DBOpmAgent(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
         if 'value' in class_dict:
             res = class_dict['value'](old_obj, trans_dict)
             new_obj.db_value = res
         elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
             new_obj.db_value = old_obj.db_value
-        if 'accounts' in class_dict:
-            res = class_dict['accounts'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_account(obj)
-        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
-            for obj in old_obj.db_accounts:
-                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
-            for obj in old_obj.db_deleted_accounts:
-                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
-                new_obj.db_deleted_accounts.append(n_obj)
+        if 'action_id' in class_dict:
+            res = class_dict['action_id'](old_obj, trans_dict)
+            new_obj.db_action_id = res
+        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
+            new_obj.db_action_id = old_obj.db_action_id
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_accounts:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_account(child)
-        children.append((self, parent[0], parent[1]))
-        return children
+        return [(self, parent[0], parent[1])]
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_accounts)
-        if remove:
-            self.db_deleted_accounts = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_accounts:
-            if child.has_changes():
-                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -15482,6 +16955,19 @@ class DBOpmAgent(object):
     def db_delete_id(self, id):
         self._db_id = None
     
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
+        self.is_dirty = True
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
     def __get_db_value(self):
         return self._db_value
     def __set_db_value(self, value):
@@ -15495,51 +16981,75 @@ class DBOpmAgent(object):
     def db_delete_value(self, value):
         self._db_value = None
     
-    def __get_db_accounts(self):
-        return self._db_accounts
-    def __set_db_accounts(self, accounts):
-        self._db_accounts = accounts
-        self.is_dirty = True
-    db_accounts = property(__get_db_accounts, __set_db_accounts)
-    def db_get_accounts(self):
-        return self._db_accounts
-    def db_add_account(self, account):
+    def __get_db_action_id(self):
+        return self._db_action_id
+    def __set_db_action_id(self, action_id):
+        self._db_action_id = action_id
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_change_account(self, account):
+    db_action_id = property(__get_db_action_id, __set_db_action_id)
+    def db_add_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_change_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_delete_action_id(self, action_id):
+        self._db_action_id = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
         self.is_dirty = True
-        self._db_accounts.append(account)
-    def db_delete_account(self, account):
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
         self.is_dirty = True
-        raise Exception('Cannot delete a non-keyed object')
-    def db_get_account(self, key):
-        return None
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBDelete(object):
+class DBOpmProcess(object):
 
-    vtType = 'delete'
+    vtType = 'opm_process'
 
-    def __init__(self, id=None, what=None, objectId=None, parentObjId=None, parentObjType=None):
+    def __init__(self, id=None, value=None, accounts=None):
         self._db_id = id
-        self._db_what = what
-        self._db_objectId = objectId
-        self._db_parentObjId = parentObjId
-        self._db_parentObjType = parentObjType
+        self.db_deleted_value = []
+        self._db_value = value
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBDelete.do_copy(self)
+        return DBOpmProcess.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBDelete(id=self._db_id,
-                      what=self._db_what,
-                      objectId=self._db_objectId,
-                      parentObjId=self._db_parentObjId,
-                      parentObjType=self._db_parentObjType)
+        cp = DBOpmProcess(id=self._db_id)
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
         
         # set new ids
         if new_ids:
@@ -15549,10 +17059,6 @@ class DBDelete(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_objectId') and (self._db_what, self._db_objectId) in id_remap:
-                cp._db_objectId = id_remap[(self._db_what, self._db_objectId)]
-            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
-                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
         
         # recreate indices and set flags
         if not new_ids:
@@ -15563,7 +17069,7 @@ class DBDelete(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBDelete()
+            new_obj = DBOpmProcess()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -15572,38 +17078,62 @@ class DBDelete(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'what' in class_dict:
-            res = class_dict['what'](old_obj, trans_dict)
-            new_obj.db_what = res
-        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
-            new_obj.db_what = old_obj.db_what
-        if 'objectId' in class_dict:
-            res = class_dict['objectId'](old_obj, trans_dict)
-            new_obj.db_objectId = res
-        elif hasattr(old_obj, 'db_objectId') and old_obj.db_objectId is not None:
-            new_obj.db_objectId = old_obj.db_objectId
-        if 'parentObjId' in class_dict:
-            res = class_dict['parentObjId'](old_obj, trans_dict)
-            new_obj.db_parentObjId = res
-        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
-            new_obj.db_parentObjId = old_obj.db_parentObjId
-        if 'parentObjType' in class_dict:
-            res = class_dict['parentObjType'](old_obj, trans_dict)
-            new_obj.db_parentObjType = res
-        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
-            new_obj.db_parentObjType = old_obj.db_parentObjType
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            new_obj.db_add_value(DBOpmProcessValue.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                n_obj = DBOpmProcessValue.update_version(obj, trans_dict)
+                new_obj.db_deleted_value.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        return [(self, parent[0], parent[1])]
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        children.append((self, parent[0], parent[1]))
+        return children
     def db_deleted_children(self, remove=False):
         children = []
+        children.extend(self.db_deleted_value)
+        children.extend(self.db_deleted_accounts)
+        if remove:
+            self.db_deleted_value = []
+            self.db_deleted_accounts = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
         return False
     def __get_db_id(self):
         return self._db_id
@@ -15618,87 +17148,69 @@ class DBDelete(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_what(self):
-        return self._db_what
-    def __set_db_what(self, what):
-        self._db_what = what
-        self.is_dirty = True
-    db_what = property(__get_db_what, __set_db_what)
-    def db_add_what(self, what):
-        self._db_what = what
-    def db_change_what(self, what):
-        self._db_what = what
-    def db_delete_what(self, what):
-        self._db_what = None
-    
-    def __get_db_objectId(self):
-        return self._db_objectId
-    def __set_db_objectId(self, objectId):
-        self._db_objectId = objectId
-        self.is_dirty = True
-    db_objectId = property(__get_db_objectId, __set_db_objectId)
-    def db_add_objectId(self, objectId):
-        self._db_objectId = objectId
-    def db_change_objectId(self, objectId):
-        self._db_objectId = objectId
-    def db_delete_objectId(self, objectId):
-        self._db_objectId = None
-    
-    def __get_db_parentObjId(self):
-        return self._db_parentObjId
-    def __set_db_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
-    def db_add_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
-    def db_change_parentObjId(self, parentObjId):
-        self._db_parentObjId = parentObjId
-    def db_delete_parentObjId(self, parentObjId):
-        self._db_parentObjId = None
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
     
-    def __get_db_parentObjType(self):
-        return self._db_parentObjType
-    def __set_db_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
         self.is_dirty = True
-    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
-    def db_add_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-    def db_change_parentObjType(self, parentObjType):
-        self._db_parentObjType = parentObjType
-    def db_delete_parentObjType(self, parentObjType):
-        self._db_parentObjType = None
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
     
     def getPrimaryKey(self):
         return self._db_id
 
-class DBProvAssociation(object):
+class DBDisabledPackages(object):
 
-    vtType = 'prov_association'
+    vtType = 'disabled_packages'
 
-    def __init__(self, prov_activity=None, prov_agent=None, prov_plan=None, prov_role=None):
-        self.db_deleted_prov_activity = []
-        self._db_prov_activity = prov_activity
-        self.db_deleted_prov_agent = []
-        self._db_prov_agent = prov_agent
-        self.db_deleted_prov_plan = []
-        self._db_prov_plan = prov_plan
-        self._db_prov_role = prov_role
+    def __init__(self, packages=None):
+        self.db_deleted_packages = []
+        self.db_packages_name_index = {}
+        if packages is None:
+            self._db_packages = []
+        else:
+            self._db_packages = packages
+            for v in self._db_packages:
+                self.db_packages_name_index[v.db_name] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBProvAssociation.do_copy(self)
+        return DBDisabledPackages.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBProvAssociation(prov_role=self._db_prov_role)
-        if self._db_prov_activity is not None:
-            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
-        if self._db_prov_agent is not None:
-            cp._db_prov_agent = self._db_prov_agent.do_copy(new_ids, id_scope, id_remap)
-        if self._db_prov_plan is not None:
-            cp._db_prov_plan = self._db_prov_plan.do_copy(new_ids, id_scope, id_remap)
+        cp = DBDisabledPackages()
+        if self._db_packages is None:
+            cp._db_packages = []
+        else:
+            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
         
         # set new ids
         if new_ids:
@@ -15710,6 +17222,7 @@ class DBProvAssociation(object):
             cp.db_id = new_id
         
         # recreate indices and set flags
+        cp.db_packages_name_index = dict((v.db_name, v) for v in cp._db_packages)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -15718,249 +17231,131 @@ class DBProvAssociation(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBProvAssociation()
+            new_obj = DBDisabledPackages()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'prov_activity' in class_dict:
-            res = class_dict['prov_activity'](old_obj, trans_dict)
-            new_obj.db_prov_activity = res
-        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
-            obj = old_obj.db_prov_activity
-            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
-            for obj in old_obj.db_deleted_prov_activity:
-                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_activity.append(n_obj)
-        if 'prov_agent' in class_dict:
-            res = class_dict['prov_agent'](old_obj, trans_dict)
-            new_obj.db_prov_agent = res
-        elif hasattr(old_obj, 'db_prov_agent') and old_obj.db_prov_agent is not None:
-            obj = old_obj.db_prov_agent
-            new_obj.db_add_prov_agent(DBRefProvAgent.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_agent') and hasattr(new_obj, 'db_deleted_prov_agent'):
-            for obj in old_obj.db_deleted_prov_agent:
-                n_obj = DBRefProvAgent.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_agent.append(n_obj)
-        if 'prov_plan' in class_dict:
-            res = class_dict['prov_plan'](old_obj, trans_dict)
-            new_obj.db_prov_plan = res
-        elif hasattr(old_obj, 'db_prov_plan') and old_obj.db_prov_plan is not None:
-            obj = old_obj.db_prov_plan
-            new_obj.db_add_prov_plan(DBRefProvPlan.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_prov_plan') and hasattr(new_obj, 'db_deleted_prov_plan'):
-            for obj in old_obj.db_deleted_prov_plan:
-                n_obj = DBRefProvPlan.update_version(obj, trans_dict)
-                new_obj.db_deleted_prov_plan.append(n_obj)
-        if 'prov_role' in class_dict:
-            res = class_dict['prov_role'](old_obj, trans_dict)
-            new_obj.db_prov_role = res
-        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
-            new_obj.db_prov_role = old_obj.db_prov_role
+        if 'packages' in class_dict:
+            res = class_dict['packages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_package(obj)
+        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
+            for obj in old_obj.db_packages:
+                new_obj.db_add_package(DBStartupPackage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
+            for obj in old_obj.db_deleted_packages:
+                n_obj = DBStartupPackage.update_version(obj, trans_dict)
+                new_obj.db_deleted_packages.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        if self._db_prov_activity is not None:
-            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_prov_activity = None
-        if self._db_prov_agent is not None:
-            children.extend(self._db_prov_agent.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                self._db_prov_agent = None
-        if self._db_prov_plan is not None:
-            children.extend(self._db_prov_plan.db_children((self.vtType, self.db_id), orphan, for_action))
+        to_del = []
+        for child in self.db_packages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                self._db_prov_plan = None
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_package(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_prov_activity)
-        children.extend(self.db_deleted_prov_agent)
-        children.extend(self.db_deleted_prov_plan)
+        children.extend(self.db_deleted_packages)
         if remove:
-            self.db_deleted_prov_activity = []
-            self.db_deleted_prov_agent = []
-            self.db_deleted_prov_plan = []
+            self.db_deleted_packages = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
-            return True
-        if self._db_prov_agent is not None and self._db_prov_agent.has_changes():
-            return True
-        if self._db_prov_plan is not None and self._db_prov_plan.has_changes():
-            return True
+        for child in self._db_packages:
+            if child.has_changes():
+                return True
         return False
-    def __get_db_prov_activity(self):
-        return self._db_prov_activity
-    def __set_db_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-        self.is_dirty = True
-    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
-    def db_add_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-    def db_change_prov_activity(self, prov_activity):
-        self._db_prov_activity = prov_activity
-    def db_delete_prov_activity(self, prov_activity):
-        if not self.is_new:
-            self.db_deleted_prov_activity.append(self._db_prov_activity)
-        self._db_prov_activity = None
-    
-    def __get_db_prov_agent(self):
-        return self._db_prov_agent
-    def __set_db_prov_agent(self, prov_agent):
-        self._db_prov_agent = prov_agent
-        self.is_dirty = True
-    db_prov_agent = property(__get_db_prov_agent, __set_db_prov_agent)
-    def db_add_prov_agent(self, prov_agent):
-        self._db_prov_agent = prov_agent
-    def db_change_prov_agent(self, prov_agent):
-        self._db_prov_agent = prov_agent
-    def db_delete_prov_agent(self, prov_agent):
-        if not self.is_new:
-            self.db_deleted_prov_agent.append(self._db_prov_agent)
-        self._db_prov_agent = None
-    
-    def __get_db_prov_plan(self):
-        return self._db_prov_plan
-    def __set_db_prov_plan(self, prov_plan):
-        self._db_prov_plan = prov_plan
+    def __get_db_packages(self):
+        return self._db_packages
+    def __set_db_packages(self, packages):
+        self._db_packages = packages
         self.is_dirty = True
-    db_prov_plan = property(__get_db_prov_plan, __set_db_prov_plan)
-    def db_add_prov_plan(self, prov_plan):
-        self._db_prov_plan = prov_plan
-    def db_change_prov_plan(self, prov_plan):
-        self._db_prov_plan = prov_plan
-    def db_delete_prov_plan(self, prov_plan):
-        if not self.is_new:
-            self.db_deleted_prov_plan.append(self._db_prov_plan)
-        self._db_prov_plan = None
-    
-    def __get_db_prov_role(self):
-        return self._db_prov_role
-    def __set_db_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
+    db_packages = property(__get_db_packages, __set_db_packages)
+    def db_get_packages(self):
+        return self._db_packages
+    def db_add_package(self, package):
         self.is_dirty = True
-    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
-    def db_add_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
-    def db_change_prov_role(self, prov_role):
-        self._db_prov_role = prov_role
-    def db_delete_prov_role(self, prov_role):
-        self._db_prov_role = None
-    
-
-
-class DBVistrail(object):
-
-    vtType = 'vistrail'
-
-    def __init__(self, id=None, entity_type=None, version=None, name=None, last_modified=None, actions=None, tags=None, annotations=None, vistrailVariables=None, parameter_explorations=None, actionAnnotations=None):
-        self._db_id = id
-        self._db_entity_type = entity_type
-        self._db_version = version
-        self._db_name = name
-        self._db_last_modified = last_modified
-        self.db_deleted_actions = []
-        self.db_actions_id_index = {}
-        if actions is None:
-            self._db_actions = []
-        else:
-            self._db_actions = actions
-            for v in self._db_actions:
-                self.db_actions_id_index[v.db_id] = v
-        self.db_deleted_tags = []
-        self.db_tags_id_index = {}
-        self.db_tags_name_index = {}
-        if tags is None:
-            self._db_tags = []
-        else:
-            self._db_tags = tags
-            for v in self._db_tags:
-                self.db_tags_id_index[v.db_id] = v
-                self.db_tags_name_index[v.db_name] = v
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_change_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_delete_package(self, package):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_package(self, key):
+        return None
+    def db_get_package_by_name(self, key):
+        return self.db_packages_name_index[key]
+    def db_has_package_with_name(self, key):
+        return key in self.db_packages_name_index
+    
+
+
+class DBModuleExec(object):
+
+    vtType = 'module_exec'
+
+    def __init__(self, id=None, ts_start=None, ts_end=None, cached=None, module_id=None, module_name=None, completed=None, error=None, machine_id=None, annotations=None, loop_execs=None):
+        self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_cached = cached
+        self._db_module_id = module_id
+        self._db_module_name = module_name
+        self._db_completed = completed
+        self._db_error = error
+        self._db_machine_id = machine_id
         self.db_deleted_annotations = []
         self.db_annotations_id_index = {}
-        self.db_annotations_key_index = {}
         if annotations is None:
             self._db_annotations = []
         else:
             self._db_annotations = annotations
             for v in self._db_annotations:
                 self.db_annotations_id_index[v.db_id] = v
-                self.db_annotations_key_index[v.db_key] = v
-        self.db_deleted_vistrailVariables = []
-        self.db_vistrailVariables_name_index = {}
-        self.db_vistrailVariables_uuid_index = {}
-        if vistrailVariables is None:
-            self._db_vistrailVariables = []
-        else:
-            self._db_vistrailVariables = vistrailVariables
-            for v in self._db_vistrailVariables:
-                self.db_vistrailVariables_name_index[v.db_name] = v
-                self.db_vistrailVariables_uuid_index[v.db_uuid] = v
-        self.db_deleted_parameter_explorations = []
-        self.db_parameter_explorations_id_index = {}
-        if parameter_explorations is None:
-            self._db_parameter_explorations = []
-        else:
-            self._db_parameter_explorations = parameter_explorations
-            for v in self._db_parameter_explorations:
-                self.db_parameter_explorations_id_index[v.db_id] = v
-        self.db_deleted_actionAnnotations = []
-        self.db_actionAnnotations_id_index = {}
-        self.db_actionAnnotations_action_id_index = {}
-        self.db_actionAnnotations_key_index = {}
-        if actionAnnotations is None:
-            self._db_actionAnnotations = []
+        self.db_deleted_loop_execs = []
+        self.db_loop_execs_id_index = {}
+        if loop_execs is None:
+            self._db_loop_execs = []
         else:
-            self._db_actionAnnotations = actionAnnotations
-            for v in self._db_actionAnnotations:
-                self.db_actionAnnotations_id_index[v.db_id] = v
-                self.db_actionAnnotations_action_id_index[(v.db_action_id,v.db_key)] = v
-                self.db_actionAnnotations_key_index[(v.db_key,v.db_value)] = v
+            self._db_loop_execs = loop_execs
+            for v in self._db_loop_execs:
+                self.db_loop_execs_id_index[v.db_id] = v
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBVistrail.do_copy(self)
+        return DBModuleExec.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBVistrail(id=self._db_id,
-                        entity_type=self._db_entity_type,
-                        version=self._db_version,
-                        name=self._db_name,
-                        last_modified=self._db_last_modified)
-        if self._db_actions is None:
-            cp._db_actions = []
-        else:
-            cp._db_actions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actions]
-        if self._db_tags is None:
-            cp._db_tags = []
-        else:
-            cp._db_tags = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_tags]
+        cp = DBModuleExec(id=self._db_id,
+                          ts_start=self._db_ts_start,
+                          ts_end=self._db_ts_end,
+                          cached=self._db_cached,
+                          module_id=self._db_module_id,
+                          module_name=self._db_module_name,
+                          completed=self._db_completed,
+                          error=self._db_error,
+                          machine_id=self._db_machine_id)
         if self._db_annotations is None:
             cp._db_annotations = []
         else:
             cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
-        if self._db_vistrailVariables is None:
-            cp._db_vistrailVariables = []
-        else:
-            cp._db_vistrailVariables = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_vistrailVariables]
-        if self._db_parameter_explorations is None:
-            cp._db_parameter_explorations = []
-        else:
-            cp._db_parameter_explorations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameter_explorations]
-        if self._db_actionAnnotations is None:
-            cp._db_actionAnnotations = []
+        if self._db_loop_execs is None:
+            cp._db_loop_execs = []
         else:
-            cp._db_actionAnnotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actionAnnotations]
+            cp._db_loop_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_loop_execs]
         
         # set new ids
         if new_ids:
@@ -15970,19 +17365,14 @@ class DBVistrail(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
+            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
+                cp._db_module_id = id_remap[('module', self._db_module_id)]
+            if hasattr(self, 'db_machine_id') and ('machine', self._db_machine_id) in id_remap:
+                cp._db_machine_id = id_remap[('machine', self._db_machine_id)]
         
         # recreate indices and set flags
-        cp.db_actions_id_index = dict((v.db_id, v) for v in cp._db_actions)
-        cp.db_tags_id_index = dict((v.db_id, v) for v in cp._db_tags)
-        cp.db_tags_name_index = dict((v.db_name, v) for v in cp._db_tags)
         cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
-        cp.db_vistrailVariables_name_index = dict((v.db_name, v) for v in cp._db_vistrailVariables)
-        cp.db_vistrailVariables_uuid_index = dict((v.db_uuid, v) for v in cp._db_vistrailVariables)
-        cp.db_parameter_explorations_id_index = dict((v.db_id, v) for v in cp._db_parameter_explorations)
-        cp.db_actionAnnotations_id_index = dict((v.db_id, v) for v in cp._db_actionAnnotations)
-        cp.db_actionAnnotations_action_id_index = dict(((v.db_action_id,v.db_key), v) for v in cp._db_actionAnnotations)
-        cp.db_actionAnnotations_key_index = dict(((v.db_key,v.db_value), v) for v in cp._db_actionAnnotations)
+        cp.db_loop_execs_id_index = dict((v.db_id, v) for v in cp._db_loop_execs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -15991,7 +17381,7 @@ class DBVistrail(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBVistrail()
+            new_obj = DBModuleExec()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
@@ -16000,48 +17390,46 @@ class DBVistrail(object):
             new_obj.db_id = res
         elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
             new_obj.db_id = old_obj.db_id
-        if 'entity_type' in class_dict:
-            res = class_dict['entity_type'](old_obj, trans_dict)
-            new_obj.db_entity_type = res
-        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
-            new_obj.db_entity_type = old_obj.db_entity_type
-        if 'version' in class_dict:
-            res = class_dict['version'](old_obj, trans_dict)
-            new_obj.db_version = res
-        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
-            new_obj.db_version = old_obj.db_version
-        if 'name' in class_dict:
-            res = class_dict['name'](old_obj, trans_dict)
-            new_obj.db_name = res
-        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
-            new_obj.db_name = old_obj.db_name
-        if 'last_modified' in class_dict:
-            res = class_dict['last_modified'](old_obj, trans_dict)
-            new_obj.db_last_modified = res
-        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
-            new_obj.db_last_modified = old_obj.db_last_modified
-        if 'actions' in class_dict:
-            res = class_dict['actions'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_action(obj)
-        elif hasattr(old_obj, 'db_actions') and old_obj.db_actions is not None:
-            for obj in old_obj.db_actions:
-                new_obj.db_add_action(DBAction.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_actions') and hasattr(new_obj, 'db_deleted_actions'):
-            for obj in old_obj.db_deleted_actions:
-                n_obj = DBAction.update_version(obj, trans_dict)
-                new_obj.db_deleted_actions.append(n_obj)
-        if 'tags' in class_dict:
-            res = class_dict['tags'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_tag(obj)
-        elif hasattr(old_obj, 'db_tags') and old_obj.db_tags is not None:
-            for obj in old_obj.db_tags:
-                new_obj.db_add_tag(DBTag.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_tags') and hasattr(new_obj, 'db_deleted_tags'):
-            for obj in old_obj.db_deleted_tags:
-                n_obj = DBTag.update_version(obj, trans_dict)
-                new_obj.db_deleted_tags.append(n_obj)
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'cached' in class_dict:
+            res = class_dict['cached'](old_obj, trans_dict)
+            new_obj.db_cached = res
+        elif hasattr(old_obj, 'db_cached') and old_obj.db_cached is not None:
+            new_obj.db_cached = old_obj.db_cached
+        if 'module_id' in class_dict:
+            res = class_dict['module_id'](old_obj, trans_dict)
+            new_obj.db_module_id = res
+        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
+            new_obj.db_module_id = old_obj.db_module_id
+        if 'module_name' in class_dict:
+            res = class_dict['module_name'](old_obj, trans_dict)
+            new_obj.db_module_name = res
+        elif hasattr(old_obj, 'db_module_name') and old_obj.db_module_name is not None:
+            new_obj.db_module_name = old_obj.db_module_name
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'error' in class_dict:
+            res = class_dict['error'](old_obj, trans_dict)
+            new_obj.db_error = res
+        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
+            new_obj.db_error = old_obj.db_error
+        if 'machine_id' in class_dict:
+            res = class_dict['machine_id'](old_obj, trans_dict)
+            new_obj.db_machine_id = res
+        elif hasattr(old_obj, 'db_machine_id') and old_obj.db_machine_id is not None:
+            new_obj.db_machine_id = old_obj.db_machine_id
         if 'annotations' in class_dict:
             res = class_dict['annotations'](old_obj, trans_dict)
             for obj in res:
@@ -16053,59 +17441,23 @@ class DBVistrail(object):
             for obj in old_obj.db_deleted_annotations:
                 n_obj = DBAnnotation.update_version(obj, trans_dict)
                 new_obj.db_deleted_annotations.append(n_obj)
-        if 'vistrailVariables' in class_dict:
-            res = class_dict['vistrailVariables'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_vistrailVariable(obj)
-        elif hasattr(old_obj, 'db_vistrailVariables') and old_obj.db_vistrailVariables is not None:
-            for obj in old_obj.db_vistrailVariables:
-                new_obj.db_add_vistrailVariable(DBVistrailVariable.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_vistrailVariables') and hasattr(new_obj, 'db_deleted_vistrailVariables'):
-            for obj in old_obj.db_deleted_vistrailVariables:
-                n_obj = DBVistrailVariable.update_version(obj, trans_dict)
-                new_obj.db_deleted_vistrailVariables.append(n_obj)
-        if 'parameter_explorations' in class_dict:
-            res = class_dict['parameter_explorations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_parameter_exploration(obj)
-        elif hasattr(old_obj, 'db_parameter_explorations') and old_obj.db_parameter_explorations is not None:
-            for obj in old_obj.db_parameter_explorations:
-                new_obj.db_add_parameter_exploration(DBParameterExploration.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_parameter_explorations') and hasattr(new_obj, 'db_deleted_parameter_explorations'):
-            for obj in old_obj.db_deleted_parameter_explorations:
-                n_obj = DBParameterExploration.update_version(obj, trans_dict)
-                new_obj.db_deleted_parameter_explorations.append(n_obj)
-        if 'actionAnnotations' in class_dict:
-            res = class_dict['actionAnnotations'](old_obj, trans_dict)
+        if 'loop_execs' in class_dict:
+            res = class_dict['loop_execs'](old_obj, trans_dict)
             for obj in res:
-                new_obj.db_add_actionAnnotation(obj)
-        elif hasattr(old_obj, 'db_actionAnnotations') and old_obj.db_actionAnnotations is not None:
-            for obj in old_obj.db_actionAnnotations:
-                new_obj.db_add_actionAnnotation(DBActionAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_actionAnnotations') and hasattr(new_obj, 'db_deleted_actionAnnotations'):
-            for obj in old_obj.db_deleted_actionAnnotations:
-                n_obj = DBActionAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_actionAnnotations.append(n_obj)
-        new_obj.is_new = old_obj.is_new
-        new_obj.is_dirty = old_obj.is_dirty
-        return new_obj
-
-    def db_children(self, parent=(None,None), orphan=False, for_action=False):
-        children = []
-        to_del = []
-        for child in self.db_actions:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_action(child)
-        to_del = []
-        for child in self.db_tags:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_tag(child)
+                new_obj.db_add_loop_exec(obj)
+        elif hasattr(old_obj, 'db_loop_execs') and old_obj.db_loop_execs is not None:
+            for obj in old_obj.db_loop_execs:
+                new_obj.db_add_loop_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_loop_execs') and hasattr(new_obj, 'db_deleted_loop_execs'):
+            for obj in old_obj.db_deleted_loop_execs:
+                n_obj = DBLoopExec.update_version(obj, trans_dict)
+                new_obj.db_deleted_loop_execs.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
         to_del = []
         for child in self.db_annotations:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
@@ -16114,63 +17466,29 @@ class DBVistrail(object):
         for child in to_del:
             self.db_delete_annotation(child)
         to_del = []
-        for child in self.db_vistrailVariables:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_vistrailVariable(child)
-        to_del = []
-        for child in self.db_parameter_explorations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_parameter_exploration(child)
-        to_del = []
-        for child in self.db_actionAnnotations:
+        for child in self.db_loop_execs:
             children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
                 to_del.append(child)
         for child in to_del:
-            self.db_delete_actionAnnotation(child)
+            self.db_delete_loop_exec(child)
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_actions)
-        children.extend(self.db_deleted_tags)
         children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_vistrailVariables)
-        children.extend(self.db_deleted_parameter_explorations)
-        children.extend(self.db_deleted_actionAnnotations)
+        children.extend(self.db_deleted_loop_execs)
         if remove:
-            self.db_deleted_actions = []
-            self.db_deleted_tags = []
             self.db_deleted_annotations = []
-            self.db_deleted_vistrailVariables = []
-            self.db_deleted_parameter_explorations = []
-            self.db_deleted_actionAnnotations = []
+            self.db_deleted_loop_execs = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_actions:
-            if child.has_changes():
-                return True
-        for child in self._db_tags:
-            if child.has_changes():
-                return True
         for child in self._db_annotations:
             if child.has_changes():
                 return True
-        for child in self._db_vistrailVariables:
-            if child.has_changes():
-                return True
-        for child in self._db_parameter_explorations:
-            if child.has_changes():
-                return True
-        for child in self._db_actionAnnotations:
+        for child in self._db_loop_execs:
             if child.has_changes():
                 return True
         return False
@@ -16187,148 +17505,109 @@ class DBVistrail(object):
     def db_delete_id(self, id):
         self._db_id = None
     
-    def __get_db_entity_type(self):
-        return self._db_entity_type
-    def __set_db_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
         self.is_dirty = True
-    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
-    def db_add_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_change_entity_type(self, entity_type):
-        self._db_entity_type = entity_type
-    def db_delete_entity_type(self, entity_type):
-        self._db_entity_type = None
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
     
-    def __get_db_version(self):
-        return self._db_version
-    def __set_db_version(self, version):
-        self._db_version = version
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
         self.is_dirty = True
-    db_version = property(__get_db_version, __set_db_version)
-    def db_add_version(self, version):
-        self._db_version = version
-    def db_change_version(self, version):
-        self._db_version = version
-    def db_delete_version(self, version):
-        self._db_version = None
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
     
-    def __get_db_name(self):
-        return self._db_name
-    def __set_db_name(self, name):
-        self._db_name = name
+    def __get_db_cached(self):
+        return self._db_cached
+    def __set_db_cached(self, cached):
+        self._db_cached = cached
         self.is_dirty = True
-    db_name = property(__get_db_name, __set_db_name)
-    def db_add_name(self, name):
-        self._db_name = name
-    def db_change_name(self, name):
-        self._db_name = name
-    def db_delete_name(self, name):
-        self._db_name = None
+    db_cached = property(__get_db_cached, __set_db_cached)
+    def db_add_cached(self, cached):
+        self._db_cached = cached
+    def db_change_cached(self, cached):
+        self._db_cached = cached
+    def db_delete_cached(self, cached):
+        self._db_cached = None
     
-    def __get_db_last_modified(self):
-        return self._db_last_modified
-    def __set_db_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
+    def __get_db_module_id(self):
+        return self._db_module_id
+    def __set_db_module_id(self, module_id):
+        self._db_module_id = module_id
         self.is_dirty = True
-    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
-    def db_add_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_change_last_modified(self, last_modified):
-        self._db_last_modified = last_modified
-    def db_delete_last_modified(self, last_modified):
-        self._db_last_modified = None
+    db_module_id = property(__get_db_module_id, __set_db_module_id)
+    def db_add_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_change_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_delete_module_id(self, module_id):
+        self._db_module_id = None
     
-    def __get_db_actions(self):
-        return self._db_actions
-    def __set_db_actions(self, actions):
-        self._db_actions = actions
-        self.is_dirty = True
-    db_actions = property(__get_db_actions, __set_db_actions)
-    def db_get_actions(self):
-        return self._db_actions
-    def db_add_action(self, action):
-        self.is_dirty = True
-        self._db_actions.append(action)
-        self.db_actions_id_index[action.db_id] = action
-    def db_change_action(self, action):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_actions)):
-            if self._db_actions[i].db_id == action.db_id:
-                self._db_actions[i] = action
-                found = True
-                break
-        if not found:
-            self._db_actions.append(action)
-        self.db_actions_id_index[action.db_id] = action
-    def db_delete_action(self, action):
+    def __get_db_module_name(self):
+        return self._db_module_name
+    def __set_db_module_name(self, module_name):
+        self._db_module_name = module_name
         self.is_dirty = True
-        for i in xrange(len(self._db_actions)):
-            if self._db_actions[i].db_id == action.db_id:
-                if not self._db_actions[i].is_new:
-                    self.db_deleted_actions.append(self._db_actions[i])
-                del self._db_actions[i]
-                break
-        del self.db_actions_id_index[action.db_id]
-    def db_get_action(self, key):
-        for i in xrange(len(self._db_actions)):
-            if self._db_actions[i].db_id == key:
-                return self._db_actions[i]
-        return None
-    def db_get_action_by_id(self, key):
-        return self.db_actions_id_index[key]
-    def db_has_action_with_id(self, key):
-        return key in self.db_actions_id_index
+    db_module_name = property(__get_db_module_name, __set_db_module_name)
+    def db_add_module_name(self, module_name):
+        self._db_module_name = module_name
+    def db_change_module_name(self, module_name):
+        self._db_module_name = module_name
+    def db_delete_module_name(self, module_name):
+        self._db_module_name = None
     
-    def __get_db_tags(self):
-        return self._db_tags
-    def __set_db_tags(self, tags):
-        self._db_tags = tags
-        self.is_dirty = True
-    db_tags = property(__get_db_tags, __set_db_tags)
-    def db_get_tags(self):
-        return self._db_tags
-    def db_add_tag(self, tag):
-        self.is_dirty = True
-        self._db_tags.append(tag)
-        self.db_tags_id_index[tag.db_id] = tag
-        self.db_tags_name_index[tag.db_name] = tag
-    def db_change_tag(self, tag):
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_tags)):
-            if self._db_tags[i].db_id == tag.db_id:
-                self._db_tags[i] = tag
-                found = True
-                break
-        if not found:
-            self._db_tags.append(tag)
-        self.db_tags_id_index[tag.db_id] = tag
-        self.db_tags_name_index[tag.db_name] = tag
-    def db_delete_tag(self, tag):
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_error(self):
+        return self._db_error
+    def __set_db_error(self, error):
+        self._db_error = error
         self.is_dirty = True
-        for i in xrange(len(self._db_tags)):
-            if self._db_tags[i].db_id == tag.db_id:
-                if not self._db_tags[i].is_new:
-                    self.db_deleted_tags.append(self._db_tags[i])
-                del self._db_tags[i]
-                break
-        del self.db_tags_id_index[tag.db_id]
-        del self.db_tags_name_index[tag.db_name]
-    def db_get_tag(self, key):
-        for i in xrange(len(self._db_tags)):
-            if self._db_tags[i].db_id == key:
-                return self._db_tags[i]
-        return None
-    def db_get_tag_by_id(self, key):
-        return self.db_tags_id_index[key]
-    def db_has_tag_with_id(self, key):
-        return key in self.db_tags_id_index
-    def db_get_tag_by_name(self, key):
-        return self.db_tags_name_index[key]
-    def db_has_tag_with_name(self, key):
-        return key in self.db_tags_name_index
+    db_error = property(__get_db_error, __set_db_error)
+    def db_add_error(self, error):
+        self._db_error = error
+    def db_change_error(self, error):
+        self._db_error = error
+    def db_delete_error(self, error):
+        self._db_error = None
+    
+    def __get_db_machine_id(self):
+        return self._db_machine_id
+    def __set_db_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+        self.is_dirty = True
+    db_machine_id = property(__get_db_machine_id, __set_db_machine_id)
+    def db_add_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_change_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_delete_machine_id(self, machine_id):
+        self._db_machine_id = None
     
     def __get_db_annotations(self):
         return self._db_annotations
@@ -16342,7 +17621,6 @@ class DBVistrail(object):
         self.is_dirty = True
         self._db_annotations.append(annotation)
         self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
     def db_change_annotation(self, annotation):
         self.is_dirty = True
         found = False
@@ -16354,7 +17632,6 @@ class DBVistrail(object):
         if not found:
             self._db_annotations.append(annotation)
         self.db_annotations_id_index[annotation.db_id] = annotation
-        self.db_annotations_key_index[annotation.db_key] = annotation
     def db_delete_annotation(self, annotation):
         self.is_dirty = True
         for i in xrange(len(self._db_annotations)):
@@ -16364,7 +17641,6 @@ class DBVistrail(object):
                 del self._db_annotations[i]
                 break
         del self.db_annotations_id_index[annotation.db_id]
-        del self.db_annotations_key_index[annotation.db_key]
     def db_get_annotation(self, key):
         for i in xrange(len(self._db_annotations)):
             if self._db_annotations[i].db_id == key:
@@ -16374,218 +17650,253 @@ class DBVistrail(object):
         return self.db_annotations_id_index[key]
     def db_has_annotation_with_id(self, key):
         return key in self.db_annotations_id_index
-    def db_get_annotation_by_key(self, key):
-        return self.db_annotations_key_index[key]
-    def db_has_annotation_with_key(self, key):
-        return key in self.db_annotations_key_index
     
-    def __get_db_vistrailVariables(self):
-        return self._db_vistrailVariables
-    def __set_db_vistrailVariables(self, vistrailVariables):
-        self._db_vistrailVariables = vistrailVariables
+    def __get_db_loop_execs(self):
+        return self._db_loop_execs
+    def __set_db_loop_execs(self, loop_execs):
+        self._db_loop_execs = loop_execs
         self.is_dirty = True
-    db_vistrailVariables = property(__get_db_vistrailVariables, __set_db_vistrailVariables)
-    def db_get_vistrailVariables(self):
-        return self._db_vistrailVariables
-    def db_add_vistrailVariable(self, vistrailVariable):
+    db_loop_execs = property(__get_db_loop_execs, __set_db_loop_execs)
+    def db_get_loop_execs(self):
+        return self._db_loop_execs
+    def db_add_loop_exec(self, loop_exec):
         self.is_dirty = True
-        self._db_vistrailVariables.append(vistrailVariable)
-        self.db_vistrailVariables_name_index[vistrailVariable.db_name] = vistrailVariable
-        self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid] = vistrailVariable
-    def db_change_vistrailVariable(self, vistrailVariable):
+        self._db_loop_execs.append(loop_exec)
+        self.db_loop_execs_id_index[loop_exec.db_id] = loop_exec
+    def db_change_loop_exec(self, loop_exec):
         self.is_dirty = True
         found = False
-        for i in xrange(len(self._db_vistrailVariables)):
-            if self._db_vistrailVariables[i].db_name == vistrailVariable.db_name:
-                self._db_vistrailVariables[i] = vistrailVariable
+        for i in xrange(len(self._db_loop_execs)):
+            if self._db_loop_execs[i].db_id == loop_exec.db_id:
+                self._db_loop_execs[i] = loop_exec
                 found = True
                 break
         if not found:
-            self._db_vistrailVariables.append(vistrailVariable)
-        self.db_vistrailVariables_name_index[vistrailVariable.db_name] = vistrailVariable
-        self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid] = vistrailVariable
-    def db_delete_vistrailVariable(self, vistrailVariable):
+            self._db_loop_execs.append(loop_exec)
+        self.db_loop_execs_id_index[loop_exec.db_id] = loop_exec
+    def db_delete_loop_exec(self, loop_exec):
         self.is_dirty = True
-        for i in xrange(len(self._db_vistrailVariables)):
-            if self._db_vistrailVariables[i].db_name == vistrailVariable.db_name:
-                if not self._db_vistrailVariables[i].is_new:
-                    self.db_deleted_vistrailVariables.append(self._db_vistrailVariables[i])
-                del self._db_vistrailVariables[i]
+        for i in xrange(len(self._db_loop_execs)):
+            if self._db_loop_execs[i].db_id == loop_exec.db_id:
+                if not self._db_loop_execs[i].is_new:
+                    self.db_deleted_loop_execs.append(self._db_loop_execs[i])
+                del self._db_loop_execs[i]
                 break
-        del self.db_vistrailVariables_name_index[vistrailVariable.db_name]
-        del self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid]
-    def db_get_vistrailVariable(self, key):
-        for i in xrange(len(self._db_vistrailVariables)):
-            if self._db_vistrailVariables[i].db_name == key:
-                return self._db_vistrailVariables[i]
+        del self.db_loop_execs_id_index[loop_exec.db_id]
+    def db_get_loop_exec(self, key):
+        for i in xrange(len(self._db_loop_execs)):
+            if self._db_loop_execs[i].db_id == key:
+                return self._db_loop_execs[i]
         return None
-    def db_get_vistrailVariable_by_name(self, key):
-        return self.db_vistrailVariables_name_index[key]
-    def db_has_vistrailVariable_with_name(self, key):
-        return key in self.db_vistrailVariables_name_index
-    def db_get_vistrailVariable_by_uuid(self, key):
-        return self.db_vistrailVariables_uuid_index[key]
-    def db_has_vistrailVariable_with_uuid(self, key):
-        return key in self.db_vistrailVariables_uuid_index
+    def db_get_loop_exec_by_id(self, key):
+        return self.db_loop_execs_id_index[key]
+    def db_has_loop_exec_with_id(self, key):
+        return key in self.db_loop_execs_id_index
     
-    def __get_db_parameter_explorations(self):
-        return self._db_parameter_explorations
-    def __set_db_parameter_explorations(self, parameter_explorations):
-        self._db_parameter_explorations = parameter_explorations
-        self.is_dirty = True
-    db_parameter_explorations = property(__get_db_parameter_explorations, __set_db_parameter_explorations)
-    def db_get_parameter_explorations(self):
-        return self._db_parameter_explorations
-    def db_add_parameter_exploration(self, parameter_exploration):
-        self.is_dirty = True
-        self._db_parameter_explorations.append(parameter_exploration)
-        self.db_parameter_explorations_id_index[parameter_exploration.db_id] = parameter_exploration
-    def db_change_parameter_exploration(self, parameter_exploration):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_parameter_explorations)):
-            if self._db_parameter_explorations[i].db_id == parameter_exploration.db_id:
-                self._db_parameter_explorations[i] = parameter_exploration
-                found = True
-                break
-        if not found:
-            self._db_parameter_explorations.append(parameter_exploration)
-        self.db_parameter_explorations_id_index[parameter_exploration.db_id] = parameter_exploration
-    def db_delete_parameter_exploration(self, parameter_exploration):
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvAssociation(object):
+
+    vtType = 'prov_association'
+
+    def __init__(self, prov_activity=None, prov_agent=None, prov_plan=None, prov_role=None):
+        self.db_deleted_prov_activity = []
+        self._db_prov_activity = prov_activity
+        self.db_deleted_prov_agent = []
+        self._db_prov_agent = prov_agent
+        self.db_deleted_prov_plan = []
+        self._db_prov_plan = prov_plan
+        self._db_prov_role = prov_role
         self.is_dirty = True
-        for i in xrange(len(self._db_parameter_explorations)):
-            if self._db_parameter_explorations[i].db_id == parameter_exploration.db_id:
-                if not self._db_parameter_explorations[i].is_new:
-                    self.db_deleted_parameter_explorations.append(self._db_parameter_explorations[i])
-                del self._db_parameter_explorations[i]
-                break
-        del self.db_parameter_explorations_id_index[parameter_exploration.db_id]
-    def db_get_parameter_exploration(self, key):
-        for i in xrange(len(self._db_parameter_explorations)):
-            if self._db_parameter_explorations[i].db_id == key:
-                return self._db_parameter_explorations[i]
-        return None
-    def db_get_parameter_exploration_by_id(self, key):
-        return self.db_parameter_explorations_id_index[key]
-    def db_has_parameter_exploration_with_id(self, key):
-        return key in self.db_parameter_explorations_id_index
+        self.is_new = True
     
-    def __get_db_actionAnnotations(self):
-        return self._db_actionAnnotations
-    def __set_db_actionAnnotations(self, actionAnnotations):
-        self._db_actionAnnotations = actionAnnotations
+    def __copy__(self):
+        return DBProvAssociation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvAssociation(prov_role=self._db_prov_role)
+        if self._db_prov_activity is not None:
+            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_agent is not None:
+            cp._db_prov_agent = self._db_prov_agent.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_plan is not None:
+            cp._db_prov_plan = self._db_prov_plan.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvAssociation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_activity' in class_dict:
+            res = class_dict['prov_activity'](old_obj, trans_dict)
+            new_obj.db_prov_activity = res
+        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
+            obj = old_obj.db_prov_activity
+            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
+            for obj in old_obj.db_deleted_prov_activity:
+                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activity.append(n_obj)
+        if 'prov_agent' in class_dict:
+            res = class_dict['prov_agent'](old_obj, trans_dict)
+            new_obj.db_prov_agent = res
+        elif hasattr(old_obj, 'db_prov_agent') and old_obj.db_prov_agent is not None:
+            obj = old_obj.db_prov_agent
+            new_obj.db_add_prov_agent(DBRefProvAgent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_agent') and hasattr(new_obj, 'db_deleted_prov_agent'):
+            for obj in old_obj.db_deleted_prov_agent:
+                n_obj = DBRefProvAgent.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_agent.append(n_obj)
+        if 'prov_plan' in class_dict:
+            res = class_dict['prov_plan'](old_obj, trans_dict)
+            new_obj.db_prov_plan = res
+        elif hasattr(old_obj, 'db_prov_plan') and old_obj.db_prov_plan is not None:
+            obj = old_obj.db_prov_plan
+            new_obj.db_add_prov_plan(DBRefProvPlan.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_plan') and hasattr(new_obj, 'db_deleted_prov_plan'):
+            for obj in old_obj.db_deleted_prov_plan:
+                n_obj = DBRefProvPlan.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_plan.append(n_obj)
+        if 'prov_role' in class_dict:
+            res = class_dict['prov_role'](old_obj, trans_dict)
+            new_obj.db_prov_role = res
+        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
+            new_obj.db_prov_role = old_obj.db_prov_role
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_prov_activity is not None:
+            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_activity = None
+        if self._db_prov_agent is not None:
+            children.extend(self._db_prov_agent.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_agent = None
+        if self._db_prov_plan is not None:
+            children.extend(self._db_prov_plan.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_plan = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_prov_activity)
+        children.extend(self.db_deleted_prov_agent)
+        children.extend(self.db_deleted_prov_plan)
+        if remove:
+            self.db_deleted_prov_activity = []
+            self.db_deleted_prov_agent = []
+            self.db_deleted_prov_plan = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
+            return True
+        if self._db_prov_agent is not None and self._db_prov_agent.has_changes():
+            return True
+        if self._db_prov_plan is not None and self._db_prov_plan.has_changes():
+            return True
+        return False
+    def __get_db_prov_activity(self):
+        return self._db_prov_activity
+    def __set_db_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
         self.is_dirty = True
-    db_actionAnnotations = property(__get_db_actionAnnotations, __set_db_actionAnnotations)
-    def db_get_actionAnnotations(self):
-        return self._db_actionAnnotations
-    def db_add_actionAnnotation(self, actionAnnotation):
+    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
+    def db_add_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        if not self.is_new:
+            self.db_deleted_prov_activity.append(self._db_prov_activity)
+        self._db_prov_activity = None
+    
+    def __get_db_prov_agent(self):
+        return self._db_prov_agent
+    def __set_db_prov_agent(self, prov_agent):
+        self._db_prov_agent = prov_agent
         self.is_dirty = True
-        self._db_actionAnnotations.append(actionAnnotation)
-        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
-        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
-        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
-    def db_change_actionAnnotation(self, actionAnnotation):
+    db_prov_agent = property(__get_db_prov_agent, __set_db_prov_agent)
+    def db_add_prov_agent(self, prov_agent):
+        self._db_prov_agent = prov_agent
+    def db_change_prov_agent(self, prov_agent):
+        self._db_prov_agent = prov_agent
+    def db_delete_prov_agent(self, prov_agent):
+        if not self.is_new:
+            self.db_deleted_prov_agent.append(self._db_prov_agent)
+        self._db_prov_agent = None
+    
+    def __get_db_prov_plan(self):
+        return self._db_prov_plan
+    def __set_db_prov_plan(self, prov_plan):
+        self._db_prov_plan = prov_plan
         self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_actionAnnotations)):
-            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
-                self._db_actionAnnotations[i] = actionAnnotation
-                found = True
-                break
-        if not found:
-            self._db_actionAnnotations.append(actionAnnotation)
-        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
-        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
-        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
-    def db_delete_actionAnnotation(self, actionAnnotation):
+    db_prov_plan = property(__get_db_prov_plan, __set_db_prov_plan)
+    def db_add_prov_plan(self, prov_plan):
+        self._db_prov_plan = prov_plan
+    def db_change_prov_plan(self, prov_plan):
+        self._db_prov_plan = prov_plan
+    def db_delete_prov_plan(self, prov_plan):
+        if not self.is_new:
+            self.db_deleted_prov_plan.append(self._db_prov_plan)
+        self._db_prov_plan = None
+    
+    def __get_db_prov_role(self):
+        return self._db_prov_role
+    def __set_db_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
         self.is_dirty = True
-        for i in xrange(len(self._db_actionAnnotations)):
-            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
-                if not self._db_actionAnnotations[i].is_new:
-                    self.db_deleted_actionAnnotations.append(self._db_actionAnnotations[i])
-                del self._db_actionAnnotations[i]
-                break
-        del self.db_actionAnnotations_id_index[actionAnnotation.db_id]
-        del self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)]
-        try:
-            del self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)]
-        except KeyError:
-            pass
-    def db_get_actionAnnotation(self, key):
-        for i in xrange(len(self._db_actionAnnotations)):
-            if self._db_actionAnnotations[i].db_id == key:
-                return self._db_actionAnnotations[i]
-        return None
-    def db_get_actionAnnotation_by_id(self, key):
-        return self.db_actionAnnotations_id_index[key]
-    def db_has_actionAnnotation_with_id(self, key):
-        return key in self.db_actionAnnotations_id_index
-    def db_get_actionAnnotation_by_action_id(self, key):
-        return self.db_actionAnnotations_action_id_index[key]
-    def db_has_actionAnnotation_with_action_id(self, key):
-        return key in self.db_actionAnnotations_action_id_index
-    def db_get_actionAnnotation_by_key(self, key):
-        return self.db_actionAnnotations_key_index[key]
-    def db_has_actionAnnotation_with_key(self, key):
-        return key in self.db_actionAnnotations_key_index
+    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
+    def db_add_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_change_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_delete_prov_role(self, prov_role):
+        self._db_prov_role = None
     
-    def getPrimaryKey(self):
-        return self._db_id
 
-class DBModuleExec(object):
 
-    vtType = 'module_exec'
+class DBOpmProcessValue(object):
 
-    def __init__(self, id=None, ts_start=None, ts_end=None, cached=None, module_id=None, module_name=None, completed=None, error=None, machine_id=None, annotations=None, loop_execs=None):
-        self._db_id = id
-        self._db_ts_start = ts_start
-        self._db_ts_end = ts_end
-        self._db_cached = cached
-        self._db_module_id = module_id
-        self._db_module_name = module_name
-        self._db_completed = completed
-        self._db_error = error
-        self._db_machine_id = machine_id
-        self.db_deleted_annotations = []
-        self.db_annotations_id_index = {}
-        if annotations is None:
-            self._db_annotations = []
-        else:
-            self._db_annotations = annotations
-            for v in self._db_annotations:
-                self.db_annotations_id_index[v.db_id] = v
-        self.db_deleted_loop_execs = []
-        self.db_loop_execs_id_index = {}
-        if loop_execs is None:
-            self._db_loop_execs = []
-        else:
-            self._db_loop_execs = loop_execs
-            for v in self._db_loop_execs:
-                self.db_loop_execs_id_index[v.db_id] = v
+    vtType = 'opm_process_value'
+
+    def __init__(self, value=None):
+        self.db_deleted_value = []
+        self._db_value = value
         self.is_dirty = True
         self.is_new = True
     
     def __copy__(self):
-        return DBModuleExec.do_copy(self)
+        return DBOpmProcessValue.do_copy(self)
 
     def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
-        cp = DBModuleExec(id=self._db_id,
-                          ts_start=self._db_ts_start,
-                          ts_end=self._db_ts_end,
-                          cached=self._db_cached,
-                          module_id=self._db_module_id,
-                          module_name=self._db_module_name,
-                          completed=self._db_completed,
-                          error=self._db_error,
-                          machine_id=self._db_machine_id)
-        if self._db_annotations is None:
-            cp._db_annotations = []
-        else:
-            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
-        if self._db_loop_execs is None:
-            cp._db_loop_execs = []
-        else:
-            cp._db_loop_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_loop_execs]
+        cp = DBOpmProcessValue()
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
         
         # set new ids
         if new_ids:
@@ -16595,14 +17906,8 @@ class DBModuleExec(object):
             else:
                 id_remap[(self.vtType, self.db_id)] = new_id
             cp.db_id = new_id
-            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
-                cp._db_module_id = id_remap[('module', self._db_module_id)]
-            if hasattr(self, 'db_machine_id') and ('machine', self._db_machine_id) in id_remap:
-                cp._db_machine_id = id_remap[('machine', self._db_machine_id)]
         
         # recreate indices and set flags
-        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
-        cp.db_loop_execs_id_index = dict((v.db_id, v) for v in cp._db_loop_execs)
         if not new_ids:
             cp.is_dirty = self.is_dirty
             cp.is_new = self.is_new
@@ -16611,318 +17916,70 @@ class DBModuleExec(object):
     @staticmethod
     def update_version(old_obj, trans_dict, new_obj=None):
         if new_obj is None:
-            new_obj = DBModuleExec()
+            new_obj = DBOpmProcessValue()
         class_dict = {}
         if new_obj.__class__.__name__ in trans_dict:
             class_dict = trans_dict[new_obj.__class__.__name__]
-        if 'id' in class_dict:
-            res = class_dict['id'](old_obj, trans_dict)
-            new_obj.db_id = res
-        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
-            new_obj.db_id = old_obj.db_id
-        if 'ts_start' in class_dict:
-            res = class_dict['ts_start'](old_obj, trans_dict)
-            new_obj.db_ts_start = res
-        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
-            new_obj.db_ts_start = old_obj.db_ts_start
-        if 'ts_end' in class_dict:
-            res = class_dict['ts_end'](old_obj, trans_dict)
-            new_obj.db_ts_end = res
-        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
-            new_obj.db_ts_end = old_obj.db_ts_end
-        if 'cached' in class_dict:
-            res = class_dict['cached'](old_obj, trans_dict)
-            new_obj.db_cached = res
-        elif hasattr(old_obj, 'db_cached') and old_obj.db_cached is not None:
-            new_obj.db_cached = old_obj.db_cached
-        if 'module_id' in class_dict:
-            res = class_dict['module_id'](old_obj, trans_dict)
-            new_obj.db_module_id = res
-        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
-            new_obj.db_module_id = old_obj.db_module_id
-        if 'module_name' in class_dict:
-            res = class_dict['module_name'](old_obj, trans_dict)
-            new_obj.db_module_name = res
-        elif hasattr(old_obj, 'db_module_name') and old_obj.db_module_name is not None:
-            new_obj.db_module_name = old_obj.db_module_name
-        if 'completed' in class_dict:
-            res = class_dict['completed'](old_obj, trans_dict)
-            new_obj.db_completed = res
-        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
-            new_obj.db_completed = old_obj.db_completed
-        if 'error' in class_dict:
-            res = class_dict['error'](old_obj, trans_dict)
-            new_obj.db_error = res
-        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
-            new_obj.db_error = old_obj.db_error
-        if 'machine_id' in class_dict:
-            res = class_dict['machine_id'](old_obj, trans_dict)
-            new_obj.db_machine_id = res
-        elif hasattr(old_obj, 'db_machine_id') and old_obj.db_machine_id is not None:
-            new_obj.db_machine_id = old_obj.db_machine_id
-        if 'annotations' in class_dict:
-            res = class_dict['annotations'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_annotation(obj)
-        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
-            for obj in old_obj.db_annotations:
-                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
-            for obj in old_obj.db_deleted_annotations:
-                n_obj = DBAnnotation.update_version(obj, trans_dict)
-                new_obj.db_deleted_annotations.append(n_obj)
-        if 'loop_execs' in class_dict:
-            res = class_dict['loop_execs'](old_obj, trans_dict)
-            for obj in res:
-                new_obj.db_add_loop_exec(obj)
-        elif hasattr(old_obj, 'db_loop_execs') and old_obj.db_loop_execs is not None:
-            for obj in old_obj.db_loop_execs:
-                new_obj.db_add_loop_exec(DBLoopExec.update_version(obj, trans_dict))
-        if hasattr(old_obj, 'db_deleted_loop_execs') and hasattr(new_obj, 'db_deleted_loop_execs'):
-            for obj in old_obj.db_deleted_loop_execs:
-                n_obj = DBLoopExec.update_version(obj, trans_dict)
-                new_obj.db_deleted_loop_execs.append(n_obj)
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            if obj.vtType == 'module_exec':
+                new_obj.db_add_value(DBModuleExec.update_version(obj, trans_dict))
+            elif obj.vtType == 'group_exec':
+                new_obj.db_add_value(DBGroupExec.update_version(obj, trans_dict))
+            elif obj.vtType == 'loop_exec':
+                new_obj.db_add_value(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
         new_obj.is_new = old_obj.is_new
         new_obj.is_dirty = old_obj.is_dirty
         return new_obj
 
     def db_children(self, parent=(None,None), orphan=False, for_action=False):
         children = []
-        to_del = []
-        for child in self.db_annotations:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
-            if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_annotation(child)
-        to_del = []
-        for child in self.db_loop_execs:
-            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
             if orphan:
-                to_del.append(child)
-        for child in to_del:
-            self.db_delete_loop_exec(child)
+                self._db_value = None
         children.append((self, parent[0], parent[1]))
         return children
     def db_deleted_children(self, remove=False):
         children = []
-        children.extend(self.db_deleted_annotations)
-        children.extend(self.db_deleted_loop_execs)
+        children.extend(self.db_deleted_value)
         if remove:
-            self.db_deleted_annotations = []
-            self.db_deleted_loop_execs = []
+            self.db_deleted_value = []
         return children
     def has_changes(self):
         if self.is_dirty:
             return True
-        for child in self._db_annotations:
-            if child.has_changes():
-                return True
-        for child in self._db_loop_execs:
-            if child.has_changes():
-                return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
         return False
-    def __get_db_id(self):
-        return self._db_id
-    def __set_db_id(self, id):
-        self._db_id = id
-        self.is_dirty = True
-    db_id = property(__get_db_id, __set_db_id)
-    def db_add_id(self, id):
-        self._db_id = id
-    def db_change_id(self, id):
-        self._db_id = id
-    def db_delete_id(self, id):
-        self._db_id = None
-    
-    def __get_db_ts_start(self):
-        return self._db_ts_start
-    def __set_db_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-        self.is_dirty = True
-    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
-    def db_add_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_change_ts_start(self, ts_start):
-        self._db_ts_start = ts_start
-    def db_delete_ts_start(self, ts_start):
-        self._db_ts_start = None
-    
-    def __get_db_ts_end(self):
-        return self._db_ts_end
-    def __set_db_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-        self.is_dirty = True
-    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
-    def db_add_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_change_ts_end(self, ts_end):
-        self._db_ts_end = ts_end
-    def db_delete_ts_end(self, ts_end):
-        self._db_ts_end = None
-    
-    def __get_db_cached(self):
-        return self._db_cached
-    def __set_db_cached(self, cached):
-        self._db_cached = cached
-        self.is_dirty = True
-    db_cached = property(__get_db_cached, __set_db_cached)
-    def db_add_cached(self, cached):
-        self._db_cached = cached
-    def db_change_cached(self, cached):
-        self._db_cached = cached
-    def db_delete_cached(self, cached):
-        self._db_cached = None
-    
-    def __get_db_module_id(self):
-        return self._db_module_id
-    def __set_db_module_id(self, module_id):
-        self._db_module_id = module_id
-        self.is_dirty = True
-    db_module_id = property(__get_db_module_id, __set_db_module_id)
-    def db_add_module_id(self, module_id):
-        self._db_module_id = module_id
-    def db_change_module_id(self, module_id):
-        self._db_module_id = module_id
-    def db_delete_module_id(self, module_id):
-        self._db_module_id = None
-    
-    def __get_db_module_name(self):
-        return self._db_module_name
-    def __set_db_module_name(self, module_name):
-        self._db_module_name = module_name
-        self.is_dirty = True
-    db_module_name = property(__get_db_module_name, __set_db_module_name)
-    def db_add_module_name(self, module_name):
-        self._db_module_name = module_name
-    def db_change_module_name(self, module_name):
-        self._db_module_name = module_name
-    def db_delete_module_name(self, module_name):
-        self._db_module_name = None
-    
-    def __get_db_completed(self):
-        return self._db_completed
-    def __set_db_completed(self, completed):
-        self._db_completed = completed
-        self.is_dirty = True
-    db_completed = property(__get_db_completed, __set_db_completed)
-    def db_add_completed(self, completed):
-        self._db_completed = completed
-    def db_change_completed(self, completed):
-        self._db_completed = completed
-    def db_delete_completed(self, completed):
-        self._db_completed = None
-    
-    def __get_db_error(self):
-        return self._db_error
-    def __set_db_error(self, error):
-        self._db_error = error
-        self.is_dirty = True
-    db_error = property(__get_db_error, __set_db_error)
-    def db_add_error(self, error):
-        self._db_error = error
-    def db_change_error(self, error):
-        self._db_error = error
-    def db_delete_error(self, error):
-        self._db_error = None
-    
-    def __get_db_machine_id(self):
-        return self._db_machine_id
-    def __set_db_machine_id(self, machine_id):
-        self._db_machine_id = machine_id
-        self.is_dirty = True
-    db_machine_id = property(__get_db_machine_id, __set_db_machine_id)
-    def db_add_machine_id(self, machine_id):
-        self._db_machine_id = machine_id
-    def db_change_machine_id(self, machine_id):
-        self._db_machine_id = machine_id
-    def db_delete_machine_id(self, machine_id):
-        self._db_machine_id = None
-    
-    def __get_db_annotations(self):
-        return self._db_annotations
-    def __set_db_annotations(self, annotations):
-        self._db_annotations = annotations
-        self.is_dirty = True
-    db_annotations = property(__get_db_annotations, __set_db_annotations)
-    def db_get_annotations(self):
-        return self._db_annotations
-    def db_add_annotation(self, annotation):
-        self.is_dirty = True
-        self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-    def db_change_annotation(self, annotation):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                self._db_annotations[i] = annotation
-                found = True
-                break
-        if not found:
-            self._db_annotations.append(annotation)
-        self.db_annotations_id_index[annotation.db_id] = annotation
-    def db_delete_annotation(self, annotation):
-        self.is_dirty = True
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == annotation.db_id:
-                if not self._db_annotations[i].is_new:
-                    self.db_deleted_annotations.append(self._db_annotations[i])
-                del self._db_annotations[i]
-                break
-        del self.db_annotations_id_index[annotation.db_id]
-    def db_get_annotation(self, key):
-        for i in xrange(len(self._db_annotations)):
-            if self._db_annotations[i].db_id == key:
-                return self._db_annotations[i]
-        return None
-    def db_get_annotation_by_id(self, key):
-        return self.db_annotations_id_index[key]
-    def db_has_annotation_with_id(self, key):
-        return key in self.db_annotations_id_index
-    
-    def __get_db_loop_execs(self):
-        return self._db_loop_execs
-    def __set_db_loop_execs(self, loop_execs):
-        self._db_loop_execs = loop_execs
-        self.is_dirty = True
-    db_loop_execs = property(__get_db_loop_execs, __set_db_loop_execs)
-    def db_get_loop_execs(self):
-        return self._db_loop_execs
-    def db_add_loop_exec(self, loop_exec):
-        self.is_dirty = True
-        self._db_loop_execs.append(loop_exec)
-        self.db_loop_execs_id_index[loop_exec.db_id] = loop_exec
-    def db_change_loop_exec(self, loop_exec):
-        self.is_dirty = True
-        found = False
-        for i in xrange(len(self._db_loop_execs)):
-            if self._db_loop_execs[i].db_id == loop_exec.db_id:
-                self._db_loop_execs[i] = loop_exec
-                found = True
-                break
-        if not found:
-            self._db_loop_execs.append(loop_exec)
-        self.db_loop_execs_id_index[loop_exec.db_id] = loop_exec
-    def db_delete_loop_exec(self, loop_exec):
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
         self.is_dirty = True
-        for i in xrange(len(self._db_loop_execs)):
-            if self._db_loop_execs[i].db_id == loop_exec.db_id:
-                if not self._db_loop_execs[i].is_new:
-                    self.db_deleted_loop_execs.append(self._db_loop_execs[i])
-                del self._db_loop_execs[i]
-                break
-        del self.db_loop_execs_id_index[loop_exec.db_id]
-    def db_get_loop_exec(self, key):
-        for i in xrange(len(self._db_loop_execs)):
-            if self._db_loop_execs[i].db_id == key:
-                return self._db_loop_execs[i]
-        return None
-    def db_get_loop_exec_by_id(self, key):
-        return self.db_loop_execs_id_index[key]
-    def db_has_loop_exec_with_id(self, key):
-        return key in self.db_loop_execs_id_index
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
     
-    def getPrimaryKey(self):
-        return self._db_id
+
 
diff --git a/vistrails/db/versions/v1_0_3/domain/id_scope.py b/vistrails/db/versions/v1_0_3/domain/id_scope.py
index 0e07f02..49f3707 100644
--- a/vistrails/db/versions/v1_0_3/domain/id_scope.py
+++ b/vistrails/db/versions/v1_0_3/domain/id_scope.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 
 class IdScope:
diff --git a/vistrails/db/versions/v1_0_3/domain/log.py b/vistrails/db/versions/v1_0_3/domain/log.py
index a127726..49b1497 100644
--- a/vistrails/db/versions/v1_0_3/domain/log.py
+++ b/vistrails/db/versions/v1_0_3/domain/log.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBLog as _DBLog
 from auto_gen import DBAbstraction, DBModule, DBGroup, DBLoopExec, \
     DBGroupExec, DBModuleExec
diff --git a/vistrails/db/versions/v1_0_3/domain/registry.py b/vistrails/db/versions/v1_0_3/domain/registry.py
index 323ebbd..677b3d1 100644
--- a/vistrails/db/versions/v1_0_3/domain/registry.py
+++ b/vistrails/db/versions/v1_0_3/domain/registry.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBRegistry as _DBRegistry, DBPackage, DBModuleDescriptor, \
     DBPortSpec
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_3/domain/vistrail.py b/vistrails/db/versions/v1_0_3/domain/vistrail.py
index 4c1e5a2..7205ec7 100644
--- a/vistrails/db/versions/v1_0_3/domain/vistrail.py
+++ b/vistrails/db/versions/v1_0_3/domain/vistrail.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import copy
 import hashlib
 from auto_gen import DBVistrail as _DBVistrail
diff --git a/vistrails/db/versions/v1_0_3/domain/workflow.py b/vistrails/db/versions/v1_0_3/domain/workflow.py
index af484e6..71aaef7 100644
--- a/vistrails/db/versions/v1_0_3/domain/workflow.py
+++ b/vistrails/db/versions/v1_0_3/domain/workflow.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from auto_gen import DBWorkflow as _DBWorkflow
 from auto_gen import DBAbstraction, DBModule, DBGroup
 from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_3/persistence/__init__.py b/vistrails/db/versions/v1_0_3/persistence/__init__.py
index 0a7bec1..3839ad6 100644
--- a/vistrails/db/versions/v1_0_3/persistence/__init__.py
+++ b/vistrails/db/versions/v1_0_3/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from xml.auto_gen import XMLDAOListBase
 from sql.auto_gen import SQLDAOListBase
 from vistrails.core.system import get_elementtree_library
diff --git a/vistrails/db/versions/v1_0_3/persistence/sql/__init__.py b/vistrails/db/versions/v1_0_3/persistence/sql/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_3/persistence/sql/__init__.py
+++ b/vistrails/db/versions/v1_0_3/persistence/sql/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_3/persistence/sql/auto_gen.py b/vistrails/db/versions/v1_0_3/persistence/sql/auto_gen.py
index db939f3..4b523f1 100644
--- a/vistrails/db/versions/v1_0_3/persistence/sql/auto_gen.py
+++ b/vistrails/db/versions/v1_0_3/persistence/sql/auto_gen.py
@@ -1,155 +1,130 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 from sql_dao import SQLDAO
 from vistrails.db.versions.v1_0_3.domain import *
 
-class DBVistrailVariableSQLDAOBase(SQLDAO):
+class DBMashupAliasSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'vistrail_variable'
+        self.table = 'mashup_alias'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
-        table = 'vistrail_variable'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
         whereMap = global_props
-        orderBy = 'name'
+        orderBy = 'id'
 
         dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
         data = self.executeSQL(db, dbCommand, True)
         res = {}
         for row in data:
-            name = self.convertFromDB(row[0], 'str', 'varchar(255)')
-            uuid = self.convertFromDB(row[1], 'str', 'char(36)')
-            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            module = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[5], 'str', 'varchar(8191)')
-            vistrail = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            parent = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
             
-            vistrailVariable = DBVistrailVariable(uuid=uuid,
-                                                  package=package,
-                                                  module=module,
-                                                  namespace=namespace,
-                                                  value=value,
-                                                  name=name)
-            vistrailVariable.db_vistrail = vistrail
-            vistrailVariable.db_entity_id = entity_id
-            vistrailVariable.db_entity_type = entity_type
-            vistrailVariable.is_dirty = False
-            res[('vistrailVariable', name)] = vistrailVariable
+            mashup_alias = DBMashupAlias(name=name,
+                                         id=id)
+            mashup_alias.db_parent = parent
+            mashup_alias.db_entity_id = entity_id
+            mashup_alias.db_entity_type = entity_type
+            mashup_alias.is_dirty = False
+            res[('mashup_alias', id)] = mashup_alias
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
-        table = 'vistrail_variable'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
         whereMap = global_props
-        orderBy = 'name'
+        orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
 
     def process_sql_columns(self, data, global_props):
         res = {}
         for row in data:
-            name = self.convertFromDB(row[0], 'str', 'varchar(255)')
-            uuid = self.convertFromDB(row[1], 'str', 'char(36)')
-            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            module = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[5], 'str', 'varchar(8191)')
-            vistrail = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            parent = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
             
-            vistrailVariable = DBVistrailVariable(uuid=uuid,
-                                                  package=package,
-                                                  module=module,
-                                                  namespace=namespace,
-                                                  value=value,
-                                                  name=name)
-            vistrailVariable.db_vistrail = vistrail
-            vistrailVariable.db_entity_id = entity_id
-            vistrailVariable.db_entity_type = entity_type
-            vistrailVariable.is_dirty = False
-            res[('vistrailVariable', name)] = vistrailVariable
+            mashup_alias = DBMashupAlias(name=name,
+                                         id=id)
+            mashup_alias.db_parent = parent
+            mashup_alias.db_entity_id = entity_id
+            mashup_alias.db_entity_type = entity_type
+            mashup_alias.is_dirty = False
+            res[('mashup_alias', id)] = mashup_alias
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('vistrail', obj.db_vistrail) in all_objects:
-            p = all_objects[('vistrail', obj.db_vistrail)]
-            p.db_add_vistrailVariable(obj)
+        if ('mashup', obj.db_parent) in all_objects:
+            p = all_objects[('mashup', obj.db_parent)]
+            p.db_add_alias(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
-        table = 'vistrail_variable'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
         whereMap = {}
         whereMap.update(global_props)
-        if obj.db_name is not None:
-            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-            whereMap['name'] = keyStr
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
         columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_uuid') and obj.db_uuid is not None:
-            columnMap['uuid'] = \
-                self.convertToDB(obj.db_uuid, 'str', 'char(36)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_module') and obj.db_module is not None:
-            columnMap['module'] = \
-                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+                self.convertToDB(obj.db_parent, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -167,35 +142,23 @@ class DBVistrailVariableSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
-        table = 'vistrail_variable'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
         whereMap = {}
         whereMap.update(global_props)
-        if obj.db_name is not None:
-            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-            whereMap['name'] = keyStr
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
         columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_uuid') and obj.db_uuid is not None:
-            columnMap['uuid'] = \
-                self.convertToDB(obj.db_uuid, 'str', 'char(36)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_module') and obj.db_module is not None:
-            columnMap['module'] = \
-                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+                self.convertToDB(obj.db_parent, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -214,30 +177,32 @@ class DBVistrailVariableSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        if obj.db_component is not None:
+            child = obj.db_component
+            child.db_mashup_alias = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'vistrail_variable'
+        table = 'mashup_alias'
         whereMap = {}
         whereMap.update(global_props)
-        if obj.db_name is not None:
-            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-            whereMap['name'] = keyStr
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPortSpecSQLDAOBase(SQLDAO):
+class DBGroupSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'port_spec'
+        self.table = 'group_tbl'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port_spec'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
         whereMap = global_props
         orderBy = 'id'
 
@@ -246,35 +211,33 @@ class DBPortSpecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            type = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            optional = self.convertFromDB(row[3], 'int', 'int')
-            sort_key = self.convertFromDB(row[4], 'int', 'int')
-            min_conns = self.convertFromDB(row[5], 'int', 'int')
-            max_conns = self.convertFromDB(row[6], 'int', 'int')
-            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
-            parent = self.convertFromDB(row[10], 'long', 'long')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            portSpec = DBPortSpec(name=name,
-                                  type=type,
-                                  optional=optional,
-                                  sort_key=sort_key,
-                                  min_conns=min_conns,
-                                  max_conns=max_conns,
-                                  id=id)
-            portSpec.db_parentType = parentType
-            portSpec.db_entity_id = entity_id
-            portSpec.db_entity_type = entity_type
-            portSpec.db_parent = parent
-            portSpec.is_dirty = False
-            res[('portSpec', id)] = portSpec
+            group = DBGroup(cache=cache,
+                            name=name,
+                            namespace=namespace,
+                            package=package,
+                            version=version,
+                            id=id)
+            group.db_parentType = parentType
+            group.db_entity_id = entity_id
+            group.db_entity_type = entity_type
+            group.db_parent = parent
+            group.is_dirty = False
+            res[('group', id)] = group
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port_spec'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -283,39 +246,34 @@ class DBPortSpecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            type = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            optional = self.convertFromDB(row[3], 'int', 'int')
-            sort_key = self.convertFromDB(row[4], 'int', 'int')
-            min_conns = self.convertFromDB(row[5], 'int', 'int')
-            max_conns = self.convertFromDB(row[6], 'int', 'int')
-            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
-            parent = self.convertFromDB(row[10], 'long', 'long')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            portSpec = DBPortSpec(name=name,
-                                  type=type,
-                                  optional=optional,
-                                  sort_key=sort_key,
-                                  min_conns=min_conns,
-                                  max_conns=max_conns,
-                                  id=id)
-            portSpec.db_parentType = parentType
-            portSpec.db_entity_id = entity_id
-            portSpec.db_entity_type = entity_type
-            portSpec.db_parent = parent
-            portSpec.is_dirty = False
-            res[('portSpec', id)] = portSpec
-        return res
-
-    def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'module':
-            p = all_objects[('module', obj.db_parent)]
-            p.db_add_portSpec(obj)
-        elif obj.db_parentType == 'module_descriptor':
-            p = all_objects[('module_descriptor', obj.db_parent)]
-            p.db_add_portSpec(obj)
+            group = DBGroup(cache=cache,
+                            name=name,
+                            namespace=namespace,
+                            package=package,
+                            version=version,
+                            id=id)
+            group.db_parentType = parentType
+            group.db_entity_id = entity_id
+            group.db_entity_type = entity_type
+            group.db_parent = parent
+            group.is_dirty = False
+            res[('group', id)] = group
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_module(obj)
         elif obj.db_parentType == 'add':
             p = all_objects[('add', obj.db_parent)]
             p.db_add_data(obj)
@@ -326,8 +284,8 @@ class DBPortSpecSQLDAOBase(SQLDAO):
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port_spec'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -337,24 +295,21 @@ class DBPortSpecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_optional') and obj.db_optional is not None:
-            columnMap['optional'] = \
-                self.convertToDB(obj.db_optional, 'int', 'int')
-        if hasattr(obj, 'db_sort_key') and obj.db_sort_key is not None:
-            columnMap['sort_key'] = \
-                self.convertToDB(obj.db_sort_key, 'int', 'int')
-        if hasattr(obj, 'db_min_conns') and obj.db_min_conns is not None:
-            columnMap['min_conns'] = \
-                self.convertToDB(obj.db_min_conns, 'int', 'int')
-        if hasattr(obj, 'db_max_conns') and obj.db_max_conns is not None:
-            columnMap['max_conns'] = \
-                self.convertToDB(obj.db_max_conns, 'int', 'int')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -378,8 +333,8 @@ class DBPortSpecSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port_spec'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -389,24 +344,21 @@ class DBPortSpecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_optional') and obj.db_optional is not None:
-            columnMap['optional'] = \
-                self.convertToDB(obj.db_optional, 'int', 'int')
-        if hasattr(obj, 'db_sort_key') and obj.db_sort_key is not None:
-            columnMap['sort_key'] = \
-                self.convertToDB(obj.db_sort_key, 'int', 'int')
-        if hasattr(obj, 'db_min_conns') and obj.db_min_conns is not None:
-            columnMap['min_conns'] = \
-                self.convertToDB(obj.db_min_conns, 'int', 'int')
-        if hasattr(obj, 'db_max_conns') and obj.db_max_conns is not None:
-            columnMap['max_conns'] = \
-                self.convertToDB(obj.db_max_conns, 'int', 'int')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -431,11 +383,22 @@ class DBPortSpecSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_portSpecItems:
-            child.db_portSpec = obj.db_id
+        if obj.db_workflow is not None:
+            child = obj.db_workflow
+            child.db_group = obj.db_id
+        if obj.db_location is not None:
+            child = obj.db_location
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_functions:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'port_spec'
+        table = 'group_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -444,18 +407,18 @@ class DBPortSpecSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBModuleSQLDAOBase(SQLDAO):
+class DBAddSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'module'
+        self.table = 'add_tbl'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'module'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
         whereMap = global_props
         orderBy = 'id'
 
@@ -464,33 +427,29 @@ class DBModuleSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            cache = self.convertFromDB(row[1], 'int', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            module = DBModule(cache=cache,
-                              name=name,
-                              namespace=namespace,
-                              package=package,
-                              version=version,
-                              id=id)
-            module.db_parentType = parentType
-            module.db_entity_id = entity_id
-            module.db_entity_type = entity_type
-            module.db_parent = parent
-            module.is_dirty = False
-            res[('module', id)] = module
+            add = DBAdd(what=what,
+                        objectId=objectId,
+                        parentObjId=parentObjId,
+                        parentObjType=parentObjType,
+                        id=id)
+            add.db_action = action
+            add.db_entity_id = entity_id
+            add.db_entity_type = entity_type
+            add.is_dirty = False
+            res[('add', id)] = add
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'module'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -499,46 +458,36 @@ class DBModuleSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            cache = self.convertFromDB(row[1], 'int', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            module = DBModule(cache=cache,
-                              name=name,
-                              namespace=namespace,
-                              package=package,
-                              version=version,
-                              id=id)
-            module.db_parentType = parentType
-            module.db_entity_id = entity_id
-            module.db_entity_type = entity_type
-            module.db_parent = parent
-            module.is_dirty = False
-            res[('module', id)] = module
+            add = DBAdd(what=what,
+                        objectId=objectId,
+                        parentObjId=parentObjId,
+                        parentObjType=parentObjType,
+                        id=id)
+            add.db_action = action
+            add.db_entity_id = entity_id
+            add.db_entity_type = entity_type
+            add.is_dirty = False
+            res[('add', id)] = add
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow':
-            p = all_objects[('workflow', obj.db_parent)]
-            p.db_add_module(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
+        if ('action', obj.db_action) in all_objects:
+            p = all_objects[('action', obj.db_action)]
+            p.db_add_operation(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'module'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -548,33 +497,27 @@ class DBModuleSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
-            columnMap['cache'] = \
-                self.convertToDB(obj.db_cache, 'int', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -586,8 +529,8 @@ class DBModuleSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'module'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -597,33 +540,27 @@ class DBModuleSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
-            columnMap['cache'] = \
-                self.convertToDB(obj.db_cache, 'int', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -636,22 +573,13 @@ class DBModuleSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_location is not None:
-            child = obj.db_location
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_functions:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_portSpecs:
+        if obj.db_data is not None:
+            child = obj.db_data
             child.db_parentType = obj.vtType
             child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'module'
+        table = 'add_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -660,18 +588,18 @@ class DBModuleSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBModuleDescriptorSQLDAOBase(SQLDAO):
+class DBGroupExecSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'module_descriptor'
+        self.table = 'group_exec'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
-        table = 'module_descriptor'
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
         whereMap = global_props
         orderBy = 'id'
 
@@ -680,33 +608,41 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            package_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            base_descriptor_id = self.convertFromDB(row[6], 'long', 'int')
-            package = self.convertFromDB(row[7], 'long', 'int')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            cached = self.convertFromDB(row[3], 'int', 'int')
+            module_id = self.convertFromDB(row[4], 'long', 'int')
+            group_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            group_type = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            completed = self.convertFromDB(row[7], 'int', 'int')
+            error = self.convertFromDB(row[8], 'str', 'varchar(1023)')
+            machine_id = self.convertFromDB(row[9], 'long', 'int')
+            parentType = self.convertFromDB(row[10], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[11], 'long', 'int')
+            entity_type = self.convertFromDB(row[12], 'str', 'char(16)')
+            parent = self.convertFromDB(row[13], 'long', 'long')
             
-            module_descriptor = DBModuleDescriptor(name=name,
-                                                   package=package,
-                                                   namespace=namespace,
-                                                   package_version=package_version,
-                                                   version=version,
-                                                   base_descriptor_id=base_descriptor_id,
-                                                   id=id)
-            module_descriptor.db_package = package
-            module_descriptor.db_entity_id = entity_id
-            module_descriptor.db_entity_type = entity_type
-            module_descriptor.is_dirty = False
-            res[('module_descriptor', id)] = module_descriptor
+            group_exec = DBGroupExec(ts_start=ts_start,
+                                     ts_end=ts_end,
+                                     cached=cached,
+                                     module_id=module_id,
+                                     group_name=group_name,
+                                     group_type=group_type,
+                                     completed=completed,
+                                     error=error,
+                                     machine_id=machine_id,
+                                     id=id)
+            group_exec.db_parentType = parentType
+            group_exec.db_entity_id = entity_id
+            group_exec.db_entity_type = entity_type
+            group_exec.db_parent = parent
+            group_exec.is_dirty = False
+            res[('group_exec', id)] = group_exec
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
-        table = 'module_descriptor'
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -715,40 +651,54 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            package_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            base_descriptor_id = self.convertFromDB(row[6], 'long', 'int')
-            package = self.convertFromDB(row[7], 'long', 'int')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            cached = self.convertFromDB(row[3], 'int', 'int')
+            module_id = self.convertFromDB(row[4], 'long', 'int')
+            group_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            group_type = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            completed = self.convertFromDB(row[7], 'int', 'int')
+            error = self.convertFromDB(row[8], 'str', 'varchar(1023)')
+            machine_id = self.convertFromDB(row[9], 'long', 'int')
+            parentType = self.convertFromDB(row[10], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[11], 'long', 'int')
+            entity_type = self.convertFromDB(row[12], 'str', 'char(16)')
+            parent = self.convertFromDB(row[13], 'long', 'long')
             
-            module_descriptor = DBModuleDescriptor(name=name,
-                                                   package=package,
-                                                   namespace=namespace,
-                                                   package_version=package_version,
-                                                   version=version,
-                                                   base_descriptor_id=base_descriptor_id,
-                                                   id=id)
-            module_descriptor.db_package = package
-            module_descriptor.db_entity_id = entity_id
-            module_descriptor.db_entity_type = entity_type
-            module_descriptor.is_dirty = False
-            res[('module_descriptor', id)] = module_descriptor
+            group_exec = DBGroupExec(ts_start=ts_start,
+                                     ts_end=ts_end,
+                                     cached=cached,
+                                     module_id=module_id,
+                                     group_name=group_name,
+                                     group_type=group_type,
+                                     completed=completed,
+                                     error=error,
+                                     machine_id=machine_id,
+                                     id=id)
+            group_exec.db_parentType = parentType
+            group_exec.db_entity_id = entity_id
+            group_exec.db_entity_type = entity_type
+            group_exec.db_parent = parent
+            group_exec.is_dirty = False
+            res[('group_exec', id)] = group_exec
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('package', obj.db_package) in all_objects:
-            p = all_objects[('package', obj.db_package)]
-            p.db_add_module_descriptor(obj)
+        if obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'loop_exec':
+            p = all_objects[('loop_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
-        table = 'module_descriptor'
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -758,33 +708,45 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package_version') and obj.db_package_version is not None:
-            columnMap['package_version'] = \
-                self.convertToDB(obj.db_package_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_base_descriptor_id') and obj.db_base_descriptor_id is not None:
-            columnMap['base_descriptor_id'] = \
-                self.convertToDB(obj.db_base_descriptor_id, 'long', 'int')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_package, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
+            columnMap['cached'] = \
+                self.convertToDB(obj.db_cached, 'int', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_group_name') and obj.db_group_name is not None:
+            columnMap['group_name'] = \
+                self.convertToDB(obj.db_group_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_group_type') and obj.db_group_type is not None:
+            columnMap['group_type'] = \
+                self.convertToDB(obj.db_group_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
+            columnMap['machine_id'] = \
+                self.convertToDB(obj.db_machine_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -796,8 +758,8 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
-        table = 'module_descriptor'
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -807,34 +769,46 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package_version') and obj.db_package_version is not None:
-            columnMap['package_version'] = \
-                self.convertToDB(obj.db_package_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_base_descriptor_id') and obj.db_base_descriptor_id is not None:
-            columnMap['base_descriptor_id'] = \
-                self.convertToDB(obj.db_base_descriptor_id, 'long', 'int')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_package, 'long', 'int')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            columnMap['entity_type'] = \
-                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        columnMap.update(global_props)
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
+            columnMap['cached'] = \
+                self.convertToDB(obj.db_cached, 'int', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_group_name') and obj.db_group_name is not None:
+            columnMap['group_name'] = \
+                self.convertToDB(obj.db_group_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_group_type') and obj.db_group_type is not None:
+            columnMap['group_type'] = \
+                self.convertToDB(obj.db_group_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
+            columnMap['machine_id'] = \
+                self.convertToDB(obj.db_machine_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
 
         if obj.is_new or do_copy:
             dbCommand = self.createSQLInsert(table, columnMap)
@@ -846,12 +820,15 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_portSpecs:
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_item_execs:
             child.db_parentType = obj.vtType
             child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'module_descriptor'
+        table = 'group_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -860,18 +837,18 @@ class DBModuleDescriptorSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBTagSQLDAOBase(SQLDAO):
+class DBParameterSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'tag'
+        self.table = 'parameter'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'tag'
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
         whereMap = global_props
         orderBy = 'id'
 
@@ -880,23 +857,33 @@ class DBTagSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[2], 'long', 'int')
-            entity_id = self.convertFromDB(row[3], 'long', 'int')
-            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[4], 'str', 'mediumtext')
+            alias = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            tag = DBTag(name=name,
-                        id=id)
-            tag.db_vistrail = vistrail
-            tag.db_entity_id = entity_id
-            tag.db_entity_type = entity_type
-            tag.is_dirty = False
-            res[('tag', id)] = tag
+            parameter = DBParameter(pos=pos,
+                                    name=name,
+                                    type=type,
+                                    val=val,
+                                    alias=alias,
+                                    id=id)
+            parameter.db_parentType = parentType
+            parameter.db_entity_id = entity_id
+            parameter.db_entity_type = entity_type
+            parameter.db_parent = parent
+            parameter.is_dirty = False
+            res[('parameter', id)] = parameter
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'tag'
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -905,30 +892,46 @@ class DBTagSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[2], 'long', 'int')
-            entity_id = self.convertFromDB(row[3], 'long', 'int')
-            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[4], 'str', 'mediumtext')
+            alias = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            tag = DBTag(name=name,
-                        id=id)
-            tag.db_vistrail = vistrail
-            tag.db_entity_id = entity_id
-            tag.db_entity_type = entity_type
-            tag.is_dirty = False
-            res[('tag', id)] = tag
+            parameter = DBParameter(pos=pos,
+                                    name=name,
+                                    type=type,
+                                    val=val,
+                                    alias=alias,
+                                    id=id)
+            parameter.db_parentType = parentType
+            parameter.db_entity_id = entity_id
+            parameter.db_entity_type = entity_type
+            parameter.db_parent = parent
+            parameter.is_dirty = False
+            res[('parameter', id)] = parameter
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('vistrail', obj.db_vistrail) in all_objects:
-            p = all_objects[('vistrail', obj.db_vistrail)]
-            p.db_add_tag(obj)
+        if obj.db_parentType == 'function':
+            p = all_objects[('function', obj.db_parent)]
+            p.db_add_parameter(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'tag'
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -938,18 +941,33 @@ class DBTagSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_alias') and obj.db_alias is not None:
+            columnMap['alias'] = \
+                self.convertToDB(obj.db_alias, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -961,8 +979,8 @@ class DBTagSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'tag'
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -972,18 +990,33 @@ class DBTagSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_alias') and obj.db_alias is not None:
+            columnMap['alias'] = \
+                self.convertToDB(obj.db_alias, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -999,7 +1032,7 @@ class DBTagSQLDAOBase(SQLDAO):
         pass
     
     def delete_sql_column(self, db, obj, global_props):
-        table = 'tag'
+        table = 'parameter'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1008,18 +1041,18 @@ class DBTagSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPortSQLDAOBase(SQLDAO):
+class DBVistrailSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'port'
+        self.table = 'vistrail'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
         whereMap = global_props
         orderBy = 'id'
 
@@ -1028,33 +1061,25 @@ class DBPortSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            type = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            moduleId = self.convertFromDB(row[2], 'long', 'int')
-            moduleName = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            signature = self.convertFromDB(row[5], 'str', 'varchar(4095)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
             
-            port = DBPort(type=type,
-                          moduleId=moduleId,
-                          moduleName=moduleName,
-                          name=name,
-                          signature=signature,
-                          id=id)
-            port.db_parentType = parentType
-            port.db_entity_id = entity_id
-            port.db_entity_type = entity_type
-            port.db_parent = parent
-            port.is_dirty = False
-            res[('port', id)] = port
+            vistrail = DBVistrail(entity_type=entity_type,
+                                  version=version,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            vistrail.is_dirty = False
+            res[('vistrail', id)] = vistrail
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -1063,46 +1088,30 @@ class DBPortSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            type = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            moduleId = self.convertFromDB(row[2], 'long', 'int')
-            moduleName = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            signature = self.convertFromDB(row[5], 'str', 'varchar(4095)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
             
-            port = DBPort(type=type,
-                          moduleId=moduleId,
-                          moduleName=moduleName,
-                          name=name,
-                          signature=signature,
-                          id=id)
-            port.db_parentType = parentType
-            port.db_entity_id = entity_id
-            port.db_entity_type = entity_type
-            port.db_parent = parent
-            port.is_dirty = False
-            res[('port', id)] = port
+            vistrail = DBVistrail(entity_type=entity_type,
+                                  version=version,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            vistrail.is_dirty = False
+            res[('vistrail', id)] = vistrail
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'connection':
-            p = all_objects[('connection', obj.db_parent)]
-            p.db_add_port(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
-        
+        pass
+    
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1112,33 +1121,18 @@ class DBPortSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_moduleId') and obj.db_moduleId is not None:
-            columnMap['moduleId'] = \
-                self.convertToDB(obj.db_moduleId, 'long', 'int')
-        if hasattr(obj, 'db_moduleName') and obj.db_moduleName is not None:
-            columnMap['moduleName'] = \
-                self.convertToDB(obj.db_moduleName, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_signature') and obj.db_signature is not None:
-            columnMap['signature'] = \
-                self.convertToDB(obj.db_signature, 'str', 'varchar(4095)')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -1146,12 +1140,19 @@ class DBPortSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'port'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1161,33 +1162,18 @@ class DBPortSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_moduleId') and obj.db_moduleId is not None:
-            columnMap['moduleId'] = \
-                self.convertToDB(obj.db_moduleId, 'long', 'int')
-        if hasattr(obj, 'db_moduleName') and obj.db_moduleName is not None:
-            columnMap['moduleName'] = \
-                self.convertToDB(obj.db_moduleName, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_signature') and obj.db_signature is not None:
-            columnMap['signature'] = \
-                self.convertToDB(obj.db_signature, 'str', 'varchar(4095)')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -1197,13 +1183,32 @@ class DBPortSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_actions:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_tags:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_vistrailVariables:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_parameter_explorations:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_actionAnnotations:
+            child.db_vistrail = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'port'
+        table = 'vistrail'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1212,18 +1217,18 @@ class DBPortSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBGroupSQLDAOBase(SQLDAO):
+class DBModuleSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'group_tbl'
+        self.table = 'module'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
         columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_tbl'
+        table = 'module'
         whereMap = global_props
         orderBy = 'id'
 
@@ -1242,23 +1247,23 @@ class DBGroupSQLDAOBase(SQLDAO):
             entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             parent = self.convertFromDB(row[9], 'long', 'long')
             
-            group = DBGroup(cache=cache,
-                            name=name,
-                            namespace=namespace,
-                            package=package,
-                            version=version,
-                            id=id)
-            group.db_parentType = parentType
-            group.db_entity_id = entity_id
-            group.db_entity_type = entity_type
-            group.db_parent = parent
-            group.is_dirty = False
-            res[('group', id)] = group
+            module = DBModule(cache=cache,
+                              name=name,
+                              namespace=namespace,
+                              package=package,
+                              version=version,
+                              id=id)
+            module.db_parentType = parentType
+            module.db_entity_id = entity_id
+            module.db_entity_type = entity_type
+            module.db_parent = parent
+            module.is_dirty = False
+            res[('module', id)] = module
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
         columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_tbl'
+        table = 'module'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -1277,18 +1282,18 @@ class DBGroupSQLDAOBase(SQLDAO):
             entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             parent = self.convertFromDB(row[9], 'long', 'long')
             
-            group = DBGroup(cache=cache,
-                            name=name,
-                            namespace=namespace,
-                            package=package,
-                            version=version,
-                            id=id)
-            group.db_parentType = parentType
-            group.db_entity_id = entity_id
-            group.db_entity_type = entity_type
-            group.db_parent = parent
-            group.is_dirty = False
-            res[('group', id)] = group
+            module = DBModule(cache=cache,
+                              name=name,
+                              namespace=namespace,
+                              package=package,
+                              version=version,
+                              id=id)
+            module.db_parentType = parentType
+            module.db_entity_id = entity_id
+            module.db_entity_type = entity_type
+            module.db_parent = parent
+            module.is_dirty = False
+            res[('module', id)] = module
         return res
 
     def from_sql_fast(self, obj, all_objects):
@@ -1306,7 +1311,7 @@ class DBGroupSQLDAOBase(SQLDAO):
         if not do_copy and not obj.is_dirty:
             return
         columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_tbl'
+        table = 'module'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1355,7 +1360,7 @@ class DBGroupSQLDAOBase(SQLDAO):
         if not do_copy and not obj.is_dirty:
             return None
         columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_tbl'
+        table = 'module'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1404,9 +1409,6 @@ class DBGroupSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_workflow is not None:
-            child = obj.db_workflow
-            child.db_group = obj.db_id
         if obj.db_location is not None:
             child = obj.db_location
             child.db_parentType = obj.vtType
@@ -1417,9 +1419,12 @@ class DBGroupSQLDAOBase(SQLDAO):
         for child in obj.db_annotations:
             child.db_parentType = obj.vtType
             child.db_parent = obj.db_id
+        for child in obj.db_portSpecs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'group_tbl'
+        table = 'module'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1428,18 +1433,18 @@ class DBGroupSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBLogSQLDAOBase(SQLDAO):
+class DBPortSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'log_tbl'
+        self.table = 'port'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
-        table = 'log_tbl'
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
         whereMap = global_props
         orderBy = 'id'
 
@@ -1448,27 +1453,33 @@ class DBLogSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
-            vistrail_id = self.convertFromDB(row[5], 'long', 'int')
+            type = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            moduleId = self.convertFromDB(row[2], 'long', 'int')
+            moduleName = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            signature = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            log = DBLog(entity_type=entity_type,
-                        version=version,
-                        name=name,
-                        last_modified=last_modified,
-                        vistrail_id=vistrail_id,
-                        id=id)
-            log.is_dirty = False
-            res[('log', id)] = log
+            port = DBPort(type=type,
+                          moduleId=moduleId,
+                          moduleName=moduleName,
+                          name=name,
+                          signature=signature,
+                          id=id)
+            port.db_parentType = parentType
+            port.db_entity_id = entity_id
+            port.db_entity_type = entity_type
+            port.db_parent = parent
+            port.is_dirty = False
+            res[('port', id)] = port
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
-        table = 'log_tbl'
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -1477,32 +1488,46 @@ class DBLogSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
-            vistrail_id = self.convertFromDB(row[5], 'long', 'int')
-            
-            log = DBLog(entity_type=entity_type,
-                        version=version,
-                        name=name,
-                        last_modified=last_modified,
-                        vistrail_id=vistrail_id,
-                        id=id)
-            log.is_dirty = False
-            res[('log', id)] = log
+            type = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            moduleId = self.convertFromDB(row[2], 'long', 'int')
+            moduleName = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            signature = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            port = DBPort(type=type,
+                          moduleId=moduleId,
+                          moduleName=moduleName,
+                          name=name,
+                          signature=signature,
+                          id=id)
+            port.db_parentType = parentType
+            port.db_entity_id = entity_id
+            port.db_entity_type = entity_type
+            port.db_parent = parent
+            port.is_dirty = False
+            res[('port', id)] = port
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        pass
-    
+        if obj.db_parentType == 'connection':
+            p = all_objects[('connection', obj.db_parent)]
+            p.db_add_port(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
-        table = 'log_tbl'
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1512,21 +1537,33 @@ class DBLogSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            columnMap['entity_type'] = \
-                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_moduleId') and obj.db_moduleId is not None:
+            columnMap['moduleId'] = \
+                self.convertToDB(obj.db_moduleId, 'long', 'int')
+        if hasattr(obj, 'db_moduleName') and obj.db_moduleName is not None:
+            columnMap['moduleName'] = \
+                self.convertToDB(obj.db_moduleName, 'str', 'varchar(255)')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
-        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
-            columnMap['vistrail_id'] = \
-                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        if hasattr(obj, 'db_signature') and obj.db_signature is not None:
+            columnMap['signature'] = \
+                self.convertToDB(obj.db_signature, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -1534,19 +1571,12 @@ class DBLogSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
-        table = 'log_tbl'
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1556,21 +1586,33 @@ class DBLogSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            columnMap['entity_type'] = \
-                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_moduleId') and obj.db_moduleId is not None:
+            columnMap['moduleId'] = \
+                self.convertToDB(obj.db_moduleId, 'long', 'int')
+        if hasattr(obj, 'db_moduleName') and obj.db_moduleName is not None:
+            columnMap['moduleName'] = \
+                self.convertToDB(obj.db_moduleName, 'str', 'varchar(255)')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
-        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
-            columnMap['vistrail_id'] = \
-                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        if hasattr(obj, 'db_signature') and obj.db_signature is not None:
+            columnMap['signature'] = \
+                self.convertToDB(obj.db_signature, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -1580,23 +1622,13 @@ class DBLogSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_workflow_execs:
-            child.db_log = obj.db_id
-        for child in obj.db_machines:
-            child.db_log = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'log_tbl'
+        table = 'port'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1605,18 +1637,18 @@ class DBLogSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMashupAliasSQLDAOBase(SQLDAO):
+class DBPEFunctionSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'mashup_alias'
+        self.table = 'pe_function'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_alias'
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
         whereMap = global_props
         orderBy = 'id'
 
@@ -1625,23 +1657,28 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            parent = self.convertFromDB(row[2], 'long', 'int')
-            entity_id = self.convertFromDB(row[3], 'long', 'int')
-            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            module_id = self.convertFromDB(row[1], 'long', 'int')
+            port_name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            is_alias = self.convertFromDB(row[3], 'long', 'int')
+            parentType = self.convertFromDB(row[4], 'str', 'char(32)')
+            parameter_exploration = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            mashup_alias = DBMashupAlias(name=name,
-                                         id=id)
-            mashup_alias.db_parent = parent
-            mashup_alias.db_entity_id = entity_id
-            mashup_alias.db_entity_type = entity_type
-            mashup_alias.is_dirty = False
-            res[('mashup_alias', id)] = mashup_alias
+            pe_function = DBPEFunction(module_id=module_id,
+                                       port_name=port_name,
+                                       id=id)
+            pe_function.db_parentType = parentType
+            pe_function.db_parameter_exploration = parameter_exploration
+            pe_function.db_entity_id = entity_id
+            pe_function.db_entity_type = entity_type
+            pe_function.is_dirty = False
+            res[('pe_function', id)] = pe_function
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_alias'
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -1650,30 +1687,35 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            parent = self.convertFromDB(row[2], 'long', 'int')
-            entity_id = self.convertFromDB(row[3], 'long', 'int')
-            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            module_id = self.convertFromDB(row[1], 'long', 'int')
+            port_name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            is_alias = self.convertFromDB(row[3], 'long', 'int')
+            parentType = self.convertFromDB(row[4], 'str', 'char(32)')
+            parameter_exploration = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            mashup_alias = DBMashupAlias(name=name,
-                                         id=id)
-            mashup_alias.db_parent = parent
-            mashup_alias.db_entity_id = entity_id
-            mashup_alias.db_entity_type = entity_type
-            mashup_alias.is_dirty = False
-            res[('mashup_alias', id)] = mashup_alias
+            pe_function = DBPEFunction(module_id=module_id,
+                                       port_name=port_name,
+                                       id=id)
+            pe_function.db_parentType = parentType
+            pe_function.db_parameter_exploration = parameter_exploration
+            pe_function.db_entity_id = entity_id
+            pe_function.db_entity_type = entity_type
+            pe_function.is_dirty = False
+            res[('pe_function', id)] = pe_function
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('mashup', obj.db_parent) in all_objects:
-            p = all_objects[('mashup', obj.db_parent)]
-            p.db_add_alias(obj)
+        if ('parameter_exploration', obj.db_parameter_exploration) in all_objects:
+            p = all_objects[('parameter_exploration', obj.db_parameter_exploration)]
+            p.db_add_function(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_alias'
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1683,12 +1725,21 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_port_name') and obj.db_port_name is not None:
+            columnMap['port_name'] = \
+                self.convertToDB(obj.db_port_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_is_alias') and obj.db_is_alias is not None:
+            columnMap['is_alias'] = \
+                self.convertToDB(obj.db_is_alias, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_parameter_exploration') and obj.db_parameter_exploration is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'int')
+                self.convertToDB(obj.db_parameter_exploration, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -1706,8 +1757,8 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_alias'
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1717,21 +1768,30 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'int')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            columnMap['entity_type'] = \
-                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        columnMap.update(global_props)
-
-        if obj.is_new or do_copy:
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_port_name') and obj.db_port_name is not None:
+            columnMap['port_name'] = \
+                self.convertToDB(obj.db_port_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_is_alias') and obj.db_is_alias is not None:
+            columnMap['is_alias'] = \
+                self.convertToDB(obj.db_is_alias, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_parameter_exploration') and obj.db_parameter_exploration is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parameter_exploration, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
             dbCommand = self.createSQLInsert(table, columnMap)
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
@@ -1741,12 +1801,11 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_component is not None:
-            child = obj.db_component
-            child.db_mashup_alias = obj.db_id
+        for child in obj.db_parameters:
+            child.db_pe_function = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'mashup_alias'
+        table = 'pe_function'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1755,18 +1814,18 @@ class DBMashupAliasSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMashupSQLDAOBase(SQLDAO):
+class DBWorkflowSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'mashup'
+        self.table = 'workflow'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup'
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
         whereMap = global_props
         orderBy = 'id'
 
@@ -1775,35 +1834,31 @@ class DBMashupSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            version = self.convertFromDB(row[2], 'long', 'int')
-            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            vtid = self.convertFromDB(row[4], 'long', 'int')
-            layout = self.convertFromDB(row[5], 'str', 'mediumtext')
-            geometry = self.convertFromDB(row[6], 'str', 'mediumtext')
-            has_seq = self.convertFromDB(row[7], 'int', 'int')
-            parent = self.convertFromDB(row[8], 'long', 'int')
-            entity_id = self.convertFromDB(row[9], 'long', 'int')
-            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_id = self.convertFromDB(row[1], 'long', 'int')
+            entity_type = self.convertFromDB(row[2], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[4], 'str', 'char(16)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[6], 'long', 'int')
+            group = self.convertFromDB(row[7], 'long', 'int')
             
-            mashup = DBMashup(name=name,
-                              version=version,
-                              type=type,
-                              vtid=vtid,
-                              layout=layout,
-                              geometry=geometry,
-                              has_seq=has_seq,
-                              id=id)
-            mashup.db_parent = parent
-            mashup.db_entity_id = entity_id
-            mashup.db_entity_type = entity_type
-            mashup.is_dirty = False
-            res[('mashup', id)] = mashup
+            workflow = DBWorkflow(entity_type=entity_type,
+                                  name=name,
+                                  version=version,
+                                  last_modified=last_modified,
+                                  vistrail_id=vistrail_id,
+                                  id=id)
+            workflow.db_entity_id = entity_id
+            workflow.db_group = group
+            workflow.is_dirty = False
+            res[('workflow', id)] = workflow
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup'
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -1812,42 +1867,38 @@ class DBMashupSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            version = self.convertFromDB(row[2], 'long', 'int')
-            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            vtid = self.convertFromDB(row[4], 'long', 'int')
-            layout = self.convertFromDB(row[5], 'str', 'mediumtext')
-            geometry = self.convertFromDB(row[6], 'str', 'mediumtext')
-            has_seq = self.convertFromDB(row[7], 'int', 'int')
-            parent = self.convertFromDB(row[8], 'long', 'int')
-            entity_id = self.convertFromDB(row[9], 'long', 'int')
-            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_id = self.convertFromDB(row[1], 'long', 'int')
+            entity_type = self.convertFromDB(row[2], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[4], 'str', 'char(16)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[6], 'long', 'int')
+            group = self.convertFromDB(row[7], 'long', 'int')
             
-            mashup = DBMashup(name=name,
-                              version=version,
-                              type=type,
-                              vtid=vtid,
-                              layout=layout,
-                              geometry=geometry,
-                              has_seq=has_seq,
-                              id=id)
-            mashup.db_parent = parent
-            mashup.db_entity_id = entity_id
-            mashup.db_entity_type = entity_type
-            mashup.is_dirty = False
-            res[('mashup', id)] = mashup
+            workflow = DBWorkflow(entity_type=entity_type,
+                                  name=name,
+                                  version=version,
+                                  last_modified=last_modified,
+                                  vistrail_id=vistrail_id,
+                                  id=id)
+            workflow.db_entity_id = entity_id
+            workflow.db_group = group
+            workflow.is_dirty = False
+            res[('workflow', id)] = workflow
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('mashup_action', obj.db_parent) in all_objects:
-            p = all_objects[('mashup_action', obj.db_parent)]
-            p.db_add_mashup(obj)
+        if ('group', obj.db_group) in all_objects:
+            p = all_objects[('group', obj.db_group)]
+            p.db_add_workflow(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup'
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1857,36 +1908,27 @@ class DBMashupSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'long', 'int')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
-            columnMap['vtid'] = \
-                self.convertToDB(obj.db_vtid, 'long', 'int')
-        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
-            columnMap['layout'] = \
-                self.convertToDB(obj.db_layout, 'str', 'mediumtext')
-        if hasattr(obj, 'db_geometry') and obj.db_geometry is not None:
-            columnMap['geometry'] = \
-                self.convertToDB(obj.db_geometry, 'str', 'mediumtext')
-        if hasattr(obj, 'db_has_seq') and obj.db_has_seq is not None:
-            columnMap['has_seq'] = \
-                self.convertToDB(obj.db_has_seq, 'int', 'int')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        if hasattr(obj, 'db_group') and obj.db_group is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_group, 'long', 'int')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -1894,12 +1936,19 @@ class DBMashupSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup'
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1909,36 +1958,27 @@ class DBMashupSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'long', 'int')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
-            columnMap['vtid'] = \
-                self.convertToDB(obj.db_vtid, 'long', 'int')
-        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
-            columnMap['layout'] = \
-                self.convertToDB(obj.db_layout, 'str', 'mediumtext')
-        if hasattr(obj, 'db_geometry') and obj.db_geometry is not None:
-            columnMap['geometry'] = \
-                self.convertToDB(obj.db_geometry, 'str', 'mediumtext')
-        if hasattr(obj, 'db_has_seq') and obj.db_has_seq is not None:
-            columnMap['has_seq'] = \
-                self.convertToDB(obj.db_has_seq, 'int', 'int')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        if hasattr(obj, 'db_group') and obj.db_group is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_group, 'long', 'int')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -1948,14 +1988,34 @@ class DBMashupSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_aliases:
+        for child in obj.db_connections:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_plugin_datas:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_others:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_modules:
+            child.db_parentType = obj.vtType
             child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'mashup'
+        table = 'workflow'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -1964,18 +2024,18 @@ class DBMashupSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPortSpecItemSQLDAOBase(SQLDAO):
+class DBMashupActionSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'port_spec_item'
+        self.table = 'mashup_action'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'port_spec_item'
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
         whereMap = global_props
         orderBy = 'id'
 
@@ -1984,37 +2044,27 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            pos = self.convertFromDB(row[1], 'long', 'int')
-            module = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            label = self.convertFromDB(row[5], 'str', 'varchar(4095)')
-            default = self.convertFromDB(row[6], 'str', 'varchar(4095)')
-            values = self.convertFromDB(row[7], 'str', 'mediumtext')
-            entry_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
-            portSpec = self.convertFromDB(row[9], 'long', 'int')
-            entity_id = self.convertFromDB(row[10], 'long', 'int')
-            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            user = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[4], 'long', 'int')
+            entity_id = self.convertFromDB(row[5], 'long', 'int')
+            entity_type = self.convertFromDB(row[6], 'str', 'char(16)')
             
-            portSpecItem = DBPortSpecItem(pos=pos,
-                                          module=module,
-                                          package=package,
-                                          namespace=namespace,
-                                          label=label,
-                                          default=default,
-                                          values=values,
-                                          entry_type=entry_type,
-                                          id=id)
-            portSpecItem.db_portSpec = portSpec
-            portSpecItem.db_entity_id = entity_id
-            portSpecItem.db_entity_type = entity_type
-            portSpecItem.is_dirty = False
-            res[('portSpecItem', id)] = portSpecItem
+            mashup_action = DBMashupAction(prevId=prevId,
+                                           date=date,
+                                           user=user,
+                                           id=id)
+            mashup_action.db_mashuptrail = mashuptrail
+            mashup_action.db_entity_id = entity_id
+            mashup_action.db_entity_type = entity_type
+            mashup_action.is_dirty = False
+            res[('mashup_action', id)] = mashup_action
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'port_spec_item'
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -2023,44 +2073,34 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            pos = self.convertFromDB(row[1], 'long', 'int')
-            module = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            label = self.convertFromDB(row[5], 'str', 'varchar(4095)')
-            default = self.convertFromDB(row[6], 'str', 'varchar(4095)')
-            values = self.convertFromDB(row[7], 'str', 'mediumtext')
-            entry_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
-            portSpec = self.convertFromDB(row[9], 'long', 'int')
-            entity_id = self.convertFromDB(row[10], 'long', 'int')
-            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            user = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[4], 'long', 'int')
+            entity_id = self.convertFromDB(row[5], 'long', 'int')
+            entity_type = self.convertFromDB(row[6], 'str', 'char(16)')
             
-            portSpecItem = DBPortSpecItem(pos=pos,
-                                          module=module,
-                                          package=package,
-                                          namespace=namespace,
-                                          label=label,
-                                          default=default,
-                                          values=values,
-                                          entry_type=entry_type,
-                                          id=id)
-            portSpecItem.db_portSpec = portSpec
-            portSpecItem.db_entity_id = entity_id
-            portSpecItem.db_entity_type = entity_type
-            portSpecItem.is_dirty = False
-            res[('portSpecItem', id)] = portSpecItem
+            mashup_action = DBMashupAction(prevId=prevId,
+                                           date=date,
+                                           user=user,
+                                           id=id)
+            mashup_action.db_mashuptrail = mashuptrail
+            mashup_action.db_entity_id = entity_id
+            mashup_action.db_entity_type = entity_type
+            mashup_action.is_dirty = False
+            res[('mashup_action', id)] = mashup_action
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('portSpec', obj.db_portSpec) in all_objects:
-            p = all_objects[('portSpec', obj.db_portSpec)]
-            p.db_add_portSpecItem(obj)
+        if ('mashuptrail', obj.db_mashuptrail) in all_objects:
+            p = all_objects[('mashuptrail', obj.db_mashuptrail)]
+            p.db_add_action(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'port_spec_item'
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2070,33 +2110,18 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_module') and obj.db_module is not None:
-            columnMap['module'] = \
-                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_label') and obj.db_label is not None:
-            columnMap['label'] = \
-                self.convertToDB(obj.db_label, 'str', 'varchar(4095)')
-        if hasattr(obj, 'db_default') and obj.db_default is not None:
-            columnMap['_default'] = \
-                self.convertToDB(obj.db_default, 'str', 'varchar(4095)')
-        if hasattr(obj, 'db_values') and obj.db_values is not None:
-            columnMap['_values'] = \
-                self.convertToDB(obj.db_values, 'str', 'mediumtext')
-        if hasattr(obj, 'db_entry_type') and obj.db_entry_type is not None:
-            columnMap['entry_type'] = \
-                self.convertToDB(obj.db_entry_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_portSpec') and obj.db_portSpec is not None:
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_portSpec, 'long', 'int')
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -2114,8 +2139,8 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'port_spec_item'
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2125,33 +2150,18 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_module') and obj.db_module is not None:
-            columnMap['module'] = \
-                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_label') and obj.db_label is not None:
-            columnMap['label'] = \
-                self.convertToDB(obj.db_label, 'str', 'varchar(4095)')
-        if hasattr(obj, 'db_default') and obj.db_default is not None:
-            columnMap['_default'] = \
-                self.convertToDB(obj.db_default, 'str', 'varchar(4095)')
-        if hasattr(obj, 'db_values') and obj.db_values is not None:
-            columnMap['_values'] = \
-                self.convertToDB(obj.db_values, 'str', 'mediumtext')
-        if hasattr(obj, 'db_entry_type') and obj.db_entry_type is not None:
-            columnMap['entry_type'] = \
-                self.convertToDB(obj.db_entry_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_portSpec') and obj.db_portSpec is not None:
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_portSpec, 'long', 'int')
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -2170,10 +2180,12 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        if obj.db_mashup is not None:
+            child = obj.db_mashup
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'port_spec_item'
+        table = 'mashup_action'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2182,18 +2194,18 @@ class DBPortSpecItemSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMachineSQLDAOBase(SQLDAO):
+class DBChangeSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'machine'
+        self.table = 'change_tbl'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
-        table = 'machine'
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
         whereMap = global_props
         orderBy = 'id'
 
@@ -2202,33 +2214,31 @@ class DBMachineSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            os = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            architecture = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            processor = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            ram = self.convertFromDB(row[5], 'int', 'bigint')
-            vistrailId = self.convertFromDB(row[6], 'long', 'int')
-            log = self.convertFromDB(row[7], 'long', 'int')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            oldObjId = self.convertFromDB(row[2], 'long', 'int')
+            newObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjId = self.convertFromDB(row[4], 'long', 'int')
+            parentObjType = self.convertFromDB(row[5], 'str', 'char(16)')
+            action = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            machine = DBMachine(name=name,
-                                os=os,
-                                architecture=architecture,
-                                processor=processor,
-                                ram=ram,
-                                id=id)
-            machine.db_vistrailId = vistrailId
-            machine.db_log = log
-            machine.db_entity_id = entity_id
-            machine.db_entity_type = entity_type
-            machine.is_dirty = False
-            res[('machine', id)] = machine
+            change = DBChange(what=what,
+                              oldObjId=oldObjId,
+                              newObjId=newObjId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            change.db_action = action
+            change.db_entity_id = entity_id
+            change.db_entity_type = entity_type
+            change.is_dirty = False
+            res[('change', id)] = change
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
-        table = 'machine'
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -2237,40 +2247,38 @@ class DBMachineSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            os = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            architecture = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            processor = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            ram = self.convertFromDB(row[5], 'int', 'bigint')
-            vistrailId = self.convertFromDB(row[6], 'long', 'int')
-            log = self.convertFromDB(row[7], 'long', 'int')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            oldObjId = self.convertFromDB(row[2], 'long', 'int')
+            newObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjId = self.convertFromDB(row[4], 'long', 'int')
+            parentObjType = self.convertFromDB(row[5], 'str', 'char(16)')
+            action = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            machine = DBMachine(name=name,
-                                os=os,
-                                architecture=architecture,
-                                processor=processor,
-                                ram=ram,
-                                id=id)
-            machine.db_vistrailId = vistrailId
-            machine.db_log = log
-            machine.db_entity_id = entity_id
-            machine.db_entity_type = entity_type
-            machine.is_dirty = False
-            res[('machine', id)] = machine
+            change = DBChange(what=what,
+                              oldObjId=oldObjId,
+                              newObjId=newObjId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            change.db_action = action
+            change.db_entity_id = entity_id
+            change.db_entity_type = entity_type
+            change.is_dirty = False
+            res[('change', id)] = change
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('log', obj.db_log) in all_objects:
-            p = all_objects[('log', obj.db_log)]
-            p.db_add_machine(obj)
+        if ('action', obj.db_action) in all_objects:
+            p = all_objects[('action', obj.db_action)]
+            p.db_add_operation(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
-        table = 'machine'
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2280,27 +2288,24 @@ class DBMachineSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_os') and obj.db_os is not None:
-            columnMap['os'] = \
-                self.convertToDB(obj.db_os, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_architecture') and obj.db_architecture is not None:
-            columnMap['architecture'] = \
-                self.convertToDB(obj.db_architecture, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_processor') and obj.db_processor is not None:
-            columnMap['processor'] = \
-                self.convertToDB(obj.db_processor, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_ram') and obj.db_ram is not None:
-            columnMap['ram'] = \
-                self.convertToDB(obj.db_ram, 'int', 'bigint')
-        if hasattr(obj, 'db_vistrailId') and obj.db_vistrailId is not None:
-            columnMap['vt_id'] = \
-                self.convertToDB(obj.db_vistrailId, 'long', 'int')
-        if hasattr(obj, 'db_log') and obj.db_log is not None:
-            columnMap['log_id'] = \
-                self.convertToDB(obj.db_log, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_oldObjId') and obj.db_oldObjId is not None:
+            columnMap['old_obj_id'] = \
+                self.convertToDB(obj.db_oldObjId, 'long', 'int')
+        if hasattr(obj, 'db_newObjId') and obj.db_newObjId is not None:
+            columnMap['new_obj_id'] = \
+                self.convertToDB(obj.db_newObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -2318,8 +2323,8 @@ class DBMachineSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
-        table = 'machine'
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2329,27 +2334,24 @@ class DBMachineSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_os') and obj.db_os is not None:
-            columnMap['os'] = \
-                self.convertToDB(obj.db_os, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_architecture') and obj.db_architecture is not None:
-            columnMap['architecture'] = \
-                self.convertToDB(obj.db_architecture, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_processor') and obj.db_processor is not None:
-            columnMap['processor'] = \
-                self.convertToDB(obj.db_processor, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_ram') and obj.db_ram is not None:
-            columnMap['ram'] = \
-                self.convertToDB(obj.db_ram, 'int', 'bigint')
-        if hasattr(obj, 'db_vistrailId') and obj.db_vistrailId is not None:
-            columnMap['vt_id'] = \
-                self.convertToDB(obj.db_vistrailId, 'long', 'int')
-        if hasattr(obj, 'db_log') and obj.db_log is not None:
-            columnMap['log_id'] = \
-                self.convertToDB(obj.db_log, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_oldObjId') and obj.db_oldObjId is not None:
+            columnMap['old_obj_id'] = \
+                self.convertToDB(obj.db_oldObjId, 'long', 'int')
+        if hasattr(obj, 'db_newObjId') and obj.db_newObjId is not None:
+            columnMap['new_obj_id'] = \
+                self.convertToDB(obj.db_newObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -2368,10 +2370,13 @@ class DBMachineSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        if obj.db_data is not None:
+            child = obj.db_data
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'machine'
+        table = 'change_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2380,18 +2385,18 @@ class DBMachineSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBAddSQLDAOBase(SQLDAO):
+class DBPackageSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'add_tbl'
+        self.table = 'package'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'add_tbl'
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
         whereMap = global_props
         orderBy = 'id'
 
@@ -2400,29 +2405,33 @@ class DBAddSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            objectId = self.convertFromDB(row[2], 'long', 'int')
-            parentObjId = self.convertFromDB(row[3], 'long', 'int')
-            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
-            action = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            identifier = self.convertFromDB(row[2], 'str', 'varchar(1023)')
+            codepath = self.convertFromDB(row[3], 'str', 'varchar(1023)')
+            load_configuration = self.convertFromDB(row[4], 'int', 'int')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            description = self.convertFromDB(row[6], 'str', 'varchar(1023)')
+            registry = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            add = DBAdd(what=what,
-                        objectId=objectId,
-                        parentObjId=parentObjId,
-                        parentObjType=parentObjType,
-                        id=id)
-            add.db_action = action
-            add.db_entity_id = entity_id
-            add.db_entity_type = entity_type
-            add.is_dirty = False
-            res[('add', id)] = add
+            package = DBPackage(name=name,
+                                identifier=identifier,
+                                codepath=codepath,
+                                load_configuration=load_configuration,
+                                version=version,
+                                description=description,
+                                id=id)
+            package.db_registry = registry
+            package.db_entity_id = entity_id
+            package.db_entity_type = entity_type
+            package.is_dirty = False
+            res[('package', id)] = package
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'add_tbl'
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -2431,36 +2440,40 @@ class DBAddSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            objectId = self.convertFromDB(row[2], 'long', 'int')
-            parentObjId = self.convertFromDB(row[3], 'long', 'int')
-            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
-            action = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            identifier = self.convertFromDB(row[2], 'str', 'varchar(1023)')
+            codepath = self.convertFromDB(row[3], 'str', 'varchar(1023)')
+            load_configuration = self.convertFromDB(row[4], 'int', 'int')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            description = self.convertFromDB(row[6], 'str', 'varchar(1023)')
+            registry = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            add = DBAdd(what=what,
-                        objectId=objectId,
-                        parentObjId=parentObjId,
-                        parentObjType=parentObjType,
-                        id=id)
-            add.db_action = action
-            add.db_entity_id = entity_id
-            add.db_entity_type = entity_type
-            add.is_dirty = False
-            res[('add', id)] = add
+            package = DBPackage(name=name,
+                                identifier=identifier,
+                                codepath=codepath,
+                                load_configuration=load_configuration,
+                                version=version,
+                                description=description,
+                                id=id)
+            package.db_registry = registry
+            package.db_entity_id = entity_id
+            package.db_entity_type = entity_type
+            package.is_dirty = False
+            res[('package', id)] = package
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('action', obj.db_action) in all_objects:
-            p = all_objects[('action', obj.db_action)]
-            p.db_add_operation(obj)
+        if ('registry', obj.db_registry) in all_objects:
+            p = all_objects[('registry', obj.db_registry)]
+            p.db_add_package(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'add_tbl'
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2470,21 +2483,27 @@ class DBAddSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_what') and obj.db_what is not None:
-            columnMap['what'] = \
-                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
-            columnMap['object_id'] = \
-                self.convertToDB(obj.db_objectId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
-            columnMap['par_obj_id'] = \
-                self.convertToDB(obj.db_parentObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
-            columnMap['par_obj_type'] = \
-                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
-        if hasattr(obj, 'db_action') and obj.db_action is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_identifier') and obj.db_identifier is not None:
+            columnMap['identifier'] = \
+                self.convertToDB(obj.db_identifier, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_codepath') and obj.db_codepath is not None:
+            columnMap['codepath'] = \
+                self.convertToDB(obj.db_codepath, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_load_configuration') and obj.db_load_configuration is not None:
+            columnMap['load_configuration'] = \
+                self.convertToDB(obj.db_load_configuration, 'int', 'int')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_description') and obj.db_description is not None:
+            columnMap['description'] = \
+                self.convertToDB(obj.db_description, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_registry') and obj.db_registry is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_registry, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -2498,12 +2517,15 @@ class DBAddSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'add_tbl'
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2513,21 +2535,27 @@ class DBAddSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_what') and obj.db_what is not None:
-            columnMap['what'] = \
-                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
-            columnMap['object_id'] = \
-                self.convertToDB(obj.db_objectId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
-            columnMap['par_obj_id'] = \
-                self.convertToDB(obj.db_parentObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
-            columnMap['par_obj_type'] = \
-                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
-        if hasattr(obj, 'db_action') and obj.db_action is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_identifier') and obj.db_identifier is not None:
+            columnMap['identifier'] = \
+                self.convertToDB(obj.db_identifier, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_codepath') and obj.db_codepath is not None:
+            columnMap['codepath'] = \
+                self.convertToDB(obj.db_codepath, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_load_configuration') and obj.db_load_configuration is not None:
+            columnMap['load_configuration'] = \
+                self.convertToDB(obj.db_load_configuration, 'int', 'int')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_description') and obj.db_description is not None:
+            columnMap['description'] = \
+                self.convertToDB(obj.db_description, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_registry') and obj.db_registry is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_registry, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -2543,16 +2571,17 @@ class DBAddSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_data is not None:
-            child = obj.db_data
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
+        for child in obj.db_module_descriptors:
+            child.db_package = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'add_tbl'
+        table = 'package'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2561,18 +2590,18 @@ class DBAddSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBOtherSQLDAOBase(SQLDAO):
+class DBLoopExecSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'other'
+        self.table = 'loop_exec'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'other'
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
         whereMap = global_props
         orderBy = 'id'
 
@@ -2581,27 +2610,33 @@ class DBOtherSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            iteration = self.convertFromDB(row[3], 'int', 'int')
+            completed = self.convertFromDB(row[4], 'int', 'int')
+            error = self.convertFromDB(row[5], 'str', 'varchar(1023)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            other = DBOther(key=key,
-                            value=value,
-                            id=id)
-            other.db_parentType = parentType
-            other.db_entity_id = entity_id
-            other.db_entity_type = entity_type
-            other.db_parent = parent
-            other.is_dirty = False
-            res[('other', id)] = other
+            loop_exec = DBLoopExec(ts_start=ts_start,
+                                   ts_end=ts_end,
+                                   iteration=iteration,
+                                   completed=completed,
+                                   error=error,
+                                   id=id)
+            loop_exec.db_parentType = parentType
+            loop_exec.db_entity_id = entity_id
+            loop_exec.db_entity_type = entity_type
+            loop_exec.db_parent = parent
+            loop_exec.is_dirty = False
+            res[('loop_exec', id)] = loop_exec
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'other'
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -2610,40 +2645,49 @@ class DBOtherSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            iteration = self.convertFromDB(row[3], 'int', 'int')
+            completed = self.convertFromDB(row[4], 'int', 'int')
+            error = self.convertFromDB(row[5], 'str', 'varchar(1023)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
             
-            other = DBOther(key=key,
-                            value=value,
-                            id=id)
-            other.db_parentType = parentType
-            other.db_entity_id = entity_id
-            other.db_entity_type = entity_type
-            other.db_parent = parent
-            other.is_dirty = False
-            res[('other', id)] = other
+            loop_exec = DBLoopExec(ts_start=ts_start,
+                                   ts_end=ts_end,
+                                   iteration=iteration,
+                                   completed=completed,
+                                   error=error,
+                                   id=id)
+            loop_exec.db_parentType = parentType
+            loop_exec.db_entity_id = entity_id
+            loop_exec.db_entity_type = entity_type
+            loop_exec.db_parent = parent
+            loop_exec.is_dirty = False
+            res[('loop_exec', id)] = loop_exec
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow':
-            p = all_objects[('workflow', obj.db_parent)]
-            p.db_add_other(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
+        if obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'loop_exec':
+            p = all_objects[('loop_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'module_exec':
+            p = all_objects[('module_exec', obj.db_parent)]
+            p.db_add_loop_exec(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'other'
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2653,12 +2697,21 @@ class DBOtherSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['okey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_iteration') and obj.db_iteration is not None:
+            columnMap['iteration'] = \
+                self.convertToDB(obj.db_iteration, 'int', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -2682,8 +2735,8 @@ class DBOtherSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'other'
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2693,12 +2746,21 @@ class DBOtherSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['okey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_iteration') and obj.db_iteration is not None:
+            columnMap['iteration'] = \
+                self.convertToDB(obj.db_iteration, 'int', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -2723,10 +2785,12 @@ class DBOtherSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_item_execs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'other'
+        table = 'loop_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2735,18 +2799,18 @@ class DBOtherSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBLocationSQLDAOBase(SQLDAO):
+class DBConnectionSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'location'
+        self.table = 'connection_tbl'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'location'
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
         whereMap = global_props
         orderBy = 'id'
 
@@ -2755,27 +2819,23 @@ class DBLocationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            x = self.convertFromDB(row[1], 'float', 'DECIMAL(18,12)')
-            y = self.convertFromDB(row[2], 'float', 'DECIMAL(18,12)')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            parentType = self.convertFromDB(row[1], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[2], 'long', 'int')
+            entity_type = self.convertFromDB(row[3], 'str', 'char(16)')
+            parent = self.convertFromDB(row[4], 'long', 'long')
             
-            location = DBLocation(x=x,
-                                  y=y,
-                                  id=id)
-            location.db_parentType = parentType
-            location.db_entity_id = entity_id
-            location.db_entity_type = entity_type
-            location.db_parent = parent
-            location.is_dirty = False
-            res[('location', id)] = location
+            connection = DBConnection(id=id)
+            connection.db_parentType = parentType
+            connection.db_entity_id = entity_id
+            connection.db_entity_type = entity_type
+            connection.db_parent = parent
+            connection.is_dirty = False
+            res[('connection', id)] = connection
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'location'
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -2784,34 +2844,24 @@ class DBLocationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            x = self.convertFromDB(row[1], 'float', 'DECIMAL(18,12)')
-            y = self.convertFromDB(row[2], 'float', 'DECIMAL(18,12)')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            parentType = self.convertFromDB(row[1], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[2], 'long', 'int')
+            entity_type = self.convertFromDB(row[3], 'str', 'char(16)')
+            parent = self.convertFromDB(row[4], 'long', 'long')
             
-            location = DBLocation(x=x,
-                                  y=y,
-                                  id=id)
-            location.db_parentType = parentType
-            location.db_entity_id = entity_id
-            location.db_entity_type = entity_type
-            location.db_parent = parent
-            location.is_dirty = False
-            res[('location', id)] = location
+            connection = DBConnection(id=id)
+            connection.db_parentType = parentType
+            connection.db_entity_id = entity_id
+            connection.db_entity_type = entity_type
+            connection.db_parent = parent
+            connection.is_dirty = False
+            res[('connection', id)] = connection
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'module':
-            p = all_objects[('module', obj.db_parent)]
-            p.db_add_location(obj)
-        elif obj.db_parentType == 'abstraction':
-            p = all_objects[('abstraction', obj.db_parent)]
-            p.db_add_location(obj)
-        elif obj.db_parentType == 'group':
-            p = all_objects[('group', obj.db_parent)]
-            p.db_add_location(obj)
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_connection(obj)
         elif obj.db_parentType == 'add':
             p = all_objects[('add', obj.db_parent)]
             p.db_add_data(obj)
@@ -2822,8 +2872,8 @@ class DBLocationSQLDAOBase(SQLDAO):
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'location'
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2833,12 +2883,6 @@ class DBLocationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_x') and obj.db_x is not None:
-            columnMap['x'] = \
-                self.convertToDB(obj.db_x, 'float', 'DECIMAL(18,12)')
-        if hasattr(obj, 'db_y') and obj.db_y is not None:
-            columnMap['y'] = \
-                self.convertToDB(obj.db_y, 'float', 'DECIMAL(18,12)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -2862,8 +2906,8 @@ class DBLocationSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'location'
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2873,12 +2917,6 @@ class DBLocationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_x') and obj.db_x is not None:
-            columnMap['x'] = \
-                self.convertToDB(obj.db_x, 'float', 'DECIMAL(18,12)')
-        if hasattr(obj, 'db_y') and obj.db_y is not None:
-            columnMap['y'] = \
-                self.convertToDB(obj.db_y, 'float', 'DECIMAL(18,12)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -2903,10 +2941,12 @@ class DBLocationSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_ports:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'location'
+        table = 'connection_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -2915,18 +2955,18 @@ class DBLocationSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPEParameterSQLDAOBase(SQLDAO):
+class DBActionSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'pe_parameter'
+        self.table = 'action'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_parameter'
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
         whereMap = global_props
         orderBy = 'id'
 
@@ -2935,31 +2975,29 @@ class DBPEParameterSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            pos = self.convertFromDB(row[1], 'long', 'int')
-            interpolator = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[3], 'str', 'mediumtext')
-            dimension = self.convertFromDB(row[4], 'long', 'int')
-            parentType = self.convertFromDB(row[5], 'str', 'char(32)')
-            pe_function = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            pe_parameter = DBPEParameter(pos=pos,
-                                         interpolator=interpolator,
-                                         value=value,
-                                         dimension=dimension,
-                                         id=id)
-            pe_parameter.db_parentType = parentType
-            pe_parameter.db_pe_function = pe_function
-            pe_parameter.db_entity_id = entity_id
-            pe_parameter.db_entity_type = entity_type
-            pe_parameter.is_dirty = False
-            res[('pe_parameter', id)] = pe_parameter
+            action = DBAction(prevId=prevId,
+                              date=date,
+                              session=session,
+                              user=user,
+                              id=id)
+            action.db_vistrail = vistrail
+            action.db_entity_id = entity_id
+            action.db_entity_type = entity_type
+            action.is_dirty = False
+            res[('action', id)] = action
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_parameter'
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -2968,38 +3006,36 @@ class DBPEParameterSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            pos = self.convertFromDB(row[1], 'long', 'int')
-            interpolator = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[3], 'str', 'mediumtext')
-            dimension = self.convertFromDB(row[4], 'long', 'int')
-            parentType = self.convertFromDB(row[5], 'str', 'char(32)')
-            pe_function = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            pe_parameter = DBPEParameter(pos=pos,
-                                         interpolator=interpolator,
-                                         value=value,
-                                         dimension=dimension,
-                                         id=id)
-            pe_parameter.db_parentType = parentType
-            pe_parameter.db_pe_function = pe_function
-            pe_parameter.db_entity_id = entity_id
-            pe_parameter.db_entity_type = entity_type
-            pe_parameter.is_dirty = False
-            res[('pe_parameter', id)] = pe_parameter
+            action = DBAction(prevId=prevId,
+                              date=date,
+                              session=session,
+                              user=user,
+                              id=id)
+            action.db_vistrail = vistrail
+            action.db_entity_id = entity_id
+            action.db_entity_type = entity_type
+            action.is_dirty = False
+            res[('action', id)] = action
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('pe_function', obj.db_pe_function) in all_objects:
-            p = all_objects[('pe_function', obj.db_pe_function)]
-            p.db_add_parameter(obj)
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_action(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_parameter'
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3009,24 +3045,21 @@ class DBPEParameterSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_interpolator') and obj.db_interpolator is not None:
-            columnMap['interpolator'] = \
-                self.convertToDB(obj.db_interpolator, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'mediumtext')
-        if hasattr(obj, 'db_dimension') and obj.db_dimension is not None:
-            columnMap['dimension'] = \
-                self.convertToDB(obj.db_dimension, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_pe_function') and obj.db_pe_function is not None:
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_pe_function, 'long', 'int')
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -3044,8 +3077,8 @@ class DBPEParameterSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_parameter'
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3055,24 +3088,21 @@ class DBPEParameterSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_interpolator') and obj.db_interpolator is not None:
-            columnMap['interpolator'] = \
-                self.convertToDB(obj.db_interpolator, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'mediumtext')
-        if hasattr(obj, 'db_dimension') and obj.db_dimension is not None:
-            columnMap['dimension'] = \
-                self.convertToDB(obj.db_dimension, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_pe_function') and obj.db_pe_function is not None:
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_pe_function, 'long', 'int')
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -3091,10 +3121,14 @@ class DBPEParameterSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_operations:
+            child.db_action = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'pe_parameter'
+        table = 'action'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3103,18 +3137,18 @@ class DBPEParameterSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBParameterSQLDAOBase(SQLDAO):
+class DBPortSpecSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'parameter'
+        self.table = 'port_spec'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'parameter'
+        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
         whereMap = global_props
         orderBy = 'id'
 
@@ -3123,33 +3157,35 @@ class DBParameterSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            pos = self.convertFromDB(row[1], 'long', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            val = self.convertFromDB(row[4], 'str', 'mediumtext')
-            alias = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
-            
-            parameter = DBParameter(pos=pos,
-                                    name=name,
-                                    type=type,
-                                    val=val,
-                                    alias=alias,
-                                    id=id)
-            parameter.db_parentType = parentType
-            parameter.db_entity_id = entity_id
-            parameter.db_entity_type = entity_type
-            parameter.db_parent = parent
-            parameter.is_dirty = False
-            res[('parameter', id)] = parameter
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            optional = self.convertFromDB(row[3], 'int', 'int')
+            sort_key = self.convertFromDB(row[4], 'int', 'int')
+            min_conns = self.convertFromDB(row[5], 'int', 'int')
+            max_conns = self.convertFromDB(row[6], 'int', 'int')
+            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            parent = self.convertFromDB(row[10], 'long', 'long')
+            
+            portSpec = DBPortSpec(name=name,
+                                  type=type,
+                                  optional=optional,
+                                  sort_key=sort_key,
+                                  min_conns=min_conns,
+                                  max_conns=max_conns,
+                                  id=id)
+            portSpec.db_parentType = parentType
+            portSpec.db_entity_id = entity_id
+            portSpec.db_entity_type = entity_type
+            portSpec.db_parent = parent
+            portSpec.is_dirty = False
+            res[('portSpec', id)] = portSpec
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'parameter'
+        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -3158,34 +3194,39 @@ class DBParameterSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            pos = self.convertFromDB(row[1], 'long', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            val = self.convertFromDB(row[4], 'str', 'mediumtext')
-            alias = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            optional = self.convertFromDB(row[3], 'int', 'int')
+            sort_key = self.convertFromDB(row[4], 'int', 'int')
+            min_conns = self.convertFromDB(row[5], 'int', 'int')
+            max_conns = self.convertFromDB(row[6], 'int', 'int')
+            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            parent = self.convertFromDB(row[10], 'long', 'long')
             
-            parameter = DBParameter(pos=pos,
-                                    name=name,
-                                    type=type,
-                                    val=val,
-                                    alias=alias,
-                                    id=id)
-            parameter.db_parentType = parentType
-            parameter.db_entity_id = entity_id
-            parameter.db_entity_type = entity_type
-            parameter.db_parent = parent
-            parameter.is_dirty = False
-            res[('parameter', id)] = parameter
+            portSpec = DBPortSpec(name=name,
+                                  type=type,
+                                  optional=optional,
+                                  sort_key=sort_key,
+                                  min_conns=min_conns,
+                                  max_conns=max_conns,
+                                  id=id)
+            portSpec.db_parentType = parentType
+            portSpec.db_entity_id = entity_id
+            portSpec.db_entity_type = entity_type
+            portSpec.db_parent = parent
+            portSpec.is_dirty = False
+            res[('portSpec', id)] = portSpec
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'function':
-            p = all_objects[('function', obj.db_parent)]
-            p.db_add_parameter(obj)
+        if obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_portSpec(obj)
+        elif obj.db_parentType == 'module_descriptor':
+            p = all_objects[('module_descriptor', obj.db_parent)]
+            p.db_add_portSpec(obj)
         elif obj.db_parentType == 'add':
             p = all_objects[('add', obj.db_parent)]
             p.db_add_data(obj)
@@ -3196,8 +3237,8 @@ class DBParameterSQLDAOBase(SQLDAO):
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'parameter'
+        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3207,21 +3248,24 @@ class DBParameterSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
         if hasattr(obj, 'db_type') and obj.db_type is not None:
             columnMap['type'] = \
                 self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_val') and obj.db_val is not None:
-            columnMap['val'] = \
-                self.convertToDB(obj.db_val, 'str', 'mediumtext')
-        if hasattr(obj, 'db_alias') and obj.db_alias is not None:
-            columnMap['alias'] = \
-                self.convertToDB(obj.db_alias, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_optional') and obj.db_optional is not None:
+            columnMap['optional'] = \
+                self.convertToDB(obj.db_optional, 'int', 'int')
+        if hasattr(obj, 'db_sort_key') and obj.db_sort_key is not None:
+            columnMap['sort_key'] = \
+                self.convertToDB(obj.db_sort_key, 'int', 'int')
+        if hasattr(obj, 'db_min_conns') and obj.db_min_conns is not None:
+            columnMap['min_conns'] = \
+                self.convertToDB(obj.db_min_conns, 'int', 'int')
+        if hasattr(obj, 'db_max_conns') and obj.db_max_conns is not None:
+            columnMap['max_conns'] = \
+                self.convertToDB(obj.db_max_conns, 'int', 'int')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -3245,8 +3289,8 @@ class DBParameterSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'parameter'
+        columns = ['id', 'name', 'type', 'optional', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3256,21 +3300,24 @@ class DBParameterSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
         if hasattr(obj, 'db_type') and obj.db_type is not None:
             columnMap['type'] = \
                 self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_val') and obj.db_val is not None:
-            columnMap['val'] = \
-                self.convertToDB(obj.db_val, 'str', 'mediumtext')
-        if hasattr(obj, 'db_alias') and obj.db_alias is not None:
-            columnMap['alias'] = \
-                self.convertToDB(obj.db_alias, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_optional') and obj.db_optional is not None:
+            columnMap['optional'] = \
+                self.convertToDB(obj.db_optional, 'int', 'int')
+        if hasattr(obj, 'db_sort_key') and obj.db_sort_key is not None:
+            columnMap['sort_key'] = \
+                self.convertToDB(obj.db_sort_key, 'int', 'int')
+        if hasattr(obj, 'db_min_conns') and obj.db_min_conns is not None:
+            columnMap['min_conns'] = \
+                self.convertToDB(obj.db_min_conns, 'int', 'int')
+        if hasattr(obj, 'db_max_conns') and obj.db_max_conns is not None:
+            columnMap['max_conns'] = \
+                self.convertToDB(obj.db_max_conns, 'int', 'int')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -3295,10 +3342,11 @@ class DBParameterSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_portSpecItems:
+            child.db_portSpec = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'parameter'
+        table = 'port_spec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3307,18 +3355,18 @@ class DBParameterSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPluginDataSQLDAOBase(SQLDAO):
+class DBLogSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'plugin_data'
+        self.table = 'log_tbl'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'plugin_data'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
         whereMap = global_props
         orderBy = 'id'
 
@@ -3327,25 +3375,27 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            data = self.convertFromDB(row[1], 'str', 'varchar(8191)')
-            parentType = self.convertFromDB(row[2], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[3], 'long', 'int')
-            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
-            parent = self.convertFromDB(row[5], 'long', 'long')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[5], 'long', 'int')
             
-            plugin_data = DBPluginData(data=data,
-                                       id=id)
-            plugin_data.db_parentType = parentType
-            plugin_data.db_entity_id = entity_id
-            plugin_data.db_entity_type = entity_type
-            plugin_data.db_parent = parent
-            plugin_data.is_dirty = False
-            res[('plugin_data', id)] = plugin_data
+            log = DBLog(entity_type=entity_type,
+                        version=version,
+                        name=name,
+                        last_modified=last_modified,
+                        vistrail_id=vistrail_id,
+                        id=id)
+            log.is_dirty = False
+            res[('log', id)] = log
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'plugin_data'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -3354,38 +3404,32 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            data = self.convertFromDB(row[1], 'str', 'varchar(8191)')
-            parentType = self.convertFromDB(row[2], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[3], 'long', 'int')
-            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
-            parent = self.convertFromDB(row[5], 'long', 'long')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[5], 'long', 'int')
             
-            plugin_data = DBPluginData(data=data,
-                                       id=id)
-            plugin_data.db_parentType = parentType
-            plugin_data.db_entity_id = entity_id
-            plugin_data.db_entity_type = entity_type
-            plugin_data.db_parent = parent
-            plugin_data.is_dirty = False
-            res[('plugin_data', id)] = plugin_data
+            log = DBLog(entity_type=entity_type,
+                        version=version,
+                        name=name,
+                        last_modified=last_modified,
+                        vistrail_id=vistrail_id,
+                        id=id)
+            log.is_dirty = False
+            res[('log', id)] = log
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow':
-            p = all_objects[('workflow', obj.db_parent)]
-            p.db_add_plugin_data(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
-        
+        pass
+    
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'plugin_data'
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3395,21 +3439,21 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_data') and obj.db_data is not None:
-            columnMap['data'] = \
-                self.convertToDB(obj.db_data, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -3417,12 +3461,19 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        
-    def set_sql_command(self, db, obj, global_props, do_copy=True):
-        if not do_copy and not obj.is_dirty:
-            return None
-        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'plugin_data'
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3432,21 +3483,21 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_data') and obj.db_data is not None:
-            columnMap['data'] = \
-                self.convertToDB(obj.db_data, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -3456,13 +3507,23 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_workflow_execs:
+            child.db_log = obj.db_id
+        for child in obj.db_machines:
+            child.db_log = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'plugin_data'
+        table = 'log_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3471,18 +3532,18 @@ class DBPluginDataSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBFunctionSQLDAOBase(SQLDAO):
+class DBPEParameterSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'function'
+        self.table = 'pe_parameter'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'function'
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
         whereMap = global_props
         orderBy = 'id'
 
@@ -3492,26 +3553,30 @@ class DBFunctionSQLDAOBase(SQLDAO):
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
             pos = self.convertFromDB(row[1], 'long', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            interpolator = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[3], 'str', 'mediumtext')
+            dimension = self.convertFromDB(row[4], 'long', 'int')
+            parentType = self.convertFromDB(row[5], 'str', 'char(32)')
+            pe_function = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            function = DBFunction(pos=pos,
-                                  name=name,
-                                  id=id)
-            function.db_parentType = parentType
-            function.db_entity_id = entity_id
-            function.db_entity_type = entity_type
-            function.db_parent = parent
-            function.is_dirty = False
-            res[('function', id)] = function
+            pe_parameter = DBPEParameter(pos=pos,
+                                         interpolator=interpolator,
+                                         value=value,
+                                         dimension=dimension,
+                                         id=id)
+            pe_parameter.db_parentType = parentType
+            pe_parameter.db_pe_function = pe_function
+            pe_parameter.db_entity_id = entity_id
+            pe_parameter.db_entity_type = entity_type
+            pe_parameter.is_dirty = False
+            res[('pe_parameter', id)] = pe_parameter
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'function'
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -3521,45 +3586,37 @@ class DBFunctionSQLDAOBase(SQLDAO):
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
             pos = self.convertFromDB(row[1], 'long', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            interpolator = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[3], 'str', 'mediumtext')
+            dimension = self.convertFromDB(row[4], 'long', 'int')
+            parentType = self.convertFromDB(row[5], 'str', 'char(32)')
+            pe_function = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            function = DBFunction(pos=pos,
-                                  name=name,
-                                  id=id)
-            function.db_parentType = parentType
-            function.db_entity_id = entity_id
-            function.db_entity_type = entity_type
-            function.db_parent = parent
-            function.is_dirty = False
-            res[('function', id)] = function
+            pe_parameter = DBPEParameter(pos=pos,
+                                         interpolator=interpolator,
+                                         value=value,
+                                         dimension=dimension,
+                                         id=id)
+            pe_parameter.db_parentType = parentType
+            pe_parameter.db_pe_function = pe_function
+            pe_parameter.db_entity_id = entity_id
+            pe_parameter.db_entity_type = entity_type
+            pe_parameter.is_dirty = False
+            res[('pe_parameter', id)] = pe_parameter
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'module':
-            p = all_objects[('module', obj.db_parent)]
-            p.db_add_function(obj)
-        elif obj.db_parentType == 'abstraction':
-            p = all_objects[('abstraction', obj.db_parent)]
-            p.db_add_function(obj)
-        elif obj.db_parentType == 'group':
-            p = all_objects[('group', obj.db_parent)]
-            p.db_add_function(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
+        if ('pe_function', obj.db_pe_function) in all_objects:
+            p = all_objects[('pe_function', obj.db_pe_function)]
+            p.db_add_parameter(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'function'
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3572,21 +3629,27 @@ class DBFunctionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_pos') and obj.db_pos is not None:
             columnMap['pos'] = \
                 self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_interpolator') and obj.db_interpolator is not None:
+            columnMap['interpolator'] = \
+                self.convertToDB(obj.db_interpolator, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_dimension') and obj.db_dimension is not None:
+            columnMap['dimension'] = \
+                self.convertToDB(obj.db_dimension, 'long', 'int')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_pe_function') and obj.db_pe_function is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_pe_function, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -3598,8 +3661,8 @@ class DBFunctionSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'function'
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3612,21 +3675,27 @@ class DBFunctionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_pos') and obj.db_pos is not None:
             columnMap['pos'] = \
                 self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_interpolator') and obj.db_interpolator is not None:
+            columnMap['interpolator'] = \
+                self.convertToDB(obj.db_interpolator, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_dimension') and obj.db_dimension is not None:
+            columnMap['dimension'] = \
+                self.convertToDB(obj.db_dimension, 'long', 'int')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_pe_function') and obj.db_pe_function is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_pe_function, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -3639,12 +3708,10 @@ class DBFunctionSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_parameters:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'function'
+        table = 'pe_parameter'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3653,18 +3720,18 @@ class DBFunctionSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBActionAnnotationSQLDAOBase(SQLDAO):
+class DBWorkflowExecSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'action_annotation'
+        self.table = 'workflow_exec'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action_annotation'
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
         whereMap = global_props
         orderBy = 'id'
 
@@ -3673,71 +3740,95 @@ class DBActionAnnotationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
-            action_id = self.convertFromDB(row[3], 'long', 'int')
-            date = self.convertFromDB(row[4], 'datetime', 'datetime')
-            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            user = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            ip = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            vt_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ts_start = self.convertFromDB(row[5], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[6], 'datetime', 'datetime')
+            parent_id = self.convertFromDB(row[7], 'long', 'int')
+            parent_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            parent_version = self.convertFromDB(row[9], 'long', 'int')
+            completed = self.convertFromDB(row[10], 'int', 'int')
+            name = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            log = self.convertFromDB(row[12], 'long', 'int')
+            entity_id = self.convertFromDB(row[13], 'long', 'int')
+            entity_type = self.convertFromDB(row[14], 'str', 'char(16)')
             
-            actionAnnotation = DBActionAnnotation(key=key,
-                                                  value=value,
-                                                  action_id=action_id,
-                                                  date=date,
-                                                  user=user,
-                                                  id=id)
-            actionAnnotation.db_vistrail = vistrail
-            actionAnnotation.db_entity_id = entity_id
-            actionAnnotation.db_entity_type = entity_type
-            actionAnnotation.is_dirty = False
-            res[('actionAnnotation', id)] = actionAnnotation
-        return res
-
-    def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action_annotation'
-        whereMap = global_props
-        orderBy = 'id'
-        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
-
-    def process_sql_columns(self, data, global_props):
-        res = {}
-        for row in data:
-            id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
-            action_id = self.convertFromDB(row[3], 'long', 'int')
-            date = self.convertFromDB(row[4], 'datetime', 'datetime')
-            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            workflow_exec = DBWorkflowExec(user=user,
+                                           ip=ip,
+                                           session=session,
+                                           vt_version=vt_version,
+                                           ts_start=ts_start,
+                                           ts_end=ts_end,
+                                           parent_id=parent_id,
+                                           parent_type=parent_type,
+                                           parent_version=parent_version,
+                                           completed=completed,
+                                           name=name,
+                                           id=id)
+            workflow_exec.db_log = log
+            workflow_exec.db_entity_id = entity_id
+            workflow_exec.db_entity_type = entity_type
+            workflow_exec.is_dirty = False
+            res[('workflow_exec', id)] = workflow_exec
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            user = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            ip = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            vt_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ts_start = self.convertFromDB(row[5], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[6], 'datetime', 'datetime')
+            parent_id = self.convertFromDB(row[7], 'long', 'int')
+            parent_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            parent_version = self.convertFromDB(row[9], 'long', 'int')
+            completed = self.convertFromDB(row[10], 'int', 'int')
+            name = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            log = self.convertFromDB(row[12], 'long', 'int')
+            entity_id = self.convertFromDB(row[13], 'long', 'int')
+            entity_type = self.convertFromDB(row[14], 'str', 'char(16)')
             
-            actionAnnotation = DBActionAnnotation(key=key,
-                                                  value=value,
-                                                  action_id=action_id,
-                                                  date=date,
-                                                  user=user,
-                                                  id=id)
-            actionAnnotation.db_vistrail = vistrail
-            actionAnnotation.db_entity_id = entity_id
-            actionAnnotation.db_entity_type = entity_type
-            actionAnnotation.is_dirty = False
-            res[('actionAnnotation', id)] = actionAnnotation
+            workflow_exec = DBWorkflowExec(user=user,
+                                           ip=ip,
+                                           session=session,
+                                           vt_version=vt_version,
+                                           ts_start=ts_start,
+                                           ts_end=ts_end,
+                                           parent_id=parent_id,
+                                           parent_type=parent_type,
+                                           parent_version=parent_version,
+                                           completed=completed,
+                                           name=name,
+                                           id=id)
+            workflow_exec.db_log = log
+            workflow_exec.db_entity_id = entity_id
+            workflow_exec.db_entity_type = entity_type
+            workflow_exec.is_dirty = False
+            res[('workflow_exec', id)] = workflow_exec
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('vistrail', obj.db_vistrail) in all_objects:
-            p = all_objects[('vistrail', obj.db_vistrail)]
-            p.db_add_actionAnnotation(obj)
+        if ('log', obj.db_log) in all_objects:
+            p = all_objects[('log', obj.db_log)]
+            p.db_add_workflow_exec(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action_annotation'
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3747,24 +3838,42 @@ class DBActionAnnotationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['akey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action_id, 'long', 'int')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
         if hasattr(obj, 'db_user') and obj.db_user is not None:
             columnMap['user'] = \
                 self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+        if hasattr(obj, 'db_ip') and obj.db_ip is not None:
+            columnMap['ip'] = \
+                self.convertToDB(obj.db_ip, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_vt_version') and obj.db_vt_version is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vt_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_parent_id') and obj.db_parent_id is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+                self.convertToDB(obj.db_parent_id, 'long', 'int')
+        if hasattr(obj, 'db_parent_type') and obj.db_parent_type is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parent_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parent_version') and obj.db_parent_version is not None:
+            columnMap['parent_version'] = \
+                self.convertToDB(obj.db_parent_version, 'long', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_log') and obj.db_log is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_log, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -3782,8 +3891,8 @@ class DBActionAnnotationSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action_annotation'
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3793,24 +3902,42 @@ class DBActionAnnotationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['akey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action_id, 'long', 'int')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
         if hasattr(obj, 'db_user') and obj.db_user is not None:
             columnMap['user'] = \
                 self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+        if hasattr(obj, 'db_ip') and obj.db_ip is not None:
+            columnMap['ip'] = \
+                self.convertToDB(obj.db_ip, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_vt_version') and obj.db_vt_version is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vt_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_parent_id') and obj.db_parent_id is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+                self.convertToDB(obj.db_parent_id, 'long', 'int')
+        if hasattr(obj, 'db_parent_type') and obj.db_parent_type is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parent_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parent_version') and obj.db_parent_version is not None:
+            columnMap['parent_version'] = \
+                self.convertToDB(obj.db_parent_version, 'long', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_log') and obj.db_log is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_log, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -3829,10 +3956,15 @@ class DBActionAnnotationSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_item_execs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'action_annotation'
+        table = 'workflow_exec'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3841,18 +3973,18 @@ class DBActionAnnotationSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBAbstractionSQLDAOBase(SQLDAO):
+class DBLocationSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'abstraction'
+        self.table = 'location'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'abstraction'
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
         whereMap = global_props
         orderBy = 'id'
 
@@ -3861,35 +3993,27 @@ class DBAbstractionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            cache = self.convertFromDB(row[1], 'int', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            internal_version = self.convertFromDB(row[6], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
-            parent = self.convertFromDB(row[10], 'long', 'long')
+            x = self.convertFromDB(row[1], 'float', 'DECIMAL(18,12)')
+            y = self.convertFromDB(row[2], 'float', 'DECIMAL(18,12)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            abstraction = DBAbstraction(cache=cache,
-                                        name=name,
-                                        namespace=namespace,
-                                        package=package,
-                                        version=version,
-                                        internal_version=internal_version,
-                                        id=id)
-            abstraction.db_parentType = parentType
-            abstraction.db_entity_id = entity_id
-            abstraction.db_entity_type = entity_type
-            abstraction.db_parent = parent
-            abstraction.is_dirty = False
-            res[('abstraction', id)] = abstraction
+            location = DBLocation(x=x,
+                                  y=y,
+                                  id=id)
+            location.db_parentType = parentType
+            location.db_entity_id = entity_id
+            location.db_entity_type = entity_type
+            location.db_parent = parent
+            location.is_dirty = False
+            res[('location', id)] = location
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'abstraction'
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -3898,36 +4022,34 @@ class DBAbstractionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            cache = self.convertFromDB(row[1], 'int', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            internal_version = self.convertFromDB(row[6], 'str', 'varchar(255)')
-            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
-            parent = self.convertFromDB(row[10], 'long', 'long')
+            x = self.convertFromDB(row[1], 'float', 'DECIMAL(18,12)')
+            y = self.convertFromDB(row[2], 'float', 'DECIMAL(18,12)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            abstraction = DBAbstraction(cache=cache,
-                                        name=name,
-                                        namespace=namespace,
-                                        package=package,
-                                        version=version,
-                                        internal_version=internal_version,
-                                        id=id)
-            abstraction.db_parentType = parentType
-            abstraction.db_entity_id = entity_id
-            abstraction.db_entity_type = entity_type
-            abstraction.db_parent = parent
-            abstraction.is_dirty = False
-            res[('abstraction', id)] = abstraction
+            location = DBLocation(x=x,
+                                  y=y,
+                                  id=id)
+            location.db_parentType = parentType
+            location.db_entity_id = entity_id
+            location.db_entity_type = entity_type
+            location.db_parent = parent
+            location.is_dirty = False
+            res[('location', id)] = location
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow':
-            p = all_objects[('workflow', obj.db_parent)]
-            p.db_add_module(obj)
+        if obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_location(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_location(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_location(obj)
         elif obj.db_parentType == 'add':
             p = all_objects[('add', obj.db_parent)]
             p.db_add_data(obj)
@@ -3938,8 +4060,8 @@ class DBAbstractionSQLDAOBase(SQLDAO):
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'abstraction'
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -3949,24 +4071,12 @@ class DBAbstractionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
-            columnMap['cache'] = \
-                self.convertToDB(obj.db_cache, 'int', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_internal_version') and obj.db_internal_version is not None:
-            columnMap['internal_version'] = \
-                self.convertToDB(obj.db_internal_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_x') and obj.db_x is not None:
+            columnMap['x'] = \
+                self.convertToDB(obj.db_x, 'float', 'DECIMAL(18,12)')
+        if hasattr(obj, 'db_y') and obj.db_y is not None:
+            columnMap['y'] = \
+                self.convertToDB(obj.db_y, 'float', 'DECIMAL(18,12)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -3990,8 +4100,8 @@ class DBAbstractionSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'abstraction'
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4001,24 +4111,12 @@ class DBAbstractionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
-            columnMap['cache'] = \
-                self.convertToDB(obj.db_cache, 'int', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
-            columnMap['namespace'] = \
-                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_package') and obj.db_package is not None:
-            columnMap['package'] = \
-                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_internal_version') and obj.db_internal_version is not None:
-            columnMap['internal_version'] = \
-                self.convertToDB(obj.db_internal_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_x') and obj.db_x is not None:
+            columnMap['x'] = \
+                self.convertToDB(obj.db_x, 'float', 'DECIMAL(18,12)')
+        if hasattr(obj, 'db_y') and obj.db_y is not None:
+            columnMap['y'] = \
+                self.convertToDB(obj.db_y, 'float', 'DECIMAL(18,12)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -4043,19 +4141,10 @@ class DBAbstractionSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_location is not None:
-            child = obj.db_location
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_functions:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'abstraction'
+        table = 'location'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4064,18 +4153,18 @@ class DBAbstractionSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBWorkflowSQLDAOBase(SQLDAO):
+class DBFunctionSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'workflow'
+        self.table = 'function'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
-        table = 'workflow'
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
         whereMap = global_props
         orderBy = 'id'
 
@@ -4084,31 +4173,27 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_id = self.convertFromDB(row[1], 'long', 'int')
-            entity_type = self.convertFromDB(row[2], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            version = self.convertFromDB(row[4], 'str', 'char(16)')
-            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
-            vistrail_id = self.convertFromDB(row[6], 'long', 'int')
-            group = self.convertFromDB(row[7], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            workflow = DBWorkflow(entity_type=entity_type,
+            function = DBFunction(pos=pos,
                                   name=name,
-                                  version=version,
-                                  last_modified=last_modified,
-                                  vistrail_id=vistrail_id,
                                   id=id)
-            workflow.db_entity_id = entity_id
-            workflow.db_group = group
-            workflow.is_dirty = False
-            res[('workflow', id)] = workflow
+            function.db_parentType = parentType
+            function.db_entity_id = entity_id
+            function.db_entity_type = entity_type
+            function.db_parent = parent
+            function.is_dirty = False
+            res[('function', id)] = function
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
-        table = 'workflow'
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -4117,38 +4202,46 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_id = self.convertFromDB(row[1], 'long', 'int')
-            entity_type = self.convertFromDB(row[2], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            version = self.convertFromDB(row[4], 'str', 'char(16)')
-            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
-            vistrail_id = self.convertFromDB(row[6], 'long', 'int')
-            group = self.convertFromDB(row[7], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            workflow = DBWorkflow(entity_type=entity_type,
+            function = DBFunction(pos=pos,
                                   name=name,
-                                  version=version,
-                                  last_modified=last_modified,
-                                  vistrail_id=vistrail_id,
                                   id=id)
-            workflow.db_entity_id = entity_id
-            workflow.db_group = group
-            workflow.is_dirty = False
-            res[('workflow', id)] = workflow
+            function.db_parentType = parentType
+            function.db_entity_id = entity_id
+            function.db_entity_type = entity_type
+            function.db_parent = parent
+            function.is_dirty = False
+            res[('function', id)] = function
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('group', obj.db_group) in all_objects:
-            p = all_objects[('group', obj.db_group)]
-            p.db_add_workflow(obj)
+        if obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_function(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_function(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_function(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
-        table = 'workflow'
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4158,27 +4251,24 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
-        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
-            columnMap['vistrail_id'] = \
-                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
-        if hasattr(obj, 'db_group') and obj.db_group is not None:
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_group, 'long', 'int')
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -4186,19 +4276,12 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
-        table = 'workflow'
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4208,27 +4291,24 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
-        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
-            columnMap['vistrail_id'] = \
-                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
-        if hasattr(obj, 'db_group') and obj.db_group is not None:
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_group, 'long', 'int')
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -4238,34 +4318,15 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_connections:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_plugin_datas:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_others:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_modules:
+        for child in obj.db_parameters:
             child.db_parentType = obj.vtType
             child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'workflow'
+        table = 'function'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4274,18 +4335,18 @@ class DBWorkflowSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMashupActionSQLDAOBase(SQLDAO):
+class DBActionAnnotationSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'mashup_action'
+        self.table = 'action_annotation'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
         whereMap = global_props
         orderBy = 'id'
 
@@ -4294,27 +4355,31 @@ class DBMashupActionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            prevId = self.convertFromDB(row[1], 'long', 'int')
-            date = self.convertFromDB(row[2], 'datetime', 'datetime')
-            user = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            mashuptrail = self.convertFromDB(row[4], 'long', 'int')
-            entity_id = self.convertFromDB(row[5], 'long', 'int')
-            entity_type = self.convertFromDB(row[6], 'str', 'char(16)')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            mashup_action = DBMashupAction(prevId=prevId,
-                                           date=date,
-                                           user=user,
-                                           id=id)
-            mashup_action.db_mashuptrail = mashuptrail
-            mashup_action.db_entity_id = entity_id
-            mashup_action.db_entity_type = entity_type
-            mashup_action.is_dirty = False
-            res[('mashup_action', id)] = mashup_action
+            actionAnnotation = DBActionAnnotation(key=key,
+                                                  value=value,
+                                                  action_id=action_id,
+                                                  date=date,
+                                                  user=user,
+                                                  id=id)
+            actionAnnotation.db_vistrail = vistrail
+            actionAnnotation.db_entity_id = entity_id
+            actionAnnotation.db_entity_type = entity_type
+            actionAnnotation.is_dirty = False
+            res[('actionAnnotation', id)] = actionAnnotation
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -4323,34 +4388,38 @@ class DBMashupActionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            prevId = self.convertFromDB(row[1], 'long', 'int')
-            date = self.convertFromDB(row[2], 'datetime', 'datetime')
-            user = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            mashuptrail = self.convertFromDB(row[4], 'long', 'int')
-            entity_id = self.convertFromDB(row[5], 'long', 'int')
-            entity_type = self.convertFromDB(row[6], 'str', 'char(16)')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            mashup_action = DBMashupAction(prevId=prevId,
-                                           date=date,
-                                           user=user,
-                                           id=id)
-            mashup_action.db_mashuptrail = mashuptrail
-            mashup_action.db_entity_id = entity_id
-            mashup_action.db_entity_type = entity_type
-            mashup_action.is_dirty = False
-            res[('mashup_action', id)] = mashup_action
+            actionAnnotation = DBActionAnnotation(key=key,
+                                                  value=value,
+                                                  action_id=action_id,
+                                                  date=date,
+                                                  user=user,
+                                                  id=id)
+            actionAnnotation.db_vistrail = vistrail
+            actionAnnotation.db_entity_id = entity_id
+            actionAnnotation.db_entity_type = entity_type
+            actionAnnotation.is_dirty = False
+            res[('actionAnnotation', id)] = actionAnnotation
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('mashuptrail', obj.db_mashuptrail) in all_objects:
-            p = all_objects[('mashuptrail', obj.db_mashuptrail)]
-            p.db_add_action(obj)
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_actionAnnotation(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4360,18 +4429,24 @@ class DBMashupActionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
-            columnMap['prev_id'] = \
-                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
         if hasattr(obj, 'db_date') and obj.db_date is not None:
             columnMap['date'] = \
                 self.convertToDB(obj.db_date, 'datetime', 'datetime')
         if hasattr(obj, 'db_user') and obj.db_user is not None:
             columnMap['user'] = \
                 self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -4389,8 +4464,8 @@ class DBMashupActionSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4400,18 +4475,24 @@ class DBMashupActionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
-            columnMap['prev_id'] = \
-                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
         if hasattr(obj, 'db_date') and obj.db_date is not None:
             columnMap['date'] = \
                 self.convertToDB(obj.db_date, 'datetime', 'datetime')
         if hasattr(obj, 'db_user') and obj.db_user is not None:
             columnMap['user'] = \
                 self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
             columnMap['parent_id'] = \
-                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -4430,12 +4511,10 @@ class DBMashupActionSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_mashup is not None:
-            child = obj.db_mashup
-            child.db_parent = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'mashup_action'
+        table = 'action_annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4444,18 +4523,18 @@ class DBMashupActionSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMashuptrailSQLDAOBase(SQLDAO):
+class DBPluginDataSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'mashuptrail'
+        self.table = 'plugin_data'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
-        table = 'mashuptrail'
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
         whereMap = global_props
         orderBy = 'id'
 
@@ -4464,26 +4543,25 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'char(36)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            vtVersion = self.convertFromDB(row[3], 'long', 'int')
-            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            data = self.convertFromDB(row[1], 'str', 'varchar(8191)')
+            parentType = self.convertFromDB(row[2], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            parent = self.convertFromDB(row[5], 'long', 'long')
             
-            mashuptrail = DBMashuptrail(name=name,
-                                        version=version,
-                                        vtVersion=vtVersion,
-                                        last_modified=last_modified,
-                                        id=id)
-            mashuptrail.db_entity_type = entity_type
-            mashuptrail.is_dirty = False
-            res[('mashuptrail', id)] = mashuptrail
+            plugin_data = DBPluginData(data=data,
+                                       id=id)
+            plugin_data.db_parentType = parentType
+            plugin_data.db_entity_id = entity_id
+            plugin_data.db_entity_type = entity_type
+            plugin_data.db_parent = parent
+            plugin_data.is_dirty = False
+            res[('plugin_data', id)] = plugin_data
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
-        table = 'mashuptrail'
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -4492,31 +4570,38 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'char(36)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            vtVersion = self.convertFromDB(row[3], 'long', 'int')
-            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            data = self.convertFromDB(row[1], 'str', 'varchar(8191)')
+            parentType = self.convertFromDB(row[2], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            parent = self.convertFromDB(row[5], 'long', 'long')
             
-            mashuptrail = DBMashuptrail(name=name,
-                                        version=version,
-                                        vtVersion=vtVersion,
-                                        last_modified=last_modified,
-                                        id=id)
-            mashuptrail.db_entity_type = entity_type
-            mashuptrail.is_dirty = False
-            res[('mashuptrail', id)] = mashuptrail
+            plugin_data = DBPluginData(data=data,
+                                       id=id)
+            plugin_data.db_parentType = parentType
+            plugin_data.db_entity_id = entity_id
+            plugin_data.db_entity_type = entity_type
+            plugin_data.db_parent = parent
+            plugin_data.is_dirty = False
+            res[('plugin_data', id)] = plugin_data
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        pass
-    
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_plugin_data(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
-        table = 'mashuptrail'
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4526,21 +4611,21 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'char(36)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_vtVersion') and obj.db_vtVersion is not None:
-            columnMap['vt_version'] = \
-                self.convertToDB(obj.db_vtVersion, 'long', 'int')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_data') and obj.db_data is not None:
+            columnMap['data'] = \
+                self.convertToDB(obj.db_data, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -4548,17 +4633,12 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
-        table = 'mashuptrail'
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4568,21 +4648,21 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'char(36)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_vtVersion') and obj.db_vtVersion is not None:
-            columnMap['vt_version'] = \
-                self.convertToDB(obj.db_vtVersion, 'long', 'int')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_data') and obj.db_data is not None:
+            columnMap['data'] = \
+                self.convertToDB(obj.db_data, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -4592,24 +4672,13 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_actions:
-            child.db_mashuptrail = obj.db_id
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_actionAnnotations:
-            child.db_mashuptrail = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'mashuptrail'
+        table = 'plugin_data'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4618,18 +4687,18 @@ class DBMashuptrailSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBRegistrySQLDAOBase(SQLDAO):
+class DBDeleteSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'registry'
+        self.table = 'delete_tbl'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
-        table = 'registry'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
         whereMap = global_props
         orderBy = 'id'
 
@@ -4638,27 +4707,29 @@ class DBRegistrySQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            root_descriptor_id = self.convertFromDB(row[3], 'long', 'int')
-            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            registry = DBRegistry(entity_type=entity_type,
-                                  version=version,
-                                  root_descriptor_id=root_descriptor_id,
-                                  name=name,
-                                  last_modified=last_modified,
-                                  id=id)
-            registry.is_dirty = False
-            res[('registry', id)] = registry
+            delete = DBDelete(what=what,
+                              objectId=objectId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            delete.db_action = action
+            delete.db_entity_id = entity_id
+            delete.db_entity_type = entity_type
+            delete.is_dirty = False
+            res[('delete', id)] = delete
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
-        table = 'registry'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -4667,32 +4738,36 @@ class DBRegistrySQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            root_descriptor_id = self.convertFromDB(row[3], 'long', 'int')
-            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
             
-            registry = DBRegistry(entity_type=entity_type,
-                                  version=version,
-                                  root_descriptor_id=root_descriptor_id,
-                                  name=name,
-                                  last_modified=last_modified,
-                                  id=id)
-            registry.is_dirty = False
-            res[('registry', id)] = registry
+            delete = DBDelete(what=what,
+                              objectId=objectId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            delete.db_action = action
+            delete.db_entity_id = entity_id
+            delete.db_entity_type = entity_type
+            delete.is_dirty = False
+            res[('delete', id)] = delete
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        pass
-    
+        if ('action', obj.db_action) in all_objects:
+            p = all_objects[('action', obj.db_action)]
+            p.db_add_operation(obj)
+        
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
-        table = 'registry'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4702,21 +4777,27 @@ class DBRegistrySQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_root_descriptor_id') and obj.db_root_descriptor_id is not None:
-            columnMap['root_descriptor_id'] = \
-                self.convertToDB(obj.db_root_descriptor_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -4724,19 +4805,12 @@ class DBRegistrySQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
-        table = 'registry'
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4746,21 +4820,27 @@ class DBRegistrySQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_root_descriptor_id') and obj.db_root_descriptor_id is not None:
-            columnMap['root_descriptor_id'] = \
-                self.convertToDB(obj.db_root_descriptor_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -4770,21 +4850,13 @@ class DBRegistrySQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_packages:
-            child.db_registry = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'registry'
+        table = 'delete_tbl'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -4793,195 +4865,118 @@ class DBRegistrySQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMashupComponentSQLDAOBase(SQLDAO):
+class DBVistrailVariableSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'mashup_component'
+        self.table = 'vistrail_variable'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
-        table = 'mashup_component'
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
         whereMap = global_props
-        orderBy = 'id'
+        orderBy = 'name'
 
         dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
         data = self.executeSQL(db, dbCommand, True)
         res = {}
         for row in data:
-            id = self.convertFromDB(row[0], 'long', 'int')
-            vtid = self.convertFromDB(row[1], 'long', 'int')
-            vttype = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            vtparent_type = self.convertFromDB(row[3], 'str', 'char(32)')
-            vtparent_id = self.convertFromDB(row[4], 'long', 'int')
-            vtpos = self.convertFromDB(row[5], 'long', 'int')
-            vtmid = self.convertFromDB(row[6], 'long', 'int')
-            pos = self.convertFromDB(row[7], 'long', 'int')
-            type = self.convertFromDB(row[8], 'str', 'varchar(255)')
-            val = self.convertFromDB(row[9], 'str', 'mediumtext')
-            minVal = self.convertFromDB(row[10], 'str', 'varchar(255)')
-            maxVal = self.convertFromDB(row[11], 'str', 'varchar(255)')
-            stepSize = self.convertFromDB(row[12], 'str', 'varchar(255)')
-            strvaluelist = self.convertFromDB(row[13], 'str', 'mediumtext')
-            widget = self.convertFromDB(row[14], 'str', 'varchar(255)')
-            seq = self.convertFromDB(row[15], 'int', 'int')
-            parent = self.convertFromDB(row[16], 'str', 'varchar(255)')
-            mashup_alias = self.convertFromDB(row[17], 'long', 'int')
-            entity_id = self.convertFromDB(row[18], 'long', 'int')
-            entity_type = self.convertFromDB(row[19], 'str', 'char(16)')
+            name = self.convertFromDB(row[0], 'str', 'varchar(255)')
+            uuid = self.convertFromDB(row[1], 'str', 'char(36)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            module = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[5], 'str', 'varchar(8191)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            mashup_component = DBMashupComponent(vtid=vtid,
-                                                 vttype=vttype,
-                                                 vtparent_type=vtparent_type,
-                                                 vtparent_id=vtparent_id,
-                                                 vtpos=vtpos,
-                                                 vtmid=vtmid,
-                                                 pos=pos,
-                                                 type=type,
-                                                 val=val,
-                                                 minVal=minVal,
-                                                 maxVal=maxVal,
-                                                 stepSize=stepSize,
-                                                 strvaluelist=strvaluelist,
-                                                 widget=widget,
-                                                 seq=seq,
-                                                 parent=parent,
-                                                 id=id)
-            mashup_component.db_mashup_alias = mashup_alias
-            mashup_component.db_entity_id = entity_id
-            mashup_component.db_entity_type = entity_type
-            mashup_component.is_dirty = False
-            res[('mashup_component', id)] = mashup_component
+            vistrailVariable = DBVistrailVariable(uuid=uuid,
+                                                  package=package,
+                                                  module=module,
+                                                  namespace=namespace,
+                                                  value=value,
+                                                  name=name)
+            vistrailVariable.db_vistrail = vistrail
+            vistrailVariable.db_entity_id = entity_id
+            vistrailVariable.db_entity_type = entity_type
+            vistrailVariable.is_dirty = False
+            res[('vistrailVariable', name)] = vistrailVariable
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
-        table = 'mashup_component'
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
         whereMap = global_props
-        orderBy = 'id'
+        orderBy = 'name'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
 
     def process_sql_columns(self, data, global_props):
         res = {}
         for row in data:
-            id = self.convertFromDB(row[0], 'long', 'int')
-            vtid = self.convertFromDB(row[1], 'long', 'int')
-            vttype = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            vtparent_type = self.convertFromDB(row[3], 'str', 'char(32)')
-            vtparent_id = self.convertFromDB(row[4], 'long', 'int')
-            vtpos = self.convertFromDB(row[5], 'long', 'int')
-            vtmid = self.convertFromDB(row[6], 'long', 'int')
-            pos = self.convertFromDB(row[7], 'long', 'int')
-            type = self.convertFromDB(row[8], 'str', 'varchar(255)')
-            val = self.convertFromDB(row[9], 'str', 'mediumtext')
-            minVal = self.convertFromDB(row[10], 'str', 'varchar(255)')
-            maxVal = self.convertFromDB(row[11], 'str', 'varchar(255)')
-            stepSize = self.convertFromDB(row[12], 'str', 'varchar(255)')
-            strvaluelist = self.convertFromDB(row[13], 'str', 'mediumtext')
-            widget = self.convertFromDB(row[14], 'str', 'varchar(255)')
-            seq = self.convertFromDB(row[15], 'int', 'int')
-            parent = self.convertFromDB(row[16], 'str', 'varchar(255)')
-            mashup_alias = self.convertFromDB(row[17], 'long', 'int')
-            entity_id = self.convertFromDB(row[18], 'long', 'int')
-            entity_type = self.convertFromDB(row[19], 'str', 'char(16)')
+            name = self.convertFromDB(row[0], 'str', 'varchar(255)')
+            uuid = self.convertFromDB(row[1], 'str', 'char(36)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            module = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[5], 'str', 'varchar(8191)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            mashup_component = DBMashupComponent(vtid=vtid,
-                                                 vttype=vttype,
-                                                 vtparent_type=vtparent_type,
-                                                 vtparent_id=vtparent_id,
-                                                 vtpos=vtpos,
-                                                 vtmid=vtmid,
-                                                 pos=pos,
-                                                 type=type,
-                                                 val=val,
-                                                 minVal=minVal,
-                                                 maxVal=maxVal,
-                                                 stepSize=stepSize,
-                                                 strvaluelist=strvaluelist,
-                                                 widget=widget,
-                                                 seq=seq,
-                                                 parent=parent,
-                                                 id=id)
-            mashup_component.db_mashup_alias = mashup_alias
-            mashup_component.db_entity_id = entity_id
-            mashup_component.db_entity_type = entity_type
-            mashup_component.is_dirty = False
-            res[('mashup_component', id)] = mashup_component
+            vistrailVariable = DBVistrailVariable(uuid=uuid,
+                                                  package=package,
+                                                  module=module,
+                                                  namespace=namespace,
+                                                  value=value,
+                                                  name=name)
+            vistrailVariable.db_vistrail = vistrail
+            vistrailVariable.db_entity_id = entity_id
+            vistrailVariable.db_entity_type = entity_type
+            vistrailVariable.is_dirty = False
+            res[('vistrailVariable', name)] = vistrailVariable
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('mashup_alias', obj.db_mashup_alias) in all_objects:
-            p = all_objects[('mashup_alias', obj.db_mashup_alias)]
-            p.db_add_component(obj)
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_vistrailVariable(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
-        table = 'mashup_component'
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
         whereMap = {}
         whereMap.update(global_props)
-        if obj.db_id is not None:
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-            whereMap['id'] = keyStr
+        if obj.db_name is not None:
+            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+            whereMap['name'] = keyStr
         columnMap = {}
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            columnMap['id'] = \
-                self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
-            columnMap['vtid'] = \
-                self.convertToDB(obj.db_vtid, 'long', 'int')
-        if hasattr(obj, 'db_vttype') and obj.db_vttype is not None:
-            columnMap['vttype'] = \
-                self.convertToDB(obj.db_vttype, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vtparent_type') and obj.db_vtparent_type is not None:
-            columnMap['vtparent_type'] = \
-                self.convertToDB(obj.db_vtparent_type, 'str', 'char(32)')
-        if hasattr(obj, 'db_vtparent_id') and obj.db_vtparent_id is not None:
-            columnMap['vtparent_id'] = \
-                self.convertToDB(obj.db_vtparent_id, 'long', 'int')
-        if hasattr(obj, 'db_vtpos') and obj.db_vtpos is not None:
-            columnMap['vtpos'] = \
-                self.convertToDB(obj.db_vtpos, 'long', 'int')
-        if hasattr(obj, 'db_vtmid') and obj.db_vtmid is not None:
-            columnMap['vtmid'] = \
-                self.convertToDB(obj.db_vtmid, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_val') and obj.db_val is not None:
-            columnMap['val'] = \
-                self.convertToDB(obj.db_val, 'str', 'mediumtext')
-        if hasattr(obj, 'db_minVal') and obj.db_minVal is not None:
-            columnMap['minVal'] = \
-                self.convertToDB(obj.db_minVal, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_maxVal') and obj.db_maxVal is not None:
-            columnMap['maxVal'] = \
-                self.convertToDB(obj.db_maxVal, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_stepSize') and obj.db_stepSize is not None:
-            columnMap['stepSize'] = \
-                self.convertToDB(obj.db_stepSize, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_strvaluelist') and obj.db_strvaluelist is not None:
-            columnMap['strvaluelist'] = \
-                self.convertToDB(obj.db_strvaluelist, 'str', 'mediumtext')
-        if hasattr(obj, 'db_widget') and obj.db_widget is not None:
-            columnMap['widget'] = \
-                self.convertToDB(obj.db_widget, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_seq') and obj.db_seq is not None:
-            columnMap['seq'] = \
-                self.convertToDB(obj.db_seq, 'int', 'int')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent'] = \
-                self.convertToDB(obj.db_parent, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_mashup_alias') and obj.db_mashup_alias is not None:
-            columnMap['alias_id'] = \
-                self.convertToDB(obj.db_mashup_alias, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_uuid') and obj.db_uuid is not None:
+            columnMap['uuid'] = \
+                self.convertToDB(obj.db_uuid, 'str', 'char(36)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -4999,68 +4994,35 @@ class DBMashupComponentSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
-        table = 'mashup_component'
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
         whereMap = {}
         whereMap.update(global_props)
-        if obj.db_id is not None:
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-            whereMap['id'] = keyStr
+        if obj.db_name is not None:
+            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+            whereMap['name'] = keyStr
         columnMap = {}
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            columnMap['id'] = \
-                self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
-            columnMap['vtid'] = \
-                self.convertToDB(obj.db_vtid, 'long', 'int')
-        if hasattr(obj, 'db_vttype') and obj.db_vttype is not None:
-            columnMap['vttype'] = \
-                self.convertToDB(obj.db_vttype, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vtparent_type') and obj.db_vtparent_type is not None:
-            columnMap['vtparent_type'] = \
-                self.convertToDB(obj.db_vtparent_type, 'str', 'char(32)')
-        if hasattr(obj, 'db_vtparent_id') and obj.db_vtparent_id is not None:
-            columnMap['vtparent_id'] = \
-                self.convertToDB(obj.db_vtparent_id, 'long', 'int')
-        if hasattr(obj, 'db_vtpos') and obj.db_vtpos is not None:
-            columnMap['vtpos'] = \
-                self.convertToDB(obj.db_vtpos, 'long', 'int')
-        if hasattr(obj, 'db_vtmid') and obj.db_vtmid is not None:
-            columnMap['vtmid'] = \
-                self.convertToDB(obj.db_vtmid, 'long', 'int')
-        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
-            columnMap['pos'] = \
-                self.convertToDB(obj.db_pos, 'long', 'int')
-        if hasattr(obj, 'db_type') and obj.db_type is not None:
-            columnMap['type'] = \
-                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_val') and obj.db_val is not None:
-            columnMap['val'] = \
-                self.convertToDB(obj.db_val, 'str', 'mediumtext')
-        if hasattr(obj, 'db_minVal') and obj.db_minVal is not None:
-            columnMap['minVal'] = \
-                self.convertToDB(obj.db_minVal, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_maxVal') and obj.db_maxVal is not None:
-            columnMap['maxVal'] = \
-                self.convertToDB(obj.db_maxVal, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_stepSize') and obj.db_stepSize is not None:
-            columnMap['stepSize'] = \
-                self.convertToDB(obj.db_stepSize, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_strvaluelist') and obj.db_strvaluelist is not None:
-            columnMap['strvaluelist'] = \
-                self.convertToDB(obj.db_strvaluelist, 'str', 'mediumtext')
-        if hasattr(obj, 'db_widget') and obj.db_widget is not None:
-            columnMap['widget'] = \
-                self.convertToDB(obj.db_widget, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_seq') and obj.db_seq is not None:
-            columnMap['seq'] = \
-                self.convertToDB(obj.db_seq, 'int', 'int')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent'] = \
-                self.convertToDB(obj.db_parent, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_mashup_alias') and obj.db_mashup_alias is not None:
-            columnMap['alias_id'] = \
-                self.convertToDB(obj.db_mashup_alias, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_uuid') and obj.db_uuid is not None:
+            columnMap['uuid'] = \
+                self.convertToDB(obj.db_uuid, 'str', 'char(36)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -5082,27 +5044,27 @@ class DBMashupComponentSQLDAOBase(SQLDAO):
         pass
     
     def delete_sql_column(self, db, obj, global_props):
-        table = 'mashup_component'
+        table = 'vistrail_variable'
         whereMap = {}
         whereMap.update(global_props)
-        if obj.db_id is not None:
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-            whereMap['id'] = keyStr
+        if obj.db_name is not None:
+            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+            whereMap['name'] = keyStr
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBAnnotationSQLDAOBase(SQLDAO):
+class DBModuleDescriptorSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'annotation'
+        self.table = 'module_descriptor'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'annotation'
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
         whereMap = global_props
         orderBy = 'id'
 
@@ -5111,27 +5073,33 @@ class DBAnnotationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'mediumtext')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            base_descriptor_id = self.convertFromDB(row[6], 'long', 'int')
+            package = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            annotation = DBAnnotation(key=key,
-                                      value=value,
-                                      id=id)
-            annotation.db_parentType = parentType
-            annotation.db_entity_id = entity_id
-            annotation.db_entity_type = entity_type
-            annotation.db_parent = parent
-            annotation.is_dirty = False
-            res[('annotation', id)] = annotation
+            module_descriptor = DBModuleDescriptor(name=name,
+                                                   package=package,
+                                                   namespace=namespace,
+                                                   package_version=package_version,
+                                                   version=version,
+                                                   base_descriptor_id=base_descriptor_id,
+                                                   id=id)
+            module_descriptor.db_package = package
+            module_descriptor.db_entity_id = entity_id
+            module_descriptor.db_entity_type = entity_type
+            module_descriptor.is_dirty = False
+            res[('module_descriptor', id)] = module_descriptor
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'annotation'
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -5140,67 +5108,40 @@ class DBAnnotationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'mediumtext')
-            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[4], 'long', 'int')
-            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
-            parent = self.convertFromDB(row[6], 'long', 'long')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            base_descriptor_id = self.convertFromDB(row[6], 'long', 'int')
+            package = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            annotation = DBAnnotation(key=key,
-                                      value=value,
-                                      id=id)
-            annotation.db_parentType = parentType
-            annotation.db_entity_id = entity_id
-            annotation.db_entity_type = entity_type
-            annotation.db_parent = parent
-            annotation.is_dirty = False
-            res[('annotation', id)] = annotation
+            module_descriptor = DBModuleDescriptor(name=name,
+                                                   package=package,
+                                                   namespace=namespace,
+                                                   package_version=package_version,
+                                                   version=version,
+                                                   base_descriptor_id=base_descriptor_id,
+                                                   id=id)
+            module_descriptor.db_package = package
+            module_descriptor.db_entity_id = entity_id
+            module_descriptor.db_entity_type = entity_type
+            module_descriptor.is_dirty = False
+            res[('module_descriptor', id)] = module_descriptor
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'vistrail':
-            p = all_objects[('vistrail', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'workflow':
-            p = all_objects[('workflow', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'module':
-            p = all_objects[('module', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'workflow_exec':
-            p = all_objects[('workflow_exec', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'module_exec':
-            p = all_objects[('module_exec', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'group_exec':
-            p = all_objects[('group_exec', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'action':
-            p = all_objects[('action', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'abstraction':
-            p = all_objects[('abstraction', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'mashuptrail':
-            p = all_objects[('mashuptrail', obj.db_parent)]
-            p.db_add_annotation(obj)
-        elif obj.db_parentType == 'group':
-            p = all_objects[('group', obj.db_parent)]
-            p.db_add_annotation(obj)
+        if ('package', obj.db_package) in all_objects:
+            p = all_objects[('package', obj.db_package)]
+            p.db_add_module_descriptor(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'annotation'
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5210,24 +5151,33 @@ class DBAnnotationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['akey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'mediumtext')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package_version') and obj.db_package_version is not None:
+            columnMap['package_version'] = \
+                self.convertToDB(obj.db_package_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_base_descriptor_id') and obj.db_base_descriptor_id is not None:
+            columnMap['base_descriptor_id'] = \
+                self.convertToDB(obj.db_base_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_package, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -5239,8 +5189,8 @@ class DBAnnotationSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'annotation'
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5250,24 +5200,33 @@ class DBAnnotationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['akey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'mediumtext')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package_version') and obj.db_package_version is not None:
+            columnMap['package_version'] = \
+                self.convertToDB(obj.db_package_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_base_descriptor_id') and obj.db_base_descriptor_id is not None:
+            columnMap['base_descriptor_id'] = \
+                self.convertToDB(obj.db_base_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_package, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -5280,10 +5239,12 @@ class DBAnnotationSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_portSpecs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'annotation'
+        table = 'module_descriptor'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5292,18 +5253,18 @@ class DBAnnotationSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBChangeSQLDAOBase(SQLDAO):
+class DBTagSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'change_tbl'
+        self.table = 'tag'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'change_tbl'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
         whereMap = global_props
         orderBy = 'id'
 
@@ -5312,31 +5273,23 @@ class DBChangeSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            oldObjId = self.convertFromDB(row[2], 'long', 'int')
-            newObjId = self.convertFromDB(row[3], 'long', 'int')
-            parentObjId = self.convertFromDB(row[4], 'long', 'int')
-            parentObjType = self.convertFromDB(row[5], 'str', 'char(16)')
-            action = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
             
-            change = DBChange(what=what,
-                              oldObjId=oldObjId,
-                              newObjId=newObjId,
-                              parentObjId=parentObjId,
-                              parentObjType=parentObjType,
-                              id=id)
-            change.db_action = action
-            change.db_entity_id = entity_id
-            change.db_entity_type = entity_type
-            change.is_dirty = False
-            res[('change', id)] = change
+            tag = DBTag(name=name,
+                        id=id)
+            tag.db_vistrail = vistrail
+            tag.db_entity_id = entity_id
+            tag.db_entity_type = entity_type
+            tag.is_dirty = False
+            res[('tag', id)] = tag
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'change_tbl'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -5345,38 +5298,30 @@ class DBChangeSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            oldObjId = self.convertFromDB(row[2], 'long', 'int')
-            newObjId = self.convertFromDB(row[3], 'long', 'int')
-            parentObjId = self.convertFromDB(row[4], 'long', 'int')
-            parentObjType = self.convertFromDB(row[5], 'str', 'char(16)')
-            action = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
             
-            change = DBChange(what=what,
-                              oldObjId=oldObjId,
-                              newObjId=newObjId,
-                              parentObjId=parentObjId,
-                              parentObjType=parentObjType,
-                              id=id)
-            change.db_action = action
-            change.db_entity_id = entity_id
-            change.db_entity_type = entity_type
-            change.is_dirty = False
-            res[('change', id)] = change
+            tag = DBTag(name=name,
+                        id=id)
+            tag.db_vistrail = vistrail
+            tag.db_entity_id = entity_id
+            tag.db_entity_type = entity_type
+            tag.is_dirty = False
+            res[('tag', id)] = tag
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('action', obj.db_action) in all_objects:
-            p = all_objects[('action', obj.db_action)]
-            p.db_add_operation(obj)
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_tag(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'change_tbl'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5386,24 +5331,12 @@ class DBChangeSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_what') and obj.db_what is not None:
-            columnMap['what'] = \
-                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_oldObjId') and obj.db_oldObjId is not None:
-            columnMap['old_obj_id'] = \
-                self.convertToDB(obj.db_oldObjId, 'long', 'int')
-        if hasattr(obj, 'db_newObjId') and obj.db_newObjId is not None:
-            columnMap['new_obj_id'] = \
-                self.convertToDB(obj.db_newObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
-            columnMap['par_obj_id'] = \
-                self.convertToDB(obj.db_parentObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
-            columnMap['par_obj_type'] = \
-                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
-        if hasattr(obj, 'db_action') and obj.db_action is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -5421,8 +5354,8 @@ class DBChangeSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'change_tbl'
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5432,24 +5365,12 @@ class DBChangeSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_what') and obj.db_what is not None:
-            columnMap['what'] = \
-                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_oldObjId') and obj.db_oldObjId is not None:
-            columnMap['old_obj_id'] = \
-                self.convertToDB(obj.db_oldObjId, 'long', 'int')
-        if hasattr(obj, 'db_newObjId') and obj.db_newObjId is not None:
-            columnMap['new_obj_id'] = \
-                self.convertToDB(obj.db_newObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
-            columnMap['par_obj_id'] = \
-                self.convertToDB(obj.db_parentObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
-            columnMap['par_obj_type'] = \
-                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
-        if hasattr(obj, 'db_action') and obj.db_action is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -5468,13 +5389,10 @@ class DBChangeSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        if obj.db_data is not None:
-            child = obj.db_data
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'change_tbl'
+        table = 'tag'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5483,18 +5401,18 @@ class DBChangeSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBGroupExecSQLDAOBase(SQLDAO):
+class DBPortSpecItemSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'group_exec'
+        self.table = 'port_spec_item'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_exec'
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
         whereMap = global_props
         orderBy = 'id'
 
@@ -5503,41 +5421,37 @@ class DBGroupExecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
-            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
-            cached = self.convertFromDB(row[3], 'int', 'int')
-            module_id = self.convertFromDB(row[4], 'long', 'int')
-            group_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            group_type = self.convertFromDB(row[6], 'str', 'varchar(255)')
-            completed = self.convertFromDB(row[7], 'int', 'int')
-            error = self.convertFromDB(row[8], 'str', 'varchar(1023)')
-            machine_id = self.convertFromDB(row[9], 'long', 'int')
-            parentType = self.convertFromDB(row[10], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[11], 'long', 'int')
-            entity_type = self.convertFromDB(row[12], 'str', 'char(16)')
-            parent = self.convertFromDB(row[13], 'long', 'long')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            module = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            label = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            default = self.convertFromDB(row[6], 'str', 'varchar(4095)')
+            values = self.convertFromDB(row[7], 'str', 'mediumtext')
+            entry_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            portSpec = self.convertFromDB(row[9], 'long', 'int')
+            entity_id = self.convertFromDB(row[10], 'long', 'int')
+            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
             
-            group_exec = DBGroupExec(ts_start=ts_start,
-                                     ts_end=ts_end,
-                                     cached=cached,
-                                     module_id=module_id,
-                                     group_name=group_name,
-                                     group_type=group_type,
-                                     completed=completed,
-                                     error=error,
-                                     machine_id=machine_id,
-                                     id=id)
-            group_exec.db_parentType = parentType
-            group_exec.db_entity_id = entity_id
-            group_exec.db_entity_type = entity_type
-            group_exec.db_parent = parent
-            group_exec.is_dirty = False
-            res[('group_exec', id)] = group_exec
+            portSpecItem = DBPortSpecItem(pos=pos,
+                                          module=module,
+                                          package=package,
+                                          namespace=namespace,
+                                          label=label,
+                                          default=default,
+                                          values=values,
+                                          entry_type=entry_type,
+                                          id=id)
+            portSpecItem.db_portSpec = portSpec
+            portSpecItem.db_entity_id = entity_id
+            portSpecItem.db_entity_type = entity_type
+            portSpecItem.is_dirty = False
+            res[('portSpecItem', id)] = portSpecItem
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_exec'
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -5546,54 +5460,44 @@ class DBGroupExecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
-            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
-            cached = self.convertFromDB(row[3], 'int', 'int')
-            module_id = self.convertFromDB(row[4], 'long', 'int')
-            group_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            group_type = self.convertFromDB(row[6], 'str', 'varchar(255)')
-            completed = self.convertFromDB(row[7], 'int', 'int')
-            error = self.convertFromDB(row[8], 'str', 'varchar(1023)')
-            machine_id = self.convertFromDB(row[9], 'long', 'int')
-            parentType = self.convertFromDB(row[10], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[11], 'long', 'int')
-            entity_type = self.convertFromDB(row[12], 'str', 'char(16)')
-            parent = self.convertFromDB(row[13], 'long', 'long')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            module = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            label = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            default = self.convertFromDB(row[6], 'str', 'varchar(4095)')
+            values = self.convertFromDB(row[7], 'str', 'mediumtext')
+            entry_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            portSpec = self.convertFromDB(row[9], 'long', 'int')
+            entity_id = self.convertFromDB(row[10], 'long', 'int')
+            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
             
-            group_exec = DBGroupExec(ts_start=ts_start,
-                                     ts_end=ts_end,
-                                     cached=cached,
-                                     module_id=module_id,
-                                     group_name=group_name,
-                                     group_type=group_type,
-                                     completed=completed,
-                                     error=error,
-                                     machine_id=machine_id,
-                                     id=id)
-            group_exec.db_parentType = parentType
-            group_exec.db_entity_id = entity_id
-            group_exec.db_entity_type = entity_type
-            group_exec.db_parent = parent
-            group_exec.is_dirty = False
-            res[('group_exec', id)] = group_exec
+            portSpecItem = DBPortSpecItem(pos=pos,
+                                          module=module,
+                                          package=package,
+                                          namespace=namespace,
+                                          label=label,
+                                          default=default,
+                                          values=values,
+                                          entry_type=entry_type,
+                                          id=id)
+            portSpecItem.db_portSpec = portSpec
+            portSpecItem.db_entity_id = entity_id
+            portSpecItem.db_entity_type = entity_type
+            portSpecItem.is_dirty = False
+            res[('portSpecItem', id)] = portSpecItem
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow_exec':
-            p = all_objects[('workflow_exec', obj.db_parent)]
-            p.db_add_item_exec(obj)
-        elif obj.db_parentType == 'loop_exec':
-            p = all_objects[('loop_exec', obj.db_parent)]
-            p.db_add_item_exec(obj)
-        elif obj.db_parentType == 'group_exec':
-            p = all_objects[('group_exec', obj.db_parent)]
-            p.db_add_item_exec(obj)
+        if ('portSpec', obj.db_portSpec) in all_objects:
+            p = all_objects[('portSpec', obj.db_portSpec)]
+            p.db_add_portSpecItem(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_exec'
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5603,45 +5507,39 @@ class DBGroupExecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
-            columnMap['ts_start'] = \
-                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
-        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
-            columnMap['ts_end'] = \
-                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
-        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
-            columnMap['cached'] = \
-                self.convertToDB(obj.db_cached, 'int', 'int')
-        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
-            columnMap['module_id'] = \
-                self.convertToDB(obj.db_module_id, 'long', 'int')
-        if hasattr(obj, 'db_group_name') and obj.db_group_name is not None:
-            columnMap['group_name'] = \
-                self.convertToDB(obj.db_group_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_group_type') and obj.db_group_type is not None:
-            columnMap['group_type'] = \
-                self.convertToDB(obj.db_group_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
-            columnMap['completed'] = \
-                self.convertToDB(obj.db_completed, 'int', 'int')
-        if hasattr(obj, 'db_error') and obj.db_error is not None:
-            columnMap['error'] = \
-                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
-            columnMap['machine_id'] = \
-                self.convertToDB(obj.db_machine_id, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_label') and obj.db_label is not None:
+            columnMap['label'] = \
+                self.convertToDB(obj.db_label, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_default') and obj.db_default is not None:
+            columnMap['_default'] = \
+                self.convertToDB(obj.db_default, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_values') and obj.db_values is not None:
+            columnMap['_values'] = \
+                self.convertToDB(obj.db_values, 'str', 'mediumtext')
+        if hasattr(obj, 'db_entry_type') and obj.db_entry_type is not None:
+            columnMap['entry_type'] = \
+                self.convertToDB(obj.db_entry_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_portSpec') and obj.db_portSpec is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_portSpec, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -5653,8 +5551,8 @@ class DBGroupExecSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'group_exec'
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5664,45 +5562,39 @@ class DBGroupExecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
-            columnMap['ts_start'] = \
-                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
-        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
-            columnMap['ts_end'] = \
-                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
-        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
-            columnMap['cached'] = \
-                self.convertToDB(obj.db_cached, 'int', 'int')
-        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
-            columnMap['module_id'] = \
-                self.convertToDB(obj.db_module_id, 'long', 'int')
-        if hasattr(obj, 'db_group_name') and obj.db_group_name is not None:
-            columnMap['group_name'] = \
-                self.convertToDB(obj.db_group_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_group_type') and obj.db_group_type is not None:
-            columnMap['group_type'] = \
-                self.convertToDB(obj.db_group_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
-            columnMap['completed'] = \
-                self.convertToDB(obj.db_completed, 'int', 'int')
-        if hasattr(obj, 'db_error') and obj.db_error is not None:
-            columnMap['error'] = \
-                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
-            columnMap['machine_id'] = \
-                self.convertToDB(obj.db_machine_id, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_label') and obj.db_label is not None:
+            columnMap['label'] = \
+                self.convertToDB(obj.db_label, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_default') and obj.db_default is not None:
+            columnMap['_default'] = \
+                self.convertToDB(obj.db_default, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_values') and obj.db_values is not None:
+            columnMap['_values'] = \
+                self.convertToDB(obj.db_values, 'str', 'mediumtext')
+        if hasattr(obj, 'db_entry_type') and obj.db_entry_type is not None:
+            columnMap['entry_type'] = \
+                self.convertToDB(obj.db_entry_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_portSpec') and obj.db_portSpec is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_portSpec, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -5715,15 +5607,10 @@ class DBGroupExecSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_item_execs:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'group_exec'
+        table = 'port_spec_item'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5732,18 +5619,18 @@ class DBGroupExecSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPackageSQLDAOBase(SQLDAO):
+class DBMashupComponentSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'package'
+        self.table = 'mashup_component'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
-        table = 'package'
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
         whereMap = global_props
         orderBy = 'id'
 
@@ -5752,33 +5639,53 @@ class DBPackageSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            identifier = self.convertFromDB(row[2], 'str', 'varchar(1023)')
-            codepath = self.convertFromDB(row[3], 'str', 'varchar(1023)')
-            load_configuration = self.convertFromDB(row[4], 'int', 'int')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            description = self.convertFromDB(row[6], 'str', 'varchar(1023)')
-            registry = self.convertFromDB(row[7], 'long', 'int')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
-            
-            package = DBPackage(name=name,
-                                identifier=identifier,
-                                codepath=codepath,
-                                load_configuration=load_configuration,
-                                version=version,
-                                description=description,
-                                id=id)
-            package.db_registry = registry
-            package.db_entity_id = entity_id
-            package.db_entity_type = entity_type
-            package.is_dirty = False
-            res[('package', id)] = package
+            vtid = self.convertFromDB(row[1], 'long', 'int')
+            vttype = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            vtparent_type = self.convertFromDB(row[3], 'str', 'char(32)')
+            vtparent_id = self.convertFromDB(row[4], 'long', 'int')
+            vtpos = self.convertFromDB(row[5], 'long', 'int')
+            vtmid = self.convertFromDB(row[6], 'long', 'int')
+            pos = self.convertFromDB(row[7], 'long', 'int')
+            type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[9], 'str', 'mediumtext')
+            minVal = self.convertFromDB(row[10], 'str', 'varchar(255)')
+            maxVal = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            stepSize = self.convertFromDB(row[12], 'str', 'varchar(255)')
+            strvaluelist = self.convertFromDB(row[13], 'str', 'mediumtext')
+            widget = self.convertFromDB(row[14], 'str', 'varchar(255)')
+            seq = self.convertFromDB(row[15], 'int', 'int')
+            parent = self.convertFromDB(row[16], 'str', 'varchar(255)')
+            mashup_alias = self.convertFromDB(row[17], 'long', 'int')
+            entity_id = self.convertFromDB(row[18], 'long', 'int')
+            entity_type = self.convertFromDB(row[19], 'str', 'char(16)')
+            
+            mashup_component = DBMashupComponent(vtid=vtid,
+                                                 vttype=vttype,
+                                                 vtparent_type=vtparent_type,
+                                                 vtparent_id=vtparent_id,
+                                                 vtpos=vtpos,
+                                                 vtmid=vtmid,
+                                                 pos=pos,
+                                                 type=type,
+                                                 val=val,
+                                                 minVal=minVal,
+                                                 maxVal=maxVal,
+                                                 stepSize=stepSize,
+                                                 strvaluelist=strvaluelist,
+                                                 widget=widget,
+                                                 seq=seq,
+                                                 parent=parent,
+                                                 id=id)
+            mashup_component.db_mashup_alias = mashup_alias
+            mashup_component.db_entity_id = entity_id
+            mashup_component.db_entity_type = entity_type
+            mashup_component.is_dirty = False
+            res[('mashup_component', id)] = mashup_component
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
-        table = 'package'
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -5787,40 +5694,60 @@ class DBPackageSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            identifier = self.convertFromDB(row[2], 'str', 'varchar(1023)')
-            codepath = self.convertFromDB(row[3], 'str', 'varchar(1023)')
-            load_configuration = self.convertFromDB(row[4], 'int', 'int')
-            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            description = self.convertFromDB(row[6], 'str', 'varchar(1023)')
-            registry = self.convertFromDB(row[7], 'long', 'int')
-            entity_id = self.convertFromDB(row[8], 'long', 'int')
-            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            vtid = self.convertFromDB(row[1], 'long', 'int')
+            vttype = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            vtparent_type = self.convertFromDB(row[3], 'str', 'char(32)')
+            vtparent_id = self.convertFromDB(row[4], 'long', 'int')
+            vtpos = self.convertFromDB(row[5], 'long', 'int')
+            vtmid = self.convertFromDB(row[6], 'long', 'int')
+            pos = self.convertFromDB(row[7], 'long', 'int')
+            type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[9], 'str', 'mediumtext')
+            minVal = self.convertFromDB(row[10], 'str', 'varchar(255)')
+            maxVal = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            stepSize = self.convertFromDB(row[12], 'str', 'varchar(255)')
+            strvaluelist = self.convertFromDB(row[13], 'str', 'mediumtext')
+            widget = self.convertFromDB(row[14], 'str', 'varchar(255)')
+            seq = self.convertFromDB(row[15], 'int', 'int')
+            parent = self.convertFromDB(row[16], 'str', 'varchar(255)')
+            mashup_alias = self.convertFromDB(row[17], 'long', 'int')
+            entity_id = self.convertFromDB(row[18], 'long', 'int')
+            entity_type = self.convertFromDB(row[19], 'str', 'char(16)')
             
-            package = DBPackage(name=name,
-                                identifier=identifier,
-                                codepath=codepath,
-                                load_configuration=load_configuration,
-                                version=version,
-                                description=description,
-                                id=id)
-            package.db_registry = registry
-            package.db_entity_id = entity_id
-            package.db_entity_type = entity_type
-            package.is_dirty = False
-            res[('package', id)] = package
+            mashup_component = DBMashupComponent(vtid=vtid,
+                                                 vttype=vttype,
+                                                 vtparent_type=vtparent_type,
+                                                 vtparent_id=vtparent_id,
+                                                 vtpos=vtpos,
+                                                 vtmid=vtmid,
+                                                 pos=pos,
+                                                 type=type,
+                                                 val=val,
+                                                 minVal=minVal,
+                                                 maxVal=maxVal,
+                                                 stepSize=stepSize,
+                                                 strvaluelist=strvaluelist,
+                                                 widget=widget,
+                                                 seq=seq,
+                                                 parent=parent,
+                                                 id=id)
+            mashup_component.db_mashup_alias = mashup_alias
+            mashup_component.db_entity_id = entity_id
+            mashup_component.db_entity_type = entity_type
+            mashup_component.is_dirty = False
+            res[('mashup_component', id)] = mashup_component
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('registry', obj.db_registry) in all_objects:
-            p = all_objects[('registry', obj.db_registry)]
-            p.db_add_package(obj)
+        if ('mashup_alias', obj.db_mashup_alias) in all_objects:
+            p = all_objects[('mashup_alias', obj.db_mashup_alias)]
+            p.db_add_component(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
-        table = 'package'
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5830,27 +5757,57 @@ class DBPackageSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_identifier') and obj.db_identifier is not None:
-            columnMap['identifier'] = \
-                self.convertToDB(obj.db_identifier, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_codepath') and obj.db_codepath is not None:
-            columnMap['codepath'] = \
-                self.convertToDB(obj.db_codepath, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_load_configuration') and obj.db_load_configuration is not None:
-            columnMap['load_configuration'] = \
-                self.convertToDB(obj.db_load_configuration, 'int', 'int')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_description') and obj.db_description is not None:
-            columnMap['description'] = \
-                self.convertToDB(obj.db_description, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_registry') and obj.db_registry is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_registry, 'long', 'int')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_vttype') and obj.db_vttype is not None:
+            columnMap['vttype'] = \
+                self.convertToDB(obj.db_vttype, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtparent_type') and obj.db_vtparent_type is not None:
+            columnMap['vtparent_type'] = \
+                self.convertToDB(obj.db_vtparent_type, 'str', 'char(32)')
+        if hasattr(obj, 'db_vtparent_id') and obj.db_vtparent_id is not None:
+            columnMap['vtparent_id'] = \
+                self.convertToDB(obj.db_vtparent_id, 'long', 'int')
+        if hasattr(obj, 'db_vtpos') and obj.db_vtpos is not None:
+            columnMap['vtpos'] = \
+                self.convertToDB(obj.db_vtpos, 'long', 'int')
+        if hasattr(obj, 'db_vtmid') and obj.db_vtmid is not None:
+            columnMap['vtmid'] = \
+                self.convertToDB(obj.db_vtmid, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_minVal') and obj.db_minVal is not None:
+            columnMap['minVal'] = \
+                self.convertToDB(obj.db_minVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_maxVal') and obj.db_maxVal is not None:
+            columnMap['maxVal'] = \
+                self.convertToDB(obj.db_maxVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_stepSize') and obj.db_stepSize is not None:
+            columnMap['stepSize'] = \
+                self.convertToDB(obj.db_stepSize, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_strvaluelist') and obj.db_strvaluelist is not None:
+            columnMap['strvaluelist'] = \
+                self.convertToDB(obj.db_strvaluelist, 'str', 'mediumtext')
+        if hasattr(obj, 'db_widget') and obj.db_widget is not None:
+            columnMap['widget'] = \
+                self.convertToDB(obj.db_widget, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_seq') and obj.db_seq is not None:
+            columnMap['seq'] = \
+                self.convertToDB(obj.db_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent'] = \
+                self.convertToDB(obj.db_parent, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashup_alias') and obj.db_mashup_alias is not None:
+            columnMap['alias_id'] = \
+                self.convertToDB(obj.db_mashup_alias, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -5864,15 +5821,12 @@ class DBPackageSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
-        table = 'package'
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5882,27 +5836,57 @@ class DBPackageSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_identifier') and obj.db_identifier is not None:
-            columnMap['identifier'] = \
-                self.convertToDB(obj.db_identifier, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_codepath') and obj.db_codepath is not None:
-            columnMap['codepath'] = \
-                self.convertToDB(obj.db_codepath, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_load_configuration') and obj.db_load_configuration is not None:
-            columnMap['load_configuration'] = \
-                self.convertToDB(obj.db_load_configuration, 'int', 'int')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_description') and obj.db_description is not None:
-            columnMap['description'] = \
-                self.convertToDB(obj.db_description, 'str', 'varchar(1023)')
-        if hasattr(obj, 'db_registry') and obj.db_registry is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_registry, 'long', 'int')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_vttype') and obj.db_vttype is not None:
+            columnMap['vttype'] = \
+                self.convertToDB(obj.db_vttype, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtparent_type') and obj.db_vtparent_type is not None:
+            columnMap['vtparent_type'] = \
+                self.convertToDB(obj.db_vtparent_type, 'str', 'char(32)')
+        if hasattr(obj, 'db_vtparent_id') and obj.db_vtparent_id is not None:
+            columnMap['vtparent_id'] = \
+                self.convertToDB(obj.db_vtparent_id, 'long', 'int')
+        if hasattr(obj, 'db_vtpos') and obj.db_vtpos is not None:
+            columnMap['vtpos'] = \
+                self.convertToDB(obj.db_vtpos, 'long', 'int')
+        if hasattr(obj, 'db_vtmid') and obj.db_vtmid is not None:
+            columnMap['vtmid'] = \
+                self.convertToDB(obj.db_vtmid, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_minVal') and obj.db_minVal is not None:
+            columnMap['minVal'] = \
+                self.convertToDB(obj.db_minVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_maxVal') and obj.db_maxVal is not None:
+            columnMap['maxVal'] = \
+                self.convertToDB(obj.db_maxVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_stepSize') and obj.db_stepSize is not None:
+            columnMap['stepSize'] = \
+                self.convertToDB(obj.db_stepSize, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_strvaluelist') and obj.db_strvaluelist is not None:
+            columnMap['strvaluelist'] = \
+                self.convertToDB(obj.db_strvaluelist, 'str', 'mediumtext')
+        if hasattr(obj, 'db_widget') and obj.db_widget is not None:
+            columnMap['widget'] = \
+                self.convertToDB(obj.db_widget, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_seq') and obj.db_seq is not None:
+            columnMap['seq'] = \
+                self.convertToDB(obj.db_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent'] = \
+                self.convertToDB(obj.db_parent, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashup_alias') and obj.db_mashup_alias is not None:
+            columnMap['alias_id'] = \
+                self.convertToDB(obj.db_mashup_alias, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -5918,17 +5902,13 @@ class DBPackageSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_module_descriptors:
-            child.db_package = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'package'
+        table = 'mashup_component'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -5937,18 +5917,18 @@ class DBPackageSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBWorkflowExecSQLDAOBase(SQLDAO):
+class DBMashupSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'workflow_exec'
+        self.table = 'mashup'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
-        table = 'workflow_exec'
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
         whereMap = global_props
         orderBy = 'id'
 
@@ -5957,43 +5937,35 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            user = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            ip = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            session = self.convertFromDB(row[3], 'long', 'int')
-            vt_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            ts_start = self.convertFromDB(row[5], 'datetime', 'datetime')
-            ts_end = self.convertFromDB(row[6], 'datetime', 'datetime')
-            parent_id = self.convertFromDB(row[7], 'long', 'int')
-            parent_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
-            parent_version = self.convertFromDB(row[9], 'long', 'int')
-            completed = self.convertFromDB(row[10], 'int', 'int')
-            name = self.convertFromDB(row[11], 'str', 'varchar(255)')
-            log = self.convertFromDB(row[12], 'long', 'int')
-            entity_id = self.convertFromDB(row[13], 'long', 'int')
-            entity_type = self.convertFromDB(row[14], 'str', 'char(16)')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[2], 'long', 'int')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            vtid = self.convertFromDB(row[4], 'long', 'int')
+            layout = self.convertFromDB(row[5], 'str', 'mediumtext')
+            geometry = self.convertFromDB(row[6], 'str', 'mediumtext')
+            has_seq = self.convertFromDB(row[7], 'int', 'int')
+            parent = self.convertFromDB(row[8], 'long', 'int')
+            entity_id = self.convertFromDB(row[9], 'long', 'int')
+            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
             
-            workflow_exec = DBWorkflowExec(user=user,
-                                           ip=ip,
-                                           session=session,
-                                           vt_version=vt_version,
-                                           ts_start=ts_start,
-                                           ts_end=ts_end,
-                                           parent_id=parent_id,
-                                           parent_type=parent_type,
-                                           parent_version=parent_version,
-                                           completed=completed,
-                                           name=name,
-                                           id=id)
-            workflow_exec.db_log = log
-            workflow_exec.db_entity_id = entity_id
-            workflow_exec.db_entity_type = entity_type
-            workflow_exec.is_dirty = False
-            res[('workflow_exec', id)] = workflow_exec
+            mashup = DBMashup(name=name,
+                              version=version,
+                              type=type,
+                              vtid=vtid,
+                              layout=layout,
+                              geometry=geometry,
+                              has_seq=has_seq,
+                              id=id)
+            mashup.db_parent = parent
+            mashup.db_entity_id = entity_id
+            mashup.db_entity_type = entity_type
+            mashup.is_dirty = False
+            res[('mashup', id)] = mashup
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
-        table = 'workflow_exec'
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -6002,50 +5974,42 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            user = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            ip = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            session = self.convertFromDB(row[3], 'long', 'int')
-            vt_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            ts_start = self.convertFromDB(row[5], 'datetime', 'datetime')
-            ts_end = self.convertFromDB(row[6], 'datetime', 'datetime')
-            parent_id = self.convertFromDB(row[7], 'long', 'int')
-            parent_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
-            parent_version = self.convertFromDB(row[9], 'long', 'int')
-            completed = self.convertFromDB(row[10], 'int', 'int')
-            name = self.convertFromDB(row[11], 'str', 'varchar(255)')
-            log = self.convertFromDB(row[12], 'long', 'int')
-            entity_id = self.convertFromDB(row[13], 'long', 'int')
-            entity_type = self.convertFromDB(row[14], 'str', 'char(16)')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[2], 'long', 'int')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            vtid = self.convertFromDB(row[4], 'long', 'int')
+            layout = self.convertFromDB(row[5], 'str', 'mediumtext')
+            geometry = self.convertFromDB(row[6], 'str', 'mediumtext')
+            has_seq = self.convertFromDB(row[7], 'int', 'int')
+            parent = self.convertFromDB(row[8], 'long', 'int')
+            entity_id = self.convertFromDB(row[9], 'long', 'int')
+            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
             
-            workflow_exec = DBWorkflowExec(user=user,
-                                           ip=ip,
-                                           session=session,
-                                           vt_version=vt_version,
-                                           ts_start=ts_start,
-                                           ts_end=ts_end,
-                                           parent_id=parent_id,
-                                           parent_type=parent_type,
-                                           parent_version=parent_version,
-                                           completed=completed,
-                                           name=name,
-                                           id=id)
-            workflow_exec.db_log = log
-            workflow_exec.db_entity_id = entity_id
-            workflow_exec.db_entity_type = entity_type
-            workflow_exec.is_dirty = False
-            res[('workflow_exec', id)] = workflow_exec
+            mashup = DBMashup(name=name,
+                              version=version,
+                              type=type,
+                              vtid=vtid,
+                              layout=layout,
+                              geometry=geometry,
+                              has_seq=has_seq,
+                              id=id)
+            mashup.db_parent = parent
+            mashup.db_entity_id = entity_id
+            mashup.db_entity_type = entity_type
+            mashup.is_dirty = False
+            res[('mashup', id)] = mashup
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('log', obj.db_log) in all_objects:
-            p = all_objects[('log', obj.db_log)]
-            p.db_add_workflow_exec(obj)
+        if ('mashup_action', obj.db_parent) in all_objects:
+            p = all_objects[('mashup_action', obj.db_parent)]
+            p.db_add_mashup(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
-        table = 'workflow_exec'
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6055,42 +6019,30 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_ip') and obj.db_ip is not None:
-            columnMap['ip'] = \
-                self.convertToDB(obj.db_ip, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_session') and obj.db_session is not None:
-            columnMap['session'] = \
-                self.convertToDB(obj.db_session, 'long', 'int')
-        if hasattr(obj, 'db_vt_version') and obj.db_vt_version is not None:
-            columnMap['vt_version'] = \
-                self.convertToDB(obj.db_vt_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
-            columnMap['ts_start'] = \
-                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
-        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
-            columnMap['ts_end'] = \
-                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
-        if hasattr(obj, 'db_parent_id') and obj.db_parent_id is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent_id, 'long', 'int')
-        if hasattr(obj, 'db_parent_type') and obj.db_parent_type is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parent_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_parent_version') and obj.db_parent_version is not None:
-            columnMap['parent_version'] = \
-                self.convertToDB(obj.db_parent_version, 'long', 'int')
-        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
-            columnMap['completed'] = \
-                self.convertToDB(obj.db_completed, 'int', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_log') and obj.db_log is not None:
-            columnMap['log_id'] = \
-                self.convertToDB(obj.db_log, 'long', 'int')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'mediumtext')
+        if hasattr(obj, 'db_geometry') and obj.db_geometry is not None:
+            columnMap['geometry'] = \
+                self.convertToDB(obj.db_geometry, 'str', 'mediumtext')
+        if hasattr(obj, 'db_has_seq') and obj.db_has_seq is not None:
+            columnMap['has_seq'] = \
+                self.convertToDB(obj.db_has_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -6108,8 +6060,8 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
-        table = 'workflow_exec'
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6119,42 +6071,30 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_ip') and obj.db_ip is not None:
-            columnMap['ip'] = \
-                self.convertToDB(obj.db_ip, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_session') and obj.db_session is not None:
-            columnMap['session'] = \
-                self.convertToDB(obj.db_session, 'long', 'int')
-        if hasattr(obj, 'db_vt_version') and obj.db_vt_version is not None:
-            columnMap['vt_version'] = \
-                self.convertToDB(obj.db_vt_version, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
-            columnMap['ts_start'] = \
-                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
-        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
-            columnMap['ts_end'] = \
-                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
-        if hasattr(obj, 'db_parent_id') and obj.db_parent_id is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent_id, 'long', 'int')
-        if hasattr(obj, 'db_parent_type') and obj.db_parent_type is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parent_type, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_parent_version') and obj.db_parent_version is not None:
-            columnMap['parent_version'] = \
-                self.convertToDB(obj.db_parent_version, 'long', 'int')
-        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
-            columnMap['completed'] = \
-                self.convertToDB(obj.db_completed, 'int', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_log') and obj.db_log is not None:
-            columnMap['log_id'] = \
-                self.convertToDB(obj.db_log, 'long', 'int')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'mediumtext')
+        if hasattr(obj, 'db_geometry') and obj.db_geometry is not None:
+            columnMap['geometry'] = \
+                self.convertToDB(obj.db_geometry, 'str', 'mediumtext')
+        if hasattr(obj, 'db_has_seq') and obj.db_has_seq is not None:
+            columnMap['has_seq'] = \
+                self.convertToDB(obj.db_has_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -6173,15 +6113,11 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_item_execs:
-            child.db_parentType = obj.vtType
+        for child in obj.db_aliases:
             child.db_parent = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'workflow_exec'
+        table = 'mashup'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6190,18 +6126,18 @@ class DBWorkflowExecSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBParameterExplorationSQLDAOBase(SQLDAO):
+class DBMachineSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'parameter_exploration'
+        self.table = 'machine'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
-        table = 'parameter_exploration'
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
         whereMap = global_props
         orderBy = 'id'
 
@@ -6210,33 +6146,33 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            action_id = self.convertFromDB(row[1], 'long', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            date = self.convertFromDB(row[3], 'datetime', 'datetime')
-            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            dims = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            layout = self.convertFromDB(row[6], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[7], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            os = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            architecture = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            processor = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ram = self.convertFromDB(row[5], 'int', 'bigint')
+            vistrailId = self.convertFromDB(row[6], 'long', 'int')
+            log = self.convertFromDB(row[7], 'long', 'int')
             entity_id = self.convertFromDB(row[8], 'long', 'int')
             entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            parameter_exploration = DBParameterExploration(action_id=action_id,
-                                                           name=name,
-                                                           date=date,
-                                                           user=user,
-                                                           dims=dims,
-                                                           layout=layout,
-                                                           id=id)
-            parameter_exploration.db_vistrail = vistrail
-            parameter_exploration.db_entity_id = entity_id
-            parameter_exploration.db_entity_type = entity_type
-            parameter_exploration.is_dirty = False
-            res[('parameter_exploration', id)] = parameter_exploration
+            machine = DBMachine(name=name,
+                                os=os,
+                                architecture=architecture,
+                                processor=processor,
+                                ram=ram,
+                                id=id)
+            machine.db_vistrailId = vistrailId
+            machine.db_log = log
+            machine.db_entity_id = entity_id
+            machine.db_entity_type = entity_type
+            machine.is_dirty = False
+            res[('machine', id)] = machine
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
-        table = 'parameter_exploration'
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -6245,40 +6181,40 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            action_id = self.convertFromDB(row[1], 'long', 'int')
-            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            date = self.convertFromDB(row[3], 'datetime', 'datetime')
-            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            dims = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            layout = self.convertFromDB(row[6], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[7], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            os = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            architecture = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            processor = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ram = self.convertFromDB(row[5], 'int', 'bigint')
+            vistrailId = self.convertFromDB(row[6], 'long', 'int')
+            log = self.convertFromDB(row[7], 'long', 'int')
             entity_id = self.convertFromDB(row[8], 'long', 'int')
             entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            parameter_exploration = DBParameterExploration(action_id=action_id,
-                                                           name=name,
-                                                           date=date,
-                                                           user=user,
-                                                           dims=dims,
-                                                           layout=layout,
-                                                           id=id)
-            parameter_exploration.db_vistrail = vistrail
-            parameter_exploration.db_entity_id = entity_id
-            parameter_exploration.db_entity_type = entity_type
-            parameter_exploration.is_dirty = False
-            res[('parameter_exploration', id)] = parameter_exploration
+            machine = DBMachine(name=name,
+                                os=os,
+                                architecture=architecture,
+                                processor=processor,
+                                ram=ram,
+                                id=id)
+            machine.db_vistrailId = vistrailId
+            machine.db_log = log
+            machine.db_entity_id = entity_id
+            machine.db_entity_type = entity_type
+            machine.is_dirty = False
+            res[('machine', id)] = machine
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('vistrail', obj.db_vistrail) in all_objects:
-            p = all_objects[('vistrail', obj.db_vistrail)]
-            p.db_add_parameter_exploration(obj)
+        if ('log', obj.db_log) in all_objects:
+            p = all_objects[('log', obj.db_log)]
+            p.db_add_machine(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
-        table = 'parameter_exploration'
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6288,27 +6224,27 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action_id, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_dims') and obj.db_dims is not None:
-            columnMap['dims'] = \
-                self.convertToDB(obj.db_dims, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
-            columnMap['layout'] = \
-                self.convertToDB(obj.db_layout, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_os') and obj.db_os is not None:
+            columnMap['os'] = \
+                self.convertToDB(obj.db_os, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_architecture') and obj.db_architecture is not None:
+            columnMap['architecture'] = \
+                self.convertToDB(obj.db_architecture, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_processor') and obj.db_processor is not None:
+            columnMap['processor'] = \
+                self.convertToDB(obj.db_processor, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ram') and obj.db_ram is not None:
+            columnMap['ram'] = \
+                self.convertToDB(obj.db_ram, 'int', 'bigint')
+        if hasattr(obj, 'db_vistrailId') and obj.db_vistrailId is not None:
+            columnMap['vt_id'] = \
+                self.convertToDB(obj.db_vistrailId, 'long', 'int')
+        if hasattr(obj, 'db_log') and obj.db_log is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_log, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -6326,8 +6262,8 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
-        table = 'parameter_exploration'
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6337,27 +6273,27 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action_id, 'long', 'int')
         if hasattr(obj, 'db_name') and obj.db_name is not None:
             columnMap['name'] = \
                 self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_dims') and obj.db_dims is not None:
-            columnMap['dims'] = \
-                self.convertToDB(obj.db_dims, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
-            columnMap['layout'] = \
-                self.convertToDB(obj.db_layout, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_os') and obj.db_os is not None:
+            columnMap['os'] = \
+                self.convertToDB(obj.db_os, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_architecture') and obj.db_architecture is not None:
+            columnMap['architecture'] = \
+                self.convertToDB(obj.db_architecture, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_processor') and obj.db_processor is not None:
+            columnMap['processor'] = \
+                self.convertToDB(obj.db_processor, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ram') and obj.db_ram is not None:
+            columnMap['ram'] = \
+                self.convertToDB(obj.db_ram, 'int', 'bigint')
+        if hasattr(obj, 'db_vistrailId') and obj.db_vistrailId is not None:
+            columnMap['vt_id'] = \
+                self.convertToDB(obj.db_vistrailId, 'long', 'int')
+        if hasattr(obj, 'db_log') and obj.db_log is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_log, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -6376,11 +6312,10 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_functions:
-            child.db_parameter_exploration = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'parameter_exploration'
+        table = 'machine'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6389,18 +6324,18 @@ class DBParameterExplorationSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBLoopExecSQLDAOBase(SQLDAO):
+class DBOtherSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'loop_exec'
+        self.table = 'other'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'loop_exec'
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
         whereMap = global_props
         orderBy = 'id'
 
@@ -6409,84 +6344,69 @@ class DBLoopExecSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
-            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
-            iteration = self.convertFromDB(row[3], 'int', 'int')
-            completed = self.convertFromDB(row[4], 'int', 'int')
-            error = self.convertFromDB(row[5], 'str', 'varchar(1023)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            loop_exec = DBLoopExec(ts_start=ts_start,
-                                   ts_end=ts_end,
-                                   iteration=iteration,
-                                   completed=completed,
-                                   error=error,
-                                   id=id)
-            loop_exec.db_parentType = parentType
-            loop_exec.db_entity_id = entity_id
-            loop_exec.db_entity_type = entity_type
-            loop_exec.db_parent = parent
-            loop_exec.is_dirty = False
-            res[('loop_exec', id)] = loop_exec
+            other = DBOther(key=key,
+                            value=value,
+                            id=id)
+            other.db_parentType = parentType
+            other.db_entity_id = entity_id
+            other.db_entity_type = entity_type
+            other.db_parent = parent
+            other.is_dirty = False
+            res[('other', id)] = other
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'loop_exec'
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
 
-    def process_sql_columns(self, data, global_props):
-        res = {}
-        for row in data:
-            id = self.convertFromDB(row[0], 'long', 'int')
-            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
-            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
-            iteration = self.convertFromDB(row[3], 'int', 'int')
-            completed = self.convertFromDB(row[4], 'int', 'int')
-            error = self.convertFromDB(row[5], 'str', 'varchar(1023)')
-            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
-            parent = self.convertFromDB(row[9], 'long', 'long')
-            
-            loop_exec = DBLoopExec(ts_start=ts_start,
-                                   ts_end=ts_end,
-                                   iteration=iteration,
-                                   completed=completed,
-                                   error=error,
-                                   id=id)
-            loop_exec.db_parentType = parentType
-            loop_exec.db_entity_id = entity_id
-            loop_exec.db_entity_type = entity_type
-            loop_exec.db_parent = parent
-            loop_exec.is_dirty = False
-            res[('loop_exec', id)] = loop_exec
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            other = DBOther(key=key,
+                            value=value,
+                            id=id)
+            other.db_parentType = parentType
+            other.db_entity_id = entity_id
+            other.db_entity_type = entity_type
+            other.db_parent = parent
+            other.is_dirty = False
+            res[('other', id)] = other
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow_exec':
-            p = all_objects[('workflow_exec', obj.db_parent)]
-            p.db_add_item_exec(obj)
-        elif obj.db_parentType == 'group_exec':
-            p = all_objects[('group_exec', obj.db_parent)]
-            p.db_add_item_exec(obj)
-        elif obj.db_parentType == 'loop_exec':
-            p = all_objects[('loop_exec', obj.db_parent)]
-            p.db_add_item_exec(obj)
-        elif obj.db_parentType == 'module_exec':
-            p = all_objects[('module_exec', obj.db_parent)]
-            p.db_add_loop_exec(obj)
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_other(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'loop_exec'
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6496,21 +6416,12 @@ class DBLoopExecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
-            columnMap['ts_start'] = \
-                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
-        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
-            columnMap['ts_end'] = \
-                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
-        if hasattr(obj, 'db_iteration') and obj.db_iteration is not None:
-            columnMap['iteration'] = \
-                self.convertToDB(obj.db_iteration, 'int', 'int')
-        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
-            columnMap['completed'] = \
-                self.convertToDB(obj.db_completed, 'int', 'int')
-        if hasattr(obj, 'db_error') and obj.db_error is not None:
-            columnMap['error'] = \
-                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['okey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(255)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -6534,8 +6445,8 @@ class DBLoopExecSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'loop_exec'
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6545,21 +6456,12 @@ class DBLoopExecSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
-            columnMap['ts_start'] = \
-                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
-        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
-            columnMap['ts_end'] = \
-                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
-        if hasattr(obj, 'db_iteration') and obj.db_iteration is not None:
-            columnMap['iteration'] = \
-                self.convertToDB(obj.db_iteration, 'int', 'int')
-        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
-            columnMap['completed'] = \
-                self.convertToDB(obj.db_completed, 'int', 'int')
-        if hasattr(obj, 'db_error') and obj.db_error is not None:
-            columnMap['error'] = \
-                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['okey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(255)')
         if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
             columnMap['parent_type'] = \
                 self.convertToDB(obj.db_parentType, 'str', 'char(32)')
@@ -6584,12 +6486,10 @@ class DBLoopExecSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_item_execs:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'loop_exec'
+        table = 'other'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6598,18 +6498,18 @@ class DBLoopExecSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
+class DBAbstractionSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'mashup_action_annotation'
+        self.table = 'abstraction'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action_annotation'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
         whereMap = global_props
         orderBy = 'id'
 
@@ -6618,31 +6518,35 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
-            action_id = self.convertFromDB(row[3], 'long', 'int')
-            date = self.convertFromDB(row[4], 'datetime', 'datetime')
-            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            mashuptrail = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            internal_version = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            parent = self.convertFromDB(row[10], 'long', 'long')
             
-            mashup_actionAnnotation = DBMashupActionAnnotation(key=key,
-                                                               value=value,
-                                                               action_id=action_id,
-                                                               date=date,
-                                                               user=user,
-                                                               id=id)
-            mashup_actionAnnotation.db_mashuptrail = mashuptrail
-            mashup_actionAnnotation.db_entity_id = entity_id
-            mashup_actionAnnotation.db_entity_type = entity_type
-            mashup_actionAnnotation.is_dirty = False
-            res[('mashup_actionAnnotation', id)] = mashup_actionAnnotation
+            abstraction = DBAbstraction(cache=cache,
+                                        name=name,
+                                        namespace=namespace,
+                                        package=package,
+                                        version=version,
+                                        internal_version=internal_version,
+                                        id=id)
+            abstraction.db_parentType = parentType
+            abstraction.db_entity_id = entity_id
+            abstraction.db_entity_type = entity_type
+            abstraction.db_parent = parent
+            abstraction.is_dirty = False
+            res[('abstraction', id)] = abstraction
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action_annotation'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -6651,38 +6555,48 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
-            action_id = self.convertFromDB(row[3], 'long', 'int')
-            date = self.convertFromDB(row[4], 'datetime', 'datetime')
-            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
-            mashuptrail = self.convertFromDB(row[6], 'long', 'int')
-            entity_id = self.convertFromDB(row[7], 'long', 'int')
-            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            internal_version = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            parent = self.convertFromDB(row[10], 'long', 'long')
             
-            mashup_actionAnnotation = DBMashupActionAnnotation(key=key,
-                                                               value=value,
-                                                               action_id=action_id,
-                                                               date=date,
-                                                               user=user,
-                                                               id=id)
-            mashup_actionAnnotation.db_mashuptrail = mashuptrail
-            mashup_actionAnnotation.db_entity_id = entity_id
-            mashup_actionAnnotation.db_entity_type = entity_type
-            mashup_actionAnnotation.is_dirty = False
-            res[('mashup_actionAnnotation', id)] = mashup_actionAnnotation
+            abstraction = DBAbstraction(cache=cache,
+                                        name=name,
+                                        namespace=namespace,
+                                        package=package,
+                                        version=version,
+                                        internal_version=internal_version,
+                                        id=id)
+            abstraction.db_parentType = parentType
+            abstraction.db_entity_id = entity_id
+            abstraction.db_entity_type = entity_type
+            abstraction.db_parent = parent
+            abstraction.is_dirty = False
+            res[('abstraction', id)] = abstraction
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('mashuptrail', obj.db_mashuptrail) in all_objects:
-            p = all_objects[('mashuptrail', obj.db_mashuptrail)]
-            p.db_add_actionAnnotation(obj)
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_module(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action_annotation'
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6692,30 +6606,36 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['akey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action_id, 'long', 'int')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_internal_version') and obj.db_internal_version is not None:
+            columnMap['internal_version'] = \
+                self.convertToDB(obj.db_internal_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -6726,9 +6646,9 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
-            return None
-        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'mashup_action_annotation'
+            return None
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6738,30 +6658,36 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_key') and obj.db_key is not None:
-            columnMap['akey'] = \
-                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_value') and obj.db_value is not None:
-            columnMap['value'] = \
-                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
-        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
-            columnMap['action_id'] = \
-                self.convertToDB(obj.db_action_id, 'long', 'int')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_internal_version') and obj.db_internal_version is not None:
+            columnMap['internal_version'] = \
+                self.convertToDB(obj.db_internal_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -6774,10 +6700,19 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        if obj.db_location is not None:
+            child = obj.db_location
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_functions:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'mashup_action_annotation'
+        table = 'abstraction'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6786,18 +6721,18 @@ class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBConnectionSQLDAOBase(SQLDAO):
+class DBMashuptrailSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'connection_tbl'
+        self.table = 'mashuptrail'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'connection_tbl'
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
         whereMap = global_props
         orderBy = 'id'
 
@@ -6806,23 +6741,26 @@ class DBConnectionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            parentType = self.convertFromDB(row[1], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[2], 'long', 'int')
-            entity_type = self.convertFromDB(row[3], 'str', 'char(16)')
-            parent = self.convertFromDB(row[4], 'long', 'long')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'char(36)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            vtVersion = self.convertFromDB(row[3], 'long', 'int')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
             
-            connection = DBConnection(id=id)
-            connection.db_parentType = parentType
-            connection.db_entity_id = entity_id
-            connection.db_entity_type = entity_type
-            connection.db_parent = parent
-            connection.is_dirty = False
-            res[('connection', id)] = connection
+            mashuptrail = DBMashuptrail(name=name,
+                                        version=version,
+                                        vtVersion=vtVersion,
+                                        last_modified=last_modified,
+                                        id=id)
+            mashuptrail.db_entity_type = entity_type
+            mashuptrail.is_dirty = False
+            res[('mashuptrail', id)] = mashuptrail
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'connection_tbl'
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -6831,36 +6769,31 @@ class DBConnectionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            parentType = self.convertFromDB(row[1], 'str', 'char(32)')
-            entity_id = self.convertFromDB(row[2], 'long', 'int')
-            entity_type = self.convertFromDB(row[3], 'str', 'char(16)')
-            parent = self.convertFromDB(row[4], 'long', 'long')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'char(36)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            vtVersion = self.convertFromDB(row[3], 'long', 'int')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
             
-            connection = DBConnection(id=id)
-            connection.db_parentType = parentType
-            connection.db_entity_id = entity_id
-            connection.db_entity_type = entity_type
-            connection.db_parent = parent
-            connection.is_dirty = False
-            res[('connection', id)] = connection
+            mashuptrail = DBMashuptrail(name=name,
+                                        version=version,
+                                        vtVersion=vtVersion,
+                                        last_modified=last_modified,
+                                        id=id)
+            mashuptrail.db_entity_type = entity_type
+            mashuptrail.is_dirty = False
+            res[('mashuptrail', id)] = mashuptrail
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if obj.db_parentType == 'workflow':
-            p = all_objects[('workflow', obj.db_parent)]
-            p.db_add_connection(obj)
-        elif obj.db_parentType == 'add':
-            p = all_objects[('add', obj.db_parent)]
-            p.db_add_data(obj)
-        elif obj.db_parentType == 'change':
-            p = all_objects[('change', obj.db_parent)]
-            p.db_add_data(obj)
-        
+        pass
+    
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'connection_tbl'
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6870,18 +6803,21 @@ class DBConnectionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'char(36)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_vtVersion') and obj.db_vtVersion is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vtVersion, 'long', 'int')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -6889,12 +6825,17 @@ class DBConnectionSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
-        table = 'connection_tbl'
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6904,18 +6845,21 @@ class DBConnectionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'char(36)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_vtVersion') and obj.db_vtVersion is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vtVersion, 'long', 'int')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -6925,15 +6869,24 @@ class DBConnectionSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_ports:
+        for child in obj.db_actions:
+            child.db_mashuptrail = obj.db_id
+        for child in obj.db_annotations:
             child.db_parentType = obj.vtType
             child.db_parent = obj.db_id
+        for child in obj.db_actionAnnotations:
+            child.db_mashuptrail = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'connection_tbl'
+        table = 'mashuptrail'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -6942,18 +6895,18 @@ class DBConnectionSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBPEFunctionSQLDAOBase(SQLDAO):
+class DBRegistrySQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'pe_function'
+        self.table = 'registry'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_function'
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
         whereMap = global_props
         orderBy = 'id'
 
@@ -6962,28 +6915,27 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            module_id = self.convertFromDB(row[1], 'long', 'int')
-            port_name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            is_alias = self.convertFromDB(row[3], 'long', 'int')
-            parentType = self.convertFromDB(row[4], 'str', 'char(32)')
-            parameter_exploration = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            root_descriptor_id = self.convertFromDB(row[3], 'long', 'int')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
             
-            pe_function = DBPEFunction(module_id=module_id,
-                                       port_name=port_name,
-                                       id=id)
-            pe_function.db_parentType = parentType
-            pe_function.db_parameter_exploration = parameter_exploration
-            pe_function.db_entity_id = entity_id
-            pe_function.db_entity_type = entity_type
-            pe_function.is_dirty = False
-            res[('pe_function', id)] = pe_function
+            registry = DBRegistry(entity_type=entity_type,
+                                  version=version,
+                                  root_descriptor_id=root_descriptor_id,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            registry.is_dirty = False
+            res[('registry', id)] = registry
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_function'
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -6992,35 +6944,32 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            module_id = self.convertFromDB(row[1], 'long', 'int')
-            port_name = self.convertFromDB(row[2], 'str', 'varchar(255)')
-            is_alias = self.convertFromDB(row[3], 'long', 'int')
-            parentType = self.convertFromDB(row[4], 'str', 'char(32)')
-            parameter_exploration = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            root_descriptor_id = self.convertFromDB(row[3], 'long', 'int')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
             
-            pe_function = DBPEFunction(module_id=module_id,
-                                       port_name=port_name,
-                                       id=id)
-            pe_function.db_parentType = parentType
-            pe_function.db_parameter_exploration = parameter_exploration
-            pe_function.db_entity_id = entity_id
-            pe_function.db_entity_type = entity_type
-            pe_function.is_dirty = False
-            res[('pe_function', id)] = pe_function
+            registry = DBRegistry(entity_type=entity_type,
+                                  version=version,
+                                  root_descriptor_id=root_descriptor_id,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            registry.is_dirty = False
+            res[('registry', id)] = registry
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('parameter_exploration', obj.db_parameter_exploration) in all_objects:
-            p = all_objects[('parameter_exploration', obj.db_parameter_exploration)]
-            p.db_add_function(obj)
-        
+        pass
+    
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_function'
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7030,27 +6979,21 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
-            columnMap['module_id'] = \
-                self.convertToDB(obj.db_module_id, 'long', 'int')
-        if hasattr(obj, 'db_port_name') and obj.db_port_name is not None:
-            columnMap['port_name'] = \
-                self.convertToDB(obj.db_port_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_is_alias') and obj.db_is_alias is not None:
-            columnMap['is_alias'] = \
-                self.convertToDB(obj.db_is_alias, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_parameter_exploration') and obj.db_parameter_exploration is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parameter_exploration, 'long', 'int')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_root_descriptor_id') and obj.db_root_descriptor_id is not None:
+            columnMap['root_descriptor_id'] = \
+                self.convertToDB(obj.db_root_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -7058,12 +7001,19 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
-        table = 'pe_function'
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7073,27 +7023,21 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
-            columnMap['module_id'] = \
-                self.convertToDB(obj.db_module_id, 'long', 'int')
-        if hasattr(obj, 'db_port_name') and obj.db_port_name is not None:
-            columnMap['port_name'] = \
-                self.convertToDB(obj.db_port_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_is_alias') and obj.db_is_alias is not None:
-            columnMap['is_alias'] = \
-                self.convertToDB(obj.db_is_alias, 'long', 'int')
-        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
-            columnMap['parent_type'] = \
-                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
-        if hasattr(obj, 'db_parameter_exploration') and obj.db_parameter_exploration is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_parameter_exploration, 'long', 'int')
-        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
-            columnMap['entity_id'] = \
-                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_root_descriptor_id') and obj.db_root_descriptor_id is not None:
+            columnMap['root_descriptor_id'] = \
+                self.convertToDB(obj.db_root_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -7103,14 +7047,21 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_parameters:
-            child.db_pe_function = obj.db_id
+        for child in obj.db_packages:
+            child.db_registry = obj.db_id
         
     def delete_sql_column(self, db, obj, global_props):
-        table = 'pe_function'
+        table = 'registry'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7119,18 +7070,18 @@ class DBPEFunctionSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBActionSQLDAOBase(SQLDAO):
+class DBAnnotationSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'action'
+        self.table = 'annotation'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action'
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
         whereMap = global_props
         orderBy = 'id'
 
@@ -7139,29 +7090,27 @@ class DBActionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            prevId = self.convertFromDB(row[1], 'long', 'int')
-            date = self.convertFromDB(row[2], 'datetime', 'datetime')
-            session = self.convertFromDB(row[3], 'long', 'int')
-            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'mediumtext')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            action = DBAction(prevId=prevId,
-                              date=date,
-                              session=session,
-                              user=user,
-                              id=id)
-            action.db_vistrail = vistrail
-            action.db_entity_id = entity_id
-            action.db_entity_type = entity_type
-            action.is_dirty = False
-            res[('action', id)] = action
+            annotation = DBAnnotation(key=key,
+                                      value=value,
+                                      id=id)
+            annotation.db_parentType = parentType
+            annotation.db_entity_id = entity_id
+            annotation.db_entity_type = entity_type
+            annotation.db_parent = parent
+            annotation.is_dirty = False
+            res[('annotation', id)] = annotation
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action'
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -7170,36 +7119,67 @@ class DBActionSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            prevId = self.convertFromDB(row[1], 'long', 'int')
-            date = self.convertFromDB(row[2], 'datetime', 'datetime')
-            session = self.convertFromDB(row[3], 'long', 'int')
-            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
-            vistrail = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'mediumtext')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
             
-            action = DBAction(prevId=prevId,
-                              date=date,
-                              session=session,
-                              user=user,
-                              id=id)
-            action.db_vistrail = vistrail
-            action.db_entity_id = entity_id
-            action.db_entity_type = entity_type
-            action.is_dirty = False
-            res[('action', id)] = action
+            annotation = DBAnnotation(key=key,
+                                      value=value,
+                                      id=id)
+            annotation.db_parentType = parentType
+            annotation.db_entity_id = entity_id
+            annotation.db_entity_type = entity_type
+            annotation.db_parent = parent
+            annotation.is_dirty = False
+            res[('annotation', id)] = annotation
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('vistrail', obj.db_vistrail) in all_objects:
-            p = all_objects[('vistrail', obj.db_vistrail)]
-            p.db_add_action(obj)
+        if obj.db_parentType == 'vistrail':
+            p = all_objects[('vistrail', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'module_exec':
+            p = all_objects[('module_exec', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'action':
+            p = all_objects[('action', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'mashuptrail':
+            p = all_objects[('mashuptrail', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_annotation(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action'
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7209,27 +7189,24 @@ class DBActionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
-            columnMap['prev_id'] = \
-                self.convertToDB(obj.db_prevId, 'long', 'int')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
-        if hasattr(obj, 'db_session') and obj.db_session is not None:
-            columnMap['session'] = \
-                self.convertToDB(obj.db_session, 'long', 'int')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -7241,8 +7218,8 @@ class DBActionSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
-        table = 'action'
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7252,27 +7229,24 @@ class DBActionSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
-            columnMap['prev_id'] = \
-                self.convertToDB(obj.db_prevId, 'long', 'int')
-        if hasattr(obj, 'db_date') and obj.db_date is not None:
-            columnMap['date'] = \
-                self.convertToDB(obj.db_date, 'datetime', 'datetime')
-        if hasattr(obj, 'db_session') and obj.db_session is not None:
-            columnMap['session'] = \
-                self.convertToDB(obj.db_session, 'long', 'int')
-        if hasattr(obj, 'db_user') and obj.db_user is not None:
-            columnMap['user'] = \
-                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
-            columnMap['parent_id'] = \
-                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -7285,14 +7259,10 @@ class DBActionSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_operations:
-            child.db_action = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'action'
+        table = 'annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7301,18 +7271,18 @@ class DBActionSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBDeleteSQLDAOBase(SQLDAO):
+class DBParameterExplorationSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'delete_tbl'
+        self.table = 'parameter_exploration'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'delete_tbl'
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
         whereMap = global_props
         orderBy = 'id'
 
@@ -7321,29 +7291,33 @@ class DBDeleteSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            objectId = self.convertFromDB(row[2], 'long', 'int')
-            parentObjId = self.convertFromDB(row[3], 'long', 'int')
-            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
-            action = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            action_id = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            date = self.convertFromDB(row[3], 'datetime', 'datetime')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            dims = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            layout = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            delete = DBDelete(what=what,
-                              objectId=objectId,
-                              parentObjId=parentObjId,
-                              parentObjType=parentObjType,
-                              id=id)
-            delete.db_action = action
-            delete.db_entity_id = entity_id
-            delete.db_entity_type = entity_type
-            delete.is_dirty = False
-            res[('delete', id)] = delete
+            parameter_exploration = DBParameterExploration(action_id=action_id,
+                                                           name=name,
+                                                           date=date,
+                                                           user=user,
+                                                           dims=dims,
+                                                           layout=layout,
+                                                           id=id)
+            parameter_exploration.db_vistrail = vistrail
+            parameter_exploration.db_entity_id = entity_id
+            parameter_exploration.db_entity_type = entity_type
+            parameter_exploration.is_dirty = False
+            res[('parameter_exploration', id)] = parameter_exploration
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'delete_tbl'
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -7352,36 +7326,40 @@ class DBDeleteSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
-            objectId = self.convertFromDB(row[2], 'long', 'int')
-            parentObjId = self.convertFromDB(row[3], 'long', 'int')
-            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
-            action = self.convertFromDB(row[5], 'long', 'int')
-            entity_id = self.convertFromDB(row[6], 'long', 'int')
-            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            action_id = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            date = self.convertFromDB(row[3], 'datetime', 'datetime')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            dims = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            layout = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
             
-            delete = DBDelete(what=what,
-                              objectId=objectId,
-                              parentObjId=parentObjId,
-                              parentObjType=parentObjType,
-                              id=id)
-            delete.db_action = action
-            delete.db_entity_id = entity_id
-            delete.db_entity_type = entity_type
-            delete.is_dirty = False
-            res[('delete', id)] = delete
+            parameter_exploration = DBParameterExploration(action_id=action_id,
+                                                           name=name,
+                                                           date=date,
+                                                           user=user,
+                                                           dims=dims,
+                                                           layout=layout,
+                                                           id=id)
+            parameter_exploration.db_vistrail = vistrail
+            parameter_exploration.db_entity_id = entity_id
+            parameter_exploration.db_entity_type = entity_type
+            parameter_exploration.is_dirty = False
+            res[('parameter_exploration', id)] = parameter_exploration
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        if ('action', obj.db_action) in all_objects:
-            p = all_objects[('action', obj.db_action)]
-            p.db_add_operation(obj)
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_parameter_exploration(obj)
         
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'delete_tbl'
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7391,21 +7369,27 @@ class DBDeleteSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_what') and obj.db_what is not None:
-            columnMap['what'] = \
-                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
-            columnMap['object_id'] = \
-                self.convertToDB(obj.db_objectId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
-            columnMap['par_obj_id'] = \
-                self.convertToDB(obj.db_parentObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
-            columnMap['par_obj_type'] = \
-                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
-        if hasattr(obj, 'db_action') and obj.db_action is not None:
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
             columnMap['action_id'] = \
-                self.convertToDB(obj.db_action, 'long', 'int')
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_dims') and obj.db_dims is not None:
+            columnMap['dims'] = \
+                self.convertToDB(obj.db_dims, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -7423,8 +7407,8 @@ class DBDeleteSQLDAOBase(SQLDAO):
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
-        table = 'delete_tbl'
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7434,21 +7418,27 @@ class DBDeleteSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_what') and obj.db_what is not None:
-            columnMap['what'] = \
-                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
-            columnMap['object_id'] = \
-                self.convertToDB(obj.db_objectId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
-            columnMap['par_obj_id'] = \
-                self.convertToDB(obj.db_parentObjId, 'long', 'int')
-        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
-            columnMap['par_obj_type'] = \
-                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
-        if hasattr(obj, 'db_action') and obj.db_action is not None:
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
             columnMap['action_id'] = \
-                self.convertToDB(obj.db_action, 'long', 'int')
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_dims') and obj.db_dims is not None:
+            columnMap['dims'] = \
+                self.convertToDB(obj.db_dims, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
         if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
             columnMap['entity_id'] = \
                 self.convertToDB(obj.db_entity_id, 'long', 'int')
@@ -7467,10 +7457,11 @@ class DBDeleteSQLDAOBase(SQLDAO):
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        pass
-    
+        for child in obj.db_functions:
+            child.db_parameter_exploration = obj.db_id
+        
     def delete_sql_column(self, db, obj, global_props):
-        table = 'delete_tbl'
+        table = 'parameter_exploration'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7479,18 +7470,18 @@ class DBDeleteSQLDAOBase(SQLDAO):
         dbCommand = self.createSQLDelete(table, whereMap)
         self.executeSQL(db, dbCommand, False)
 
-class DBVistrailSQLDAOBase(SQLDAO):
+class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
-        self.table = 'vistrail'
+        self.table = 'mashup_action_annotation'
 
     def getDao(self, dao):
         return self.daoList[dao]
 
     def get_sql_columns(self, db, global_props,lock=False):
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
-        table = 'vistrail'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
         whereMap = global_props
         orderBy = 'id'
 
@@ -7499,25 +7490,31 @@ class DBVistrailSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            vistrail = DBVistrail(entity_type=entity_type,
-                                  version=version,
-                                  name=name,
-                                  last_modified=last_modified,
-                                  id=id)
-            vistrail.is_dirty = False
-            res[('vistrail', id)] = vistrail
+            mashup_actionAnnotation = DBMashupActionAnnotation(key=key,
+                                                               value=value,
+                                                               action_id=action_id,
+                                                               date=date,
+                                                               user=user,
+                                                               id=id)
+            mashup_actionAnnotation.db_mashuptrail = mashuptrail
+            mashup_actionAnnotation.db_entity_id = entity_id
+            mashup_actionAnnotation.db_entity_type = entity_type
+            mashup_actionAnnotation.is_dirty = False
+            res[('mashup_actionAnnotation', id)] = mashup_actionAnnotation
         return res
 
     def get_sql_select(self, db, global_props,lock=False):
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
-        table = 'vistrail'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
         whereMap = global_props
         orderBy = 'id'
         return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
@@ -7526,30 +7523,38 @@ class DBVistrailSQLDAOBase(SQLDAO):
         res = {}
         for row in data:
             id = self.convertFromDB(row[0], 'long', 'int')
-            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
-            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
-            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
-            version = self.convertFromDB(row[2], 'str', 'char(16)')
-            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
-            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
             
-            vistrail = DBVistrail(entity_type=entity_type,
-                                  version=version,
-                                  name=name,
-                                  last_modified=last_modified,
-                                  id=id)
-            vistrail.is_dirty = False
-            res[('vistrail', id)] = vistrail
+            mashup_actionAnnotation = DBMashupActionAnnotation(key=key,
+                                                               value=value,
+                                                               action_id=action_id,
+                                                               date=date,
+                                                               user=user,
+                                                               id=id)
+            mashup_actionAnnotation.db_mashuptrail = mashuptrail
+            mashup_actionAnnotation.db_entity_id = entity_id
+            mashup_actionAnnotation.db_entity_type = entity_type
+            mashup_actionAnnotation.is_dirty = False
+            res[('mashup_actionAnnotation', id)] = mashup_actionAnnotation
         return res
 
     def from_sql_fast(self, obj, all_objects):
-        pass
-    
+        if ('mashuptrail', obj.db_mashuptrail) in all_objects:
+            p = all_objects[('mashuptrail', obj.db_mashuptrail)]
+            p.db_add_actionAnnotation(obj)
+        
     def set_sql_columns(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
-        table = 'vistrail'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7559,18 +7564,30 @@ class DBVistrailSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -7578,19 +7595,12 @@ class DBVistrailSQLDAOBase(SQLDAO):
         else:
             dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
         lastId = self.executeSQL(db, dbCommand, False)
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         
     def set_sql_command(self, db, obj, global_props, do_copy=True):
         if not do_copy and not obj.is_dirty:
             return None
-        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
-        table = 'vistrail'
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7600,18 +7610,30 @@ class DBVistrailSQLDAOBase(SQLDAO):
         if hasattr(obj, 'db_id') and obj.db_id is not None:
             columnMap['id'] = \
                 self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
         if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
             columnMap['entity_type'] = \
                 self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_version') and obj.db_version is not None:
-            columnMap['version'] = \
-                self.convertToDB(obj.db_version, 'str', 'char(16)')
-        if hasattr(obj, 'db_name') and obj.db_name is not None:
-            columnMap['name'] = \
-                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
-        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
-            columnMap['last_modified'] = \
-                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
         columnMap.update(global_props)
 
         if obj.is_new or do_copy:
@@ -7621,32 +7643,13 @@ class DBVistrailSQLDAOBase(SQLDAO):
         return dbCommand
 
     def set_sql_process(self, obj, global_props, lastId):
-        if obj.db_id is None:
-            obj.db_id = lastId
-            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
-        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
-            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
-        if hasattr(obj, 'db_id') and obj.db_id is not None:
-            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
         pass
 
     def to_sql_fast(self, obj, do_copy=True):
-        for child in obj.db_actions:
-            child.db_vistrail = obj.db_id
-        for child in obj.db_tags:
-            child.db_vistrail = obj.db_id
-        for child in obj.db_annotations:
-            child.db_parentType = obj.vtType
-            child.db_parent = obj.db_id
-        for child in obj.db_vistrailVariables:
-            child.db_vistrail = obj.db_id
-        for child in obj.db_parameter_explorations:
-            child.db_vistrail = obj.db_id
-        for child in obj.db_actionAnnotations:
-            child.db_vistrail = obj.db_id
-        
+        pass
+    
     def delete_sql_column(self, db, obj, global_props):
-        table = 'vistrail'
+        table = 'mashup_action_annotation'
         whereMap = {}
         whereMap.update(global_props)
         if obj.db_id is not None:
@@ -7902,83 +7905,83 @@ class SQLDAOListBase(dict):
         if daos is not None:
             dict.update(self, daos)
 
-        if 'vistrailVariable' not in self:
-            self['vistrailVariable'] = DBVistrailVariableSQLDAOBase(self)
-        if 'portSpec' not in self:
-            self['portSpec'] = DBPortSpecSQLDAOBase(self)
+        if 'mashup_alias' not in self:
+            self['mashup_alias'] = DBMashupAliasSQLDAOBase(self)
+        if 'group' not in self:
+            self['group'] = DBGroupSQLDAOBase(self)
+        if 'add' not in self:
+            self['add'] = DBAddSQLDAOBase(self)
+        if 'group_exec' not in self:
+            self['group_exec'] = DBGroupExecSQLDAOBase(self)
+        if 'parameter' not in self:
+            self['parameter'] = DBParameterSQLDAOBase(self)
+        if 'vistrail' not in self:
+            self['vistrail'] = DBVistrailSQLDAOBase(self)
         if 'module' not in self:
             self['module'] = DBModuleSQLDAOBase(self)
-        if 'module_descriptor' not in self:
-            self['module_descriptor'] = DBModuleDescriptorSQLDAOBase(self)
-        if 'tag' not in self:
-            self['tag'] = DBTagSQLDAOBase(self)
         if 'port' not in self:
             self['port'] = DBPortSQLDAOBase(self)
-        if 'group' not in self:
-            self['group'] = DBGroupSQLDAOBase(self)
+        if 'pe_function' not in self:
+            self['pe_function'] = DBPEFunctionSQLDAOBase(self)
+        if 'workflow' not in self:
+            self['workflow'] = DBWorkflowSQLDAOBase(self)
+        if 'mashup_action' not in self:
+            self['mashup_action'] = DBMashupActionSQLDAOBase(self)
+        if 'change' not in self:
+            self['change'] = DBChangeSQLDAOBase(self)
+        if 'package' not in self:
+            self['package'] = DBPackageSQLDAOBase(self)
+        if 'loop_exec' not in self:
+            self['loop_exec'] = DBLoopExecSQLDAOBase(self)
+        if 'connection' not in self:
+            self['connection'] = DBConnectionSQLDAOBase(self)
+        if 'action' not in self:
+            self['action'] = DBActionSQLDAOBase(self)
+        if 'portSpec' not in self:
+            self['portSpec'] = DBPortSpecSQLDAOBase(self)
         if 'log' not in self:
             self['log'] = DBLogSQLDAOBase(self)
-        if 'mashup_alias' not in self:
-            self['mashup_alias'] = DBMashupAliasSQLDAOBase(self)
-        if 'mashup' not in self:
-            self['mashup'] = DBMashupSQLDAOBase(self)
-        if 'portSpecItem' not in self:
-            self['portSpecItem'] = DBPortSpecItemSQLDAOBase(self)
-        if 'machine' not in self:
-            self['machine'] = DBMachineSQLDAOBase(self)
-        if 'add' not in self:
-            self['add'] = DBAddSQLDAOBase(self)
-        if 'other' not in self:
-            self['other'] = DBOtherSQLDAOBase(self)
-        if 'location' not in self:
-            self['location'] = DBLocationSQLDAOBase(self)
         if 'pe_parameter' not in self:
             self['pe_parameter'] = DBPEParameterSQLDAOBase(self)
-        if 'parameter' not in self:
-            self['parameter'] = DBParameterSQLDAOBase(self)
-        if 'plugin_data' not in self:
-            self['plugin_data'] = DBPluginDataSQLDAOBase(self)
+        if 'workflow_exec' not in self:
+            self['workflow_exec'] = DBWorkflowExecSQLDAOBase(self)
+        if 'location' not in self:
+            self['location'] = DBLocationSQLDAOBase(self)
         if 'function' not in self:
             self['function'] = DBFunctionSQLDAOBase(self)
         if 'actionAnnotation' not in self:
             self['actionAnnotation'] = DBActionAnnotationSQLDAOBase(self)
+        if 'plugin_data' not in self:
+            self['plugin_data'] = DBPluginDataSQLDAOBase(self)
+        if 'delete' not in self:
+            self['delete'] = DBDeleteSQLDAOBase(self)
+        if 'vistrailVariable' not in self:
+            self['vistrailVariable'] = DBVistrailVariableSQLDAOBase(self)
+        if 'module_descriptor' not in self:
+            self['module_descriptor'] = DBModuleDescriptorSQLDAOBase(self)
+        if 'tag' not in self:
+            self['tag'] = DBTagSQLDAOBase(self)
+        if 'portSpecItem' not in self:
+            self['portSpecItem'] = DBPortSpecItemSQLDAOBase(self)
+        if 'mashup_component' not in self:
+            self['mashup_component'] = DBMashupComponentSQLDAOBase(self)
+        if 'mashup' not in self:
+            self['mashup'] = DBMashupSQLDAOBase(self)
+        if 'machine' not in self:
+            self['machine'] = DBMachineSQLDAOBase(self)
+        if 'other' not in self:
+            self['other'] = DBOtherSQLDAOBase(self)
         if 'abstraction' not in self:
             self['abstraction'] = DBAbstractionSQLDAOBase(self)
-        if 'workflow' not in self:
-            self['workflow'] = DBWorkflowSQLDAOBase(self)
-        if 'mashup_action' not in self:
-            self['mashup_action'] = DBMashupActionSQLDAOBase(self)
         if 'mashuptrail' not in self:
             self['mashuptrail'] = DBMashuptrailSQLDAOBase(self)
         if 'registry' not in self:
             self['registry'] = DBRegistrySQLDAOBase(self)
-        if 'mashup_component' not in self:
-            self['mashup_component'] = DBMashupComponentSQLDAOBase(self)
         if 'annotation' not in self:
             self['annotation'] = DBAnnotationSQLDAOBase(self)
-        if 'change' not in self:
-            self['change'] = DBChangeSQLDAOBase(self)
-        if 'group_exec' not in self:
-            self['group_exec'] = DBGroupExecSQLDAOBase(self)
-        if 'package' not in self:
-            self['package'] = DBPackageSQLDAOBase(self)
-        if 'workflow_exec' not in self:
-            self['workflow_exec'] = DBWorkflowExecSQLDAOBase(self)
         if 'parameter_exploration' not in self:
             self['parameter_exploration'] = DBParameterExplorationSQLDAOBase(self)
-        if 'loop_exec' not in self:
-            self['loop_exec'] = DBLoopExecSQLDAOBase(self)
         if 'mashup_actionAnnotation' not in self:
             self['mashup_actionAnnotation'] = DBMashupActionAnnotationSQLDAOBase(self)
-        if 'connection' not in self:
-            self['connection'] = DBConnectionSQLDAOBase(self)
-        if 'pe_function' not in self:
-            self['pe_function'] = DBPEFunctionSQLDAOBase(self)
-        if 'action' not in self:
-            self['action'] = DBActionSQLDAOBase(self)
-        if 'delete' not in self:
-            self['delete'] = DBDeleteSQLDAOBase(self)
-        if 'vistrail' not in self:
-            self['vistrail'] = DBVistrailSQLDAOBase(self)
         if 'module_exec' not in self:
             self['module_exec'] = DBModuleExecSQLDAOBase(self)
diff --git a/vistrails/db/versions/v1_0_3/persistence/sql/sql_dao.py b/vistrails/db/versions/v1_0_3/persistence/sql/sql_dao.py
index eab1acc..9eb069d 100644
--- a/vistrails/db/versions/v1_0_3/persistence/sql/sql_dao.py
+++ b/vistrails/db/versions/v1_0_3/persistence/sql/sql_dao.py
@@ -1,44 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
 
+from vistrails.core import debug
+from vistrails.core.system import strftime, time_strptime
 from vistrails.db import VistrailsDBException
 from vistrails.db.services.io import get_db_lib
-from vistrails.core import debug
 
 class SQLDAO:
     def __init__(self):
@@ -58,13 +61,13 @@ class SQLDAO:
                 if db_type == 'date':
                     return value
                 else:
-                    return date(*strptime(str(value), '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
             elif type == 'datetime':
                 if db_type == 'datetime':
                     return value
                 else:
-                    return datetime(*strptime(str(value), 
-                                              '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertWarning(self, before, after, _from, to):
@@ -121,7 +124,7 @@ class SQLDAO:
             elif type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
 
diff --git a/vistrails/db/versions/v1_0_3/persistence/xml/__init__.py b/vistrails/db/versions/v1_0_3/persistence/xml/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/db/versions/v1_0_3/persistence/xml/__init__.py
+++ b/vistrails/db/versions/v1_0_3/persistence/xml/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_3/persistence/xml/auto_gen.py b/vistrails/db/versions/v1_0_3/persistence/xml/auto_gen.py
index d09cce4..297a51e 100644
--- a/vistrails/db/versions/v1_0_3/persistence/xml/auto_gen.py
+++ b/vistrails/db/versions/v1_0_3/persistence/xml/auto_gen.py
@@ -1,242 +1,49 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """generated automatically by auto_dao.py"""
 
+from __future__ import division
+
 from vistrails.core.system import get_elementtree_library
 ElementTree = get_elementtree_library()
 
 from xml_dao import XMLDAO
 from vistrails.db.versions.v1_0_3.domain import *
 
-class DBOpmProcessIdEffectXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'effect':
-            return None
-        
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
-        
-        obj = DBOpmProcessIdEffect(id=id)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, opm_process_id_effect, node=None):
-        if node is None:
-            node = ElementTree.Element('effect')
-        
-        # set attributes
-        node.set('id',self.convertToStr(opm_process_id_effect.db_id, 'str'))
-        
-        return node
-
-class DBVistrailVariableXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'vistrailVariable':
-            return None
-        
-        # read attributes
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('uuid', None)
-        uuid = self.convertFromStr(data, 'str')
-        data = node.get('package', None)
-        package = self.convertFromStr(data, 'str')
-        data = node.get('module', None)
-        module = self.convertFromStr(data, 'str')
-        data = node.get('namespace', None)
-        namespace = self.convertFromStr(data, 'str')
-        data = node.get('value', None)
-        value = self.convertFromStr(data, 'str')
-        
-        obj = DBVistrailVariable(name=name,
-                                 uuid=uuid,
-                                 package=package,
-                                 module=module,
-                                 namespace=namespace,
-                                 value=value)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, vistrailVariable, node=None):
-        if node is None:
-            node = ElementTree.Element('vistrailVariable')
-        
-        # set attributes
-        node.set('name',self.convertToStr(vistrailVariable.db_name, 'str'))
-        node.set('uuid',self.convertToStr(vistrailVariable.db_uuid, 'str'))
-        node.set('package',self.convertToStr(vistrailVariable.db_package, 'str'))
-        node.set('module',self.convertToStr(vistrailVariable.db_module, 'str'))
-        node.set('namespace',self.convertToStr(vistrailVariable.db_namespace, 'str'))
-        node.set('value',self.convertToStr(vistrailVariable.db_value, 'str'))
-        
-        return node
-
-class DBProvAgentXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'prov:agent':
-            return None
-        
-        # read attributes
-        data = node.get('prov:id', None)
-        id = self.convertFromStr(data, 'str')
-        
-        vt_id = None
-        prov_type = None
-        prov_label = None
-        vt_machine_os = None
-        vt_machine_architecture = None
-        vt_machine_processor = None
-        vt_machine_ram = None
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'vt:id':
-                _data = self.convertFromStr(child.text,'str')
-                vt_id = _data
-            elif child_tag == 'prov:type':
-                _data = self.convertFromStr(child.text,'str')
-                prov_type = _data
-            elif child_tag == 'prov:label':
-                _data = self.convertFromStr(child.text,'str')
-                prov_label = _data
-            elif child_tag == 'vt:machine_os':
-                _data = self.convertFromStr(child.text,'str')
-                vt_machine_os = _data
-            elif child_tag == 'vt:machine_architecture':
-                _data = self.convertFromStr(child.text,'str')
-                vt_machine_architecture = _data
-            elif child_tag == 'vt:machine_processor':
-                _data = self.convertFromStr(child.text,'str')
-                vt_machine_processor = _data
-            elif child_tag == 'vt:machine_ram':
-                _data = self.convertFromStr(child.text,'str')
-                vt_machine_ram = _data
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
-        
-        obj = DBProvAgent(id=id,
-                          vt_id=vt_id,
-                          prov_type=prov_type,
-                          prov_label=prov_label,
-                          vt_machine_os=vt_machine_os,
-                          vt_machine_architecture=vt_machine_architecture,
-                          vt_machine_processor=vt_machine_processor,
-                          vt_machine_ram=vt_machine_ram)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, prov_agent, node=None):
-        if node is None:
-            node = ElementTree.Element('prov:agent')
-        
-        # set attributes
-        node.set('prov:id',self.convertToStr(prov_agent.db_id, 'str'))
-        
-        # set elements
-        vt_id = prov_agent.db_vt_id
-        if (vt_id is not None) and (vt_id != ""):
-            childNode = ElementTree.SubElement(node, 'vt:id')
-            childNode.text = self.convertToStr(vt_id, 'str')
-        prov_type = prov_agent.db_prov_type
-        if (prov_type is not None) and (prov_type != ""):
-            childNode = ElementTree.SubElement(node, 'prov:type')
-            childNode.text = self.convertToStr(prov_type, 'str')
-        prov_label = prov_agent.db_prov_label
-        if (prov_label is not None) and (prov_label != ""):
-            childNode = ElementTree.SubElement(node, 'prov:label')
-            childNode.text = self.convertToStr(prov_label, 'str')
-        vt_machine_os = prov_agent.db_vt_machine_os
-        if (vt_machine_os is not None) and (vt_machine_os != ""):
-            childNode = ElementTree.SubElement(node, 'vt:machine_os')
-            childNode.text = self.convertToStr(vt_machine_os, 'str')
-        vt_machine_architecture = prov_agent.db_vt_machine_architecture
-        if (vt_machine_architecture is not None) and (vt_machine_architecture != ""):
-            childNode = ElementTree.SubElement(node, 'vt:machine_architecture')
-            childNode.text = self.convertToStr(vt_machine_architecture, 'str')
-        vt_machine_processor = prov_agent.db_vt_machine_processor
-        if (vt_machine_processor is not None) and (vt_machine_processor != ""):
-            childNode = ElementTree.SubElement(node, 'vt:machine_processor')
-            childNode.text = self.convertToStr(vt_machine_processor, 'str')
-        vt_machine_ram = prov_agent.db_vt_machine_ram
-        if (vt_machine_ram is not None) and (vt_machine_ram != ""):
-            childNode = ElementTree.SubElement(node, 'vt:machine_ram')
-            childNode.text = self.convertToStr(vt_machine_ram, 'str')
-        
-        return node
-
 class DBOpmWasGeneratedByXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
@@ -326,7 +133,7 @@ class DBOpmWasGeneratedByXMLDAOBase(XMLDAO):
         
         return node
 
-class DBOpmAccountsXMLDAOBase(XMLDAO):
+class DBConfigKeyXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -339,11 +146,14 @@ class DBOpmAccountsXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'accounts':
+        if node_tag != 'key':
             return None
         
-        accounts = []
-        opm_overlapss = []
+        # read attributes
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        value = None
         
         # read children
         for child in node.getchildren():
@@ -351,41 +161,60 @@ class DBOpmAccountsXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'account':
-                _data = self.getDao('opm_account').fromXML(child)
-                accounts.append(_data)
-            elif child_tag == 'overlaps':
-                _data = self.getDao('opm_overlaps').fromXML(child)
-                opm_overlapss.append(_data)
+            if child_tag == 'str':
+                _data = self.getDao('config_str').fromXML(child)
+                value = _data
+            elif child_tag == 'int':
+                _data = self.getDao('config_int').fromXML(child)
+                value = _data
+            elif child_tag == 'float':
+                _data = self.getDao('config_float').fromXML(child)
+                value = _data
+            elif child_tag == 'bool':
+                _data = self.getDao('config_bool').fromXML(child)
+                value = _data
+            elif child_tag == 'configuration':
+                _data = self.getDao('configuration').fromXML(child)
+                value = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmAccounts(accounts=accounts,
-                            opm_overlapss=opm_overlapss)
+        obj = DBConfigKey(value=value,
+                          name=name)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_accounts, node=None):
+    def toXML(self, config_key, node=None):
         if node is None:
-            node = ElementTree.Element('accounts')
+            node = ElementTree.Element('key')
+        
+        # set attributes
+        node.set('name',self.convertToStr(config_key.db_name, 'str'))
         
         # set elements
-        accounts = opm_accounts.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account').toXML(account, childNode)
-        opm_overlapss = opm_accounts.db_opm_overlapss
-        for opm_overlaps in opm_overlapss:
-            if (opm_overlapss is not None) and (opm_overlapss != ""):
-                childNode = ElementTree.SubElement(node, 'overlaps')
-                self.getDao('opm_overlaps').toXML(opm_overlaps, childNode)
+        value = config_key.db_value
+        if value is not None:
+            if value.vtType == 'config_str':
+                childNode = ElementTree.SubElement(node, 'str')
+                self.getDao('config_str').toXML(value, childNode)
+            elif value.vtType == 'config_int':
+                childNode = ElementTree.SubElement(node, 'int')
+                self.getDao('config_int').toXML(value, childNode)
+            elif value.vtType == 'config_float':
+                childNode = ElementTree.SubElement(node, 'float')
+                self.getDao('config_float').toXML(value, childNode)
+            elif value.vtType == 'config_bool':
+                childNode = ElementTree.SubElement(node, 'bool')
+                self.getDao('config_bool').toXML(value, childNode)
+            elif value.vtType == 'configuration':
+                childNode = ElementTree.SubElement(node, 'configuration')
+                self.getDao('configuration').toXML(value, childNode)
         
         return node
 
-class DBRefProvAgentXMLDAOBase(XMLDAO):
+class DBMashupAliasXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -398,59 +227,16 @@ class DBRefProvAgentXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:agent':
+        if node_tag != 'alias':
             return None
         
         # read attributes
-        data = node.get('prov:ref', None)
-        prov_ref = self.convertFromStr(data, 'str')
-        
-        obj = DBRefProvAgent(prov_ref=prov_ref)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, ref_prov_agent, node=None):
-        if node is None:
-            node = ElementTree.Element('prov:agent')
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
         
-        # set attributes
-        node.set('prov:ref',self.convertToStr(ref_prov_agent.db_prov_ref, 'str'))
-        
-        return node
-
-class DBPortSpecXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'portSpec':
-            return None
-        
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('type', None)
-        type = self.convertFromStr(data, 'str')
-        data = node.get('optional', None)
-        optional = self.convertFromStr(data, 'int')
-        data = node.get('sortKey', None)
-        sort_key = self.convertFromStr(data, 'int')
-        data = node.get('minConns', None)
-        min_conns = self.convertFromStr(data, 'int')
-        data = node.get('maxConns', None)
-        max_conns = self.convertFromStr(data, 'int')
-        
-        portSpecItems = []
+        component = None
         
         # read children
         for child in node.getchildren():
@@ -458,48 +244,38 @@ class DBPortSpecXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'portSpecItem':
-                _data = self.getDao('portSpecItem').fromXML(child)
-                portSpecItems.append(_data)
+            if child_tag == 'component':
+                _data = self.getDao('mashup_component').fromXML(child)
+                component = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBPortSpec(id=id,
-                         name=name,
-                         type=type,
-                         optional=optional,
-                         sort_key=sort_key,
-                         portSpecItems=portSpecItems,
-                         min_conns=min_conns,
-                         max_conns=max_conns)
+        obj = DBMashupAlias(id=id,
+                            name=name,
+                            component=component)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, portSpec, node=None):
+    def toXML(self, mashup_alias, node=None):
         if node is None:
-            node = ElementTree.Element('portSpec')
+            node = ElementTree.Element('alias')
         
         # set attributes
-        node.set('id',self.convertToStr(portSpec.db_id, 'long'))
-        node.set('name',self.convertToStr(portSpec.db_name, 'str'))
-        node.set('type',self.convertToStr(portSpec.db_type, 'str'))
-        node.set('optional',self.convertToStr(portSpec.db_optional, 'int'))
-        node.set('sortKey',self.convertToStr(portSpec.db_sort_key, 'int'))
-        node.set('minConns',self.convertToStr(portSpec.db_min_conns, 'int'))
-        node.set('maxConns',self.convertToStr(portSpec.db_max_conns, 'int'))
+        node.set('id',self.convertToStr(mashup_alias.db_id, 'long'))
+        node.set('name',self.convertToStr(mashup_alias.db_name, 'str'))
         
         # set elements
-        portSpecItems = portSpec.db_portSpecItems
-        for portSpecItem in portSpecItems:
-            if (portSpecItems is not None) and (portSpecItems != ""):
-                childNode = ElementTree.SubElement(node, 'portSpecItem')
-                self.getDao('portSpecItem').toXML(portSpecItem, childNode)
+        component = mashup_alias.db_component
+        if component is not None:
+            if (component is not None) and (component != ""):
+                childNode = ElementTree.SubElement(node, 'component')
+                self.getDao('mashup_component').toXML(component, childNode)
         
         return node
 
-class DBModuleXMLDAOBase(XMLDAO):
+class DBGroupXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -512,7 +288,7 @@ class DBModuleXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'module':
+        if node_tag != 'group':
             return None
         
         # read attributes
@@ -529,10 +305,10 @@ class DBModuleXMLDAOBase(XMLDAO):
         data = node.get('version', None)
         version = self.convertFromStr(data, 'str')
         
+        workflow = None
         location = None
         functions = []
         annotations = []
-        portSpecs = []
         
         # read children
         for child in node.getchildren():
@@ -540,7 +316,10 @@ class DBModuleXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'location':
+            if child_tag == 'workflow':
+                _data = self.getDao('workflow').fromXML(child)
+                workflow = _data
+            elif child_tag == 'location':
                 _data = self.getDao('location').fromXML(child)
                 location = _data
             elif child_tag == 'function':
@@ -549,64 +328,61 @@ class DBModuleXMLDAOBase(XMLDAO):
             elif child_tag == 'annotation':
                 _data = self.getDao('annotation').fromXML(child)
                 annotations.append(_data)
-            elif child_tag == 'portSpec':
-                _data = self.getDao('portSpec').fromXML(child)
-                portSpecs.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBModule(id=id,
-                       cache=cache,
-                       name=name,
-                       namespace=namespace,
-                       package=package,
-                       version=version,
-                       location=location,
-                       functions=functions,
-                       annotations=annotations,
-                       portSpecs=portSpecs)
+        obj = DBGroup(id=id,
+                      workflow=workflow,
+                      cache=cache,
+                      name=name,
+                      namespace=namespace,
+                      package=package,
+                      version=version,
+                      location=location,
+                      functions=functions,
+                      annotations=annotations)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, module, node=None):
+    def toXML(self, group, node=None):
         if node is None:
-            node = ElementTree.Element('module')
+            node = ElementTree.Element('group')
         
         # set attributes
-        node.set('id',self.convertToStr(module.db_id, 'long'))
-        node.set('cache',self.convertToStr(module.db_cache, 'int'))
-        node.set('name',self.convertToStr(module.db_name, 'str'))
-        node.set('namespace',self.convertToStr(module.db_namespace, 'str'))
-        node.set('package',self.convertToStr(module.db_package, 'str'))
-        node.set('version',self.convertToStr(module.db_version, 'str'))
+        node.set('id',self.convertToStr(group.db_id, 'long'))
+        node.set('cache',self.convertToStr(group.db_cache, 'int'))
+        node.set('name',self.convertToStr(group.db_name, 'str'))
+        node.set('namespace',self.convertToStr(group.db_namespace, 'str'))
+        node.set('package',self.convertToStr(group.db_package, 'str'))
+        node.set('version',self.convertToStr(group.db_version, 'str'))
         
         # set elements
-        location = module.db_location
+        workflow = group.db_workflow
+        if workflow is not None:
+            if (workflow is not None) and (workflow != ""):
+                childNode = ElementTree.SubElement(node, 'workflow')
+                self.getDao('workflow').toXML(workflow, childNode)
+        location = group.db_location
         if location is not None:
             if (location is not None) and (location != ""):
                 childNode = ElementTree.SubElement(node, 'location')
                 self.getDao('location').toXML(location, childNode)
-        functions = module.db_functions
+        functions = group.db_functions
         for function in functions:
             if (functions is not None) and (functions != ""):
                 childNode = ElementTree.SubElement(node, 'function')
                 self.getDao('function').toXML(function, childNode)
-        annotations = module.db_annotations
+        annotations = group.db_annotations
         for annotation in annotations:
             if (annotations is not None) and (annotations != ""):
                 childNode = ElementTree.SubElement(node, 'annotation')
                 self.getDao('annotation').toXML(annotation, childNode)
-        portSpecs = module.db_portSpecs
-        for portSpec in portSpecs:
-            if (portSpecs is not None) and (portSpecs != ""):
-                childNode = ElementTree.SubElement(node, 'portSpec')
-                self.getDao('portSpec').toXML(portSpec, childNode)
         
         return node
 
-class DBModuleDescriptorXMLDAOBase(XMLDAO):
+class DBOpmWasControlledByXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -619,26 +395,15 @@ class DBModuleDescriptorXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'moduleDescriptor':
+        if node_tag != 'wasControlledBy':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('package', None)
-        package = self.convertFromStr(data, 'str')
-        data = node.get('namespace', None)
-        namespace = self.convertFromStr(data, 'str')
-        data = node.get('packageVersion', None)
-        package_version = self.convertFromStr(data, 'str')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
-        data = node.get('baseDescriptorId', None)
-        base_descriptor_id = self.convertFromStr(data, 'long')
-        
-        portSpecs = []
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        starts = []
+        ends = []
         
         # read children
         for child in node.getchildren():
@@ -646,48 +411,77 @@ class DBModuleDescriptorXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'portSpec':
-                _data = self.getDao('portSpec').fromXML(child)
-                portSpecs.append(_data)
+            if child_tag == 'effect':
+                _data = self.getDao('opm_process_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'agent':
+                _data = self.getDao('opm_agent_id').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                starts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                ends.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBModuleDescriptor(id=id,
-                                 name=name,
-                                 package=package,
-                                 namespace=namespace,
-                                 package_version=package_version,
-                                 version=version,
-                                 base_descriptor_id=base_descriptor_id,
-                                 portSpecs=portSpecs)
+        obj = DBOpmWasControlledBy(effect=effect,
+                                   role=role,
+                                   cause=cause,
+                                   accounts=accounts,
+                                   starts=starts,
+                                   ends=ends)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, module_descriptor, node=None):
+    def toXML(self, opm_was_controlled_by, node=None):
         if node is None:
-            node = ElementTree.Element('moduleDescriptor')
-        
-        # set attributes
-        node.set('id',self.convertToStr(module_descriptor.db_id, 'long'))
-        node.set('name',self.convertToStr(module_descriptor.db_name, 'str'))
-        node.set('package',self.convertToStr(module_descriptor.db_package, 'str'))
-        node.set('namespace',self.convertToStr(module_descriptor.db_namespace, 'str'))
-        node.set('packageVersion',self.convertToStr(module_descriptor.db_package_version, 'str'))
-        node.set('version',self.convertToStr(module_descriptor.db_version, 'str'))
-        node.set('baseDescriptorId',self.convertToStr(module_descriptor.db_base_descriptor_id, 'long'))
+            node = ElementTree.Element('wasControlledBy')
         
         # set elements
-        portSpecs = module_descriptor.db_portSpecs
-        for portSpec in portSpecs:
-            if (portSpecs is not None) and (portSpecs != ""):
-                childNode = ElementTree.SubElement(node, 'portSpec')
-                self.getDao('portSpec').toXML(portSpec, childNode)
+        effect = opm_was_controlled_by.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_process_id_effect').toXML(effect, childNode)
+        role = opm_was_controlled_by.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_was_controlled_by.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'agent')
+                self.getDao('opm_agent_id').toXML(cause, childNode)
+        accounts = opm_was_controlled_by.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        starts = opm_was_controlled_by.db_starts
+        for start in starts:
+            if (starts is not None) and (starts != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(start, childNode)
+        ends = opm_was_controlled_by.db_ends
+        for end in ends:
+            if (ends is not None) and (ends != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(end, childNode)
         
         return node
 
-class DBTagXMLDAOBase(XMLDAO):
+class DBAddXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -700,64 +494,133 @@ class DBTagXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'tag':
+        if node_tag != 'add':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        
-        obj = DBTag(id=id,
-                    name=name)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, tag, node=None):
-        if node is None:
-            node = ElementTree.Element('tag')
-        
-        # set attributes
-        node.set('id',self.convertToStr(tag.db_id, 'long'))
-        node.set('name',self.convertToStr(tag.db_name, 'str'))
+        data = node.get('what', None)
+        what = self.convertFromStr(data, 'str')
+        data = node.get('objectId', None)
+        objectId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjId', None)
+        parentObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjType', None)
+        parentObjType = self.convertFromStr(data, 'str')
         
-        return node
-
-class DBOpmRoleXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'role':
-            return None
+        data = None
         
-        # read attributes
-        data = node.get('value', None)
-        value = self.convertFromStr(data, 'str')
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'module':
+                _data = self.getDao('module').fromXML(child)
+                data = _data
+            elif child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                data = _data
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                data = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                data = _data
+            elif child_tag == 'connection':
+                _data = self.getDao('connection').fromXML(child)
+                data = _data
+            elif child_tag == 'port':
+                _data = self.getDao('port').fromXML(child)
+                data = _data
+            elif child_tag == 'parameter':
+                _data = self.getDao('parameter').fromXML(child)
+                data = _data
+            elif child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                data = _data
+            elif child_tag == 'abstraction':
+                _data = self.getDao('abstraction').fromXML(child)
+                data = _data
+            elif child_tag == 'group':
+                _data = self.getDao('group').fromXML(child)
+                data = _data
+            elif child_tag == 'other':
+                _data = self.getDao('other').fromXML(child)
+                data = _data
+            elif child_tag == 'plugin_data':
+                _data = self.getDao('plugin_data').fromXML(child)
+                data = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmRole(value=value)
+        obj = DBAdd(data=data,
+                    id=id,
+                    what=what,
+                    objectId=objectId,
+                    parentObjId=parentObjId,
+                    parentObjType=parentObjType)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_role, node=None):
+    def toXML(self, add, node=None):
         if node is None:
-            node = ElementTree.Element('role')
+            node = ElementTree.Element('add')
         
         # set attributes
-        node.set('value',self.convertToStr(opm_role.db_value, 'str'))
+        node.set('id',self.convertToStr(add.db_id, 'long'))
+        node.set('what',self.convertToStr(add.db_what, 'str'))
+        node.set('objectId',self.convertToStr(add.db_objectId, 'long'))
+        node.set('parentObjId',self.convertToStr(add.db_parentObjId, 'long'))
+        node.set('parentObjType',self.convertToStr(add.db_parentObjType, 'str'))
+        
+        # set elements
+        data = add.db_data
+        if data is not None:
+            if data.vtType == 'module':
+                childNode = ElementTree.SubElement(node, 'module')
+                self.getDao('module').toXML(data, childNode)
+            elif data.vtType == 'location':
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(data, childNode)
+            elif data.vtType == 'annotation':
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(data, childNode)
+            elif data.vtType == 'function':
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(data, childNode)
+            elif data.vtType == 'connection':
+                childNode = ElementTree.SubElement(node, 'connection')
+                self.getDao('connection').toXML(data, childNode)
+            elif data.vtType == 'port':
+                childNode = ElementTree.SubElement(node, 'port')
+                self.getDao('port').toXML(data, childNode)
+            elif data.vtType == 'parameter':
+                childNode = ElementTree.SubElement(node, 'parameter')
+                self.getDao('parameter').toXML(data, childNode)
+            elif data.vtType == 'portSpec':
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(data, childNode)
+            elif data.vtType == 'abstraction':
+                childNode = ElementTree.SubElement(node, 'abstraction')
+                self.getDao('abstraction').toXML(data, childNode)
+            elif data.vtType == 'group':
+                childNode = ElementTree.SubElement(node, 'group')
+                self.getDao('group').toXML(data, childNode)
+            elif data.vtType == 'other':
+                childNode = ElementTree.SubElement(node, 'other')
+                self.getDao('other').toXML(data, childNode)
+            elif data.vtType == 'plugin_data':
+                childNode = ElementTree.SubElement(node, 'plugin_data')
+                self.getDao('plugin_data').toXML(data, childNode)
         
         return node
 
-class DBProvDocumentXMLDAOBase(XMLDAO):
+class DBProvGenerationXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -770,16 +633,12 @@ class DBProvDocumentXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:document':
+        if node_tag != 'prov:wasGeneratedBy':
             return None
         
-        prov_entitys = []
-        prov_activitys = []
-        prov_agents = []
-        vt_connections = []
-        prov_usages = []
-        prov_generations = []
-        prov_associations = []
+        prov_entity = None
+        prov_activity = None
+        prov_role = None
         
         # read children
         for child in node.getchildren():
@@ -788,85 +647,48 @@ class DBProvDocumentXMLDAOBase(XMLDAO):
             else:
                 child_tag = child.tag
             if child_tag == 'prov:entity':
-                _data = self.getDao('prov_entity').fromXML(child)
-                prov_entitys.append(_data)
+                _data = self.getDao('ref_prov_entity').fromXML(child)
+                prov_entity = _data
             elif child_tag == 'prov:activity':
-                _data = self.getDao('prov_activity').fromXML(child)
-                prov_activitys.append(_data)
-            elif child_tag == 'prov:agent':
-                _data = self.getDao('prov_agent').fromXML(child)
-                prov_agents.append(_data)
-            elif child_tag == 'vt:connection':
-                _data = self.getDao('vt_connection').fromXML(child)
-                vt_connections.append(_data)
-            elif child_tag == 'prov:used':
-                _data = self.getDao('prov_usage').fromXML(child)
-                prov_usages.append(_data)
-            elif child_tag == 'prov:wasGeneratedBy':
-                _data = self.getDao('prov_generation').fromXML(child)
-                prov_generations.append(_data)
-            elif child_tag == 'prov:wasAssociatedWith':
-                _data = self.getDao('prov_association').fromXML(child)
-                prov_associations.append(_data)
+                _data = self.getDao('ref_prov_activity').fromXML(child)
+                prov_activity = _data
+            elif child_tag == 'prov:role':
+                _data = self.convertFromStr(child.text,'str')
+                prov_role = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBProvDocument(prov_entitys=prov_entitys,
-                             prov_activitys=prov_activitys,
-                             prov_agents=prov_agents,
-                             vt_connections=vt_connections,
-                             prov_usages=prov_usages,
-                             prov_generations=prov_generations,
-                             prov_associations=prov_associations)
+        obj = DBProvGeneration(prov_entity=prov_entity,
+                               prov_activity=prov_activity,
+                               prov_role=prov_role)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, prov_document, node=None):
+    def toXML(self, prov_generation, node=None):
         if node is None:
-            node = ElementTree.Element('prov:document')
+            node = ElementTree.Element('prov:wasGeneratedBy')
         
         # set elements
-        prov_entitys = prov_document.db_prov_entitys
-        for prov_entity in prov_entitys:
-            if (prov_entitys is not None) and (prov_entitys != ""):
+        prov_entity = prov_generation.db_prov_entity
+        if prov_entity is not None:
+            if (prov_entity is not None) and (prov_entity != ""):
                 childNode = ElementTree.SubElement(node, 'prov:entity')
-                self.getDao('prov_entity').toXML(prov_entity, childNode)
-        prov_activitys = prov_document.db_prov_activitys
-        for prov_activity in prov_activitys:
-            if (prov_activitys is not None) and (prov_activitys != ""):
+                self.getDao('ref_prov_entity').toXML(prov_entity, childNode)
+        prov_activity = prov_generation.db_prov_activity
+        if prov_activity is not None:
+            if (prov_activity is not None) and (prov_activity != ""):
                 childNode = ElementTree.SubElement(node, 'prov:activity')
-                self.getDao('prov_activity').toXML(prov_activity, childNode)
-        prov_agents = prov_document.db_prov_agents
-        for prov_agent in prov_agents:
-            if (prov_agents is not None) and (prov_agents != ""):
-                childNode = ElementTree.SubElement(node, 'prov:agent')
-                self.getDao('prov_agent').toXML(prov_agent, childNode)
-        vt_connections = prov_document.db_vt_connections
-        for vt_connection in vt_connections:
-            if (vt_connections is not None) and (vt_connections != ""):
-                childNode = ElementTree.SubElement(node, 'vt:connection')
-                self.getDao('vt_connection').toXML(vt_connection, childNode)
-        prov_usages = prov_document.db_prov_usages
-        for prov_usage in prov_usages:
-            if (prov_usages is not None) and (prov_usages != ""):
-                childNode = ElementTree.SubElement(node, 'prov:used')
-                self.getDao('prov_usage').toXML(prov_usage, childNode)
-        prov_generations = prov_document.db_prov_generations
-        for prov_generation in prov_generations:
-            if (prov_generations is not None) and (prov_generations != ""):
-                childNode = ElementTree.SubElement(node, 'prov:wasGeneratedBy')
-                self.getDao('prov_generation').toXML(prov_generation, childNode)
-        prov_associations = prov_document.db_prov_associations
-        for prov_association in prov_associations:
-            if (prov_associations is not None) and (prov_associations != ""):
-                childNode = ElementTree.SubElement(node, 'prov:wasAssociatedWith')
-                self.getDao('prov_association').toXML(prov_association, childNode)
+                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
+        prov_role = prov_generation.db_prov_role
+        if (prov_role is not None) and (prov_role != ""):
+            childNode = ElementTree.SubElement(node, 'prov:role')
+            childNode.text = self.convertToStr(prov_role, 'str')
         
         return node
 
-class DBOpmAccountXMLDAOBase(XMLDAO):
+class DBOpmUsedXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -879,50 +701,83 @@ class DBOpmAccountXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'account':
+        if node_tag != 'used':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
-        
-        value = None
-        
-        # read children
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        opm_times = []
+        
+        # read children
         for child in node.getchildren():
             if child.tag[0] == "{":
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'value':
-                _data = self.convertFromStr(child.text,'str')
-                value = _data
+            if child_tag == 'effect':
+                _data = self.getDao('opm_process_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'cause':
+                _data = self.getDao('opm_artifact_id_cause').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                opm_times.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmAccount(id=id,
-                           value=value)
+        obj = DBOpmUsed(effect=effect,
+                        role=role,
+                        cause=cause,
+                        accounts=accounts,
+                        opm_times=opm_times)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_account, node=None):
+    def toXML(self, opm_used, node=None):
         if node is None:
-            node = ElementTree.Element('account')
-        
-        # set attributes
-        node.set('id',self.convertToStr(opm_account.db_id, 'str'))
+            node = ElementTree.Element('used')
         
         # set elements
-        value = opm_account.db_value
-        if (value is not None) and (value != ""):
-            childNode = ElementTree.SubElement(node, 'value')
-            childNode.text = self.convertToStr(value, 'str')
+        effect = opm_used.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_process_id_effect').toXML(effect, childNode)
+        role = opm_used.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_used.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'cause')
+                self.getDao('opm_artifact_id_cause').toXML(cause, childNode)
+        accounts = opm_used.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        opm_times = opm_used.db_opm_times
+        for opm_time in opm_times:
+            if (opm_times is not None) and (opm_times != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(opm_time, childNode)
         
         return node
 
-class DBOpmProcessesXMLDAOBase(XMLDAO):
+class DBOpmArtifactIdCauseXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -935,43 +790,27 @@ class DBOpmProcessesXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'processes':
+        if node_tag != 'cause':
             return None
         
-        processs = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'process':
-                _data = self.getDao('opm_process').fromXML(child)
-                processs.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
         
-        obj = DBOpmProcesses(processs=processs)
+        obj = DBOpmArtifactIdCause(id=id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_processes, node=None):
+    def toXML(self, opm_artifact_id_cause, node=None):
         if node is None:
-            node = ElementTree.Element('processes')
+            node = ElementTree.Element('cause')
         
-        # set elements
-        processs = opm_processes.db_processs
-        for process in processs:
-            if (processs is not None) and (processs != ""):
-                childNode = ElementTree.SubElement(node, 'process')
-                self.getDao('opm_process').toXML(process, childNode)
+        # set attributes
+        node.set('id',self.convertToStr(opm_artifact_id_cause.db_id, 'str'))
         
         return node
 
-class DBRefProvActivityXMLDAOBase(XMLDAO):
+class DBRefProvEntityXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -984,27 +823,27 @@ class DBRefProvActivityXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:activity':
+        if node_tag != 'prov:entity':
             return None
         
         # read attributes
         data = node.get('prov:ref', None)
         prov_ref = self.convertFromStr(data, 'str')
         
-        obj = DBRefProvActivity(prov_ref=prov_ref)
+        obj = DBRefProvEntity(prov_ref=prov_ref)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, ref_prov_activity, node=None):
+    def toXML(self, ref_prov_entity, node=None):
         if node is None:
-            node = ElementTree.Element('prov:activity')
+            node = ElementTree.Element('prov:entity')
         
         # set attributes
-        node.set('prov:ref',self.convertToStr(ref_prov_activity.db_prov_ref, 'str'))
+        node.set('prov:ref',self.convertToStr(ref_prov_entity.db_prov_ref, 'str'))
         
         return node
 
-class DBOpmAccountIdXMLDAOBase(XMLDAO):
+class DBVtConnectionXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1017,27 +856,95 @@ class DBOpmAccountIdXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'account':
+        if node_tag != 'vt:connection':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'str')
         
-        obj = DBOpmAccountId(id=id)
+        vt_source = None
+        vt_dest = None
+        vt_source_port = None
+        vt_dest_port = None
+        vt_source_signature = None
+        vt_dest_signature = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'vt:source':
+                _data = self.convertFromStr(child.text,'str')
+                vt_source = _data
+            elif child_tag == 'vt:dest':
+                _data = self.convertFromStr(child.text,'str')
+                vt_dest = _data
+            elif child_tag == 'vt:source_port':
+                _data = self.convertFromStr(child.text,'str')
+                vt_source_port = _data
+            elif child_tag == 'vt:dest_port':
+                _data = self.convertFromStr(child.text,'str')
+                vt_dest_port = _data
+            elif child_tag == 'vt:source_signature':
+                _data = self.convertFromStr(child.text,'str')
+                vt_source_signature = _data
+            elif child_tag == 'vt:dest_signature':
+                _data = self.convertFromStr(child.text,'str')
+                vt_dest_signature = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBVtConnection(id=id,
+                             vt_source=vt_source,
+                             vt_dest=vt_dest,
+                             vt_source_port=vt_source_port,
+                             vt_dest_port=vt_dest_port,
+                             vt_source_signature=vt_source_signature,
+                             vt_dest_signature=vt_dest_signature)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_account_id, node=None):
+    def toXML(self, vt_connection, node=None):
         if node is None:
-            node = ElementTree.Element('account')
+            node = ElementTree.Element('vt:connection')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_account_id.db_id, 'str'))
+        node.set('id',self.convertToStr(vt_connection.db_id, 'str'))
+        
+        # set elements
+        vt_source = vt_connection.db_vt_source
+        if (vt_source is not None) and (vt_source != ""):
+            childNode = ElementTree.SubElement(node, 'vt:source')
+            childNode.text = self.convertToStr(vt_source, 'str')
+        vt_dest = vt_connection.db_vt_dest
+        if (vt_dest is not None) and (vt_dest != ""):
+            childNode = ElementTree.SubElement(node, 'vt:dest')
+            childNode.text = self.convertToStr(vt_dest, 'str')
+        vt_source_port = vt_connection.db_vt_source_port
+        if (vt_source_port is not None) and (vt_source_port != ""):
+            childNode = ElementTree.SubElement(node, 'vt:source_port')
+            childNode.text = self.convertToStr(vt_source_port, 'str')
+        vt_dest_port = vt_connection.db_vt_dest_port
+        if (vt_dest_port is not None) and (vt_dest_port != ""):
+            childNode = ElementTree.SubElement(node, 'vt:dest_port')
+            childNode.text = self.convertToStr(vt_dest_port, 'str')
+        vt_source_signature = vt_connection.db_vt_source_signature
+        if (vt_source_signature is not None) and (vt_source_signature != ""):
+            childNode = ElementTree.SubElement(node, 'vt:source_signature')
+            childNode.text = self.convertToStr(vt_source_signature, 'str')
+        vt_dest_signature = vt_connection.db_vt_dest_signature
+        if (vt_dest_signature is not None) and (vt_dest_signature != ""):
+            childNode = ElementTree.SubElement(node, 'vt:dest_signature')
+            childNode.text = self.convertToStr(vt_dest_signature, 'str')
         
         return node
 
-class DBPortXMLDAOBase(XMLDAO):
+class DBOpmAccountXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1050,47 +957,50 @@ class DBPortXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'port':
+        if node_tag != 'account':
             return None
         
         # read attributes
         data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('type', None)
-        type = self.convertFromStr(data, 'str')
-        data = node.get('moduleId', None)
-        moduleId = self.convertFromStr(data, 'long')
-        data = node.get('moduleName', None)
-        moduleName = self.convertFromStr(data, 'str')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('signature', None)
-        signature = self.convertFromStr(data, 'str')
+        id = self.convertFromStr(data, 'str')
         
-        obj = DBPort(id=id,
-                     type=type,
-                     moduleId=moduleId,
-                     moduleName=moduleName,
-                     name=name,
-                     signature=signature)
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.convertFromStr(child.text,'str')
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAccount(id=id,
+                           value=value)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, port, node=None):
+    def toXML(self, opm_account, node=None):
         if node is None:
-            node = ElementTree.Element('port')
+            node = ElementTree.Element('account')
         
         # set attributes
-        node.set('id',self.convertToStr(port.db_id, 'long'))
-        node.set('type',self.convertToStr(port.db_type, 'str'))
-        node.set('moduleId',self.convertToStr(port.db_moduleId, 'long'))
-        node.set('moduleName',self.convertToStr(port.db_moduleName, 'str'))
-        node.set('name',self.convertToStr(port.db_name, 'str'))
-        node.set('signature',self.convertToStr(port.db_signature, 'str'))
+        node.set('id',self.convertToStr(opm_account.db_id, 'str'))
+        
+        # set elements
+        value = opm_account.db_value
+        if (value is not None) and (value != ""):
+            childNode = ElementTree.SubElement(node, 'value')
+            childNode.text = self.convertToStr(value, 'str')
         
         return node
 
-class DBRefProvPlanXMLDAOBase(XMLDAO):
+class DBGroupExecXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1103,27 +1013,109 @@ class DBRefProvPlanXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:plan':
+        if node_tag != 'groupExec':
             return None
         
         # read attributes
-        data = node.get('prov:ref', None)
-        prov_ref = self.convertFromStr(data, 'str')
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('cached', None)
+        cached = self.convertFromStr(data, 'int')
+        data = node.get('moduleId', None)
+        module_id = self.convertFromStr(data, 'long')
+        data = node.get('groupName', None)
+        group_name = self.convertFromStr(data, 'str')
+        data = node.get('groupType', None)
+        group_type = self.convertFromStr(data, 'str')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('error', None)
+        error = self.convertFromStr(data, 'str')
+        data = node.get('machine_id', None)
+        machine_id = self.convertFromStr(data, 'long')
         
-        obj = DBRefProvPlan(prov_ref=prov_ref)
+        annotations = []
+        item_execs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBGroupExec(item_execs=item_execs,
+                          id=id,
+                          ts_start=ts_start,
+                          ts_end=ts_end,
+                          cached=cached,
+                          module_id=module_id,
+                          group_name=group_name,
+                          group_type=group_type,
+                          completed=completed,
+                          error=error,
+                          machine_id=machine_id,
+                          annotations=annotations)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, ref_prov_plan, node=None):
+    def toXML(self, group_exec, node=None):
         if node is None:
-            node = ElementTree.Element('prov:plan')
+            node = ElementTree.Element('groupExec')
         
         # set attributes
-        node.set('prov:ref',self.convertToStr(ref_prov_plan.db_prov_ref, 'str'))
+        node.set('id',self.convertToStr(group_exec.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(group_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(group_exec.db_ts_end, 'datetime'))
+        node.set('cached',self.convertToStr(group_exec.db_cached, 'int'))
+        node.set('moduleId',self.convertToStr(group_exec.db_module_id, 'long'))
+        node.set('groupName',self.convertToStr(group_exec.db_group_name, 'str'))
+        node.set('groupType',self.convertToStr(group_exec.db_group_type, 'str'))
+        node.set('completed',self.convertToStr(group_exec.db_completed, 'int'))
+        node.set('error',self.convertToStr(group_exec.db_error, 'str'))
+        node.set('machine_id',self.convertToStr(group_exec.db_machine_id, 'long'))
+        
+        # set elements
+        annotations = group_exec.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        item_execs = group_exec.db_item_execs
+        for item_exec in item_execs:
+            if item_exec.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(item_exec, childNode)
         
         return node
 
-class DBOpmArtifactXMLDAOBase(XMLDAO):
+class DBOpmAgentIdXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1136,61 +1128,27 @@ class DBOpmArtifactXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'artifact':
+        if node_tag != 'agent':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'str')
         
-        value = None
-        accounts = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'value':
-                _data = self.getDao('opm_artifact_value').fromXML(child)
-                value = _data
-            elif child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                accounts.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
-        
-        obj = DBOpmArtifact(id=id,
-                            value=value,
-                            accounts=accounts)
+        obj = DBOpmAgentId(id=id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_artifact, node=None):
+    def toXML(self, opm_agent_id, node=None):
         if node is None:
-            node = ElementTree.Element('artifact')
+            node = ElementTree.Element('agent')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_artifact.db_id, 'str'))
-        
-        # set elements
-        value = opm_artifact.db_value
-        if value is not None:
-            if (value is not None) and (value != ""):
-                childNode = ElementTree.SubElement(node, 'value')
-                self.getDao('opm_artifact_value').toXML(value, childNode)
-        accounts = opm_artifact.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(account, childNode)
+        node.set('id',self.convertToStr(opm_agent_id.db_id, 'str'))
         
         return node
 
-class DBGroupXMLDAOBase(XMLDAO):
+class DBParameterXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1203,101 +1161,47 @@ class DBGroupXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'group':
+        if node_tag != 'parameter':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('cache', None)
-        cache = self.convertFromStr(data, 'int')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
         data = node.get('name', None)
         name = self.convertFromStr(data, 'str')
-        data = node.get('namespace', None)
-        namespace = self.convertFromStr(data, 'str')
-        data = node.get('package', None)
-        package = self.convertFromStr(data, 'str')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
-        
-        workflow = None
-        location = None
-        functions = []
-        annotations = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'workflow':
-                _data = self.getDao('workflow').fromXML(child)
-                workflow = _data
-            elif child_tag == 'location':
-                _data = self.getDao('location').fromXML(child)
-                location = _data
-            elif child_tag == 'function':
-                _data = self.getDao('function').fromXML(child)
-                functions.append(_data)
-            elif child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('val', None)
+        val = self.convertFromStr(data, 'str')
+        data = node.get('alias', None)
+        alias = self.convertFromStr(data, 'str')
         
-        obj = DBGroup(id=id,
-                      workflow=workflow,
-                      cache=cache,
-                      name=name,
-                      namespace=namespace,
-                      package=package,
-                      version=version,
-                      location=location,
-                      functions=functions,
-                      annotations=annotations)
+        obj = DBParameter(id=id,
+                          pos=pos,
+                          name=name,
+                          type=type,
+                          val=val,
+                          alias=alias)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, group, node=None):
+    def toXML(self, parameter, node=None):
         if node is None:
-            node = ElementTree.Element('group')
+            node = ElementTree.Element('parameter')
         
         # set attributes
-        node.set('id',self.convertToStr(group.db_id, 'long'))
-        node.set('cache',self.convertToStr(group.db_cache, 'int'))
-        node.set('name',self.convertToStr(group.db_name, 'str'))
-        node.set('namespace',self.convertToStr(group.db_namespace, 'str'))
-        node.set('package',self.convertToStr(group.db_package, 'str'))
-        node.set('version',self.convertToStr(group.db_version, 'str'))
-        
-        # set elements
-        workflow = group.db_workflow
-        if workflow is not None:
-            if (workflow is not None) and (workflow != ""):
-                childNode = ElementTree.SubElement(node, 'workflow')
-                self.getDao('workflow').toXML(workflow, childNode)
-        location = group.db_location
-        if location is not None:
-            if (location is not None) and (location != ""):
-                childNode = ElementTree.SubElement(node, 'location')
-                self.getDao('location').toXML(location, childNode)
-        functions = group.db_functions
-        for function in functions:
-            if (functions is not None) and (functions != ""):
-                childNode = ElementTree.SubElement(node, 'function')
-                self.getDao('function').toXML(function, childNode)
-        annotations = group.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
+        node.set('id',self.convertToStr(parameter.db_id, 'long'))
+        node.set('pos',self.convertToStr(parameter.db_pos, 'long'))
+        node.set('name',self.convertToStr(parameter.db_name, 'str'))
+        node.set('type',self.convertToStr(parameter.db_type, 'str'))
+        node.set('val',self.convertToStr(parameter.db_val, 'str'))
+        node.set('alias',self.convertToStr(parameter.db_alias, 'str'))
         
         return node
 
-class DBLogXMLDAOBase(XMLDAO):
+class DBVistrailXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1310,7 +1214,7 @@ class DBLogXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'log':
+        if node_tag != 'vistrail':
             return None
         
         # read attributes
@@ -1320,63 +1224,99 @@ class DBLogXMLDAOBase(XMLDAO):
         version = self.convertFromStr(data, 'str')
         data = node.get('name', None)
         name = self.convertFromStr(data, 'str')
-        data = node.get('vistrail_id', None)
-        vistrail_id = self.convertFromStr(data, 'long')
-        
-        workflow_execs = []
-        machines = []
         
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
+        actions = []
+        tags = []
+        annotations = []
+        vistrailVariables = []
+        parameter_explorations = []
+        actionAnnotations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'workflowExec':
-                _data = self.getDao('workflow_exec').fromXML(child)
-                workflow_execs.append(_data)
-            elif child_tag == 'machine':
-                _data = self.getDao('machine').fromXML(child)
-                machines.append(_data)
+            if child_tag == 'action':
+                _data = self.getDao('action').fromXML(child)
+                actions.append(_data)
+            elif child_tag == 'tag':
+                _data = self.getDao('tag').fromXML(child)
+                tags.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'vistrailVariable':
+                _data = self.getDao('vistrailVariable').fromXML(child)
+                vistrailVariables.append(_data)
+            elif child_tag == 'parameterExploration':
+                _data = self.getDao('parameter_exploration').fromXML(child)
+                parameter_explorations.append(_data)
+            elif child_tag == 'actionAnnotation':
+                _data = self.getDao('actionAnnotation').fromXML(child)
+                actionAnnotations.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBLog(id=id,
-                    version=version,
-                    name=name,
-                    workflow_execs=workflow_execs,
-                    machines=machines,
-                    vistrail_id=vistrail_id)
+        obj = DBVistrail(id=id,
+                         version=version,
+                         name=name,
+                         actions=actions,
+                         tags=tags,
+                         annotations=annotations,
+                         vistrailVariables=vistrailVariables,
+                         parameter_explorations=parameter_explorations,
+                         actionAnnotations=actionAnnotations)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, log, node=None):
+    def toXML(self, vistrail, node=None):
         if node is None:
-            node = ElementTree.Element('log')
+            node = ElementTree.Element('vistrail')
         
         # set attributes
-        node.set('id',self.convertToStr(log.db_id, 'long'))
-        node.set('version',self.convertToStr(log.db_version, 'str'))
-        node.set('name',self.convertToStr(log.db_name, 'str'))
-        node.set('vistrail_id',self.convertToStr(log.db_vistrail_id, 'long'))
+        node.set('id',self.convertToStr(vistrail.db_id, 'long'))
+        node.set('version',self.convertToStr(vistrail.db_version, 'str'))
+        node.set('name',self.convertToStr(vistrail.db_name, 'str'))
         
         # set elements
-        workflow_execs = log.db_workflow_execs
-        for workflow_exec in workflow_execs:
-            if (workflow_execs is not None) and (workflow_execs != ""):
-                childNode = ElementTree.SubElement(node, 'workflowExec')
-                self.getDao('workflow_exec').toXML(workflow_exec, childNode)
-        machines = log.db_machines
-        for machine in machines:
-            if (machines is not None) and (machines != ""):
-                childNode = ElementTree.SubElement(node, 'machine')
-                self.getDao('machine').toXML(machine, childNode)
+        actions = vistrail.db_actions
+        for action in actions:
+            if (actions is not None) and (actions != ""):
+                childNode = ElementTree.SubElement(node, 'action')
+                self.getDao('action').toXML(action, childNode)
+        tags = vistrail.db_tags
+        for tag in tags:
+            if (tags is not None) and (tags != ""):
+                childNode = ElementTree.SubElement(node, 'tag')
+                self.getDao('tag').toXML(tag, childNode)
+        annotations = vistrail.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        vistrailVariables = vistrail.db_vistrailVariables
+        for vistrailVariable in vistrailVariables:
+            if (vistrailVariables is not None) and (vistrailVariables != ""):
+                childNode = ElementTree.SubElement(node, 'vistrailVariable')
+                self.getDao('vistrailVariable').toXML(vistrailVariable, childNode)
+        parameter_explorations = vistrail.db_parameter_explorations
+        for parameter_exploration in parameter_explorations:
+            if (parameter_explorations is not None) and (parameter_explorations != ""):
+                childNode = ElementTree.SubElement(node, 'parameterExploration')
+                self.getDao('parameter_exploration').toXML(parameter_exploration, childNode)
+        actionAnnotations = vistrail.db_actionAnnotations
+        for actionAnnotation in actionAnnotations:
+            if (actionAnnotations is not None) and (actionAnnotations != ""):
+                childNode = ElementTree.SubElement(node, 'actionAnnotation')
+                self.getDao('actionAnnotation').toXML(actionAnnotation, childNode)
         
         return node
 
-class DBMashupAliasXMLDAOBase(XMLDAO):
+class DBOpmArtifactValueXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1389,16 +1329,10 @@ class DBMashupAliasXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'alias':
+        if node_tag != 'value':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        
-        component = None
+        value = None
         
         # read children
         for child in node.getchildren():
@@ -1406,38 +1340,38 @@ class DBMashupAliasXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'component':
-                _data = self.getDao('mashup_component').fromXML(child)
-                component = _data
+            if child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                value = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                value = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBMashupAlias(id=id,
-                            name=name,
-                            component=component)
+        obj = DBOpmArtifactValue(value=value)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, mashup_alias, node=None):
+    def toXML(self, opm_artifact_value, node=None):
         if node is None:
-            node = ElementTree.Element('alias')
-        
-        # set attributes
-        node.set('id',self.convertToStr(mashup_alias.db_id, 'long'))
-        node.set('name',self.convertToStr(mashup_alias.db_name, 'str'))
+            node = ElementTree.Element('value')
         
         # set elements
-        component = mashup_alias.db_component
-        if component is not None:
-            if (component is not None) and (component != ""):
-                childNode = ElementTree.SubElement(node, 'component')
-                self.getDao('mashup_component').toXML(component, childNode)
+        value = opm_artifact_value.db_value
+        if value is not None:
+            if value.vtType == 'portSpec':
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(value, childNode)
+            elif value.vtType == 'function':
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(value, childNode)
         
         return node
 
-class DBOpmAgentsXMLDAOBase(XMLDAO):
+class DBConfigStrXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1450,43 +1384,27 @@ class DBOpmAgentsXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'agents':
+        if node_tag != 'str':
             return None
         
-        agents = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'agent':
-                _data = self.getDao('opm_agent').fromXML(child)
-                agents.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        # read attributes
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
         
-        obj = DBOpmAgents(agents=agents)
+        obj = DBConfigStr(value=value)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_agents, node=None):
+    def toXML(self, config_str, node=None):
         if node is None:
-            node = ElementTree.Element('agents')
+            node = ElementTree.Element('str')
         
-        # set elements
-        agents = opm_agents.db_agents
-        for agent in agents:
-            if (agents is not None) and (agents != ""):
-                childNode = ElementTree.SubElement(node, 'agent')
-                self.getDao('opm_agent').toXML(agent, childNode)
+        # set attributes
+        node.set('value',self.convertToStr(config_str.db_value, 'str'))
         
         return node
 
-class DBMashupXMLDAOBase(XMLDAO):
+class DBStartupXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1499,26 +1417,16 @@ class DBMashupXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'mashup':
+        if node_tag != 'startup':
             return None
         
         # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
         data = node.get('version', None)
-        version = self.convertFromStr(data, 'long')
-        data = node.get('type', None)
-        type = self.convertFromStr(data, 'str')
-        data = node.get('vtid', None)
-        vtid = self.convertFromStr(data, 'long')
-        data = node.get('has_seq', None)
-        has_seq = self.convertFromStr(data, 'int')
+        version = self.convertFromStr(data, 'str')
         
-        aliases = []
-        layout = None
-        geometry = None
+        configuration = None
+        enabled_packages = None
+        disabled_packages = None
         
         # read children
         for child in node.getchildren():
@@ -1526,62 +1434,54 @@ class DBMashupXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'alias':
-                _data = self.getDao('mashup_alias').fromXML(child)
-                aliases.append(_data)
-            elif child_tag == 'layout':
-                _data = self.convertFromStr(child.text,'str')
-                layout = _data
-            elif child_tag == 'geometry':
-                _data = self.convertFromStr(child.text,'str')
-                geometry = _data
+            if child_tag == 'configuration':
+                _data = self.getDao('configuration').fromXML(child)
+                configuration = _data
+            elif child_tag == 'packages':
+                _data = self.getDao('enabled_packages').fromXML(child)
+                enabled_packages = _data
+            elif child_tag == 'disabledpackages':
+                _data = self.getDao('disabled_packages').fromXML(child)
+                disabled_packages = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBMashup(id=id,
-                       name=name,
-                       version=version,
-                       aliases=aliases,
-                       type=type,
-                       vtid=vtid,
-                       layout=layout,
-                       geometry=geometry,
-                       has_seq=has_seq)
+        obj = DBStartup(version=version,
+                        configuration=configuration,
+                        enabled_packages=enabled_packages,
+                        disabled_packages=disabled_packages)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, mashup, node=None):
+    def toXML(self, startup, node=None):
         if node is None:
-            node = ElementTree.Element('mashup')
+            node = ElementTree.Element('startup')
         
         # set attributes
-        node.set('id',self.convertToStr(mashup.db_id, 'long'))
-        node.set('name',self.convertToStr(mashup.db_name, 'str'))
-        node.set('version',self.convertToStr(mashup.db_version, 'long'))
-        node.set('type',self.convertToStr(mashup.db_type, 'str'))
-        node.set('vtid',self.convertToStr(mashup.db_vtid, 'long'))
-        node.set('has_seq',self.convertToStr(mashup.db_has_seq, 'int'))
+        node.set('version',self.convertToStr(startup.db_version, 'str'))
         
         # set elements
-        aliases = mashup.db_aliases
-        for alias in aliases:
-            if (aliases is not None) and (aliases != ""):
-                childNode = ElementTree.SubElement(node, 'alias')
-                self.getDao('mashup_alias').toXML(alias, childNode)
-        layout = mashup.db_layout
-        if (layout is not None) and (layout != ""):
-            childNode = ElementTree.SubElement(node, 'layout')
-            childNode.text = self.convertToStr(layout, 'str')
-        geometry = mashup.db_geometry
-        if (geometry is not None) and (geometry != ""):
-            childNode = ElementTree.SubElement(node, 'geometry')
-            childNode.text = self.convertToStr(geometry, 'str')
+        configuration = startup.db_configuration
+        if configuration is not None:
+            if (configuration is not None) and (configuration != ""):
+                childNode = ElementTree.SubElement(node, 'configuration')
+                self.getDao('configuration').toXML(configuration, childNode)
+        enabled_packages = startup.db_enabled_packages
+        if enabled_packages is not None:
+            if (enabled_packages is not None) and (enabled_packages != ""):
+                childNode = ElementTree.SubElement(node, 'packages')
+                self.getDao('enabled_packages').toXML(enabled_packages, childNode)
+        disabled_packages = startup.db_disabled_packages
+        if disabled_packages is not None:
+            if (disabled_packages is not None) and (disabled_packages != ""):
+                childNode = ElementTree.SubElement(node, 'disabledpackages')
+                self.getDao('disabled_packages').toXML(disabled_packages, childNode)
         
         return node
 
-class DBOpmProcessIdCauseXMLDAOBase(XMLDAO):
+class DBModuleXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1594,45 +1494,27 @@ class DBOpmProcessIdCauseXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'cause':
+        if node_tag != 'module':
             return None
         
         # read attributes
         data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
+        id = self.convertFromStr(data, 'long')
+        data = node.get('cache', None)
+        cache = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
         
-        obj = DBOpmProcessIdCause(id=id)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, opm_process_id_cause, node=None):
-        if node is None:
-            node = ElementTree.Element('cause')
-        
-        # set attributes
-        node.set('id',self.convertToStr(opm_process_id_cause.db_id, 'str'))
-        
-        return node
-
-class DBProvGenerationXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'prov:wasGeneratedBy':
-            return None
-        
-        prov_entity = None
-        prov_activity = None
-        prov_role = None
+        location = None
+        functions = []
+        annotations = []
+        portSpecs = []
         
         # read children
         for child in node.getchildren():
@@ -1640,49 +1522,73 @@ class DBProvGenerationXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'prov:entity':
-                _data = self.getDao('ref_prov_entity').fromXML(child)
-                prov_entity = _data
-            elif child_tag == 'prov:activity':
-                _data = self.getDao('ref_prov_activity').fromXML(child)
-                prov_activity = _data
-            elif child_tag == 'prov:role':
-                _data = self.convertFromStr(child.text,'str')
-                prov_role = _data
+            if child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                location = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                functions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                portSpecs.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBProvGeneration(prov_entity=prov_entity,
-                               prov_activity=prov_activity,
-                               prov_role=prov_role)
+        obj = DBModule(id=id,
+                       cache=cache,
+                       name=name,
+                       namespace=namespace,
+                       package=package,
+                       version=version,
+                       location=location,
+                       functions=functions,
+                       annotations=annotations,
+                       portSpecs=portSpecs)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, prov_generation, node=None):
+    def toXML(self, module, node=None):
         if node is None:
-            node = ElementTree.Element('prov:wasGeneratedBy')
+            node = ElementTree.Element('module')
+        
+        # set attributes
+        node.set('id',self.convertToStr(module.db_id, 'long'))
+        node.set('cache',self.convertToStr(module.db_cache, 'int'))
+        node.set('name',self.convertToStr(module.db_name, 'str'))
+        node.set('namespace',self.convertToStr(module.db_namespace, 'str'))
+        node.set('package',self.convertToStr(module.db_package, 'str'))
+        node.set('version',self.convertToStr(module.db_version, 'str'))
         
         # set elements
-        prov_entity = prov_generation.db_prov_entity
-        if prov_entity is not None:
-            if (prov_entity is not None) and (prov_entity != ""):
-                childNode = ElementTree.SubElement(node, 'prov:entity')
-                self.getDao('ref_prov_entity').toXML(prov_entity, childNode)
-        prov_activity = prov_generation.db_prov_activity
-        if prov_activity is not None:
-            if (prov_activity is not None) and (prov_activity != ""):
-                childNode = ElementTree.SubElement(node, 'prov:activity')
-                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
-        prov_role = prov_generation.db_prov_role
-        if (prov_role is not None) and (prov_role != ""):
-            childNode = ElementTree.SubElement(node, 'prov:role')
-            childNode.text = self.convertToStr(prov_role, 'str')
+        location = module.db_location
+        if location is not None:
+            if (location is not None) and (location != ""):
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(location, childNode)
+        functions = module.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(function, childNode)
+        annotations = module.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        portSpecs = module.db_portSpecs
+        for portSpec in portSpecs:
+            if (portSpecs is not None) and (portSpecs != ""):
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(portSpec, childNode)
         
         return node
 
-class DBPortSpecItemXMLDAOBase(XMLDAO):
+class DBPortXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1695,59 +1601,47 @@ class DBPortSpecItemXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'portSpecItem':
+        if node_tag != 'port':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('pos', None)
-        pos = self.convertFromStr(data, 'long')
-        data = node.get('module', None)
-        module = self.convertFromStr(data, 'str')
-        data = node.get('package', None)
-        package = self.convertFromStr(data, 'str')
-        data = node.get('namespace', None)
-        namespace = self.convertFromStr(data, 'str')
-        data = node.get('label', None)
-        label = self.convertFromStr(data, 'str')
-        data = node.get('default', None)
-        default = self.convertFromStr(data, 'str')
-        data = node.get('values', None)
-        values = self.convertFromStr(data, 'str')
-        data = node.get('entryType', None)
-        entry_type = self.convertFromStr(data, 'str')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('moduleId', None)
+        moduleId = self.convertFromStr(data, 'long')
+        data = node.get('moduleName', None)
+        moduleName = self.convertFromStr(data, 'str')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('signature', None)
+        signature = self.convertFromStr(data, 'str')
         
-        obj = DBPortSpecItem(id=id,
-                             pos=pos,
-                             module=module,
-                             package=package,
-                             namespace=namespace,
-                             label=label,
-                             default=default,
-                             values=values,
-                             entry_type=entry_type)
+        obj = DBPort(id=id,
+                     type=type,
+                     moduleId=moduleId,
+                     moduleName=moduleName,
+                     name=name,
+                     signature=signature)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, portSpecItem, node=None):
+    def toXML(self, port, node=None):
         if node is None:
-            node = ElementTree.Element('portSpecItem')
+            node = ElementTree.Element('port')
         
         # set attributes
-        node.set('id',self.convertToStr(portSpecItem.db_id, 'long'))
-        node.set('pos',self.convertToStr(portSpecItem.db_pos, 'long'))
-        node.set('module',self.convertToStr(portSpecItem.db_module, 'str'))
-        node.set('package',self.convertToStr(portSpecItem.db_package, 'str'))
-        node.set('namespace',self.convertToStr(portSpecItem.db_namespace, 'str'))
-        node.set('label',self.convertToStr(portSpecItem.db_label, 'str'))
-        node.set('default',self.convertToStr(portSpecItem.db_default, 'str'))
-        node.set('values',self.convertToStr(portSpecItem.db_values, 'str'))
-        node.set('entryType',self.convertToStr(portSpecItem.db_entry_type, 'str'))
+        node.set('id',self.convertToStr(port.db_id, 'long'))
+        node.set('type',self.convertToStr(port.db_type, 'str'))
+        node.set('moduleId',self.convertToStr(port.db_moduleId, 'long'))
+        node.set('moduleName',self.convertToStr(port.db_moduleName, 'str'))
+        node.set('name',self.convertToStr(port.db_name, 'str'))
+        node.set('signature',self.convertToStr(port.db_signature, 'str'))
         
         return node
 
-class DBMachineXMLDAOBase(XMLDAO):
+class DBOpmAgentsXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1760,47 +1654,43 @@ class DBMachineXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'machine':
+        if node_tag != 'agents':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('os', None)
-        os = self.convertFromStr(data, 'str')
-        data = node.get('architecture', None)
-        architecture = self.convertFromStr(data, 'str')
-        data = node.get('processor', None)
-        processor = self.convertFromStr(data, 'str')
-        data = node.get('ram', None)
-        ram = self.convertFromStr(data, 'int')
+        agents = []
         
-        obj = DBMachine(id=id,
-                        name=name,
-                        os=os,
-                        architecture=architecture,
-                        processor=processor,
-                        ram=ram)
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'agent':
+                _data = self.getDao('opm_agent').fromXML(child)
+                agents.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAgents(agents=agents)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, machine, node=None):
+    def toXML(self, opm_agents, node=None):
         if node is None:
-            node = ElementTree.Element('machine')
+            node = ElementTree.Element('agents')
         
-        # set attributes
-        node.set('id',self.convertToStr(machine.db_id, 'long'))
-        node.set('name',self.convertToStr(machine.db_name, 'str'))
-        node.set('os',self.convertToStr(machine.db_os, 'str'))
-        node.set('architecture',self.convertToStr(machine.db_architecture, 'str'))
-        node.set('processor',self.convertToStr(machine.db_processor, 'str'))
-        node.set('ram',self.convertToStr(machine.db_ram, 'int'))
+        # set elements
+        agents = opm_agents.db_agents
+        for agent in agents:
+            if (agents is not None) and (agents != ""):
+                childNode = ElementTree.SubElement(node, 'agent')
+                self.getDao('opm_agent').toXML(agent, childNode)
         
         return node
 
-class DBAddXMLDAOBase(XMLDAO):
+class DBOpmDependenciesXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1813,22 +1703,10 @@ class DBAddXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'add':
+        if node_tag != 'causalDependencies':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('what', None)
-        what = self.convertFromStr(data, 'str')
-        data = node.get('objectId', None)
-        objectId = self.convertFromStr(data, 'long')
-        data = node.get('parentObjId', None)
-        parentObjId = self.convertFromStr(data, 'long')
-        data = node.get('parentObjType', None)
-        parentObjType = self.convertFromStr(data, 'str')
-        
-        data = None
+        dependencys = []
         
         # read children
         for child in node.getchildren():
@@ -1836,110 +1714,56 @@ class DBAddXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'module':
-                _data = self.getDao('module').fromXML(child)
-                data = _data
-            elif child_tag == 'location':
-                _data = self.getDao('location').fromXML(child)
-                data = _data
-            elif child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                data = _data
-            elif child_tag == 'function':
-                _data = self.getDao('function').fromXML(child)
-                data = _data
-            elif child_tag == 'connection':
-                _data = self.getDao('connection').fromXML(child)
-                data = _data
-            elif child_tag == 'port':
-                _data = self.getDao('port').fromXML(child)
-                data = _data
-            elif child_tag == 'parameter':
-                _data = self.getDao('parameter').fromXML(child)
-                data = _data
-            elif child_tag == 'portSpec':
-                _data = self.getDao('portSpec').fromXML(child)
-                data = _data
-            elif child_tag == 'abstraction':
-                _data = self.getDao('abstraction').fromXML(child)
-                data = _data
-            elif child_tag == 'group':
-                _data = self.getDao('group').fromXML(child)
-                data = _data
-            elif child_tag == 'other':
-                _data = self.getDao('other').fromXML(child)
-                data = _data
-            elif child_tag == 'plugin_data':
-                _data = self.getDao('plugin_data').fromXML(child)
-                data = _data
+            if child_tag == 'used':
+                _data = self.getDao('opm_used').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasGeneratedBy':
+                _data = self.getDao('opm_was_generated_by').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasTriggeredBy':
+                _data = self.getDao('opm_was_triggered_by').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasDerivedFrom':
+                _data = self.getDao('opm_was_derived_from').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasControlledBy':
+                _data = self.getDao('opm_was_controlled_by').fromXML(child)
+                dependencys.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBAdd(data=data,
-                    id=id,
-                    what=what,
-                    objectId=objectId,
-                    parentObjId=parentObjId,
-                    parentObjType=parentObjType)
+        obj = DBOpmDependencies(dependencys=dependencys)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, add, node=None):
+    def toXML(self, opm_dependencies, node=None):
         if node is None:
-            node = ElementTree.Element('add')
-        
-        # set attributes
-        node.set('id',self.convertToStr(add.db_id, 'long'))
-        node.set('what',self.convertToStr(add.db_what, 'str'))
-        node.set('objectId',self.convertToStr(add.db_objectId, 'long'))
-        node.set('parentObjId',self.convertToStr(add.db_parentObjId, 'long'))
-        node.set('parentObjType',self.convertToStr(add.db_parentObjType, 'str'))
+            node = ElementTree.Element('causalDependencies')
         
         # set elements
-        data = add.db_data
-        if data is not None:
-            if data.vtType == 'module':
-                childNode = ElementTree.SubElement(node, 'module')
-                self.getDao('module').toXML(data, childNode)
-            elif data.vtType == 'location':
-                childNode = ElementTree.SubElement(node, 'location')
-                self.getDao('location').toXML(data, childNode)
-            elif data.vtType == 'annotation':
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(data, childNode)
-            elif data.vtType == 'function':
-                childNode = ElementTree.SubElement(node, 'function')
-                self.getDao('function').toXML(data, childNode)
-            elif data.vtType == 'connection':
-                childNode = ElementTree.SubElement(node, 'connection')
-                self.getDao('connection').toXML(data, childNode)
-            elif data.vtType == 'port':
-                childNode = ElementTree.SubElement(node, 'port')
-                self.getDao('port').toXML(data, childNode)
-            elif data.vtType == 'parameter':
-                childNode = ElementTree.SubElement(node, 'parameter')
-                self.getDao('parameter').toXML(data, childNode)
-            elif data.vtType == 'portSpec':
-                childNode = ElementTree.SubElement(node, 'portSpec')
-                self.getDao('portSpec').toXML(data, childNode)
-            elif data.vtType == 'abstraction':
-                childNode = ElementTree.SubElement(node, 'abstraction')
-                self.getDao('abstraction').toXML(data, childNode)
-            elif data.vtType == 'group':
-                childNode = ElementTree.SubElement(node, 'group')
-                self.getDao('group').toXML(data, childNode)
-            elif data.vtType == 'other':
-                childNode = ElementTree.SubElement(node, 'other')
-                self.getDao('other').toXML(data, childNode)
-            elif data.vtType == 'plugin_data':
-                childNode = ElementTree.SubElement(node, 'plugin_data')
-                self.getDao('plugin_data').toXML(data, childNode)
+        dependencys = opm_dependencies.db_dependencys
+        for dependency in dependencys:
+            if dependency.vtType == 'opm_used':
+                childNode = ElementTree.SubElement(node, 'used')
+                self.getDao('opm_used').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_generated_by':
+                childNode = ElementTree.SubElement(node, 'wasGeneratedBy')
+                self.getDao('opm_was_generated_by').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_triggered_by':
+                childNode = ElementTree.SubElement(node, 'wasTriggeredBy')
+                self.getDao('opm_was_triggered_by').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_derived_from':
+                childNode = ElementTree.SubElement(node, 'wasDerivedFrom')
+                self.getDao('opm_was_derived_from').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_controlled_by':
+                childNode = ElementTree.SubElement(node, 'wasControlledBy')
+                self.getDao('opm_was_controlled_by').toXML(dependency, childNode)
         
         return node
 
-class DBOtherXMLDAOBase(XMLDAO):
+class DBPEFunctionXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -1952,16 +1776,20 @@ class DBOtherXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'other':
+        if node_tag != 'peFunction':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('key', None)
-        key = self.convertFromStr(data, 'str')
+        data = node.get('moduleId', None)
+        module_id = self.convertFromStr(data, 'long')
+        data = node.get('port_name', None)
+        port_name = self.convertFromStr(data, 'str')
+        data = node.get('is_alias', None)
+        is_alias = self.convertFromStr(data, 'long')
         
-        value = None
+        parameters = []
         
         # read children
         for child in node.getchildren():
@@ -1969,37 +1797,42 @@ class DBOtherXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'value':
-                _data = self.convertFromStr(child.text,'str')
-                value = _data
+            if child_tag == 'peParameter':
+                _data = self.getDao('pe_parameter').fromXML(child)
+                parameters.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOther(id=id,
-                      key=key,
-                      value=value)
+        obj = DBPEFunction(id=id,
+                           module_id=module_id,
+                           port_name=port_name,
+                           is_alias=is_alias,
+                           parameters=parameters)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, other, node=None):
+    def toXML(self, pe_function, node=None):
         if node is None:
-            node = ElementTree.Element('other')
+            node = ElementTree.Element('peFunction')
         
         # set attributes
-        node.set('id',self.convertToStr(other.db_id, 'long'))
-        node.set('key',self.convertToStr(other.db_key, 'str'))
+        node.set('id',self.convertToStr(pe_function.db_id, 'long'))
+        node.set('moduleId',self.convertToStr(pe_function.db_module_id, 'long'))
+        node.set('port_name',self.convertToStr(pe_function.db_port_name, 'str'))
+        node.set('is_alias',self.convertToStr(pe_function.db_is_alias, 'long'))
         
         # set elements
-        value = other.db_value
-        if (value is not None) and (value != ""):
-            childNode = ElementTree.SubElement(node, 'value')
-            childNode.text = self.convertToStr(value, 'str')
+        parameters = pe_function.db_parameters
+        for parameter in parameters:
+            if (parameters is not None) and (parameters != ""):
+                childNode = ElementTree.SubElement(node, 'peParameter')
+                self.getDao('pe_parameter').toXML(parameter, childNode)
         
         return node
 
-class DBLocationXMLDAOBase(XMLDAO):
+class DBWorkflowXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2012,51 +1845,24 @@ class DBLocationXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'location':
+        if node_tag != 'workflow':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('x', None)
-        x = self.convertFromStr(data, 'float')
-        data = node.get('y', None)
-        y = self.convertFromStr(data, 'float')
-        
-        obj = DBLocation(id=id,
-                         x=x,
-                         y=y)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, location, node=None):
-        if node is None:
-            node = ElementTree.Element('location')
-        
-        # set attributes
-        node.set('id',self.convertToStr(location.db_id, 'long'))
-        node.set('x',self.convertToStr(location.db_x, 'float'))
-        node.set('y',self.convertToStr(location.db_y, 'float'))
-        
-        return node
-
-class DBOpmOverlapsXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'overlaps':
-            return None
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('vistrail_id', None)
+        vistrail_id = self.convertFromStr(data, 'long')
         
-        opm_account_ids = []
+        connections = []
+        annotations = []
+        plugin_datas = []
+        others = []
+        modules = []
         
         # read children
         for child in node.getchildren():
@@ -2064,32 +1870,90 @@ class DBOpmOverlapsXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                opm_account_ids.append(_data)
+            if child_tag == 'connection':
+                _data = self.getDao('connection').fromXML(child)
+                connections.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'plugin_data':
+                _data = self.getDao('plugin_data').fromXML(child)
+                plugin_datas.append(_data)
+            elif child_tag == 'other':
+                _data = self.getDao('other').fromXML(child)
+                others.append(_data)
+            elif child_tag == 'module':
+                _data = self.getDao('module').fromXML(child)
+                modules.append(_data)
+            elif child_tag == 'abstraction':
+                _data = self.getDao('abstraction').fromXML(child)
+                modules.append(_data)
+            elif child_tag == 'group':
+                _data = self.getDao('group').fromXML(child)
+                modules.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmOverlaps(opm_account_ids=opm_account_ids)
+        obj = DBWorkflow(modules=modules,
+                         id=id,
+                         name=name,
+                         version=version,
+                         connections=connections,
+                         annotations=annotations,
+                         plugin_datas=plugin_datas,
+                         others=others,
+                         vistrail_id=vistrail_id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_overlaps, node=None):
+    def toXML(self, workflow, node=None):
         if node is None:
-            node = ElementTree.Element('overlaps')
+            node = ElementTree.Element('workflow')
         
-        # set elements
-        opm_account_ids = opm_overlaps.db_opm_account_ids
-        for opm_account_id in opm_account_ids:
-            if (opm_account_ids is not None) and (opm_account_ids != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(opm_account_id, childNode)
+        # set attributes
+        node.set('id',self.convertToStr(workflow.db_id, 'long'))
+        node.set('name',self.convertToStr(workflow.db_name, 'str'))
+        node.set('version',self.convertToStr(workflow.db_version, 'str'))
+        node.set('vistrail_id',self.convertToStr(workflow.db_vistrail_id, 'long'))
+        
+        # set elements
+        connections = workflow.db_connections
+        for connection in connections:
+            if (connections is not None) and (connections != ""):
+                childNode = ElementTree.SubElement(node, 'connection')
+                self.getDao('connection').toXML(connection, childNode)
+        annotations = workflow.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        plugin_datas = workflow.db_plugin_datas
+        for plugin_data in plugin_datas:
+            if (plugin_datas is not None) and (plugin_datas != ""):
+                childNode = ElementTree.SubElement(node, 'plugin_data')
+                self.getDao('plugin_data').toXML(plugin_data, childNode)
+        others = workflow.db_others
+        for other in others:
+            if (others is not None) and (others != ""):
+                childNode = ElementTree.SubElement(node, 'other')
+                self.getDao('other').toXML(other, childNode)
+        modules = workflow.db_modules
+        for module in modules:
+            if module.vtType == 'module':
+                childNode = ElementTree.SubElement(node, 'module')
+                self.getDao('module').toXML(module, childNode)
+            elif module.vtType == 'abstraction':
+                childNode = ElementTree.SubElement(node, 'abstraction')
+                self.getDao('abstraction').toXML(module, childNode)
+            elif module.vtType == 'group':
+                childNode = ElementTree.SubElement(node, 'group')
+                self.getDao('group').toXML(module, childNode)
         
         return node
 
-class DBPEParameterXMLDAOBase(XMLDAO):
+class DBMashupActionXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2102,43 +1966,63 @@ class DBPEParameterXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'peParameter':
+        if node_tag != 'action':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('pos', None)
-        pos = self.convertFromStr(data, 'long')
-        data = node.get('interpolator', None)
-        interpolator = self.convertFromStr(data, 'str')
-        data = node.get('value', None)
-        value = self.convertFromStr(data, 'str')
-        data = node.get('dimension', None)
-        dimension = self.convertFromStr(data, 'long')
+        data = node.get('prevId', None)
+        prevId = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
         
-        obj = DBPEParameter(id=id,
-                            pos=pos,
-                            interpolator=interpolator,
-                            value=value,
-                            dimension=dimension)
+        mashup = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'mashup':
+                _data = self.getDao('mashup').fromXML(child)
+                mashup = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBMashupAction(id=id,
+                             prevId=prevId,
+                             date=date,
+                             user=user,
+                             mashup=mashup)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, pe_parameter, node=None):
+    def toXML(self, mashup_action, node=None):
         if node is None:
-            node = ElementTree.Element('peParameter')
+            node = ElementTree.Element('action')
         
         # set attributes
-        node.set('id',self.convertToStr(pe_parameter.db_id, 'long'))
-        node.set('pos',self.convertToStr(pe_parameter.db_pos, 'long'))
-        node.set('interpolator',self.convertToStr(pe_parameter.db_interpolator, 'str'))
-        node.set('value',self.convertToStr(pe_parameter.db_value, 'str'))
-        node.set('dimension',self.convertToStr(pe_parameter.db_dimension, 'long'))
+        node.set('id',self.convertToStr(mashup_action.db_id, 'long'))
+        node.set('prevId',self.convertToStr(mashup_action.db_prevId, 'long'))
+        node.set('date',self.convertToStr(mashup_action.db_date, 'datetime'))
+        node.set('user',self.convertToStr(mashup_action.db_user, 'str'))
+        
+        # set elements
+        mashup = mashup_action.db_mashup
+        if mashup is not None:
+            if (mashup is not None) and (mashup != ""):
+                childNode = ElementTree.SubElement(node, 'mashup')
+                self.getDao('mashup').toXML(mashup, childNode)
         
         return node
 
-class DBOpmDependenciesXMLDAOBase(XMLDAO):
+class DBConfigurationXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2151,10 +2035,10 @@ class DBOpmDependenciesXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'causalDependencies':
+        if node_tag != 'configuration':
             return None
         
-        dependencys = []
+        config_keys = []
         
         # read children
         for child in node.getchildren():
@@ -2162,56 +2046,32 @@ class DBOpmDependenciesXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'used':
-                _data = self.getDao('opm_used').fromXML(child)
-                dependencys.append(_data)
-            elif child_tag == 'wasGeneratedBy':
-                _data = self.getDao('opm_was_generated_by').fromXML(child)
-                dependencys.append(_data)
-            elif child_tag == 'wasTriggeredBy':
-                _data = self.getDao('opm_was_triggered_by').fromXML(child)
-                dependencys.append(_data)
-            elif child_tag == 'wasDerivedFrom':
-                _data = self.getDao('opm_was_derived_from').fromXML(child)
-                dependencys.append(_data)
-            elif child_tag == 'wasControlledBy':
-                _data = self.getDao('opm_was_controlled_by').fromXML(child)
-                dependencys.append(_data)
+            if child_tag == 'key':
+                _data = self.getDao('config_key').fromXML(child)
+                config_keys.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmDependencies(dependencys=dependencys)
+        obj = DBConfiguration(config_keys=config_keys)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_dependencies, node=None):
+    def toXML(self, configuration, node=None):
         if node is None:
-            node = ElementTree.Element('causalDependencies')
+            node = ElementTree.Element('configuration')
         
         # set elements
-        dependencys = opm_dependencies.db_dependencys
-        for dependency in dependencys:
-            if dependency.vtType == 'opm_used':
-                childNode = ElementTree.SubElement(node, 'used')
-                self.getDao('opm_used').toXML(dependency, childNode)
-            elif dependency.vtType == 'opm_was_generated_by':
-                childNode = ElementTree.SubElement(node, 'wasGeneratedBy')
-                self.getDao('opm_was_generated_by').toXML(dependency, childNode)
-            elif dependency.vtType == 'opm_was_triggered_by':
-                childNode = ElementTree.SubElement(node, 'wasTriggeredBy')
-                self.getDao('opm_was_triggered_by').toXML(dependency, childNode)
-            elif dependency.vtType == 'opm_was_derived_from':
-                childNode = ElementTree.SubElement(node, 'wasDerivedFrom')
-                self.getDao('opm_was_derived_from').toXML(dependency, childNode)
-            elif dependency.vtType == 'opm_was_controlled_by':
-                childNode = ElementTree.SubElement(node, 'wasControlledBy')
-                self.getDao('opm_was_controlled_by').toXML(dependency, childNode)
+        config_keys = configuration.db_config_keys
+        for config_key in config_keys:
+            if (config_keys is not None) and (config_keys != ""):
+                childNode = ElementTree.SubElement(node, 'key')
+                self.getDao('config_key').toXML(config_key, childNode)
         
         return node
 
-class DBParameterXMLDAOBase(XMLDAO):
+class DBChangeXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2224,67 +2084,24 @@ class DBParameterXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'parameter':
+        if node_tag != 'change':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('pos', None)
-        pos = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('type', None)
-        type = self.convertFromStr(data, 'str')
-        data = node.get('val', None)
-        val = self.convertFromStr(data, 'str')
-        data = node.get('alias', None)
-        alias = self.convertFromStr(data, 'str')
-        
-        obj = DBParameter(id=id,
-                          pos=pos,
-                          name=name,
-                          type=type,
-                          val=val,
-                          alias=alias)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, parameter, node=None):
-        if node is None:
-            node = ElementTree.Element('parameter')
-        
-        # set attributes
-        node.set('id',self.convertToStr(parameter.db_id, 'long'))
-        node.set('pos',self.convertToStr(parameter.db_pos, 'long'))
-        node.set('name',self.convertToStr(parameter.db_name, 'str'))
-        node.set('type',self.convertToStr(parameter.db_type, 'str'))
-        node.set('val',self.convertToStr(parameter.db_val, 'str'))
-        node.set('alias',self.convertToStr(parameter.db_alias, 'str'))
-        
-        return node
-
-class DBOpmUsedXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'used':
-            return None
+        data = node.get('what', None)
+        what = self.convertFromStr(data, 'str')
+        data = node.get('oldObjId', None)
+        oldObjId = self.convertFromStr(data, 'long')
+        data = node.get('newObjId', None)
+        newObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjId', None)
+        parentObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjType', None)
+        parentObjType = self.convertFromStr(data, 'str')
         
-        effect = None
-        role = None
-        cause = None
-        accounts = []
-        opm_times = []
+        data = None
         
         # read children
         for child in node.getchildren():
@@ -2292,68 +2109,112 @@ class DBOpmUsedXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'effect':
-                _data = self.getDao('opm_process_id_effect').fromXML(child)
-                effect = _data
-            elif child_tag == 'role':
-                _data = self.getDao('opm_role').fromXML(child)
-                role = _data
-            elif child_tag == 'cause':
-                _data = self.getDao('opm_artifact_id_cause').fromXML(child)
-                cause = _data
-            elif child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                accounts.append(_data)
-            elif child_tag == 'time':
-                _data = self.getDao('opm_time').fromXML(child)
-                opm_times.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
-        
-        obj = DBOpmUsed(effect=effect,
-                        role=role,
-                        cause=cause,
-                        accounts=accounts,
-                        opm_times=opm_times)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, opm_used, node=None):
-        if node is None:
-            node = ElementTree.Element('used')
-        
-        # set elements
-        effect = opm_used.db_effect
-        if effect is not None:
-            if (effect is not None) and (effect != ""):
-                childNode = ElementTree.SubElement(node, 'effect')
-                self.getDao('opm_process_id_effect').toXML(effect, childNode)
-        role = opm_used.db_role
-        if role is not None:
-            if (role is not None) and (role != ""):
-                childNode = ElementTree.SubElement(node, 'role')
-                self.getDao('opm_role').toXML(role, childNode)
-        cause = opm_used.db_cause
-        if cause is not None:
-            if (cause is not None) and (cause != ""):
-                childNode = ElementTree.SubElement(node, 'cause')
-                self.getDao('opm_artifact_id_cause').toXML(cause, childNode)
-        accounts = opm_used.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(account, childNode)
-        opm_times = opm_used.db_opm_times
-        for opm_time in opm_times:
-            if (opm_times is not None) and (opm_times != ""):
-                childNode = ElementTree.SubElement(node, 'time')
-                self.getDao('opm_time').toXML(opm_time, childNode)
+            if child_tag == 'module':
+                _data = self.getDao('module').fromXML(child)
+                data = _data
+            elif child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                data = _data
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                data = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                data = _data
+            elif child_tag == 'connection':
+                _data = self.getDao('connection').fromXML(child)
+                data = _data
+            elif child_tag == 'port':
+                _data = self.getDao('port').fromXML(child)
+                data = _data
+            elif child_tag == 'parameter':
+                _data = self.getDao('parameter').fromXML(child)
+                data = _data
+            elif child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                data = _data
+            elif child_tag == 'abstraction':
+                _data = self.getDao('abstraction').fromXML(child)
+                data = _data
+            elif child_tag == 'group':
+                _data = self.getDao('group').fromXML(child)
+                data = _data
+            elif child_tag == 'other':
+                _data = self.getDao('other').fromXML(child)
+                data = _data
+            elif child_tag == 'plugin_data':
+                _data = self.getDao('plugin_data').fromXML(child)
+                data = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBChange(data=data,
+                       id=id,
+                       what=what,
+                       oldObjId=oldObjId,
+                       newObjId=newObjId,
+                       parentObjId=parentObjId,
+                       parentObjType=parentObjType)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, change, node=None):
+        if node is None:
+            node = ElementTree.Element('change')
+        
+        # set attributes
+        node.set('id',self.convertToStr(change.db_id, 'long'))
+        node.set('what',self.convertToStr(change.db_what, 'str'))
+        node.set('oldObjId',self.convertToStr(change.db_oldObjId, 'long'))
+        node.set('newObjId',self.convertToStr(change.db_newObjId, 'long'))
+        node.set('parentObjId',self.convertToStr(change.db_parentObjId, 'long'))
+        node.set('parentObjType',self.convertToStr(change.db_parentObjType, 'str'))
+        
+        # set elements
+        data = change.db_data
+        if data is not None:
+            if data.vtType == 'module':
+                childNode = ElementTree.SubElement(node, 'module')
+                self.getDao('module').toXML(data, childNode)
+            elif data.vtType == 'location':
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(data, childNode)
+            elif data.vtType == 'annotation':
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(data, childNode)
+            elif data.vtType == 'function':
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(data, childNode)
+            elif data.vtType == 'connection':
+                childNode = ElementTree.SubElement(node, 'connection')
+                self.getDao('connection').toXML(data, childNode)
+            elif data.vtType == 'port':
+                childNode = ElementTree.SubElement(node, 'port')
+                self.getDao('port').toXML(data, childNode)
+            elif data.vtType == 'parameter':
+                childNode = ElementTree.SubElement(node, 'parameter')
+                self.getDao('parameter').toXML(data, childNode)
+            elif data.vtType == 'portSpec':
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(data, childNode)
+            elif data.vtType == 'abstraction':
+                childNode = ElementTree.SubElement(node, 'abstraction')
+                self.getDao('abstraction').toXML(data, childNode)
+            elif data.vtType == 'group':
+                childNode = ElementTree.SubElement(node, 'group')
+                self.getDao('group').toXML(data, childNode)
+            elif data.vtType == 'other':
+                childNode = ElementTree.SubElement(node, 'other')
+                self.getDao('other').toXML(data, childNode)
+            elif data.vtType == 'plugin_data':
+                childNode = ElementTree.SubElement(node, 'plugin_data')
+                self.getDao('plugin_data').toXML(data, childNode)
         
         return node
 
-class DBPluginDataXMLDAOBase(XMLDAO):
+class DBPackageXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2366,31 +2227,75 @@ class DBPluginDataXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'plugin_data':
+        if node_tag != 'package':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('data', None)
-        data = self.convertFromStr(data, 'str')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('identifier', None)
+        identifier = self.convertFromStr(data, 'str')
+        data = node.get('codepath', None)
+        codepath = self.convertFromStr(data, 'str')
+        data = node.get('loadConfiguration', None)
+        load_configuration = self.convertFromStr(data, 'int')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('description', None)
+        description = self.convertFromStr(data, 'str')
         
-        obj = DBPluginData(id=id,
-                           data=data)
+        module_descriptors = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'moduleDescriptor':
+                _data = self.getDao('module_descriptor').fromXML(child)
+                module_descriptors.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBPackage(id=id,
+                        name=name,
+                        identifier=identifier,
+                        codepath=codepath,
+                        load_configuration=load_configuration,
+                        version=version,
+                        description=description,
+                        module_descriptors=module_descriptors)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, plugin_data, node=None):
+    def toXML(self, package, node=None):
         if node is None:
-            node = ElementTree.Element('plugin_data')
+            node = ElementTree.Element('package')
         
         # set attributes
-        node.set('id',self.convertToStr(plugin_data.db_id, 'long'))
-        node.set('data',self.convertToStr(plugin_data.db_data, 'str'))
+        node.set('id',self.convertToStr(package.db_id, 'long'))
+        node.set('name',self.convertToStr(package.db_name, 'str'))
+        node.set('identifier',self.convertToStr(package.db_identifier, 'str'))
+        node.set('codepath',self.convertToStr(package.db_codepath, 'str'))
+        node.set('loadConfiguration',self.convertToStr(package.db_load_configuration, 'int'))
+        node.set('version',self.convertToStr(package.db_version, 'str'))
+        node.set('description',self.convertToStr(package.db_description, 'str'))
+        
+        # set elements
+        module_descriptors = package.db_module_descriptors
+        for module_descriptor in module_descriptors:
+            if (module_descriptors is not None) and (module_descriptors != ""):
+                childNode = ElementTree.SubElement(node, 'moduleDescriptor')
+                self.getDao('module_descriptor').toXML(module_descriptor, childNode)
         
         return node
 
-class DBFunctionXMLDAOBase(XMLDAO):
+class DBLoopExecXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2403,18 +2308,24 @@ class DBFunctionXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'function':
+        if node_tag != 'loopExec':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('pos', None)
-        pos = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('iteration', None)
+        iteration = self.convertFromStr(data, 'int')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('error', None)
+        error = self.convertFromStr(data, 'str')
         
-        parameters = []
+        item_execs = []
         
         # read children
         for child in node.getchildren():
@@ -2422,40 +2333,58 @@ class DBFunctionXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'parameter':
-                _data = self.getDao('parameter').fromXML(child)
-                parameters.append(_data)
+            if child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                item_execs.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBFunction(id=id,
-                         pos=pos,
-                         name=name,
-                         parameters=parameters)
+        obj = DBLoopExec(item_execs=item_execs,
+                         id=id,
+                         ts_start=ts_start,
+                         ts_end=ts_end,
+                         iteration=iteration,
+                         completed=completed,
+                         error=error)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, function, node=None):
+    def toXML(self, loop_exec, node=None):
         if node is None:
-            node = ElementTree.Element('function')
+            node = ElementTree.Element('loopExec')
         
         # set attributes
-        node.set('id',self.convertToStr(function.db_id, 'long'))
-        node.set('pos',self.convertToStr(function.db_pos, 'long'))
-        node.set('name',self.convertToStr(function.db_name, 'str'))
+        node.set('id',self.convertToStr(loop_exec.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(loop_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(loop_exec.db_ts_end, 'datetime'))
+        node.set('iteration',self.convertToStr(loop_exec.db_iteration, 'int'))
+        node.set('completed',self.convertToStr(loop_exec.db_completed, 'int'))
+        node.set('error',self.convertToStr(loop_exec.db_error, 'str'))
         
         # set elements
-        parameters = function.db_parameters
-        for parameter in parameters:
-            if (parameters is not None) and (parameters != ""):
-                childNode = ElementTree.SubElement(node, 'parameter')
-                self.getDao('parameter').toXML(parameter, childNode)
+        item_execs = loop_exec.db_item_execs
+        for item_exec in item_execs:
+            if item_exec.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(item_exec, childNode)
         
         return node
 
-class DBActionAnnotationXMLDAOBase(XMLDAO):
+class DBConnectionXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2468,47 +2397,51 @@ class DBActionAnnotationXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'actionAnnotation':
+        if node_tag != 'connection':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('key', None)
-        key = self.convertFromStr(data, 'str')
-        data = node.get('value', None)
-        value = self.convertFromStr(data, 'str')
-        data = node.get('actionId', None)
-        action_id = self.convertFromStr(data, 'long')
-        data = node.get('date', None)
-        date = self.convertFromStr(data, 'datetime')
-        data = node.get('user', None)
-        user = self.convertFromStr(data, 'str')
         
-        obj = DBActionAnnotation(id=id,
-                                 key=key,
-                                 value=value,
-                                 action_id=action_id,
-                                 date=date,
-                                 user=user)
+        ports = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'port':
+                _data = self.getDao('port').fromXML(child)
+                ports.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBConnection(id=id,
+                           ports=ports)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, actionAnnotation, node=None):
+    def toXML(self, connection, node=None):
         if node is None:
-            node = ElementTree.Element('actionAnnotation')
+            node = ElementTree.Element('connection')
         
         # set attributes
-        node.set('id',self.convertToStr(actionAnnotation.db_id, 'long'))
-        node.set('key',self.convertToStr(actionAnnotation.db_key, 'str'))
-        node.set('value',self.convertToStr(actionAnnotation.db_value, 'str'))
-        node.set('actionId',self.convertToStr(actionAnnotation.db_action_id, 'long'))
-        node.set('date',self.convertToStr(actionAnnotation.db_date, 'datetime'))
-        node.set('user',self.convertToStr(actionAnnotation.db_user, 'str'))
+        node.set('id',self.convertToStr(connection.db_id, 'long'))
+        
+        # set elements
+        ports = connection.db_ports
+        for port in ports:
+            if (ports is not None) and (ports != ""):
+                childNode = ElementTree.SubElement(node, 'port')
+                self.getDao('port').toXML(port, childNode)
         
         return node
 
-class DBAbstractionXMLDAOBase(XMLDAO):
+class DBConfigBoolXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2521,95 +2454,27 @@ class DBAbstractionXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'abstraction':
+        if node_tag != 'bool':
             return None
         
         # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('cache', None)
-        cache = self.convertFromStr(data, 'int')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('namespace', None)
-        namespace = self.convertFromStr(data, 'str')
-        data = node.get('package', None)
-        package = self.convertFromStr(data, 'str')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
-        data = node.get('internalVersion', None)
-        internal_version = self.convertFromStr(data, 'str')
-        
-        location = None
-        functions = []
-        annotations = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'location':
-                _data = self.getDao('location').fromXML(child)
-                location = _data
-            elif child_tag == 'function':
-                _data = self.getDao('function').fromXML(child)
-                functions.append(_data)
-            elif child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
         
-        obj = DBAbstraction(id=id,
-                            cache=cache,
-                            name=name,
-                            namespace=namespace,
-                            package=package,
-                            version=version,
-                            internal_version=internal_version,
-                            location=location,
-                            functions=functions,
-                            annotations=annotations)
+        obj = DBConfigBool(value=value)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, abstraction, node=None):
+    def toXML(self, config_bool, node=None):
         if node is None:
-            node = ElementTree.Element('abstraction')
+            node = ElementTree.Element('bool')
         
         # set attributes
-        node.set('id',self.convertToStr(abstraction.db_id, 'long'))
-        node.set('cache',self.convertToStr(abstraction.db_cache, 'int'))
-        node.set('name',self.convertToStr(abstraction.db_name, 'str'))
-        node.set('namespace',self.convertToStr(abstraction.db_namespace, 'str'))
-        node.set('package',self.convertToStr(abstraction.db_package, 'str'))
-        node.set('version',self.convertToStr(abstraction.db_version, 'str'))
-        node.set('internalVersion',self.convertToStr(abstraction.db_internal_version, 'str'))
-        
-        # set elements
-        location = abstraction.db_location
-        if location is not None:
-            if (location is not None) and (location != ""):
-                childNode = ElementTree.SubElement(node, 'location')
-                self.getDao('location').toXML(location, childNode)
-        functions = abstraction.db_functions
-        for function in functions:
-            if (functions is not None) and (functions != ""):
-                childNode = ElementTree.SubElement(node, 'function')
-                self.getDao('function').toXML(function, childNode)
-        annotations = abstraction.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
+        node.set('value',self.convertToStr(config_bool.db_value, 'str'))
         
         return node
 
-class DBWorkflowXMLDAOBase(XMLDAO):
+class DBActionXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2622,24 +2487,23 @@ class DBWorkflowXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'workflow':
+        if node_tag != 'action':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
-        data = node.get('vistrail_id', None)
-        vistrail_id = self.convertFromStr(data, 'long')
+        data = node.get('prevId', None)
+        prevId = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('session', None)
+        session = self.convertFromStr(data, 'long')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
         
-        connections = []
         annotations = []
-        plugin_datas = []
-        others = []
-        modules = []
+        operations = []
         
         # read children
         for child in node.getchildren():
@@ -2647,90 +2511,65 @@ class DBWorkflowXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'connection':
-                _data = self.getDao('connection').fromXML(child)
-                connections.append(_data)
-            elif child_tag == 'annotation':
+            if child_tag == 'annotation':
                 _data = self.getDao('annotation').fromXML(child)
                 annotations.append(_data)
-            elif child_tag == 'plugin_data':
-                _data = self.getDao('plugin_data').fromXML(child)
-                plugin_datas.append(_data)
-            elif child_tag == 'other':
-                _data = self.getDao('other').fromXML(child)
-                others.append(_data)
-            elif child_tag == 'module':
-                _data = self.getDao('module').fromXML(child)
-                modules.append(_data)
-            elif child_tag == 'abstraction':
-                _data = self.getDao('abstraction').fromXML(child)
-                modules.append(_data)
-            elif child_tag == 'group':
-                _data = self.getDao('group').fromXML(child)
-                modules.append(_data)
+            elif child_tag == 'add':
+                _data = self.getDao('add').fromXML(child)
+                operations.append(_data)
+            elif child_tag == 'delete':
+                _data = self.getDao('delete').fromXML(child)
+                operations.append(_data)
+            elif child_tag == 'change':
+                _data = self.getDao('change').fromXML(child)
+                operations.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBWorkflow(modules=modules,
-                         id=id,
-                         name=name,
-                         version=version,
-                         connections=connections,
-                         annotations=annotations,
-                         plugin_datas=plugin_datas,
-                         others=others,
-                         vistrail_id=vistrail_id)
+        obj = DBAction(operations=operations,
+                       id=id,
+                       prevId=prevId,
+                       date=date,
+                       session=session,
+                       user=user,
+                       annotations=annotations)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, workflow, node=None):
+    def toXML(self, action, node=None):
         if node is None:
-            node = ElementTree.Element('workflow')
+            node = ElementTree.Element('action')
         
         # set attributes
-        node.set('id',self.convertToStr(workflow.db_id, 'long'))
-        node.set('name',self.convertToStr(workflow.db_name, 'str'))
-        node.set('version',self.convertToStr(workflow.db_version, 'str'))
-        node.set('vistrail_id',self.convertToStr(workflow.db_vistrail_id, 'long'))
+        node.set('id',self.convertToStr(action.db_id, 'long'))
+        node.set('prevId',self.convertToStr(action.db_prevId, 'long'))
+        node.set('date',self.convertToStr(action.db_date, 'datetime'))
+        node.set('session',self.convertToStr(action.db_session, 'long'))
+        node.set('user',self.convertToStr(action.db_user, 'str'))
         
         # set elements
-        connections = workflow.db_connections
-        for connection in connections:
-            if (connections is not None) and (connections != ""):
-                childNode = ElementTree.SubElement(node, 'connection')
-                self.getDao('connection').toXML(connection, childNode)
-        annotations = workflow.db_annotations
+        annotations = action.db_annotations
         for annotation in annotations:
             if (annotations is not None) and (annotations != ""):
                 childNode = ElementTree.SubElement(node, 'annotation')
                 self.getDao('annotation').toXML(annotation, childNode)
-        plugin_datas = workflow.db_plugin_datas
-        for plugin_data in plugin_datas:
-            if (plugin_datas is not None) and (plugin_datas != ""):
-                childNode = ElementTree.SubElement(node, 'plugin_data')
-                self.getDao('plugin_data').toXML(plugin_data, childNode)
-        others = workflow.db_others
-        for other in others:
-            if (others is not None) and (others != ""):
-                childNode = ElementTree.SubElement(node, 'other')
-                self.getDao('other').toXML(other, childNode)
-        modules = workflow.db_modules
-        for module in modules:
-            if module.vtType == 'module':
-                childNode = ElementTree.SubElement(node, 'module')
-                self.getDao('module').toXML(module, childNode)
-            elif module.vtType == 'abstraction':
-                childNode = ElementTree.SubElement(node, 'abstraction')
-                self.getDao('abstraction').toXML(module, childNode)
-            elif module.vtType == 'group':
-                childNode = ElementTree.SubElement(node, 'group')
-                self.getDao('group').toXML(module, childNode)
+        operations = action.db_operations
+        for operation in operations:
+            if operation.vtType == 'add':
+                childNode = ElementTree.SubElement(node, 'add')
+                self.getDao('add').toXML(operation, childNode)
+            elif operation.vtType == 'delete':
+                childNode = ElementTree.SubElement(node, 'delete')
+                self.getDao('delete').toXML(operation, childNode)
+            elif operation.vtType == 'change':
+                childNode = ElementTree.SubElement(node, 'change')
+                self.getDao('change').toXML(operation, childNode)
         
         return node
 
-class DBOpmArtifactIdCauseXMLDAOBase(XMLDAO):
+class DBStartupPackageXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2743,27 +2582,51 @@ class DBOpmArtifactIdCauseXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'cause':
+        if node_tag != 'package':
             return None
         
         # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
-        
-        obj = DBOpmArtifactIdCause(id=id)
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        configuration = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'configuration':
+                _data = self.getDao('configuration').fromXML(child)
+                configuration = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBStartupPackage(name=name,
+                               configuration=configuration)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_artifact_id_cause, node=None):
+    def toXML(self, startup_package, node=None):
         if node is None:
-            node = ElementTree.Element('cause')
+            node = ElementTree.Element('package')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_artifact_id_cause.db_id, 'str'))
+        node.set('name',self.convertToStr(startup_package.db_name, 'str'))
+        
+        # set elements
+        configuration = startup_package.db_configuration
+        if configuration is not None:
+            if (configuration is not None) and (configuration != ""):
+                childNode = ElementTree.SubElement(node, 'configuration')
+                self.getDao('configuration').toXML(configuration, childNode)
         
         return node
 
-class DBRefProvEntityXMLDAOBase(XMLDAO):
+class DBConfigIntXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2776,27 +2639,27 @@ class DBRefProvEntityXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:entity':
+        if node_tag != 'int':
             return None
         
         # read attributes
-        data = node.get('prov:ref', None)
-        prov_ref = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'int')
         
-        obj = DBRefProvEntity(prov_ref=prov_ref)
+        obj = DBConfigInt(value=value)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, ref_prov_entity, node=None):
+    def toXML(self, config_int, node=None):
         if node is None:
-            node = ElementTree.Element('prov:entity')
+            node = ElementTree.Element('int')
         
         # set attributes
-        node.set('prov:ref',self.convertToStr(ref_prov_entity.db_prov_ref, 'str'))
+        node.set('value',self.convertToStr(config_int.db_value, 'int'))
         
         return node
 
-class DBProvActivityXMLDAOBase(XMLDAO):
+class DBOpmProcessIdEffectXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2809,123 +2672,27 @@ class DBProvActivityXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:activity':
+        if node_tag != 'effect':
             return None
         
         # read attributes
-        data = node.get('prov:id', None)
+        data = node.get('id', None)
         id = self.convertFromStr(data, 'str')
         
-        startTime = None
-        endTime = None
-        vt_id = None
-        vt_type = None
-        vt_cached = None
-        vt_completed = None
-        vt_machine_id = None
-        vt_error = None
-        is_part_of = None
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'prov:startTime':
-                _data = self.convertFromStr(child.text,'str')
-                startTime = _data
-            elif child_tag == 'prov:endTime':
-                _data = self.convertFromStr(child.text,'str')
-                endTime = _data
-            elif child_tag == 'vt:id':
-                _data = self.convertFromStr(child.text,'str')
-                vt_id = _data
-            elif child_tag == 'vt:type':
-                _data = self.convertFromStr(child.text,'str')
-                vt_type = _data
-            elif child_tag == 'vt:cached':
-                _data = self.convertFromStr(child.text,'str')
-                vt_cached = _data
-            elif child_tag == 'vt:completed':
-                _data = self.convertFromStr(child.text,'str')
-                vt_completed = _data
-            elif child_tag == 'vt:machine_id':
-                _data = self.convertFromStr(child.text,'str')
-                vt_machine_id = _data
-            elif child_tag == 'vt:error':
-                _data = self.convertFromStr(child.text,'str')
-                vt_error = _data
-            elif child_tag == 'dcterms:isPartOf':
-                _data = self.getDao('is_part_of').fromXML(child)
-                is_part_of = _data
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
-        
-        obj = DBProvActivity(id=id,
-                             startTime=startTime,
-                             endTime=endTime,
-                             vt_id=vt_id,
-                             vt_type=vt_type,
-                             vt_cached=vt_cached,
-                             vt_completed=vt_completed,
-                             vt_machine_id=vt_machine_id,
-                             vt_error=vt_error,
-                             is_part_of=is_part_of)
+        obj = DBOpmProcessIdEffect(id=id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, prov_activity, node=None):
+    def toXML(self, opm_process_id_effect, node=None):
         if node is None:
-            node = ElementTree.Element('prov:activity')
+            node = ElementTree.Element('effect')
         
         # set attributes
-        node.set('prov:id',self.convertToStr(prov_activity.db_id, 'str'))
-        
-        # set elements
-        startTime = prov_activity.db_startTime
-        if (startTime is not None) and (startTime != ""):
-            childNode = ElementTree.SubElement(node, 'prov:startTime')
-            childNode.text = self.convertToStr(startTime, 'str')
-        endTime = prov_activity.db_endTime
-        if (endTime is not None) and (endTime != ""):
-            childNode = ElementTree.SubElement(node, 'prov:endTime')
-            childNode.text = self.convertToStr(endTime, 'str')
-        vt_id = prov_activity.db_vt_id
-        if (vt_id is not None) and (vt_id != ""):
-            childNode = ElementTree.SubElement(node, 'vt:id')
-            childNode.text = self.convertToStr(vt_id, 'str')
-        vt_type = prov_activity.db_vt_type
-        if (vt_type is not None) and (vt_type != ""):
-            childNode = ElementTree.SubElement(node, 'vt:type')
-            childNode.text = self.convertToStr(vt_type, 'str')
-        vt_cached = prov_activity.db_vt_cached
-        if (vt_cached is not None) and (vt_cached != ""):
-            childNode = ElementTree.SubElement(node, 'vt:cached')
-            childNode.text = self.convertToStr(vt_cached, 'str')
-        vt_completed = prov_activity.db_vt_completed
-        if (vt_completed is not None) and (vt_completed != ""):
-            childNode = ElementTree.SubElement(node, 'vt:completed')
-            childNode.text = self.convertToStr(vt_completed, 'str')
-        vt_machine_id = prov_activity.db_vt_machine_id
-        if (vt_machine_id is not None) and (vt_machine_id != ""):
-            childNode = ElementTree.SubElement(node, 'vt:machine_id')
-            childNode.text = self.convertToStr(vt_machine_id, 'str')
-        vt_error = prov_activity.db_vt_error
-        if (vt_error is not None) and (vt_error != ""):
-            childNode = ElementTree.SubElement(node, 'vt:error')
-            childNode.text = self.convertToStr(vt_error, 'str')
-        is_part_of = prov_activity.db_is_part_of
-        if is_part_of is not None:
-            if (is_part_of is not None) and (is_part_of != ""):
-                childNode = ElementTree.SubElement(node, 'dcterms:isPartOf')
-                self.getDao('is_part_of').toXML(is_part_of, childNode)
+        node.set('id',self.convertToStr(opm_process_id_effect.db_id, 'str'))
         
         return node
 
-class DBMashupActionXMLDAOBase(XMLDAO):
+class DBRefProvPlanXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -2938,63 +2705,27 @@ class DBMashupActionXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'action':
+        if node_tag != 'prov:plan':
             return None
         
         # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('prevId', None)
-        prevId = self.convertFromStr(data, 'long')
-        data = node.get('date', None)
-        date = self.convertFromStr(data, 'datetime')
-        data = node.get('user', None)
-        user = self.convertFromStr(data, 'str')
-        
-        mashup = None
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'mashup':
-                _data = self.getDao('mashup').fromXML(child)
-                mashup = _data
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
         
-        obj = DBMashupAction(id=id,
-                             prevId=prevId,
-                             date=date,
-                             user=user,
-                             mashup=mashup)
+        obj = DBRefProvPlan(prov_ref=prov_ref)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, mashup_action, node=None):
+    def toXML(self, ref_prov_plan, node=None):
         if node is None:
-            node = ElementTree.Element('action')
+            node = ElementTree.Element('prov:plan')
         
         # set attributes
-        node.set('id',self.convertToStr(mashup_action.db_id, 'long'))
-        node.set('prevId',self.convertToStr(mashup_action.db_prevId, 'long'))
-        node.set('date',self.convertToStr(mashup_action.db_date, 'datetime'))
-        node.set('user',self.convertToStr(mashup_action.db_user, 'str'))
-        
-        # set elements
-        mashup = mashup_action.db_mashup
-        if mashup is not None:
-            if (mashup is not None) and (mashup != ""):
-                childNode = ElementTree.SubElement(node, 'mashup')
-                self.getDao('mashup').toXML(mashup, childNode)
+        node.set('prov:ref',self.convertToStr(ref_prov_plan.db_prov_ref, 'str'))
         
         return node
 
-class DBProvUsageXMLDAOBase(XMLDAO):
+class DBOpmAccountsXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3007,12 +2738,11 @@ class DBProvUsageXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:used':
+        if node_tag != 'accounts':
             return None
         
-        prov_activity = None
-        prov_entity = None
-        prov_role = None
+        accounts = []
+        opm_overlapss = []
         
         # read children
         for child in node.getchildren():
@@ -3020,49 +2750,41 @@ class DBProvUsageXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'prov:activity':
-                _data = self.getDao('ref_prov_activity').fromXML(child)
-                prov_activity = _data
-            elif child_tag == 'prov:entity':
-                _data = self.getDao('ref_prov_entity').fromXML(child)
-                prov_entity = _data
-            elif child_tag == 'prov:role':
-                _data = self.convertFromStr(child.text,'str')
-                prov_role = _data
+            if child_tag == 'account':
+                _data = self.getDao('opm_account').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'overlaps':
+                _data = self.getDao('opm_overlaps').fromXML(child)
+                opm_overlapss.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBProvUsage(prov_activity=prov_activity,
-                          prov_entity=prov_entity,
-                          prov_role=prov_role)
+        obj = DBOpmAccounts(accounts=accounts,
+                            opm_overlapss=opm_overlapss)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, prov_usage, node=None):
+    def toXML(self, opm_accounts, node=None):
         if node is None:
-            node = ElementTree.Element('prov:used')
+            node = ElementTree.Element('accounts')
         
         # set elements
-        prov_activity = prov_usage.db_prov_activity
-        if prov_activity is not None:
-            if (prov_activity is not None) and (prov_activity != ""):
-                childNode = ElementTree.SubElement(node, 'prov:activity')
-                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
-        prov_entity = prov_usage.db_prov_entity
-        if prov_entity is not None:
-            if (prov_entity is not None) and (prov_entity != ""):
-                childNode = ElementTree.SubElement(node, 'prov:entity')
-                self.getDao('ref_prov_entity').toXML(prov_entity, childNode)
-        prov_role = prov_usage.db_prov_role
-        if (prov_role is not None) and (prov_role != ""):
-            childNode = ElementTree.SubElement(node, 'prov:role')
-            childNode.text = self.convertToStr(prov_role, 'str')
+        accounts = opm_accounts.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account').toXML(account, childNode)
+        opm_overlapss = opm_accounts.db_opm_overlapss
+        for opm_overlaps in opm_overlapss:
+            if (opm_overlapss is not None) and (opm_overlapss != ""):
+                childNode = ElementTree.SubElement(node, 'overlaps')
+                self.getDao('opm_overlaps').toXML(opm_overlaps, childNode)
         
         return node
 
-class DBOpmArtifactValueXMLDAOBase(XMLDAO):
+class DBRefProvAgentXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3075,49 +2797,27 @@ class DBOpmArtifactValueXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'value':
+        if node_tag != 'prov:agent':
             return None
         
-        value = None
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'portSpec':
-                _data = self.getDao('portSpec').fromXML(child)
-                value = _data
-            elif child_tag == 'function':
-                _data = self.getDao('function').fromXML(child)
-                value = _data
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
         
-        obj = DBOpmArtifactValue(value=value)
+        obj = DBRefProvAgent(prov_ref=prov_ref)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_artifact_value, node=None):
+    def toXML(self, ref_prov_agent, node=None):
         if node is None:
-            node = ElementTree.Element('value')
+            node = ElementTree.Element('prov:agent')
         
-        # set elements
-        value = opm_artifact_value.db_value
-        if value is not None:
-            if value.vtType == 'portSpec':
-                childNode = ElementTree.SubElement(node, 'portSpec')
-                self.getDao('portSpec').toXML(value, childNode)
-            elif value.vtType == 'function':
-                childNode = ElementTree.SubElement(node, 'function')
-                self.getDao('function').toXML(value, childNode)
+        # set attributes
+        node.set('prov:ref',self.convertToStr(ref_prov_agent.db_prov_ref, 'str'))
         
         return node
 
-class DBOpmArtifactIdEffectXMLDAOBase(XMLDAO):
+class DBPortSpecXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3130,27 +2830,75 @@ class DBOpmArtifactIdEffectXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'effect':
+        if node_tag != 'portSpec':
             return None
         
         # read attributes
         data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('optional', None)
+        optional = self.convertFromStr(data, 'int')
+        data = node.get('sortKey', None)
+        sort_key = self.convertFromStr(data, 'int')
+        data = node.get('minConns', None)
+        min_conns = self.convertFromStr(data, 'int')
+        data = node.get('maxConns', None)
+        max_conns = self.convertFromStr(data, 'int')
         
-        obj = DBOpmArtifactIdEffect(id=id)
+        portSpecItems = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'portSpecItem':
+                _data = self.getDao('portSpecItem').fromXML(child)
+                portSpecItems.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBPortSpec(id=id,
+                         name=name,
+                         type=type,
+                         optional=optional,
+                         sort_key=sort_key,
+                         portSpecItems=portSpecItems,
+                         min_conns=min_conns,
+                         max_conns=max_conns)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_artifact_id_effect, node=None):
+    def toXML(self, portSpec, node=None):
         if node is None:
-            node = ElementTree.Element('effect')
+            node = ElementTree.Element('portSpec')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_artifact_id_effect.db_id, 'str'))
+        node.set('id',self.convertToStr(portSpec.db_id, 'long'))
+        node.set('name',self.convertToStr(portSpec.db_name, 'str'))
+        node.set('type',self.convertToStr(portSpec.db_type, 'str'))
+        node.set('optional',self.convertToStr(portSpec.db_optional, 'int'))
+        node.set('sortKey',self.convertToStr(portSpec.db_sort_key, 'int'))
+        node.set('minConns',self.convertToStr(portSpec.db_min_conns, 'int'))
+        node.set('maxConns',self.convertToStr(portSpec.db_max_conns, 'int'))
+        
+        # set elements
+        portSpecItems = portSpec.db_portSpecItems
+        for portSpecItem in portSpecItems:
+            if (portSpecItems is not None) and (portSpecItems != ""):
+                childNode = ElementTree.SubElement(node, 'portSpecItem')
+                self.getDao('portSpecItem').toXML(portSpecItem, childNode)
         
         return node
 
-class DBOpmGraphXMLDAOBase(XMLDAO):
+class DBEnabledPackagesXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3163,14 +2911,10 @@ class DBOpmGraphXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'opmGraph':
+        if node_tag != 'packages':
             return None
         
-        accounts = None
-        processes = None
-        artifacts = None
-        agents = None
-        dependencies = None
+        packages = []
         
         # read children
         for child in node.getchildren():
@@ -3178,68 +2922,32 @@ class DBOpmGraphXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'accounts':
-                _data = self.getDao('opm_accounts').fromXML(child)
-                accounts = _data
-            elif child_tag == 'processes':
-                _data = self.getDao('opm_processes').fromXML(child)
-                processes = _data
-            elif child_tag == 'artifacts':
-                _data = self.getDao('opm_artifacts').fromXML(child)
-                artifacts = _data
-            elif child_tag == 'agents':
-                _data = self.getDao('opm_agents').fromXML(child)
-                agents = _data
-            elif child_tag == 'causalDependencies':
-                _data = self.getDao('opm_dependencies').fromXML(child)
-                dependencies = _data
+            if child_tag == 'package':
+                _data = self.getDao('startup_package').fromXML(child)
+                packages.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmGraph(accounts=accounts,
-                         processes=processes,
-                         artifacts=artifacts,
-                         agents=agents,
-                         dependencies=dependencies)
+        obj = DBEnabledPackages(packages=packages)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_graph, node=None):
+    def toXML(self, enabled_packages, node=None):
         if node is None:
-            node = ElementTree.Element('opmGraph')
+            node = ElementTree.Element('packages')
         
         # set elements
-        accounts = opm_graph.db_accounts
-        if accounts is not None:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'accounts')
-                self.getDao('opm_accounts').toXML(accounts, childNode)
-        processes = opm_graph.db_processes
-        if processes is not None:
-            if (processes is not None) and (processes != ""):
-                childNode = ElementTree.SubElement(node, 'processes')
-                self.getDao('opm_processes').toXML(processes, childNode)
-        artifacts = opm_graph.db_artifacts
-        if artifacts is not None:
-            if (artifacts is not None) and (artifacts != ""):
-                childNode = ElementTree.SubElement(node, 'artifacts')
-                self.getDao('opm_artifacts').toXML(artifacts, childNode)
-        agents = opm_graph.db_agents
-        if agents is not None:
-            if (agents is not None) and (agents != ""):
-                childNode = ElementTree.SubElement(node, 'agents')
-                self.getDao('opm_agents').toXML(agents, childNode)
-        dependencies = opm_graph.db_dependencies
-        if dependencies is not None:
-            if (dependencies is not None) and (dependencies != ""):
-                childNode = ElementTree.SubElement(node, 'causalDependencies')
-                self.getDao('opm_dependencies').toXML(dependencies, childNode)
+        packages = enabled_packages.db_packages
+        for package in packages:
+            if (packages is not None) and (packages != ""):
+                childNode = ElementTree.SubElement(node, 'package')
+                self.getDao('startup_package').toXML(package, childNode)
         
         return node
 
-class DBMashuptrailXMLDAOBase(XMLDAO):
+class DBOpmArtifactXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3252,20 +2960,15 @@ class DBMashuptrailXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'mashuptrail':
+        if node_tag != 'artifact':
             return None
         
         # read attributes
         data = node.get('id', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
-        data = node.get('vtVersion', None)
-        vtVersion = self.convertFromStr(data, 'long')
+        id = self.convertFromStr(data, 'str')
         
-        actions = []
-        annotations = []
-        actionAnnotations = []
+        value = None
+        accounts = []
         
         # read children
         for child in node.getchildren():
@@ -3273,58 +2976,45 @@ class DBMashuptrailXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'action':
-                _data = self.getDao('mashup_action').fromXML(child)
-                actions.append(_data)
-            elif child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child_tag == 'actionAnnotation':
-                _data = self.getDao('mashup_actionAnnotation').fromXML(child)
-                actionAnnotations.append(_data)
+            if child_tag == 'value':
+                _data = self.getDao('opm_artifact_value').fromXML(child)
+                value = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBMashuptrail(name=name,
-                            version=version,
-                            vtVersion=vtVersion,
-                            actions=actions,
-                            annotations=annotations,
-                            actionAnnotations=actionAnnotations)
+        obj = DBOpmArtifact(id=id,
+                            value=value,
+                            accounts=accounts)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, mashuptrail, node=None):
+    def toXML(self, opm_artifact, node=None):
         if node is None:
-            node = ElementTree.Element('mashuptrail')
+            node = ElementTree.Element('artifact')
         
         # set attributes
-        node.set('id',self.convertToStr(mashuptrail.db_name, 'str'))
-        node.set('version',self.convertToStr(mashuptrail.db_version, 'str'))
-        node.set('vtVersion',self.convertToStr(mashuptrail.db_vtVersion, 'long'))
+        node.set('id',self.convertToStr(opm_artifact.db_id, 'str'))
         
         # set elements
-        actions = mashuptrail.db_actions
-        for action in actions:
-            if (actions is not None) and (actions != ""):
-                childNode = ElementTree.SubElement(node, 'action')
-                self.getDao('mashup_action').toXML(action, childNode)
-        annotations = mashuptrail.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
-        actionAnnotations = mashuptrail.db_actionAnnotations
-        for actionAnnotation in actionAnnotations:
-            if (actionAnnotations is not None) and (actionAnnotations != ""):
-                childNode = ElementTree.SubElement(node, 'actionAnnotation')
-                self.getDao('mashup_actionAnnotation').toXML(actionAnnotation, childNode)
+        value = opm_artifact.db_value
+        if value is not None:
+            if (value is not None) and (value != ""):
+                childNode = ElementTree.SubElement(node, 'value')
+                self.getDao('opm_artifact_value').toXML(value, childNode)
+        accounts = opm_artifact.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
         
         return node
 
-class DBRegistryXMLDAOBase(XMLDAO):
+class DBLogXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3337,7 +3027,7 @@ class DBRegistryXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'registry':
+        if node_tag != 'log':
             return None
         
         # read attributes
@@ -3345,10 +3035,13 @@ class DBRegistryXMLDAOBase(XMLDAO):
         id = self.convertFromStr(data, 'long')
         data = node.get('version', None)
         version = self.convertFromStr(data, 'str')
-        data = node.get('rootDescriptorId', None)
-        root_descriptor_id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('vistrail_id', None)
+        vistrail_id = self.convertFromStr(data, 'long')
         
-        packages = []
+        workflow_execs = []
+        machines = []
         
         # read children
         for child in node.getchildren():
@@ -3356,40 +3049,51 @@ class DBRegistryXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'package':
-                _data = self.getDao('package').fromXML(child)
-                packages.append(_data)
+            if child_tag == 'workflowExec':
+                _data = self.getDao('workflow_exec').fromXML(child)
+                workflow_execs.append(_data)
+            elif child_tag == 'machine':
+                _data = self.getDao('machine').fromXML(child)
+                machines.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBRegistry(id=id,
-                         version=version,
-                         root_descriptor_id=root_descriptor_id,
-                         packages=packages)
+        obj = DBLog(id=id,
+                    version=version,
+                    name=name,
+                    workflow_execs=workflow_execs,
+                    machines=machines,
+                    vistrail_id=vistrail_id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, registry, node=None):
+    def toXML(self, log, node=None):
         if node is None:
-            node = ElementTree.Element('registry')
+            node = ElementTree.Element('log')
         
         # set attributes
-        node.set('id',self.convertToStr(registry.db_id, 'long'))
-        node.set('version',self.convertToStr(registry.db_version, 'str'))
-        node.set('rootDescriptorId',self.convertToStr(registry.db_root_descriptor_id, 'long'))
+        node.set('id',self.convertToStr(log.db_id, 'long'))
+        node.set('version',self.convertToStr(log.db_version, 'str'))
+        node.set('name',self.convertToStr(log.db_name, 'str'))
+        node.set('vistrail_id',self.convertToStr(log.db_vistrail_id, 'long'))
         
         # set elements
-        packages = registry.db_packages
-        for package in packages:
-            if (packages is not None) and (packages != ""):
-                childNode = ElementTree.SubElement(node, 'package')
-                self.getDao('package').toXML(package, childNode)
+        workflow_execs = log.db_workflow_execs
+        for workflow_exec in workflow_execs:
+            if (workflow_execs is not None) and (workflow_execs != ""):
+                childNode = ElementTree.SubElement(node, 'workflowExec')
+                self.getDao('workflow_exec').toXML(workflow_exec, childNode)
+        machines = log.db_machines
+        for machine in machines:
+            if (machines is not None) and (machines != ""):
+                childNode = ElementTree.SubElement(node, 'machine')
+                self.getDao('machine').toXML(machine, childNode)
         
         return node
 
-class DBVtConnectionXMLDAOBase(XMLDAO):
+class DBOpmProcessIdCauseXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3402,19 +3106,43 @@ class DBVtConnectionXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'vt:connection':
+        if node_tag != 'cause':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'str')
         
-        vt_source = None
-        vt_dest = None
-        vt_source_port = None
-        vt_dest_port = None
-        vt_source_signature = None
-        vt_dest_signature = None
+        obj = DBOpmProcessIdCause(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process_id_cause, node=None):
+        if node is None:
+            node = ElementTree.Element('cause')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_process_id_cause.db_id, 'str'))
+        
+        return node
+
+class DBOpmArtifactsXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'artifacts':
+            return None
+        
+        artifacts = []
         
         # read children
         for child in node.getchildren():
@@ -3422,75 +3150,32 @@ class DBVtConnectionXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'vt:source':
-                _data = self.convertFromStr(child.text,'str')
-                vt_source = _data
-            elif child_tag == 'vt:dest':
-                _data = self.convertFromStr(child.text,'str')
-                vt_dest = _data
-            elif child_tag == 'vt:source_port':
-                _data = self.convertFromStr(child.text,'str')
-                vt_source_port = _data
-            elif child_tag == 'vt:dest_port':
-                _data = self.convertFromStr(child.text,'str')
-                vt_dest_port = _data
-            elif child_tag == 'vt:source_signature':
-                _data = self.convertFromStr(child.text,'str')
-                vt_source_signature = _data
-            elif child_tag == 'vt:dest_signature':
-                _data = self.convertFromStr(child.text,'str')
-                vt_dest_signature = _data
+            if child_tag == 'artifact':
+                _data = self.getDao('opm_artifact').fromXML(child)
+                artifacts.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBVtConnection(id=id,
-                             vt_source=vt_source,
-                             vt_dest=vt_dest,
-                             vt_source_port=vt_source_port,
-                             vt_dest_port=vt_dest_port,
-                             vt_source_signature=vt_source_signature,
-                             vt_dest_signature=vt_dest_signature)
+        obj = DBOpmArtifacts(artifacts=artifacts)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, vt_connection, node=None):
+    def toXML(self, opm_artifacts, node=None):
         if node is None:
-            node = ElementTree.Element('vt:connection')
-        
-        # set attributes
-        node.set('id',self.convertToStr(vt_connection.db_id, 'str'))
+            node = ElementTree.Element('artifacts')
         
         # set elements
-        vt_source = vt_connection.db_vt_source
-        if (vt_source is not None) and (vt_source != ""):
-            childNode = ElementTree.SubElement(node, 'vt:source')
-            childNode.text = self.convertToStr(vt_source, 'str')
-        vt_dest = vt_connection.db_vt_dest
-        if (vt_dest is not None) and (vt_dest != ""):
-            childNode = ElementTree.SubElement(node, 'vt:dest')
-            childNode.text = self.convertToStr(vt_dest, 'str')
-        vt_source_port = vt_connection.db_vt_source_port
-        if (vt_source_port is not None) and (vt_source_port != ""):
-            childNode = ElementTree.SubElement(node, 'vt:source_port')
-            childNode.text = self.convertToStr(vt_source_port, 'str')
-        vt_dest_port = vt_connection.db_vt_dest_port
-        if (vt_dest_port is not None) and (vt_dest_port != ""):
-            childNode = ElementTree.SubElement(node, 'vt:dest_port')
-            childNode.text = self.convertToStr(vt_dest_port, 'str')
-        vt_source_signature = vt_connection.db_vt_source_signature
-        if (vt_source_signature is not None) and (vt_source_signature != ""):
-            childNode = ElementTree.SubElement(node, 'vt:source_signature')
-            childNode.text = self.convertToStr(vt_source_signature, 'str')
-        vt_dest_signature = vt_connection.db_vt_dest_signature
-        if (vt_dest_signature is not None) and (vt_dest_signature != ""):
-            childNode = ElementTree.SubElement(node, 'vt:dest_signature')
-            childNode.text = self.convertToStr(vt_dest_signature, 'str')
+        artifacts = opm_artifacts.db_artifacts
+        for artifact in artifacts:
+            if (artifacts is not None) and (artifacts != ""):
+                childNode = ElementTree.SubElement(node, 'artifact')
+                self.getDao('opm_artifact').toXML(artifact, childNode)
         
         return node
 
-class DBMashupComponentXMLDAOBase(XMLDAO):
+class DBPEParameterXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3503,91 +3188,43 @@ class DBMashupComponentXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'component':
+        if node_tag != 'peParameter':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('vtid', None)
-        vtid = self.convertFromStr(data, 'long')
-        data = node.get('vttype', None)
-        vttype = self.convertFromStr(data, 'str')
-        data = node.get('vtparent_type', None)
-        vtparent_type = self.convertFromStr(data, 'str')
-        data = node.get('vtparent_id', None)
-        vtparent_id = self.convertFromStr(data, 'long')
-        data = node.get('vtpos', None)
-        vtpos = self.convertFromStr(data, 'long')
-        data = node.get('vtmid', None)
-        vtmid = self.convertFromStr(data, 'long')
         data = node.get('pos', None)
         pos = self.convertFromStr(data, 'long')
-        data = node.get('type', None)
-        type = self.convertFromStr(data, 'str')
-        data = node.get('val', None)
-        val = self.convertFromStr(data, 'str')
-        data = node.get('minVal', None)
-        minVal = self.convertFromStr(data, 'str')
-        data = node.get('maxVal', None)
-        maxVal = self.convertFromStr(data, 'str')
-        data = node.get('stepSize', None)
-        stepSize = self.convertFromStr(data, 'str')
-        data = node.get('valueList', None)
-        strvaluelist = self.convertFromStr(data, 'str')
-        data = node.get('widget', None)
-        widget = self.convertFromStr(data, 'str')
-        data = node.get('seq', None)
-        seq = self.convertFromStr(data, 'int')
-        data = node.get('parent', None)
-        parent = self.convertFromStr(data, 'str')
+        data = node.get('interpolator', None)
+        interpolator = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        data = node.get('dimension', None)
+        dimension = self.convertFromStr(data, 'long')
         
-        obj = DBMashupComponent(id=id,
-                                vtid=vtid,
-                                vttype=vttype,
-                                vtparent_type=vtparent_type,
-                                vtparent_id=vtparent_id,
-                                vtpos=vtpos,
-                                vtmid=vtmid,
-                                pos=pos,
-                                type=type,
-                                val=val,
-                                minVal=minVal,
-                                maxVal=maxVal,
-                                stepSize=stepSize,
-                                strvaluelist=strvaluelist,
-                                widget=widget,
-                                seq=seq,
-                                parent=parent)
+        obj = DBPEParameter(id=id,
+                            pos=pos,
+                            interpolator=interpolator,
+                            value=value,
+                            dimension=dimension)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, mashup_component, node=None):
+    def toXML(self, pe_parameter, node=None):
         if node is None:
-            node = ElementTree.Element('component')
+            node = ElementTree.Element('peParameter')
         
         # set attributes
-        node.set('id',self.convertToStr(mashup_component.db_id, 'long'))
-        node.set('vtid',self.convertToStr(mashup_component.db_vtid, 'long'))
-        node.set('vttype',self.convertToStr(mashup_component.db_vttype, 'str'))
-        node.set('vtparent_type',self.convertToStr(mashup_component.db_vtparent_type, 'str'))
-        node.set('vtparent_id',self.convertToStr(mashup_component.db_vtparent_id, 'long'))
-        node.set('vtpos',self.convertToStr(mashup_component.db_vtpos, 'long'))
-        node.set('vtmid',self.convertToStr(mashup_component.db_vtmid, 'long'))
-        node.set('pos',self.convertToStr(mashup_component.db_pos, 'long'))
-        node.set('type',self.convertToStr(mashup_component.db_type, 'str'))
-        node.set('val',self.convertToStr(mashup_component.db_val, 'str'))
-        node.set('minVal',self.convertToStr(mashup_component.db_minVal, 'str'))
-        node.set('maxVal',self.convertToStr(mashup_component.db_maxVal, 'str'))
-        node.set('stepSize',self.convertToStr(mashup_component.db_stepSize, 'str'))
-        node.set('valueList',self.convertToStr(mashup_component.db_strvaluelist, 'str'))
-        node.set('widget',self.convertToStr(mashup_component.db_widget, 'str'))
-        node.set('seq',self.convertToStr(mashup_component.db_seq, 'int'))
-        node.set('parent',self.convertToStr(mashup_component.db_parent, 'str'))
+        node.set('id',self.convertToStr(pe_parameter.db_id, 'long'))
+        node.set('pos',self.convertToStr(pe_parameter.db_pos, 'long'))
+        node.set('interpolator',self.convertToStr(pe_parameter.db_interpolator, 'str'))
+        node.set('value',self.convertToStr(pe_parameter.db_value, 'str'))
+        node.set('dimension',self.convertToStr(pe_parameter.db_dimension, 'long'))
         
         return node
 
-class DBProvEntityXMLDAOBase(XMLDAO):
+class DBWorkflowExecXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3600,25 +3237,37 @@ class DBProvEntityXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:entity':
+        if node_tag != 'workflowExec':
             return None
         
         # read attributes
-        data = node.get('prov:id', None)
-        id = self.convertFromStr(data, 'str')
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        data = node.get('ip', None)
+        ip = self.convertFromStr(data, 'str')
+        data = node.get('session', None)
+        session = self.convertFromStr(data, 'long')
+        data = node.get('vtVersion', None)
+        vt_version = self.convertFromStr(data, 'str')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('parentId', None)
+        parent_id = self.convertFromStr(data, 'long')
+        data = node.get('parentType', None)
+        parent_type = self.convertFromStr(data, 'str')
+        data = node.get('parentVersion', None)
+        parent_version = self.convertFromStr(data, 'long')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
         
-        prov_type = None
-        prov_label = None
-        prov_value = None
-        vt_id = None
-        vt_type = None
-        vt_desc = None
-        vt_package = None
-        vt_version = None
-        vt_cache = None
-        vt_location_x = None
-        vt_location_y = None
-        is_part_of = None
+        annotations = []
+        item_execs = []
         
         # read children
         for child in node.getchildren():
@@ -3626,124 +3275,79 @@ class DBProvEntityXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'prov:type':
-                _data = self.convertFromStr(child.text,'str')
-                prov_type = _data
-            elif child_tag == 'prov:label':
-                _data = self.convertFromStr(child.text,'str')
-                prov_label = _data
-            elif child_tag == 'prov:value':
-                _data = self.convertFromStr(child.text,'str')
-                prov_value = _data
-            elif child_tag == 'vt:id':
-                _data = self.convertFromStr(child.text,'str')
-                vt_id = _data
-            elif child_tag == 'vt:type':
-                _data = self.convertFromStr(child.text,'str')
-                vt_type = _data
-            elif child_tag == 'vt:desc':
-                _data = self.convertFromStr(child.text,'str')
-                vt_desc = _data
-            elif child_tag == 'vt:package':
-                _data = self.convertFromStr(child.text,'str')
-                vt_package = _data
-            elif child_tag == 'vt:version':
-                _data = self.convertFromStr(child.text,'str')
-                vt_version = _data
-            elif child_tag == 'vt:cache':
-                _data = self.convertFromStr(child.text,'str')
-                vt_cache = _data
-            elif child_tag == 'vt:location_x':
-                _data = self.convertFromStr(child.text,'str')
-                vt_location_x = _data
-            elif child_tag == 'vt:location_y':
-                _data = self.convertFromStr(child.text,'str')
-                vt_location_y = _data
-            elif child_tag == 'dcterms:isPartOf':
-                _data = self.getDao('is_part_of').fromXML(child)
-                is_part_of = _data
+            if child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                item_execs.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBProvEntity(id=id,
-                           prov_type=prov_type,
-                           prov_label=prov_label,
-                           prov_value=prov_value,
-                           vt_id=vt_id,
-                           vt_type=vt_type,
-                           vt_desc=vt_desc,
-                           vt_package=vt_package,
-                           vt_version=vt_version,
-                           vt_cache=vt_cache,
-                           vt_location_x=vt_location_x,
-                           vt_location_y=vt_location_y,
-                           is_part_of=is_part_of)
+        obj = DBWorkflowExec(item_execs=item_execs,
+                             id=id,
+                             user=user,
+                             ip=ip,
+                             session=session,
+                             vt_version=vt_version,
+                             ts_start=ts_start,
+                             ts_end=ts_end,
+                             parent_id=parent_id,
+                             parent_type=parent_type,
+                             parent_version=parent_version,
+                             completed=completed,
+                             name=name,
+                             annotations=annotations)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, prov_entity, node=None):
+    def toXML(self, workflow_exec, node=None):
         if node is None:
-            node = ElementTree.Element('prov:entity')
+            node = ElementTree.Element('workflowExec')
         
         # set attributes
-        node.set('prov:id',self.convertToStr(prov_entity.db_id, 'str'))
+        node.set('id',self.convertToStr(workflow_exec.db_id, 'long'))
+        node.set('user',self.convertToStr(workflow_exec.db_user, 'str'))
+        node.set('ip',self.convertToStr(workflow_exec.db_ip, 'str'))
+        node.set('session',self.convertToStr(workflow_exec.db_session, 'long'))
+        node.set('vtVersion',self.convertToStr(workflow_exec.db_vt_version, 'str'))
+        node.set('tsStart',self.convertToStr(workflow_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(workflow_exec.db_ts_end, 'datetime'))
+        node.set('parentId',self.convertToStr(workflow_exec.db_parent_id, 'long'))
+        node.set('parentType',self.convertToStr(workflow_exec.db_parent_type, 'str'))
+        node.set('parentVersion',self.convertToStr(workflow_exec.db_parent_version, 'long'))
+        node.set('completed',self.convertToStr(workflow_exec.db_completed, 'int'))
+        node.set('name',self.convertToStr(workflow_exec.db_name, 'str'))
         
         # set elements
-        prov_type = prov_entity.db_prov_type
-        if (prov_type is not None) and (prov_type != ""):
-            childNode = ElementTree.SubElement(node, 'prov:type')
-            childNode.text = self.convertToStr(prov_type, 'str')
-        prov_label = prov_entity.db_prov_label
-        if (prov_label is not None) and (prov_label != ""):
-            childNode = ElementTree.SubElement(node, 'prov:label')
-            childNode.text = self.convertToStr(prov_label, 'str')
-        prov_value = prov_entity.db_prov_value
-        if (prov_value is not None) and (prov_value != ""):
-            childNode = ElementTree.SubElement(node, 'prov:value')
-            childNode.text = self.convertToStr(prov_value, 'str')
-        vt_id = prov_entity.db_vt_id
-        if (vt_id is not None) and (vt_id != ""):
-            childNode = ElementTree.SubElement(node, 'vt:id')
-            childNode.text = self.convertToStr(vt_id, 'str')
-        vt_type = prov_entity.db_vt_type
-        if (vt_type is not None) and (vt_type != ""):
-            childNode = ElementTree.SubElement(node, 'vt:type')
-            childNode.text = self.convertToStr(vt_type, 'str')
-        vt_desc = prov_entity.db_vt_desc
-        if (vt_desc is not None) and (vt_desc != ""):
-            childNode = ElementTree.SubElement(node, 'vt:desc')
-            childNode.text = self.convertToStr(vt_desc, 'str')
-        vt_package = prov_entity.db_vt_package
-        if (vt_package is not None) and (vt_package != ""):
-            childNode = ElementTree.SubElement(node, 'vt:package')
-            childNode.text = self.convertToStr(vt_package, 'str')
-        vt_version = prov_entity.db_vt_version
-        if (vt_version is not None) and (vt_version != ""):
-            childNode = ElementTree.SubElement(node, 'vt:version')
-            childNode.text = self.convertToStr(vt_version, 'str')
-        vt_cache = prov_entity.db_vt_cache
-        if (vt_cache is not None) and (vt_cache != ""):
-            childNode = ElementTree.SubElement(node, 'vt:cache')
-            childNode.text = self.convertToStr(vt_cache, 'str')
-        vt_location_x = prov_entity.db_vt_location_x
-        if (vt_location_x is not None) and (vt_location_x != ""):
-            childNode = ElementTree.SubElement(node, 'vt:location_x')
-            childNode.text = self.convertToStr(vt_location_x, 'str')
-        vt_location_y = prov_entity.db_vt_location_y
-        if (vt_location_y is not None) and (vt_location_y != ""):
-            childNode = ElementTree.SubElement(node, 'vt:location_y')
-            childNode.text = self.convertToStr(vt_location_y, 'str')
-        is_part_of = prov_entity.db_is_part_of
-        if is_part_of is not None:
-            if (is_part_of is not None) and (is_part_of != ""):
-                childNode = ElementTree.SubElement(node, 'dcterms:isPartOf')
-                self.getDao('is_part_of').toXML(is_part_of, childNode)
+        annotations = workflow_exec.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        item_execs = workflow_exec.db_item_execs
+        for item_exec in item_execs:
+            if item_exec.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(item_exec, childNode)
         
         return node
 
-class DBAnnotationXMLDAOBase(XMLDAO):
+class DBLocationXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3756,35 +3360,35 @@ class DBAnnotationXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'annotation':
+        if node_tag != 'location':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('key', None)
-        key = self.convertFromStr(data, 'str')
-        data = node.get('value', None)
-        value = self.convertFromStr(data, 'str')
+        data = node.get('x', None)
+        x = self.convertFromStr(data, 'float')
+        data = node.get('y', None)
+        y = self.convertFromStr(data, 'float')
         
-        obj = DBAnnotation(id=id,
-                           key=key,
-                           value=value)
+        obj = DBLocation(id=id,
+                         x=x,
+                         y=y)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, annotation, node=None):
+    def toXML(self, location, node=None):
         if node is None:
-            node = ElementTree.Element('annotation')
+            node = ElementTree.Element('location')
         
         # set attributes
-        node.set('id',self.convertToStr(annotation.db_id, 'long'))
-        node.set('key',self.convertToStr(annotation.db_key, 'str'))
-        node.set('value',self.convertToStr(annotation.db_value, 'str'))
+        node.set('id',self.convertToStr(location.db_id, 'long'))
+        node.set('x',self.convertToStr(location.db_x, 'float'))
+        node.set('y',self.convertToStr(location.db_y, 'float'))
         
         return node
 
-class DBChangeXMLDAOBase(XMLDAO):
+class DBFunctionXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3797,24 +3401,18 @@ class DBChangeXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'change':
+        if node_tag != 'function':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('what', None)
-        what = self.convertFromStr(data, 'str')
-        data = node.get('oldObjId', None)
-        oldObjId = self.convertFromStr(data, 'long')
-        data = node.get('newObjId', None)
-        newObjId = self.convertFromStr(data, 'long')
-        data = node.get('parentObjId', None)
-        parentObjId = self.convertFromStr(data, 'long')
-        data = node.get('parentObjType', None)
-        parentObjType = self.convertFromStr(data, 'str')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
         
-        data = None
+        parameters = []
         
         # read children
         for child in node.getchildren():
@@ -3822,112 +3420,40 @@ class DBChangeXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'module':
-                _data = self.getDao('module').fromXML(child)
-                data = _data
-            elif child_tag == 'location':
-                _data = self.getDao('location').fromXML(child)
-                data = _data
-            elif child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                data = _data
-            elif child_tag == 'function':
-                _data = self.getDao('function').fromXML(child)
-                data = _data
-            elif child_tag == 'connection':
-                _data = self.getDao('connection').fromXML(child)
-                data = _data
-            elif child_tag == 'port':
-                _data = self.getDao('port').fromXML(child)
-                data = _data
-            elif child_tag == 'parameter':
+            if child_tag == 'parameter':
                 _data = self.getDao('parameter').fromXML(child)
-                data = _data
-            elif child_tag == 'portSpec':
-                _data = self.getDao('portSpec').fromXML(child)
-                data = _data
-            elif child_tag == 'abstraction':
-                _data = self.getDao('abstraction').fromXML(child)
-                data = _data
-            elif child_tag == 'group':
-                _data = self.getDao('group').fromXML(child)
-                data = _data
-            elif child_tag == 'other':
-                _data = self.getDao('other').fromXML(child)
-                data = _data
-            elif child_tag == 'plugin_data':
-                _data = self.getDao('plugin_data').fromXML(child)
-                data = _data
+                parameters.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBChange(data=data,
-                       id=id,
-                       what=what,
-                       oldObjId=oldObjId,
-                       newObjId=newObjId,
-                       parentObjId=parentObjId,
-                       parentObjType=parentObjType)
+        obj = DBFunction(id=id,
+                         pos=pos,
+                         name=name,
+                         parameters=parameters)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, change, node=None):
+    def toXML(self, function, node=None):
         if node is None:
-            node = ElementTree.Element('change')
+            node = ElementTree.Element('function')
         
         # set attributes
-        node.set('id',self.convertToStr(change.db_id, 'long'))
-        node.set('what',self.convertToStr(change.db_what, 'str'))
-        node.set('oldObjId',self.convertToStr(change.db_oldObjId, 'long'))
-        node.set('newObjId',self.convertToStr(change.db_newObjId, 'long'))
-        node.set('parentObjId',self.convertToStr(change.db_parentObjId, 'long'))
-        node.set('parentObjType',self.convertToStr(change.db_parentObjType, 'str'))
+        node.set('id',self.convertToStr(function.db_id, 'long'))
+        node.set('pos',self.convertToStr(function.db_pos, 'long'))
+        node.set('name',self.convertToStr(function.db_name, 'str'))
         
         # set elements
-        data = change.db_data
-        if data is not None:
-            if data.vtType == 'module':
-                childNode = ElementTree.SubElement(node, 'module')
-                self.getDao('module').toXML(data, childNode)
-            elif data.vtType == 'location':
-                childNode = ElementTree.SubElement(node, 'location')
-                self.getDao('location').toXML(data, childNode)
-            elif data.vtType == 'annotation':
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(data, childNode)
-            elif data.vtType == 'function':
-                childNode = ElementTree.SubElement(node, 'function')
-                self.getDao('function').toXML(data, childNode)
-            elif data.vtType == 'connection':
-                childNode = ElementTree.SubElement(node, 'connection')
-                self.getDao('connection').toXML(data, childNode)
-            elif data.vtType == 'port':
-                childNode = ElementTree.SubElement(node, 'port')
-                self.getDao('port').toXML(data, childNode)
-            elif data.vtType == 'parameter':
+        parameters = function.db_parameters
+        for parameter in parameters:
+            if (parameters is not None) and (parameters != ""):
                 childNode = ElementTree.SubElement(node, 'parameter')
-                self.getDao('parameter').toXML(data, childNode)
-            elif data.vtType == 'portSpec':
-                childNode = ElementTree.SubElement(node, 'portSpec')
-                self.getDao('portSpec').toXML(data, childNode)
-            elif data.vtType == 'abstraction':
-                childNode = ElementTree.SubElement(node, 'abstraction')
-                self.getDao('abstraction').toXML(data, childNode)
-            elif data.vtType == 'group':
-                childNode = ElementTree.SubElement(node, 'group')
-                self.getDao('group').toXML(data, childNode)
-            elif data.vtType == 'other':
-                childNode = ElementTree.SubElement(node, 'other')
-                self.getDao('other').toXML(data, childNode)
-            elif data.vtType == 'plugin_data':
-                childNode = ElementTree.SubElement(node, 'plugin_data')
-                self.getDao('plugin_data').toXML(data, childNode)
+                self.getDao('parameter').toXML(parameter, childNode)
         
         return node
 
-class DBOpmWasDerivedFromXMLDAOBase(XMLDAO):
+class DBActionAnnotationXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -3940,83 +3466,47 @@ class DBOpmWasDerivedFromXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'wasDerivedFrom':
+        if node_tag != 'actionAnnotation':
             return None
         
-        effect = None
-        role = None
-        cause = None
-        accounts = []
-        opm_times = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'effect':
-                _data = self.getDao('opm_artifact_id_effect').fromXML(child)
-                effect = _data
-            elif child_tag == 'role':
-                _data = self.getDao('opm_role').fromXML(child)
-                role = _data
-            elif child_tag == 'cause':
-                _data = self.getDao('opm_artifact_id_cause').fromXML(child)
-                cause = _data
-            elif child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                accounts.append(_data)
-            elif child_tag == 'time':
-                _data = self.getDao('opm_time').fromXML(child)
-                opm_times.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        data = node.get('actionId', None)
+        action_id = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
         
-        obj = DBOpmWasDerivedFrom(effect=effect,
-                                  role=role,
-                                  cause=cause,
-                                  accounts=accounts,
-                                  opm_times=opm_times)
+        obj = DBActionAnnotation(id=id,
+                                 key=key,
+                                 value=value,
+                                 action_id=action_id,
+                                 date=date,
+                                 user=user)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_was_derived_from, node=None):
+    def toXML(self, actionAnnotation, node=None):
         if node is None:
-            node = ElementTree.Element('wasDerivedFrom')
+            node = ElementTree.Element('actionAnnotation')
         
-        # set elements
-        effect = opm_was_derived_from.db_effect
-        if effect is not None:
-            if (effect is not None) and (effect != ""):
-                childNode = ElementTree.SubElement(node, 'effect')
-                self.getDao('opm_artifact_id_effect').toXML(effect, childNode)
-        role = opm_was_derived_from.db_role
-        if role is not None:
-            if (role is not None) and (role != ""):
-                childNode = ElementTree.SubElement(node, 'role')
-                self.getDao('opm_role').toXML(role, childNode)
-        cause = opm_was_derived_from.db_cause
-        if cause is not None:
-            if (cause is not None) and (cause != ""):
-                childNode = ElementTree.SubElement(node, 'cause')
-                self.getDao('opm_artifact_id_cause').toXML(cause, childNode)
-        accounts = opm_was_derived_from.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(account, childNode)
-        opm_times = opm_was_derived_from.db_opm_times
-        for opm_time in opm_times:
-            if (opm_times is not None) and (opm_times != ""):
-                childNode = ElementTree.SubElement(node, 'time')
-                self.getDao('opm_time').toXML(opm_time, childNode)
+        # set attributes
+        node.set('id',self.convertToStr(actionAnnotation.db_id, 'long'))
+        node.set('key',self.convertToStr(actionAnnotation.db_key, 'str'))
+        node.set('value',self.convertToStr(actionAnnotation.db_value, 'str'))
+        node.set('actionId',self.convertToStr(actionAnnotation.db_action_id, 'long'))
+        node.set('date',self.convertToStr(actionAnnotation.db_date, 'datetime'))
+        node.set('user',self.convertToStr(actionAnnotation.db_user, 'str'))
         
         return node
 
-class DBOpmArtifactsXMLDAOBase(XMLDAO):
+class DBProvActivityXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4029,10 +3519,22 @@ class DBOpmArtifactsXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'artifacts':
+        if node_tag != 'prov:activity':
             return None
         
-        artifacts = []
+        # read attributes
+        data = node.get('prov:id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        startTime = None
+        endTime = None
+        vt_id = None
+        vt_type = None
+        vt_cached = None
+        vt_completed = None
+        vt_machine_id = None
+        vt_error = None
+        is_part_of = None
         
         # read children
         for child in node.getchildren():
@@ -4040,53 +3542,118 @@ class DBOpmArtifactsXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'artifact':
-                _data = self.getDao('opm_artifact').fromXML(child)
-                artifacts.append(_data)
+            if child_tag == 'prov:startTime':
+                _data = self.convertFromStr(child.text,'str')
+                startTime = _data
+            elif child_tag == 'prov:endTime':
+                _data = self.convertFromStr(child.text,'str')
+                endTime = _data
+            elif child_tag == 'vt:id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_id = _data
+            elif child_tag == 'vt:type':
+                _data = self.convertFromStr(child.text,'str')
+                vt_type = _data
+            elif child_tag == 'vt:cached':
+                _data = self.convertFromStr(child.text,'str')
+                vt_cached = _data
+            elif child_tag == 'vt:completed':
+                _data = self.convertFromStr(child.text,'str')
+                vt_completed = _data
+            elif child_tag == 'vt:machine_id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_id = _data
+            elif child_tag == 'vt:error':
+                _data = self.convertFromStr(child.text,'str')
+                vt_error = _data
+            elif child_tag == 'dcterms:isPartOf':
+                _data = self.getDao('is_part_of').fromXML(child)
+                is_part_of = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmArtifacts(artifacts=artifacts)
+        obj = DBProvActivity(id=id,
+                             startTime=startTime,
+                             endTime=endTime,
+                             vt_id=vt_id,
+                             vt_type=vt_type,
+                             vt_cached=vt_cached,
+                             vt_completed=vt_completed,
+                             vt_machine_id=vt_machine_id,
+                             vt_error=vt_error,
+                             is_part_of=is_part_of)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_artifacts, node=None):
+    def toXML(self, prov_activity, node=None):
         if node is None:
-            node = ElementTree.Element('artifacts')
-        
-        # set elements
-        artifacts = opm_artifacts.db_artifacts
-        for artifact in artifacts:
-            if (artifacts is not None) and (artifacts != ""):
-                childNode = ElementTree.SubElement(node, 'artifact')
-                self.getDao('opm_artifact').toXML(artifact, childNode)
-        
-        return node
-
-class DBOpmWasControlledByXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'wasControlledBy':
-            return None
+            node = ElementTree.Element('prov:activity')
         
-        effect = None
-        role = None
-        cause = None
-        accounts = []
-        starts = []
-        ends = []
+        # set attributes
+        node.set('prov:id',self.convertToStr(prov_activity.db_id, 'str'))
+        
+        # set elements
+        startTime = prov_activity.db_startTime
+        if (startTime is not None) and (startTime != ""):
+            childNode = ElementTree.SubElement(node, 'prov:startTime')
+            childNode.text = self.convertToStr(startTime, 'str')
+        endTime = prov_activity.db_endTime
+        if (endTime is not None) and (endTime != ""):
+            childNode = ElementTree.SubElement(node, 'prov:endTime')
+            childNode.text = self.convertToStr(endTime, 'str')
+        vt_id = prov_activity.db_vt_id
+        if (vt_id is not None) and (vt_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:id')
+            childNode.text = self.convertToStr(vt_id, 'str')
+        vt_type = prov_activity.db_vt_type
+        if (vt_type is not None) and (vt_type != ""):
+            childNode = ElementTree.SubElement(node, 'vt:type')
+            childNode.text = self.convertToStr(vt_type, 'str')
+        vt_cached = prov_activity.db_vt_cached
+        if (vt_cached is not None) and (vt_cached != ""):
+            childNode = ElementTree.SubElement(node, 'vt:cached')
+            childNode.text = self.convertToStr(vt_cached, 'str')
+        vt_completed = prov_activity.db_vt_completed
+        if (vt_completed is not None) and (vt_completed != ""):
+            childNode = ElementTree.SubElement(node, 'vt:completed')
+            childNode.text = self.convertToStr(vt_completed, 'str')
+        vt_machine_id = prov_activity.db_vt_machine_id
+        if (vt_machine_id is not None) and (vt_machine_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_id')
+            childNode.text = self.convertToStr(vt_machine_id, 'str')
+        vt_error = prov_activity.db_vt_error
+        if (vt_error is not None) and (vt_error != ""):
+            childNode = ElementTree.SubElement(node, 'vt:error')
+            childNode.text = self.convertToStr(vt_error, 'str')
+        is_part_of = prov_activity.db_is_part_of
+        if is_part_of is not None:
+            if (is_part_of is not None) and (is_part_of != ""):
+                childNode = ElementTree.SubElement(node, 'dcterms:isPartOf')
+                self.getDao('is_part_of').toXML(is_part_of, childNode)
+        
+        return node
+
+class DBProvUsageXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:used':
+            return None
+        
+        prov_activity = None
+        prov_entity = None
+        prov_role = None
         
         # read children
         for child in node.getchildren():
@@ -4094,77 +3661,49 @@ class DBOpmWasControlledByXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'effect':
-                _data = self.getDao('opm_process_id_effect').fromXML(child)
-                effect = _data
-            elif child_tag == 'role':
-                _data = self.getDao('opm_role').fromXML(child)
-                role = _data
-            elif child_tag == 'agent':
-                _data = self.getDao('opm_agent_id').fromXML(child)
-                cause = _data
-            elif child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                accounts.append(_data)
-            elif child_tag == 'time':
-                _data = self.getDao('opm_time').fromXML(child)
-                starts.append(_data)
-            elif child_tag == 'time':
-                _data = self.getDao('opm_time').fromXML(child)
-                ends.append(_data)
+            if child_tag == 'prov:activity':
+                _data = self.getDao('ref_prov_activity').fromXML(child)
+                prov_activity = _data
+            elif child_tag == 'prov:entity':
+                _data = self.getDao('ref_prov_entity').fromXML(child)
+                prov_entity = _data
+            elif child_tag == 'prov:role':
+                _data = self.convertFromStr(child.text,'str')
+                prov_role = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmWasControlledBy(effect=effect,
-                                   role=role,
-                                   cause=cause,
-                                   accounts=accounts,
-                                   starts=starts,
-                                   ends=ends)
+        obj = DBProvUsage(prov_activity=prov_activity,
+                          prov_entity=prov_entity,
+                          prov_role=prov_role)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_was_controlled_by, node=None):
+    def toXML(self, prov_usage, node=None):
         if node is None:
-            node = ElementTree.Element('wasControlledBy')
+            node = ElementTree.Element('prov:used')
         
         # set elements
-        effect = opm_was_controlled_by.db_effect
-        if effect is not None:
-            if (effect is not None) and (effect != ""):
-                childNode = ElementTree.SubElement(node, 'effect')
-                self.getDao('opm_process_id_effect').toXML(effect, childNode)
-        role = opm_was_controlled_by.db_role
-        if role is not None:
-            if (role is not None) and (role != ""):
-                childNode = ElementTree.SubElement(node, 'role')
-                self.getDao('opm_role').toXML(role, childNode)
-        cause = opm_was_controlled_by.db_cause
-        if cause is not None:
-            if (cause is not None) and (cause != ""):
-                childNode = ElementTree.SubElement(node, 'agent')
-                self.getDao('opm_agent_id').toXML(cause, childNode)
-        accounts = opm_was_controlled_by.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(account, childNode)
-        starts = opm_was_controlled_by.db_starts
-        for start in starts:
-            if (starts is not None) and (starts != ""):
-                childNode = ElementTree.SubElement(node, 'time')
-                self.getDao('opm_time').toXML(start, childNode)
-        ends = opm_was_controlled_by.db_ends
-        for end in ends:
-            if (ends is not None) and (ends != ""):
-                childNode = ElementTree.SubElement(node, 'time')
-                self.getDao('opm_time').toXML(end, childNode)
+        prov_activity = prov_usage.db_prov_activity
+        if prov_activity is not None:
+            if (prov_activity is not None) and (prov_activity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
+        prov_entity = prov_usage.db_prov_entity
+        if prov_entity is not None:
+            if (prov_entity is not None) and (prov_entity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:entity')
+                self.getDao('ref_prov_entity').toXML(prov_entity, childNode)
+        prov_role = prov_usage.db_prov_role
+        if (prov_role is not None) and (prov_role != ""):
+            childNode = ElementTree.SubElement(node, 'prov:role')
+            childNode.text = self.convertToStr(prov_role, 'str')
         
         return node
 
-class DBOpmAgentIdXMLDAOBase(XMLDAO):
+class DBOpmArtifactIdEffectXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4177,27 +3716,27 @@ class DBOpmAgentIdXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'agent':
+        if node_tag != 'effect':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'str')
         
-        obj = DBOpmAgentId(id=id)
+        obj = DBOpmArtifactIdEffect(id=id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_agent_id, node=None):
+    def toXML(self, opm_artifact_id_effect, node=None):
         if node is None:
-            node = ElementTree.Element('agent')
+            node = ElementTree.Element('effect')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_agent_id.db_id, 'str'))
+        node.set('id',self.convertToStr(opm_artifact_id_effect.db_id, 'str'))
         
         return node
 
-class DBGroupExecXMLDAOBase(XMLDAO):
+class DBOpmGraphXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4210,33 +3749,14 @@ class DBGroupExecXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'groupExec':
+        if node_tag != 'opmGraph':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('tsStart', None)
-        ts_start = self.convertFromStr(data, 'datetime')
-        data = node.get('tsEnd', None)
-        ts_end = self.convertFromStr(data, 'datetime')
-        data = node.get('cached', None)
-        cached = self.convertFromStr(data, 'int')
-        data = node.get('moduleId', None)
-        module_id = self.convertFromStr(data, 'long')
-        data = node.get('groupName', None)
-        group_name = self.convertFromStr(data, 'str')
-        data = node.get('groupType', None)
-        group_type = self.convertFromStr(data, 'str')
-        data = node.get('completed', None)
-        completed = self.convertFromStr(data, 'int')
-        data = node.get('error', None)
-        error = self.convertFromStr(data, 'str')
-        data = node.get('machine_id', None)
-        machine_id = self.convertFromStr(data, 'long')
-        
-        annotations = []
-        item_execs = []
+        accounts = None
+        processes = None
+        artifacts = None
+        agents = None
+        dependencies = None
         
         # read children
         for child in node.getchildren():
@@ -4244,75 +3764,68 @@ class DBGroupExecXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child_tag == 'moduleExec':
-                _data = self.getDao('module_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child_tag == 'groupExec':
-                _data = self.getDao('group_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child_tag == 'loopExec':
-                _data = self.getDao('loop_exec').fromXML(child)
-                item_execs.append(_data)
+            if child_tag == 'accounts':
+                _data = self.getDao('opm_accounts').fromXML(child)
+                accounts = _data
+            elif child_tag == 'processes':
+                _data = self.getDao('opm_processes').fromXML(child)
+                processes = _data
+            elif child_tag == 'artifacts':
+                _data = self.getDao('opm_artifacts').fromXML(child)
+                artifacts = _data
+            elif child_tag == 'agents':
+                _data = self.getDao('opm_agents').fromXML(child)
+                agents = _data
+            elif child_tag == 'causalDependencies':
+                _data = self.getDao('opm_dependencies').fromXML(child)
+                dependencies = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBGroupExec(item_execs=item_execs,
-                          id=id,
-                          ts_start=ts_start,
-                          ts_end=ts_end,
-                          cached=cached,
-                          module_id=module_id,
-                          group_name=group_name,
-                          group_type=group_type,
-                          completed=completed,
-                          error=error,
-                          machine_id=machine_id,
-                          annotations=annotations)
+        obj = DBOpmGraph(accounts=accounts,
+                         processes=processes,
+                         artifacts=artifacts,
+                         agents=agents,
+                         dependencies=dependencies)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, group_exec, node=None):
+    def toXML(self, opm_graph, node=None):
         if node is None:
-            node = ElementTree.Element('groupExec')
-        
-        # set attributes
-        node.set('id',self.convertToStr(group_exec.db_id, 'long'))
-        node.set('tsStart',self.convertToStr(group_exec.db_ts_start, 'datetime'))
-        node.set('tsEnd',self.convertToStr(group_exec.db_ts_end, 'datetime'))
-        node.set('cached',self.convertToStr(group_exec.db_cached, 'int'))
-        node.set('moduleId',self.convertToStr(group_exec.db_module_id, 'long'))
-        node.set('groupName',self.convertToStr(group_exec.db_group_name, 'str'))
-        node.set('groupType',self.convertToStr(group_exec.db_group_type, 'str'))
-        node.set('completed',self.convertToStr(group_exec.db_completed, 'int'))
-        node.set('error',self.convertToStr(group_exec.db_error, 'str'))
-        node.set('machine_id',self.convertToStr(group_exec.db_machine_id, 'long'))
+            node = ElementTree.Element('opmGraph')
         
         # set elements
-        annotations = group_exec.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
-        item_execs = group_exec.db_item_execs
-        for item_exec in item_execs:
-            if item_exec.vtType == 'module_exec':
-                childNode = ElementTree.SubElement(node, 'moduleExec')
-                self.getDao('module_exec').toXML(item_exec, childNode)
-            elif item_exec.vtType == 'group_exec':
-                childNode = ElementTree.SubElement(node, 'groupExec')
-                self.getDao('group_exec').toXML(item_exec, childNode)
-            elif item_exec.vtType == 'loop_exec':
-                childNode = ElementTree.SubElement(node, 'loopExec')
-                self.getDao('loop_exec').toXML(item_exec, childNode)
+        accounts = opm_graph.db_accounts
+        if accounts is not None:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'accounts')
+                self.getDao('opm_accounts').toXML(accounts, childNode)
+        processes = opm_graph.db_processes
+        if processes is not None:
+            if (processes is not None) and (processes != ""):
+                childNode = ElementTree.SubElement(node, 'processes')
+                self.getDao('opm_processes').toXML(processes, childNode)
+        artifacts = opm_graph.db_artifacts
+        if artifacts is not None:
+            if (artifacts is not None) and (artifacts != ""):
+                childNode = ElementTree.SubElement(node, 'artifacts')
+                self.getDao('opm_artifacts').toXML(artifacts, childNode)
+        agents = opm_graph.db_agents
+        if agents is not None:
+            if (agents is not None) and (agents != ""):
+                childNode = ElementTree.SubElement(node, 'agents')
+                self.getDao('opm_agents').toXML(agents, childNode)
+        dependencies = opm_graph.db_dependencies
+        if dependencies is not None:
+            if (dependencies is not None) and (dependencies != ""):
+                childNode = ElementTree.SubElement(node, 'causalDependencies')
+                self.getDao('opm_dependencies').toXML(dependencies, childNode)
         
         return node
 
-class DBOpmTimeXMLDAOBase(XMLDAO):
+class DBIsPartOfXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4325,35 +3838,27 @@ class DBOpmTimeXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'time':
+        if node_tag != 'dcterms:isPartOf':
             return None
         
         # read attributes
-        data = node.get('noLaterThan', None)
-        no_later_than = self.convertFromStr(data, 'datetime')
-        data = node.get('noEarlierThan', None)
-        no_earlier_than = self.convertFromStr(data, 'datetime')
-        data = node.get('clockId', None)
-        clock_id = self.convertFromStr(data, 'str')
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
         
-        obj = DBOpmTime(no_later_than=no_later_than,
-                        no_earlier_than=no_earlier_than,
-                        clock_id=clock_id)
+        obj = DBIsPartOf(prov_ref=prov_ref)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_time, node=None):
+    def toXML(self, is_part_of, node=None):
         if node is None:
-            node = ElementTree.Element('time')
+            node = ElementTree.Element('dcterms:isPartOf')
         
         # set attributes
-        node.set('noLaterThan',self.convertToStr(opm_time.db_no_later_than, 'datetime'))
-        node.set('noEarlierThan',self.convertToStr(opm_time.db_no_earlier_than, 'datetime'))
-        node.set('clockId',self.convertToStr(opm_time.db_clock_id, 'str'))
+        node.set('prov:ref',self.convertToStr(is_part_of.db_prov_ref, 'str'))
         
         return node
 
-class DBPackageXMLDAOBase(XMLDAO):
+class DBOpmWasDerivedFromXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4366,26 +3871,14 @@ class DBPackageXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'package':
+        if node_tag != 'wasDerivedFrom':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('identifier', None)
-        identifier = self.convertFromStr(data, 'str')
-        data = node.get('codepath', None)
-        codepath = self.convertFromStr(data, 'str')
-        data = node.get('loadConfiguration', None)
-        load_configuration = self.convertFromStr(data, 'int')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
-        data = node.get('description', None)
-        description = self.convertFromStr(data, 'str')
-        
-        module_descriptors = []
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        opm_times = []
         
         # read children
         for child in node.getchildren():
@@ -4393,48 +3886,68 @@ class DBPackageXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'moduleDescriptor':
-                _data = self.getDao('module_descriptor').fromXML(child)
-                module_descriptors.append(_data)
+            if child_tag == 'effect':
+                _data = self.getDao('opm_artifact_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'cause':
+                _data = self.getDao('opm_artifact_id_cause').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                opm_times.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBPackage(id=id,
-                        name=name,
-                        identifier=identifier,
-                        codepath=codepath,
-                        load_configuration=load_configuration,
-                        version=version,
-                        description=description,
-                        module_descriptors=module_descriptors)
+        obj = DBOpmWasDerivedFrom(effect=effect,
+                                  role=role,
+                                  cause=cause,
+                                  accounts=accounts,
+                                  opm_times=opm_times)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, package, node=None):
+    def toXML(self, opm_was_derived_from, node=None):
         if node is None:
-            node = ElementTree.Element('package')
-        
-        # set attributes
-        node.set('id',self.convertToStr(package.db_id, 'long'))
-        node.set('name',self.convertToStr(package.db_name, 'str'))
-        node.set('identifier',self.convertToStr(package.db_identifier, 'str'))
-        node.set('codepath',self.convertToStr(package.db_codepath, 'str'))
-        node.set('loadConfiguration',self.convertToStr(package.db_load_configuration, 'int'))
-        node.set('version',self.convertToStr(package.db_version, 'str'))
-        node.set('description',self.convertToStr(package.db_description, 'str'))
+            node = ElementTree.Element('wasDerivedFrom')
         
         # set elements
-        module_descriptors = package.db_module_descriptors
-        for module_descriptor in module_descriptors:
-            if (module_descriptors is not None) and (module_descriptors != ""):
-                childNode = ElementTree.SubElement(node, 'moduleDescriptor')
-                self.getDao('module_descriptor').toXML(module_descriptor, childNode)
+        effect = opm_was_derived_from.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_artifact_id_effect').toXML(effect, childNode)
+        role = opm_was_derived_from.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_was_derived_from.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'cause')
+                self.getDao('opm_artifact_id_cause').toXML(cause, childNode)
+        accounts = opm_was_derived_from.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        opm_times = opm_was_derived_from.db_opm_times
+        for opm_time in opm_times:
+            if (opm_times is not None) and (opm_times != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(opm_time, childNode)
         
         return node
 
-class DBWorkflowExecXMLDAOBase(XMLDAO):
+class DBPluginDataXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4447,117 +3960,31 @@ class DBWorkflowExecXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'workflowExec':
+        if node_tag != 'plugin_data':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('user', None)
-        user = self.convertFromStr(data, 'str')
-        data = node.get('ip', None)
-        ip = self.convertFromStr(data, 'str')
-        data = node.get('session', None)
-        session = self.convertFromStr(data, 'long')
-        data = node.get('vtVersion', None)
-        vt_version = self.convertFromStr(data, 'str')
-        data = node.get('tsStart', None)
-        ts_start = self.convertFromStr(data, 'datetime')
-        data = node.get('tsEnd', None)
-        ts_end = self.convertFromStr(data, 'datetime')
-        data = node.get('parentId', None)
-        parent_id = self.convertFromStr(data, 'long')
-        data = node.get('parentType', None)
-        parent_type = self.convertFromStr(data, 'str')
-        data = node.get('parentVersion', None)
-        parent_version = self.convertFromStr(data, 'long')
-        data = node.get('completed', None)
-        completed = self.convertFromStr(data, 'int')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        
-        annotations = []
-        item_execs = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child_tag == 'moduleExec':
-                _data = self.getDao('module_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child_tag == 'groupExec':
-                _data = self.getDao('group_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child_tag == 'loopExec':
-                _data = self.getDao('loop_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        data = node.get('data', None)
+        data = self.convertFromStr(data, 'str')
         
-        obj = DBWorkflowExec(item_execs=item_execs,
-                             id=id,
-                             user=user,
-                             ip=ip,
-                             session=session,
-                             vt_version=vt_version,
-                             ts_start=ts_start,
-                             ts_end=ts_end,
-                             parent_id=parent_id,
-                             parent_type=parent_type,
-                             parent_version=parent_version,
-                             completed=completed,
-                             name=name,
-                             annotations=annotations)
+        obj = DBPluginData(id=id,
+                           data=data)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, workflow_exec, node=None):
+    def toXML(self, plugin_data, node=None):
         if node is None:
-            node = ElementTree.Element('workflowExec')
+            node = ElementTree.Element('plugin_data')
         
         # set attributes
-        node.set('id',self.convertToStr(workflow_exec.db_id, 'long'))
-        node.set('user',self.convertToStr(workflow_exec.db_user, 'str'))
-        node.set('ip',self.convertToStr(workflow_exec.db_ip, 'str'))
-        node.set('session',self.convertToStr(workflow_exec.db_session, 'long'))
-        node.set('vtVersion',self.convertToStr(workflow_exec.db_vt_version, 'str'))
-        node.set('tsStart',self.convertToStr(workflow_exec.db_ts_start, 'datetime'))
-        node.set('tsEnd',self.convertToStr(workflow_exec.db_ts_end, 'datetime'))
-        node.set('parentId',self.convertToStr(workflow_exec.db_parent_id, 'long'))
-        node.set('parentType',self.convertToStr(workflow_exec.db_parent_type, 'str'))
-        node.set('parentVersion',self.convertToStr(workflow_exec.db_parent_version, 'long'))
-        node.set('completed',self.convertToStr(workflow_exec.db_completed, 'int'))
-        node.set('name',self.convertToStr(workflow_exec.db_name, 'str'))
-        
-        # set elements
-        annotations = workflow_exec.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
-        item_execs = workflow_exec.db_item_execs
-        for item_exec in item_execs:
-            if item_exec.vtType == 'module_exec':
-                childNode = ElementTree.SubElement(node, 'moduleExec')
-                self.getDao('module_exec').toXML(item_exec, childNode)
-            elif item_exec.vtType == 'group_exec':
-                childNode = ElementTree.SubElement(node, 'groupExec')
-                self.getDao('group_exec').toXML(item_exec, childNode)
-            elif item_exec.vtType == 'loop_exec':
-                childNode = ElementTree.SubElement(node, 'loopExec')
-                self.getDao('loop_exec').toXML(item_exec, childNode)
+        node.set('id',self.convertToStr(plugin_data.db_id, 'long'))
+        node.set('data',self.convertToStr(plugin_data.db_data, 'str'))
         
         return node
 
-class DBParameterExplorationXMLDAOBase(XMLDAO):
+class DBDeleteXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4570,75 +3997,43 @@ class DBParameterExplorationXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'parameterExploration':
+        if node_tag != 'delete':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('actionId', None)
-        action_id = self.convertFromStr(data, 'long')
-        data = node.get('name', None)
-        name = self.convertFromStr(data, 'str')
-        data = node.get('date', None)
-        date = self.convertFromStr(data, 'datetime')
-        data = node.get('user', None)
-        user = self.convertFromStr(data, 'str')
-        data = node.get('dims', None)
-        dims = self.convertFromStr(data, 'str')
-        data = node.get('layout', None)
-        layout = self.convertFromStr(data, 'str')
-        
-        functions = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'peFunction':
-                _data = self.getDao('pe_function').fromXML(child)
-                functions.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        data = node.get('what', None)
+        what = self.convertFromStr(data, 'str')
+        data = node.get('objectId', None)
+        objectId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjId', None)
+        parentObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjType', None)
+        parentObjType = self.convertFromStr(data, 'str')
         
-        obj = DBParameterExploration(id=id,
-                                     action_id=action_id,
-                                     name=name,
-                                     date=date,
-                                     user=user,
-                                     dims=dims,
-                                     layout=layout,
-                                     functions=functions)
+        obj = DBDelete(id=id,
+                       what=what,
+                       objectId=objectId,
+                       parentObjId=parentObjId,
+                       parentObjType=parentObjType)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, parameter_exploration, node=None):
+    def toXML(self, delete, node=None):
         if node is None:
-            node = ElementTree.Element('parameterExploration')
+            node = ElementTree.Element('delete')
         
         # set attributes
-        node.set('id',self.convertToStr(parameter_exploration.db_id, 'long'))
-        node.set('actionId',self.convertToStr(parameter_exploration.db_action_id, 'long'))
-        node.set('name',self.convertToStr(parameter_exploration.db_name, 'str'))
-        node.set('date',self.convertToStr(parameter_exploration.db_date, 'datetime'))
-        node.set('user',self.convertToStr(parameter_exploration.db_user, 'str'))
-        node.set('dims',self.convertToStr(parameter_exploration.db_dims, 'str'))
-        node.set('layout',self.convertToStr(parameter_exploration.db_layout, 'str'))
-        
-        # set elements
-        functions = parameter_exploration.db_functions
-        for function in functions:
-            if (functions is not None) and (functions != ""):
-                childNode = ElementTree.SubElement(node, 'peFunction')
-                self.getDao('pe_function').toXML(function, childNode)
+        node.set('id',self.convertToStr(delete.db_id, 'long'))
+        node.set('what',self.convertToStr(delete.db_what, 'str'))
+        node.set('objectId',self.convertToStr(delete.db_objectId, 'long'))
+        node.set('parentObjId',self.convertToStr(delete.db_parentObjId, 'long'))
+        node.set('parentObjType',self.convertToStr(delete.db_parentObjType, 'str'))
         
         return node
 
-class DBLoopExecXMLDAOBase(XMLDAO):
+class DBVistrailVariableXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4651,24 +4046,63 @@ class DBLoopExecXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'loopExec':
+        if node_tag != 'vistrailVariable':
             return None
         
         # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('tsStart', None)
-        ts_start = self.convertFromStr(data, 'datetime')
-        data = node.get('tsEnd', None)
-        ts_end = self.convertFromStr(data, 'datetime')
-        data = node.get('iteration', None)
-        iteration = self.convertFromStr(data, 'int')
-        data = node.get('completed', None)
-        completed = self.convertFromStr(data, 'int')
-        data = node.get('error', None)
-        error = self.convertFromStr(data, 'str')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('uuid', None)
+        uuid = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('module', None)
+        module = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
         
-        item_execs = []
+        obj = DBVistrailVariable(name=name,
+                                 uuid=uuid,
+                                 package=package,
+                                 module=module,
+                                 namespace=namespace,
+                                 value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, vistrailVariable, node=None):
+        if node is None:
+            node = ElementTree.Element('vistrailVariable')
+        
+        # set attributes
+        node.set('name',self.convertToStr(vistrailVariable.db_name, 'str'))
+        node.set('uuid',self.convertToStr(vistrailVariable.db_uuid, 'str'))
+        node.set('package',self.convertToStr(vistrailVariable.db_package, 'str'))
+        node.set('module',self.convertToStr(vistrailVariable.db_module, 'str'))
+        node.set('namespace',self.convertToStr(vistrailVariable.db_namespace, 'str'))
+        node.set('value',self.convertToStr(vistrailVariable.db_value, 'str'))
+        
+        return node
+
+class DBOpmOverlapsXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'overlaps':
+            return None
+        
+        opm_account_ids = []
         
         # read children
         for child in node.getchildren():
@@ -4676,54 +4110,28 @@ class DBLoopExecXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'moduleExec':
-                _data = self.getDao('module_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child_tag == 'groupExec':
-                _data = self.getDao('group_exec').fromXML(child)
-                item_execs.append(_data)
-            elif child_tag == 'loopExec':
-                _data = self.getDao('loop_exec').fromXML(child)
-                item_execs.append(_data)
+            if child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                opm_account_ids.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBLoopExec(item_execs=item_execs,
-                         id=id,
-                         ts_start=ts_start,
-                         ts_end=ts_end,
-                         iteration=iteration,
-                         completed=completed,
-                         error=error)
+        obj = DBOpmOverlaps(opm_account_ids=opm_account_ids)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, loop_exec, node=None):
+    def toXML(self, opm_overlaps, node=None):
         if node is None:
-            node = ElementTree.Element('loopExec')
-        
-        # set attributes
-        node.set('id',self.convertToStr(loop_exec.db_id, 'long'))
-        node.set('tsStart',self.convertToStr(loop_exec.db_ts_start, 'datetime'))
-        node.set('tsEnd',self.convertToStr(loop_exec.db_ts_end, 'datetime'))
-        node.set('iteration',self.convertToStr(loop_exec.db_iteration, 'int'))
-        node.set('completed',self.convertToStr(loop_exec.db_completed, 'int'))
-        node.set('error',self.convertToStr(loop_exec.db_error, 'str'))
+            node = ElementTree.Element('overlaps')
         
         # set elements
-        item_execs = loop_exec.db_item_execs
-        for item_exec in item_execs:
-            if item_exec.vtType == 'module_exec':
-                childNode = ElementTree.SubElement(node, 'moduleExec')
-                self.getDao('module_exec').toXML(item_exec, childNode)
-            elif item_exec.vtType == 'group_exec':
-                childNode = ElementTree.SubElement(node, 'groupExec')
-                self.getDao('group_exec').toXML(item_exec, childNode)
-            elif item_exec.vtType == 'loop_exec':
-                childNode = ElementTree.SubElement(node, 'loopExec')
-                self.getDao('loop_exec').toXML(item_exec, childNode)
+        opm_account_ids = opm_overlaps.db_opm_account_ids
+        for opm_account_id in opm_account_ids:
+            if (opm_account_ids is not None) and (opm_account_ids != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(opm_account_id, childNode)
         
         return node
 
@@ -4816,7 +4224,7 @@ class DBOpmWasTriggeredByXMLDAOBase(XMLDAO):
         
         return node
 
-class DBMashupActionAnnotationXMLDAOBase(XMLDAO):
+class DBModuleDescriptorXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4829,67 +4237,26 @@ class DBMashupActionAnnotationXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'actionAnnotation':
+        if node_tag != 'moduleDescriptor':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('key', None)
-        key = self.convertFromStr(data, 'str')
-        data = node.get('value', None)
-        value = self.convertFromStr(data, 'str')
-        data = node.get('action_id', None)
-        action_id = self.convertFromStr(data, 'long')
-        data = node.get('date', None)
-        date = self.convertFromStr(data, 'datetime')
-        data = node.get('user', None)
-        user = self.convertFromStr(data, 'str')
-        
-        obj = DBMashupActionAnnotation(id=id,
-                                       key=key,
-                                       value=value,
-                                       action_id=action_id,
-                                       date=date,
-                                       user=user)
-        obj.is_dirty = False
-        return obj
-    
-    def toXML(self, mashup_actionAnnotation, node=None):
-        if node is None:
-            node = ElementTree.Element('actionAnnotation')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('packageVersion', None)
+        package_version = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('baseDescriptorId', None)
+        base_descriptor_id = self.convertFromStr(data, 'long')
         
-        # set attributes
-        node.set('id',self.convertToStr(mashup_actionAnnotation.db_id, 'long'))
-        node.set('key',self.convertToStr(mashup_actionAnnotation.db_key, 'str'))
-        node.set('value',self.convertToStr(mashup_actionAnnotation.db_value, 'str'))
-        node.set('action_id',self.convertToStr(mashup_actionAnnotation.db_action_id, 'long'))
-        node.set('date',self.convertToStr(mashup_actionAnnotation.db_date, 'datetime'))
-        node.set('user',self.convertToStr(mashup_actionAnnotation.db_user, 'str'))
-        
-        return node
-
-class DBConnectionXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
-    def fromXML(self, node):
-        if node.tag[0] == "{":
-            node_tag = node.tag.split("}")[1]
-        else:
-            node_tag = node.tag
-        if node_tag != 'connection':
-            return None
-        
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        
-        ports = []
+        portSpecs = []
         
         # read children
         for child in node.getchildren():
@@ -4897,36 +4264,48 @@ class DBConnectionXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'port':
-                _data = self.getDao('port').fromXML(child)
-                ports.append(_data)
+            if child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                portSpecs.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBConnection(id=id,
-                           ports=ports)
+        obj = DBModuleDescriptor(id=id,
+                                 name=name,
+                                 package=package,
+                                 namespace=namespace,
+                                 package_version=package_version,
+                                 version=version,
+                                 base_descriptor_id=base_descriptor_id,
+                                 portSpecs=portSpecs)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, connection, node=None):
+    def toXML(self, module_descriptor, node=None):
         if node is None:
-            node = ElementTree.Element('connection')
+            node = ElementTree.Element('moduleDescriptor')
         
         # set attributes
-        node.set('id',self.convertToStr(connection.db_id, 'long'))
+        node.set('id',self.convertToStr(module_descriptor.db_id, 'long'))
+        node.set('name',self.convertToStr(module_descriptor.db_name, 'str'))
+        node.set('package',self.convertToStr(module_descriptor.db_package, 'str'))
+        node.set('namespace',self.convertToStr(module_descriptor.db_namespace, 'str'))
+        node.set('packageVersion',self.convertToStr(module_descriptor.db_package_version, 'str'))
+        node.set('version',self.convertToStr(module_descriptor.db_version, 'str'))
+        node.set('baseDescriptorId',self.convertToStr(module_descriptor.db_base_descriptor_id, 'long'))
         
         # set elements
-        ports = connection.db_ports
-        for port in ports:
-            if (ports is not None) and (ports != ""):
-                childNode = ElementTree.SubElement(node, 'port')
-                self.getDao('port').toXML(port, childNode)
+        portSpecs = module_descriptor.db_portSpecs
+        for portSpec in portSpecs:
+            if (portSpecs is not None) and (portSpecs != ""):
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(portSpec, childNode)
         
         return node
 
-class DBOpmProcessXMLDAOBase(XMLDAO):
+class DBTagXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -4939,61 +4318,31 @@ class DBOpmProcessXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'process':
+        if node_tag != 'tag':
             return None
         
         # read attributes
         data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
-        
-        value = None
-        accounts = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'value':
-                _data = self.getDao('opm_process_value').fromXML(child)
-                value = _data
-            elif child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                accounts.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
         
-        obj = DBOpmProcess(id=id,
-                           value=value,
-                           accounts=accounts)
+        obj = DBTag(id=id,
+                    name=name)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_process, node=None):
+    def toXML(self, tag, node=None):
         if node is None:
-            node = ElementTree.Element('process')
+            node = ElementTree.Element('tag')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_process.db_id, 'str'))
-        
-        # set elements
-        value = opm_process.db_value
-        if value is not None:
-            if (value is not None) and (value != ""):
-                childNode = ElementTree.SubElement(node, 'value')
-                self.getDao('opm_process_value').toXML(value, childNode)
-        accounts = opm_process.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(account, childNode)
+        node.set('id',self.convertToStr(tag.db_id, 'long'))
+        node.set('name',self.convertToStr(tag.db_name, 'str'))
         
         return node
 
-class DBIsPartOfXMLDAOBase(XMLDAO):
+class DBOpmRoleXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5006,27 +4355,27 @@ class DBIsPartOfXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'dcterms:isPartOf':
+        if node_tag != 'role':
             return None
         
         # read attributes
-        data = node.get('prov:ref', None)
-        prov_ref = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
         
-        obj = DBIsPartOf(prov_ref=prov_ref)
+        obj = DBOpmRole(value=value)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, is_part_of, node=None):
+    def toXML(self, opm_role, node=None):
         if node is None:
-            node = ElementTree.Element('dcterms:isPartOf')
+            node = ElementTree.Element('role')
         
         # set attributes
-        node.set('prov:ref',self.convertToStr(is_part_of.db_prov_ref, 'str'))
+        node.set('value',self.convertToStr(opm_role.db_value, 'str'))
         
         return node
 
-class DBPEFunctionXMLDAOBase(XMLDAO):
+class DBProvDocumentXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5039,20 +4388,16 @@ class DBPEFunctionXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'peFunction':
+        if node_tag != 'prov:document':
             return None
         
-        # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('moduleId', None)
-        module_id = self.convertFromStr(data, 'long')
-        data = node.get('port_name', None)
-        port_name = self.convertFromStr(data, 'str')
-        data = node.get('is_alias', None)
-        is_alias = self.convertFromStr(data, 'long')
-        
-        parameters = []
+        prov_entitys = []
+        prov_activitys = []
+        prov_agents = []
+        vt_connections = []
+        prov_usages = []
+        prov_generations = []
+        prov_associations = []
         
         # read children
         for child in node.getchildren():
@@ -5060,42 +4405,86 @@ class DBPEFunctionXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'peParameter':
-                _data = self.getDao('pe_parameter').fromXML(child)
-                parameters.append(_data)
+            if child_tag == 'prov:entity':
+                _data = self.getDao('prov_entity').fromXML(child)
+                prov_entitys.append(_data)
+            elif child_tag == 'prov:activity':
+                _data = self.getDao('prov_activity').fromXML(child)
+                prov_activitys.append(_data)
+            elif child_tag == 'prov:agent':
+                _data = self.getDao('prov_agent').fromXML(child)
+                prov_agents.append(_data)
+            elif child_tag == 'vt:connection':
+                _data = self.getDao('vt_connection').fromXML(child)
+                vt_connections.append(_data)
+            elif child_tag == 'prov:used':
+                _data = self.getDao('prov_usage').fromXML(child)
+                prov_usages.append(_data)
+            elif child_tag == 'prov:wasGeneratedBy':
+                _data = self.getDao('prov_generation').fromXML(child)
+                prov_generations.append(_data)
+            elif child_tag == 'prov:wasAssociatedWith':
+                _data = self.getDao('prov_association').fromXML(child)
+                prov_associations.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBPEFunction(id=id,
-                           module_id=module_id,
-                           port_name=port_name,
-                           is_alias=is_alias,
-                           parameters=parameters)
+        obj = DBProvDocument(prov_entitys=prov_entitys,
+                             prov_activitys=prov_activitys,
+                             prov_agents=prov_agents,
+                             vt_connections=vt_connections,
+                             prov_usages=prov_usages,
+                             prov_generations=prov_generations,
+                             prov_associations=prov_associations)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, pe_function, node=None):
+    def toXML(self, prov_document, node=None):
         if node is None:
-            node = ElementTree.Element('peFunction')
-        
-        # set attributes
-        node.set('id',self.convertToStr(pe_function.db_id, 'long'))
-        node.set('moduleId',self.convertToStr(pe_function.db_module_id, 'long'))
-        node.set('port_name',self.convertToStr(pe_function.db_port_name, 'str'))
-        node.set('is_alias',self.convertToStr(pe_function.db_is_alias, 'long'))
+            node = ElementTree.Element('prov:document')
         
         # set elements
-        parameters = pe_function.db_parameters
-        for parameter in parameters:
-            if (parameters is not None) and (parameters != ""):
-                childNode = ElementTree.SubElement(node, 'peParameter')
-                self.getDao('pe_parameter').toXML(parameter, childNode)
+        prov_entitys = prov_document.db_prov_entitys
+        for prov_entity in prov_entitys:
+            if (prov_entitys is not None) and (prov_entitys != ""):
+                childNode = ElementTree.SubElement(node, 'prov:entity')
+                self.getDao('prov_entity').toXML(prov_entity, childNode)
+        prov_activitys = prov_document.db_prov_activitys
+        for prov_activity in prov_activitys:
+            if (prov_activitys is not None) and (prov_activitys != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('prov_activity').toXML(prov_activity, childNode)
+        prov_agents = prov_document.db_prov_agents
+        for prov_agent in prov_agents:
+            if (prov_agents is not None) and (prov_agents != ""):
+                childNode = ElementTree.SubElement(node, 'prov:agent')
+                self.getDao('prov_agent').toXML(prov_agent, childNode)
+        vt_connections = prov_document.db_vt_connections
+        for vt_connection in vt_connections:
+            if (vt_connections is not None) and (vt_connections != ""):
+                childNode = ElementTree.SubElement(node, 'vt:connection')
+                self.getDao('vt_connection').toXML(vt_connection, childNode)
+        prov_usages = prov_document.db_prov_usages
+        for prov_usage in prov_usages:
+            if (prov_usages is not None) and (prov_usages != ""):
+                childNode = ElementTree.SubElement(node, 'prov:used')
+                self.getDao('prov_usage').toXML(prov_usage, childNode)
+        prov_generations = prov_document.db_prov_generations
+        for prov_generation in prov_generations:
+            if (prov_generations is not None) and (prov_generations != ""):
+                childNode = ElementTree.SubElement(node, 'prov:wasGeneratedBy')
+                self.getDao('prov_generation').toXML(prov_generation, childNode)
+        prov_associations = prov_document.db_prov_associations
+        for prov_association in prov_associations:
+            if (prov_associations is not None) and (prov_associations != ""):
+                childNode = ElementTree.SubElement(node, 'prov:wasAssociatedWith')
+                self.getDao('prov_association').toXML(prov_association, childNode)
         
         return node
 
-class DBOpmProcessValueXMLDAOBase(XMLDAO):
+class DBOpmProcessesXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5108,10 +4497,10 @@ class DBOpmProcessValueXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'value':
+        if node_tag != 'processes':
             return None
         
-        value = None
+        processs = []
         
         # read children
         for child in node.getchildren():
@@ -5119,44 +4508,32 @@ class DBOpmProcessValueXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'moduleExec':
-                _data = self.getDao('module_exec').fromXML(child)
-                value = _data
-            elif child_tag == 'groupExec':
-                _data = self.getDao('group_exec').fromXML(child)
-                value = _data
-            elif child_tag == 'loopExec':
-                _data = self.getDao('loop_exec').fromXML(child)
-                value = _data
+            if child_tag == 'process':
+                _data = self.getDao('opm_process').fromXML(child)
+                processs.append(_data)
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBOpmProcessValue(value=value)
+        obj = DBOpmProcesses(processs=processs)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_process_value, node=None):
+    def toXML(self, opm_processes, node=None):
         if node is None:
-            node = ElementTree.Element('value')
+            node = ElementTree.Element('processes')
         
         # set elements
-        value = opm_process_value.db_value
-        if value is not None:
-            if value.vtType == 'module_exec':
-                childNode = ElementTree.SubElement(node, 'moduleExec')
-                self.getDao('module_exec').toXML(value, childNode)
-            elif value.vtType == 'group_exec':
-                childNode = ElementTree.SubElement(node, 'groupExec')
-                self.getDao('group_exec').toXML(value, childNode)
-            elif value.vtType == 'loop_exec':
-                childNode = ElementTree.SubElement(node, 'loopExec')
-                self.getDao('loop_exec').toXML(value, childNode)
+        processs = opm_processes.db_processs
+        for process in processs:
+            if (processs is not None) and (processs != ""):
+                childNode = ElementTree.SubElement(node, 'process')
+                self.getDao('opm_process').toXML(process, childNode)
         
         return node
 
-class DBActionXMLDAOBase(XMLDAO):
+class DBOpmAccountIdXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5169,89 +4546,27 @@ class DBActionXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'action':
+        if node_tag != 'account':
             return None
         
         # read attributes
         data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('prevId', None)
-        prevId = self.convertFromStr(data, 'long')
-        data = node.get('date', None)
-        date = self.convertFromStr(data, 'datetime')
-        data = node.get('session', None)
-        session = self.convertFromStr(data, 'long')
-        data = node.get('user', None)
-        user = self.convertFromStr(data, 'str')
-        
-        annotations = []
-        operations = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child_tag == 'add':
-                _data = self.getDao('add').fromXML(child)
-                operations.append(_data)
-            elif child_tag == 'delete':
-                _data = self.getDao('delete').fromXML(child)
-                operations.append(_data)
-            elif child_tag == 'change':
-                _data = self.getDao('change').fromXML(child)
-                operations.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        id = self.convertFromStr(data, 'str')
         
-        obj = DBAction(operations=operations,
-                       id=id,
-                       prevId=prevId,
-                       date=date,
-                       session=session,
-                       user=user,
-                       annotations=annotations)
+        obj = DBOpmAccountId(id=id)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, action, node=None):
+    def toXML(self, opm_account_id, node=None):
         if node is None:
-            node = ElementTree.Element('action')
+            node = ElementTree.Element('account')
         
         # set attributes
-        node.set('id',self.convertToStr(action.db_id, 'long'))
-        node.set('prevId',self.convertToStr(action.db_prevId, 'long'))
-        node.set('date',self.convertToStr(action.db_date, 'datetime'))
-        node.set('session',self.convertToStr(action.db_session, 'long'))
-        node.set('user',self.convertToStr(action.db_user, 'str'))
-        
-        # set elements
-        annotations = action.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
-        operations = action.db_operations
-        for operation in operations:
-            if operation.vtType == 'add':
-                childNode = ElementTree.SubElement(node, 'add')
-                self.getDao('add').toXML(operation, childNode)
-            elif operation.vtType == 'delete':
-                childNode = ElementTree.SubElement(node, 'delete')
-                self.getDao('delete').toXML(operation, childNode)
-            elif operation.vtType == 'change':
-                childNode = ElementTree.SubElement(node, 'change')
-                self.getDao('change').toXML(operation, childNode)
+        node.set('id',self.convertToStr(opm_account_id.db_id, 'str'))
         
         return node
 
-class DBOpmAgentXMLDAOBase(XMLDAO):
+class DBPortSpecItemXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5264,60 +4579,59 @@ class DBOpmAgentXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'agent':
+        if node_tag != 'portSpecItem':
             return None
         
         # read attributes
         data = node.get('id', None)
-        id = self.convertFromStr(data, 'str')
-        
-        value = None
-        accounts = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'value':
-                _data = self.convertFromStr(child.text,'str')
-                value = _data
-            elif child_tag == 'account':
-                _data = self.getDao('opm_account_id').fromXML(child)
-                accounts.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
+        id = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('module', None)
+        module = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('label', None)
+        label = self.convertFromStr(data, 'str')
+        data = node.get('default', None)
+        default = self.convertFromStr(data, 'str')
+        data = node.get('values', None)
+        values = self.convertFromStr(data, 'str')
+        data = node.get('entryType', None)
+        entry_type = self.convertFromStr(data, 'str')
         
-        obj = DBOpmAgent(id=id,
-                         value=value,
-                         accounts=accounts)
+        obj = DBPortSpecItem(id=id,
+                             pos=pos,
+                             module=module,
+                             package=package,
+                             namespace=namespace,
+                             label=label,
+                             default=default,
+                             values=values,
+                             entry_type=entry_type)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, opm_agent, node=None):
+    def toXML(self, portSpecItem, node=None):
         if node is None:
-            node = ElementTree.Element('agent')
+            node = ElementTree.Element('portSpecItem')
         
         # set attributes
-        node.set('id',self.convertToStr(opm_agent.db_id, 'str'))
-        
-        # set elements
-        value = opm_agent.db_value
-        if (value is not None) and (value != ""):
-            childNode = ElementTree.SubElement(node, 'value')
-            childNode.text = self.convertToStr(value, 'str')
-        accounts = opm_agent.db_accounts
-        for account in accounts:
-            if (accounts is not None) and (accounts != ""):
-                childNode = ElementTree.SubElement(node, 'account')
-                self.getDao('opm_account_id').toXML(account, childNode)
+        node.set('id',self.convertToStr(portSpecItem.db_id, 'long'))
+        node.set('pos',self.convertToStr(portSpecItem.db_pos, 'long'))
+        node.set('module',self.convertToStr(portSpecItem.db_module, 'str'))
+        node.set('package',self.convertToStr(portSpecItem.db_package, 'str'))
+        node.set('namespace',self.convertToStr(portSpecItem.db_namespace, 'str'))
+        node.set('label',self.convertToStr(portSpecItem.db_label, 'str'))
+        node.set('default',self.convertToStr(portSpecItem.db_default, 'str'))
+        node.set('values',self.convertToStr(portSpecItem.db_values, 'str'))
+        node.set('entryType',self.convertToStr(portSpecItem.db_entry_type, 'str'))
         
         return node
 
-class DBDeleteXMLDAOBase(XMLDAO):
+class DBMashupComponentXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5330,62 +4644,123 @@ class DBDeleteXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'delete':
+        if node_tag != 'component':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('what', None)
-        what = self.convertFromStr(data, 'str')
-        data = node.get('objectId', None)
-        objectId = self.convertFromStr(data, 'long')
-        data = node.get('parentObjId', None)
-        parentObjId = self.convertFromStr(data, 'long')
-        data = node.get('parentObjType', None)
-        parentObjType = self.convertFromStr(data, 'str')
+        data = node.get('vtid', None)
+        vtid = self.convertFromStr(data, 'long')
+        data = node.get('vttype', None)
+        vttype = self.convertFromStr(data, 'str')
+        data = node.get('vtparent_type', None)
+        vtparent_type = self.convertFromStr(data, 'str')
+        data = node.get('vtparent_id', None)
+        vtparent_id = self.convertFromStr(data, 'long')
+        data = node.get('vtpos', None)
+        vtpos = self.convertFromStr(data, 'long')
+        data = node.get('vtmid', None)
+        vtmid = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('val', None)
+        val = self.convertFromStr(data, 'str')
+        data = node.get('minVal', None)
+        minVal = self.convertFromStr(data, 'str')
+        data = node.get('maxVal', None)
+        maxVal = self.convertFromStr(data, 'str')
+        data = node.get('stepSize', None)
+        stepSize = self.convertFromStr(data, 'str')
+        data = node.get('valueList', None)
+        strvaluelist = self.convertFromStr(data, 'str')
+        data = node.get('widget', None)
+        widget = self.convertFromStr(data, 'str')
+        data = node.get('seq', None)
+        seq = self.convertFromStr(data, 'int')
+        data = node.get('parent', None)
+        parent = self.convertFromStr(data, 'str')
         
-        obj = DBDelete(id=id,
-                       what=what,
-                       objectId=objectId,
-                       parentObjId=parentObjId,
-                       parentObjType=parentObjType)
+        obj = DBMashupComponent(id=id,
+                                vtid=vtid,
+                                vttype=vttype,
+                                vtparent_type=vtparent_type,
+                                vtparent_id=vtparent_id,
+                                vtpos=vtpos,
+                                vtmid=vtmid,
+                                pos=pos,
+                                type=type,
+                                val=val,
+                                minVal=minVal,
+                                maxVal=maxVal,
+                                stepSize=stepSize,
+                                strvaluelist=strvaluelist,
+                                widget=widget,
+                                seq=seq,
+                                parent=parent)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, delete, node=None):
+    def toXML(self, mashup_component, node=None):
         if node is None:
-            node = ElementTree.Element('delete')
+            node = ElementTree.Element('component')
         
         # set attributes
-        node.set('id',self.convertToStr(delete.db_id, 'long'))
-        node.set('what',self.convertToStr(delete.db_what, 'str'))
-        node.set('objectId',self.convertToStr(delete.db_objectId, 'long'))
-        node.set('parentObjId',self.convertToStr(delete.db_parentObjId, 'long'))
-        node.set('parentObjType',self.convertToStr(delete.db_parentObjType, 'str'))
-        
-        return node
-
-class DBProvAssociationXMLDAOBase(XMLDAO):
-
-    def __init__(self, daoList):
-        self.daoList = daoList
-
-    def getDao(self, dao):
-        return self.daoList[dao]
-
+        node.set('id',self.convertToStr(mashup_component.db_id, 'long'))
+        node.set('vtid',self.convertToStr(mashup_component.db_vtid, 'long'))
+        node.set('vttype',self.convertToStr(mashup_component.db_vttype, 'str'))
+        node.set('vtparent_type',self.convertToStr(mashup_component.db_vtparent_type, 'str'))
+        node.set('vtparent_id',self.convertToStr(mashup_component.db_vtparent_id, 'long'))
+        node.set('vtpos',self.convertToStr(mashup_component.db_vtpos, 'long'))
+        node.set('vtmid',self.convertToStr(mashup_component.db_vtmid, 'long'))
+        node.set('pos',self.convertToStr(mashup_component.db_pos, 'long'))
+        node.set('type',self.convertToStr(mashup_component.db_type, 'str'))
+        node.set('val',self.convertToStr(mashup_component.db_val, 'str'))
+        node.set('minVal',self.convertToStr(mashup_component.db_minVal, 'str'))
+        node.set('maxVal',self.convertToStr(mashup_component.db_maxVal, 'str'))
+        node.set('stepSize',self.convertToStr(mashup_component.db_stepSize, 'str'))
+        node.set('valueList',self.convertToStr(mashup_component.db_strvaluelist, 'str'))
+        node.set('widget',self.convertToStr(mashup_component.db_widget, 'str'))
+        node.set('seq',self.convertToStr(mashup_component.db_seq, 'int'))
+        node.set('parent',self.convertToStr(mashup_component.db_parent, 'str'))
+        
+        return node
+
+class DBMashupXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
     def fromXML(self, node):
         if node.tag[0] == "{":
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'prov:wasAssociatedWith':
+        if node_tag != 'mashup':
             return None
         
-        prov_activity = None
-        prov_agent = None
-        prov_plan = None
-        prov_role = None
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'long')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('vtid', None)
+        vtid = self.convertFromStr(data, 'long')
+        data = node.get('has_seq', None)
+        has_seq = self.convertFromStr(data, 'int')
+        
+        aliases = []
+        layout = None
+        geometry = None
         
         # read children
         for child in node.getchildren():
@@ -5393,58 +4768,62 @@ class DBProvAssociationXMLDAOBase(XMLDAO):
                 child_tag = child.tag.split("}")[1]
             else:
                 child_tag = child.tag
-            if child_tag == 'prov:activity':
-                _data = self.getDao('ref_prov_activity').fromXML(child)
-                prov_activity = _data
-            elif child_tag == 'prov:agent':
-                _data = self.getDao('ref_prov_agent').fromXML(child)
-                prov_agent = _data
-            elif child_tag == 'prov:plan':
-                _data = self.getDao('ref_prov_plan').fromXML(child)
-                prov_plan = _data
-            elif child_tag == 'prov:role':
+            if child_tag == 'alias':
+                _data = self.getDao('mashup_alias').fromXML(child)
+                aliases.append(_data)
+            elif child_tag == 'layout':
                 _data = self.convertFromStr(child.text,'str')
-                prov_role = _data
+                layout = _data
+            elif child_tag == 'geometry':
+                _data = self.convertFromStr(child.text,'str')
+                geometry = _data
             elif child.text is None or child.text.strip() == '':
                 pass
             else:
                 print '*** ERROR *** tag = %s' % child.tag
         
-        obj = DBProvAssociation(prov_activity=prov_activity,
-                                prov_agent=prov_agent,
-                                prov_plan=prov_plan,
-                                prov_role=prov_role)
+        obj = DBMashup(id=id,
+                       name=name,
+                       version=version,
+                       aliases=aliases,
+                       type=type,
+                       vtid=vtid,
+                       layout=layout,
+                       geometry=geometry,
+                       has_seq=has_seq)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, prov_association, node=None):
+    def toXML(self, mashup, node=None):
         if node is None:
-            node = ElementTree.Element('prov:wasAssociatedWith')
+            node = ElementTree.Element('mashup')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup.db_id, 'long'))
+        node.set('name',self.convertToStr(mashup.db_name, 'str'))
+        node.set('version',self.convertToStr(mashup.db_version, 'long'))
+        node.set('type',self.convertToStr(mashup.db_type, 'str'))
+        node.set('vtid',self.convertToStr(mashup.db_vtid, 'long'))
+        node.set('has_seq',self.convertToStr(mashup.db_has_seq, 'int'))
         
         # set elements
-        prov_activity = prov_association.db_prov_activity
-        if prov_activity is not None:
-            if (prov_activity is not None) and (prov_activity != ""):
-                childNode = ElementTree.SubElement(node, 'prov:activity')
-                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
-        prov_agent = prov_association.db_prov_agent
-        if prov_agent is not None:
-            if (prov_agent is not None) and (prov_agent != ""):
-                childNode = ElementTree.SubElement(node, 'prov:agent')
-                self.getDao('ref_prov_agent').toXML(prov_agent, childNode)
-        prov_plan = prov_association.db_prov_plan
-        if prov_plan is not None:
-            if (prov_plan is not None) and (prov_plan != ""):
-                childNode = ElementTree.SubElement(node, 'prov:plan')
-                self.getDao('ref_prov_plan').toXML(prov_plan, childNode)
-        prov_role = prov_association.db_prov_role
-        if (prov_role is not None) and (prov_role != ""):
-            childNode = ElementTree.SubElement(node, 'prov:role')
-            childNode.text = self.convertToStr(prov_role, 'str')
+        aliases = mashup.db_aliases
+        for alias in aliases:
+            if (aliases is not None) and (aliases != ""):
+                childNode = ElementTree.SubElement(node, 'alias')
+                self.getDao('mashup_alias').toXML(alias, childNode)
+        layout = mashup.db_layout
+        if (layout is not None) and (layout != ""):
+            childNode = ElementTree.SubElement(node, 'layout')
+            childNode.text = self.convertToStr(layout, 'str')
+        geometry = mashup.db_geometry
+        if (geometry is not None) and (geometry != ""):
+            childNode = ElementTree.SubElement(node, 'geometry')
+            childNode.text = self.convertToStr(geometry, 'str')
         
         return node
 
-class DBVistrailXMLDAOBase(XMLDAO):
+class DBMachineXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5457,109 +4836,47 @@ class DBVistrailXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'vistrail':
+        if node_tag != 'machine':
             return None
         
         # read attributes
         data = node.get('id', None)
         id = self.convertFromStr(data, 'long')
-        data = node.get('version', None)
-        version = self.convertFromStr(data, 'str')
         data = node.get('name', None)
         name = self.convertFromStr(data, 'str')
+        data = node.get('os', None)
+        os = self.convertFromStr(data, 'str')
+        data = node.get('architecture', None)
+        architecture = self.convertFromStr(data, 'str')
+        data = node.get('processor', None)
+        processor = self.convertFromStr(data, 'str')
+        data = node.get('ram', None)
+        ram = self.convertFromStr(data, 'int')
         
-        actions = []
-        tags = []
-        annotations = []
-        vistrailVariables = []
-        parameter_explorations = []
-        actionAnnotations = []
-        
-        # read children
-        for child in node.getchildren():
-            if child.tag[0] == "{":
-                child_tag = child.tag.split("}")[1]
-            else:
-                child_tag = child.tag
-            if child_tag == 'action':
-                _data = self.getDao('action').fromXML(child)
-                actions.append(_data)
-            elif child_tag == 'tag':
-                _data = self.getDao('tag').fromXML(child)
-                tags.append(_data)
-            elif child_tag == 'annotation':
-                _data = self.getDao('annotation').fromXML(child)
-                annotations.append(_data)
-            elif child_tag == 'vistrailVariable':
-                _data = self.getDao('vistrailVariable').fromXML(child)
-                vistrailVariables.append(_data)
-            elif child_tag == 'parameterExploration':
-                _data = self.getDao('parameter_exploration').fromXML(child)
-                parameter_explorations.append(_data)
-            elif child_tag == 'actionAnnotation':
-                _data = self.getDao('actionAnnotation').fromXML(child)
-                actionAnnotations.append(_data)
-            elif child.text is None or child.text.strip() == '':
-                pass
-            else:
-                print '*** ERROR *** tag = %s' % child.tag
-        
-        obj = DBVistrail(id=id,
-                         version=version,
-                         name=name,
-                         actions=actions,
-                         tags=tags,
-                         annotations=annotations,
-                         vistrailVariables=vistrailVariables,
-                         parameter_explorations=parameter_explorations,
-                         actionAnnotations=actionAnnotations)
+        obj = DBMachine(id=id,
+                        name=name,
+                        os=os,
+                        architecture=architecture,
+                        processor=processor,
+                        ram=ram)
         obj.is_dirty = False
         return obj
     
-    def toXML(self, vistrail, node=None):
+    def toXML(self, machine, node=None):
         if node is None:
-            node = ElementTree.Element('vistrail')
+            node = ElementTree.Element('machine')
         
         # set attributes
-        node.set('id',self.convertToStr(vistrail.db_id, 'long'))
-        node.set('version',self.convertToStr(vistrail.db_version, 'str'))
-        node.set('name',self.convertToStr(vistrail.db_name, 'str'))
-        
-        # set elements
-        actions = vistrail.db_actions
-        for action in actions:
-            if (actions is not None) and (actions != ""):
-                childNode = ElementTree.SubElement(node, 'action')
-                self.getDao('action').toXML(action, childNode)
-        tags = vistrail.db_tags
-        for tag in tags:
-            if (tags is not None) and (tags != ""):
-                childNode = ElementTree.SubElement(node, 'tag')
-                self.getDao('tag').toXML(tag, childNode)
-        annotations = vistrail.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
-        vistrailVariables = vistrail.db_vistrailVariables
-        for vistrailVariable in vistrailVariables:
-            if (vistrailVariables is not None) and (vistrailVariables != ""):
-                childNode = ElementTree.SubElement(node, 'vistrailVariable')
-                self.getDao('vistrailVariable').toXML(vistrailVariable, childNode)
-        parameter_explorations = vistrail.db_parameter_explorations
-        for parameter_exploration in parameter_explorations:
-            if (parameter_explorations is not None) and (parameter_explorations != ""):
-                childNode = ElementTree.SubElement(node, 'parameterExploration')
-                self.getDao('parameter_exploration').toXML(parameter_exploration, childNode)
-        actionAnnotations = vistrail.db_actionAnnotations
-        for actionAnnotation in actionAnnotations:
-            if (actionAnnotations is not None) and (actionAnnotations != ""):
-                childNode = ElementTree.SubElement(node, 'actionAnnotation')
-                self.getDao('actionAnnotation').toXML(actionAnnotation, childNode)
+        node.set('id',self.convertToStr(machine.db_id, 'long'))
+        node.set('name',self.convertToStr(machine.db_name, 'str'))
+        node.set('os',self.convertToStr(machine.db_os, 'str'))
+        node.set('architecture',self.convertToStr(machine.db_architecture, 'str'))
+        node.set('processor',self.convertToStr(machine.db_processor, 'str'))
+        node.set('ram',self.convertToStr(machine.db_ram, 'int'))
         
         return node
 
-class DBModuleExecXMLDAOBase(XMLDAO):
+class DBConfigFloatXMLDAOBase(XMLDAO):
 
     def __init__(self, daoList):
         self.daoList = daoList
@@ -5572,27 +4889,1068 @@ class DBModuleExecXMLDAOBase(XMLDAO):
             node_tag = node.tag.split("}")[1]
         else:
             node_tag = node.tag
-        if node_tag != 'moduleExec':
+        if node_tag != 'float':
             return None
         
         # read attributes
-        data = node.get('id', None)
-        id = self.convertFromStr(data, 'long')
-        data = node.get('tsStart', None)
-        ts_start = self.convertFromStr(data, 'datetime')
-        data = node.get('tsEnd', None)
-        ts_end = self.convertFromStr(data, 'datetime')
-        data = node.get('cached', None)
-        cached = self.convertFromStr(data, 'int')
-        data = node.get('moduleId', None)
-        module_id = self.convertFromStr(data, 'long')
-        data = node.get('moduleName', None)
-        module_name = self.convertFromStr(data, 'str')
-        data = node.get('completed', None)
-        completed = self.convertFromStr(data, 'int')
-        data = node.get('error', None)
-        error = self.convertFromStr(data, 'str')
-        data = node.get('machine_id', None)
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'float')
+        
+        obj = DBConfigFloat(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, config_float, node=None):
+        if node is None:
+            node = ElementTree.Element('float')
+        
+        # set attributes
+        node.set('value',self.convertToStr(config_float.db_value, 'float'))
+        
+        return node
+
+class DBOtherXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'other':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.convertFromStr(child.text,'str')
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOther(id=id,
+                      key=key,
+                      value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, other, node=None):
+        if node is None:
+            node = ElementTree.Element('other')
+        
+        # set attributes
+        node.set('id',self.convertToStr(other.db_id, 'long'))
+        node.set('key',self.convertToStr(other.db_key, 'str'))
+        
+        # set elements
+        value = other.db_value
+        if (value is not None) and (value != ""):
+            childNode = ElementTree.SubElement(node, 'value')
+            childNode.text = self.convertToStr(value, 'str')
+        
+        return node
+
+class DBRefProvActivityXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:activity':
+            return None
+        
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
+        
+        obj = DBRefProvActivity(prov_ref=prov_ref)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, ref_prov_activity, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:activity')
+        
+        # set attributes
+        node.set('prov:ref',self.convertToStr(ref_prov_activity.db_prov_ref, 'str'))
+        
+        return node
+
+class DBAbstractionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'abstraction':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('cache', None)
+        cache = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('internalVersion', None)
+        internal_version = self.convertFromStr(data, 'str')
+        
+        location = None
+        functions = []
+        annotations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                location = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                functions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBAbstraction(id=id,
+                            cache=cache,
+                            name=name,
+                            namespace=namespace,
+                            package=package,
+                            version=version,
+                            internal_version=internal_version,
+                            location=location,
+                            functions=functions,
+                            annotations=annotations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, abstraction, node=None):
+        if node is None:
+            node = ElementTree.Element('abstraction')
+        
+        # set attributes
+        node.set('id',self.convertToStr(abstraction.db_id, 'long'))
+        node.set('cache',self.convertToStr(abstraction.db_cache, 'int'))
+        node.set('name',self.convertToStr(abstraction.db_name, 'str'))
+        node.set('namespace',self.convertToStr(abstraction.db_namespace, 'str'))
+        node.set('package',self.convertToStr(abstraction.db_package, 'str'))
+        node.set('version',self.convertToStr(abstraction.db_version, 'str'))
+        node.set('internalVersion',self.convertToStr(abstraction.db_internal_version, 'str'))
+        
+        # set elements
+        location = abstraction.db_location
+        if location is not None:
+            if (location is not None) and (location != ""):
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(location, childNode)
+        functions = abstraction.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(function, childNode)
+        annotations = abstraction.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        
+        return node
+
+class DBProvAgentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:agent':
+            return None
+        
+        # read attributes
+        data = node.get('prov:id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        vt_id = None
+        prov_type = None
+        prov_label = None
+        vt_machine_os = None
+        vt_machine_architecture = None
+        vt_machine_processor = None
+        vt_machine_ram = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'vt:id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_id = _data
+            elif child_tag == 'prov:type':
+                _data = self.convertFromStr(child.text,'str')
+                prov_type = _data
+            elif child_tag == 'prov:label':
+                _data = self.convertFromStr(child.text,'str')
+                prov_label = _data
+            elif child_tag == 'vt:machine_os':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_os = _data
+            elif child_tag == 'vt:machine_architecture':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_architecture = _data
+            elif child_tag == 'vt:machine_processor':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_processor = _data
+            elif child_tag == 'vt:machine_ram':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_ram = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvAgent(id=id,
+                          vt_id=vt_id,
+                          prov_type=prov_type,
+                          prov_label=prov_label,
+                          vt_machine_os=vt_machine_os,
+                          vt_machine_architecture=vt_machine_architecture,
+                          vt_machine_processor=vt_machine_processor,
+                          vt_machine_ram=vt_machine_ram)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_agent, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:agent')
+        
+        # set attributes
+        node.set('prov:id',self.convertToStr(prov_agent.db_id, 'str'))
+        
+        # set elements
+        vt_id = prov_agent.db_vt_id
+        if (vt_id is not None) and (vt_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:id')
+            childNode.text = self.convertToStr(vt_id, 'str')
+        prov_type = prov_agent.db_prov_type
+        if (prov_type is not None) and (prov_type != ""):
+            childNode = ElementTree.SubElement(node, 'prov:type')
+            childNode.text = self.convertToStr(prov_type, 'str')
+        prov_label = prov_agent.db_prov_label
+        if (prov_label is not None) and (prov_label != ""):
+            childNode = ElementTree.SubElement(node, 'prov:label')
+            childNode.text = self.convertToStr(prov_label, 'str')
+        vt_machine_os = prov_agent.db_vt_machine_os
+        if (vt_machine_os is not None) and (vt_machine_os != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_os')
+            childNode.text = self.convertToStr(vt_machine_os, 'str')
+        vt_machine_architecture = prov_agent.db_vt_machine_architecture
+        if (vt_machine_architecture is not None) and (vt_machine_architecture != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_architecture')
+            childNode.text = self.convertToStr(vt_machine_architecture, 'str')
+        vt_machine_processor = prov_agent.db_vt_machine_processor
+        if (vt_machine_processor is not None) and (vt_machine_processor != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_processor')
+            childNode.text = self.convertToStr(vt_machine_processor, 'str')
+        vt_machine_ram = prov_agent.db_vt_machine_ram
+        if (vt_machine_ram is not None) and (vt_machine_ram != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_ram')
+            childNode.text = self.convertToStr(vt_machine_ram, 'str')
+        
+        return node
+
+class DBMashuptrailXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'mashuptrail':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('vtVersion', None)
+        vtVersion = self.convertFromStr(data, 'long')
+        
+        actions = []
+        annotations = []
+        actionAnnotations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'action':
+                _data = self.getDao('mashup_action').fromXML(child)
+                actions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'actionAnnotation':
+                _data = self.getDao('mashup_actionAnnotation').fromXML(child)
+                actionAnnotations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBMashuptrail(name=name,
+                            version=version,
+                            vtVersion=vtVersion,
+                            actions=actions,
+                            annotations=annotations,
+                            actionAnnotations=actionAnnotations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashuptrail, node=None):
+        if node is None:
+            node = ElementTree.Element('mashuptrail')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashuptrail.db_name, 'str'))
+        node.set('version',self.convertToStr(mashuptrail.db_version, 'str'))
+        node.set('vtVersion',self.convertToStr(mashuptrail.db_vtVersion, 'long'))
+        
+        # set elements
+        actions = mashuptrail.db_actions
+        for action in actions:
+            if (actions is not None) and (actions != ""):
+                childNode = ElementTree.SubElement(node, 'action')
+                self.getDao('mashup_action').toXML(action, childNode)
+        annotations = mashuptrail.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        actionAnnotations = mashuptrail.db_actionAnnotations
+        for actionAnnotation in actionAnnotations:
+            if (actionAnnotations is not None) and (actionAnnotations != ""):
+                childNode = ElementTree.SubElement(node, 'actionAnnotation')
+                self.getDao('mashup_actionAnnotation').toXML(actionAnnotation, childNode)
+        
+        return node
+
+class DBRegistryXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'registry':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('rootDescriptorId', None)
+        root_descriptor_id = self.convertFromStr(data, 'long')
+        
+        packages = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'package':
+                _data = self.getDao('package').fromXML(child)
+                packages.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBRegistry(id=id,
+                         version=version,
+                         root_descriptor_id=root_descriptor_id,
+                         packages=packages)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, registry, node=None):
+        if node is None:
+            node = ElementTree.Element('registry')
+        
+        # set attributes
+        node.set('id',self.convertToStr(registry.db_id, 'long'))
+        node.set('version',self.convertToStr(registry.db_version, 'str'))
+        node.set('rootDescriptorId',self.convertToStr(registry.db_root_descriptor_id, 'long'))
+        
+        # set elements
+        packages = registry.db_packages
+        for package in packages:
+            if (packages is not None) and (packages != ""):
+                childNode = ElementTree.SubElement(node, 'package')
+                self.getDao('package').toXML(package, childNode)
+        
+        return node
+
+class DBOpmAgentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'agent':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        value = None
+        accounts = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.convertFromStr(child.text,'str')
+                value = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAgent(id=id,
+                         value=value,
+                         accounts=accounts)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_agent, node=None):
+        if node is None:
+            node = ElementTree.Element('agent')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_agent.db_id, 'str'))
+        
+        # set elements
+        value = opm_agent.db_value
+        if (value is not None) and (value != ""):
+            childNode = ElementTree.SubElement(node, 'value')
+            childNode.text = self.convertToStr(value, 'str')
+        accounts = opm_agent.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        
+        return node
+
+class DBProvEntityXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:entity':
+            return None
+        
+        # read attributes
+        data = node.get('prov:id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        prov_type = None
+        prov_label = None
+        prov_value = None
+        vt_id = None
+        vt_type = None
+        vt_desc = None
+        vt_package = None
+        vt_version = None
+        vt_cache = None
+        vt_location_x = None
+        vt_location_y = None
+        is_part_of = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:type':
+                _data = self.convertFromStr(child.text,'str')
+                prov_type = _data
+            elif child_tag == 'prov:label':
+                _data = self.convertFromStr(child.text,'str')
+                prov_label = _data
+            elif child_tag == 'prov:value':
+                _data = self.convertFromStr(child.text,'str')
+                prov_value = _data
+            elif child_tag == 'vt:id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_id = _data
+            elif child_tag == 'vt:type':
+                _data = self.convertFromStr(child.text,'str')
+                vt_type = _data
+            elif child_tag == 'vt:desc':
+                _data = self.convertFromStr(child.text,'str')
+                vt_desc = _data
+            elif child_tag == 'vt:package':
+                _data = self.convertFromStr(child.text,'str')
+                vt_package = _data
+            elif child_tag == 'vt:version':
+                _data = self.convertFromStr(child.text,'str')
+                vt_version = _data
+            elif child_tag == 'vt:cache':
+                _data = self.convertFromStr(child.text,'str')
+                vt_cache = _data
+            elif child_tag == 'vt:location_x':
+                _data = self.convertFromStr(child.text,'str')
+                vt_location_x = _data
+            elif child_tag == 'vt:location_y':
+                _data = self.convertFromStr(child.text,'str')
+                vt_location_y = _data
+            elif child_tag == 'dcterms:isPartOf':
+                _data = self.getDao('is_part_of').fromXML(child)
+                is_part_of = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvEntity(id=id,
+                           prov_type=prov_type,
+                           prov_label=prov_label,
+                           prov_value=prov_value,
+                           vt_id=vt_id,
+                           vt_type=vt_type,
+                           vt_desc=vt_desc,
+                           vt_package=vt_package,
+                           vt_version=vt_version,
+                           vt_cache=vt_cache,
+                           vt_location_x=vt_location_x,
+                           vt_location_y=vt_location_y,
+                           is_part_of=is_part_of)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_entity, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:entity')
+        
+        # set attributes
+        node.set('prov:id',self.convertToStr(prov_entity.db_id, 'str'))
+        
+        # set elements
+        prov_type = prov_entity.db_prov_type
+        if (prov_type is not None) and (prov_type != ""):
+            childNode = ElementTree.SubElement(node, 'prov:type')
+            childNode.text = self.convertToStr(prov_type, 'str')
+        prov_label = prov_entity.db_prov_label
+        if (prov_label is not None) and (prov_label != ""):
+            childNode = ElementTree.SubElement(node, 'prov:label')
+            childNode.text = self.convertToStr(prov_label, 'str')
+        prov_value = prov_entity.db_prov_value
+        if (prov_value is not None) and (prov_value != ""):
+            childNode = ElementTree.SubElement(node, 'prov:value')
+            childNode.text = self.convertToStr(prov_value, 'str')
+        vt_id = prov_entity.db_vt_id
+        if (vt_id is not None) and (vt_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:id')
+            childNode.text = self.convertToStr(vt_id, 'str')
+        vt_type = prov_entity.db_vt_type
+        if (vt_type is not None) and (vt_type != ""):
+            childNode = ElementTree.SubElement(node, 'vt:type')
+            childNode.text = self.convertToStr(vt_type, 'str')
+        vt_desc = prov_entity.db_vt_desc
+        if (vt_desc is not None) and (vt_desc != ""):
+            childNode = ElementTree.SubElement(node, 'vt:desc')
+            childNode.text = self.convertToStr(vt_desc, 'str')
+        vt_package = prov_entity.db_vt_package
+        if (vt_package is not None) and (vt_package != ""):
+            childNode = ElementTree.SubElement(node, 'vt:package')
+            childNode.text = self.convertToStr(vt_package, 'str')
+        vt_version = prov_entity.db_vt_version
+        if (vt_version is not None) and (vt_version != ""):
+            childNode = ElementTree.SubElement(node, 'vt:version')
+            childNode.text = self.convertToStr(vt_version, 'str')
+        vt_cache = prov_entity.db_vt_cache
+        if (vt_cache is not None) and (vt_cache != ""):
+            childNode = ElementTree.SubElement(node, 'vt:cache')
+            childNode.text = self.convertToStr(vt_cache, 'str')
+        vt_location_x = prov_entity.db_vt_location_x
+        if (vt_location_x is not None) and (vt_location_x != ""):
+            childNode = ElementTree.SubElement(node, 'vt:location_x')
+            childNode.text = self.convertToStr(vt_location_x, 'str')
+        vt_location_y = prov_entity.db_vt_location_y
+        if (vt_location_y is not None) and (vt_location_y != ""):
+            childNode = ElementTree.SubElement(node, 'vt:location_y')
+            childNode.text = self.convertToStr(vt_location_y, 'str')
+        is_part_of = prov_entity.db_is_part_of
+        if is_part_of is not None:
+            if (is_part_of is not None) and (is_part_of != ""):
+                childNode = ElementTree.SubElement(node, 'dcterms:isPartOf')
+                self.getDao('is_part_of').toXML(is_part_of, childNode)
+        
+        return node
+
+class DBAnnotationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'annotation':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBAnnotation(id=id,
+                           key=key,
+                           value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, annotation, node=None):
+        if node is None:
+            node = ElementTree.Element('annotation')
+        
+        # set attributes
+        node.set('id',self.convertToStr(annotation.db_id, 'long'))
+        node.set('key',self.convertToStr(annotation.db_key, 'str'))
+        node.set('value',self.convertToStr(annotation.db_value, 'str'))
+        
+        return node
+
+class DBOpmTimeXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'time':
+            return None
+        
+        # read attributes
+        data = node.get('noLaterThan', None)
+        no_later_than = self.convertFromStr(data, 'datetime')
+        data = node.get('noEarlierThan', None)
+        no_earlier_than = self.convertFromStr(data, 'datetime')
+        data = node.get('clockId', None)
+        clock_id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmTime(no_later_than=no_later_than,
+                        no_earlier_than=no_earlier_than,
+                        clock_id=clock_id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_time, node=None):
+        if node is None:
+            node = ElementTree.Element('time')
+        
+        # set attributes
+        node.set('noLaterThan',self.convertToStr(opm_time.db_no_later_than, 'datetime'))
+        node.set('noEarlierThan',self.convertToStr(opm_time.db_no_earlier_than, 'datetime'))
+        node.set('clockId',self.convertToStr(opm_time.db_clock_id, 'str'))
+        
+        return node
+
+class DBParameterExplorationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'parameterExploration':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('actionId', None)
+        action_id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        data = node.get('dims', None)
+        dims = self.convertFromStr(data, 'str')
+        data = node.get('layout', None)
+        layout = self.convertFromStr(data, 'str')
+        
+        functions = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'peFunction':
+                _data = self.getDao('pe_function').fromXML(child)
+                functions.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBParameterExploration(id=id,
+                                     action_id=action_id,
+                                     name=name,
+                                     date=date,
+                                     user=user,
+                                     dims=dims,
+                                     layout=layout,
+                                     functions=functions)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, parameter_exploration, node=None):
+        if node is None:
+            node = ElementTree.Element('parameterExploration')
+        
+        # set attributes
+        node.set('id',self.convertToStr(parameter_exploration.db_id, 'long'))
+        node.set('actionId',self.convertToStr(parameter_exploration.db_action_id, 'long'))
+        node.set('name',self.convertToStr(parameter_exploration.db_name, 'str'))
+        node.set('date',self.convertToStr(parameter_exploration.db_date, 'datetime'))
+        node.set('user',self.convertToStr(parameter_exploration.db_user, 'str'))
+        node.set('dims',self.convertToStr(parameter_exploration.db_dims, 'str'))
+        node.set('layout',self.convertToStr(parameter_exploration.db_layout, 'str'))
+        
+        # set elements
+        functions = parameter_exploration.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'peFunction')
+                self.getDao('pe_function').toXML(function, childNode)
+        
+        return node
+
+class DBMashupActionAnnotationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'actionAnnotation':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        data = node.get('action_id', None)
+        action_id = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        
+        obj = DBMashupActionAnnotation(id=id,
+                                       key=key,
+                                       value=value,
+                                       action_id=action_id,
+                                       date=date,
+                                       user=user)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashup_actionAnnotation, node=None):
+        if node is None:
+            node = ElementTree.Element('actionAnnotation')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup_actionAnnotation.db_id, 'long'))
+        node.set('key',self.convertToStr(mashup_actionAnnotation.db_key, 'str'))
+        node.set('value',self.convertToStr(mashup_actionAnnotation.db_value, 'str'))
+        node.set('action_id',self.convertToStr(mashup_actionAnnotation.db_action_id, 'long'))
+        node.set('date',self.convertToStr(mashup_actionAnnotation.db_date, 'datetime'))
+        node.set('user',self.convertToStr(mashup_actionAnnotation.db_user, 'str'))
+        
+        return node
+
+class DBOpmProcessXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'process':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        value = None
+        accounts = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.getDao('opm_process_value').fromXML(child)
+                value = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmProcess(id=id,
+                           value=value,
+                           accounts=accounts)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process, node=None):
+        if node is None:
+            node = ElementTree.Element('process')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_process.db_id, 'str'))
+        
+        # set elements
+        value = opm_process.db_value
+        if value is not None:
+            if (value is not None) and (value != ""):
+                childNode = ElementTree.SubElement(node, 'value')
+                self.getDao('opm_process_value').toXML(value, childNode)
+        accounts = opm_process.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        
+        return node
+
+class DBDisabledPackagesXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'disabledpackages':
+            return None
+        
+        packages = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'package':
+                _data = self.getDao('startup_package').fromXML(child)
+                packages.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBDisabledPackages(packages=packages)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, disabled_packages, node=None):
+        if node is None:
+            node = ElementTree.Element('disabledpackages')
+        
+        # set elements
+        packages = disabled_packages.db_packages
+        for package in packages:
+            if (packages is not None) and (packages != ""):
+                childNode = ElementTree.SubElement(node, 'package')
+                self.getDao('startup_package').toXML(package, childNode)
+        
+        return node
+
+class DBModuleExecXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'moduleExec':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('cached', None)
+        cached = self.convertFromStr(data, 'int')
+        data = node.get('moduleId', None)
+        module_id = self.convertFromStr(data, 'long')
+        data = node.get('moduleName', None)
+        module_name = self.convertFromStr(data, 'str')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('error', None)
+        error = self.convertFromStr(data, 'str')
+        data = node.get('machine_id', None)
         machine_id = self.convertFromStr(data, 'long')
         
         annotations = []
@@ -5631,30 +5989,169 @@ class DBModuleExecXMLDAOBase(XMLDAO):
     
     def toXML(self, module_exec, node=None):
         if node is None:
-            node = ElementTree.Element('moduleExec')
-        
-        # set attributes
-        node.set('id',self.convertToStr(module_exec.db_id, 'long'))
-        node.set('tsStart',self.convertToStr(module_exec.db_ts_start, 'datetime'))
-        node.set('tsEnd',self.convertToStr(module_exec.db_ts_end, 'datetime'))
-        node.set('cached',self.convertToStr(module_exec.db_cached, 'int'))
-        node.set('moduleId',self.convertToStr(module_exec.db_module_id, 'long'))
-        node.set('moduleName',self.convertToStr(module_exec.db_module_name, 'str'))
-        node.set('completed',self.convertToStr(module_exec.db_completed, 'int'))
-        node.set('error',self.convertToStr(module_exec.db_error, 'str'))
-        node.set('machine_id',self.convertToStr(module_exec.db_machine_id, 'long'))
+            node = ElementTree.Element('moduleExec')
+        
+        # set attributes
+        node.set('id',self.convertToStr(module_exec.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(module_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(module_exec.db_ts_end, 'datetime'))
+        node.set('cached',self.convertToStr(module_exec.db_cached, 'int'))
+        node.set('moduleId',self.convertToStr(module_exec.db_module_id, 'long'))
+        node.set('moduleName',self.convertToStr(module_exec.db_module_name, 'str'))
+        node.set('completed',self.convertToStr(module_exec.db_completed, 'int'))
+        node.set('error',self.convertToStr(module_exec.db_error, 'str'))
+        node.set('machine_id',self.convertToStr(module_exec.db_machine_id, 'long'))
+        
+        # set elements
+        annotations = module_exec.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        loop_execs = module_exec.db_loop_execs
+        for loop_exec in loop_execs:
+            if (loop_execs is not None) and (loop_execs != ""):
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(loop_exec, childNode)
+        
+        return node
+
+class DBProvAssociationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:wasAssociatedWith':
+            return None
+        
+        prov_activity = None
+        prov_agent = None
+        prov_plan = None
+        prov_role = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:activity':
+                _data = self.getDao('ref_prov_activity').fromXML(child)
+                prov_activity = _data
+            elif child_tag == 'prov:agent':
+                _data = self.getDao('ref_prov_agent').fromXML(child)
+                prov_agent = _data
+            elif child_tag == 'prov:plan':
+                _data = self.getDao('ref_prov_plan').fromXML(child)
+                prov_plan = _data
+            elif child_tag == 'prov:role':
+                _data = self.convertFromStr(child.text,'str')
+                prov_role = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvAssociation(prov_activity=prov_activity,
+                                prov_agent=prov_agent,
+                                prov_plan=prov_plan,
+                                prov_role=prov_role)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_association, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:wasAssociatedWith')
+        
+        # set elements
+        prov_activity = prov_association.db_prov_activity
+        if prov_activity is not None:
+            if (prov_activity is not None) and (prov_activity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
+        prov_agent = prov_association.db_prov_agent
+        if prov_agent is not None:
+            if (prov_agent is not None) and (prov_agent != ""):
+                childNode = ElementTree.SubElement(node, 'prov:agent')
+                self.getDao('ref_prov_agent').toXML(prov_agent, childNode)
+        prov_plan = prov_association.db_prov_plan
+        if prov_plan is not None:
+            if (prov_plan is not None) and (prov_plan != ""):
+                childNode = ElementTree.SubElement(node, 'prov:plan')
+                self.getDao('ref_prov_plan').toXML(prov_plan, childNode)
+        prov_role = prov_association.db_prov_role
+        if (prov_role is not None) and (prov_role != ""):
+            childNode = ElementTree.SubElement(node, 'prov:role')
+            childNode.text = self.convertToStr(prov_role, 'str')
+        
+        return node
+
+class DBOpmProcessValueXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'value':
+            return None
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                value = _data
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                value = _data
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmProcessValue(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process_value, node=None):
+        if node is None:
+            node = ElementTree.Element('value')
         
         # set elements
-        annotations = module_exec.db_annotations
-        for annotation in annotations:
-            if (annotations is not None) and (annotations != ""):
-                childNode = ElementTree.SubElement(node, 'annotation')
-                self.getDao('annotation').toXML(annotation, childNode)
-        loop_execs = module_exec.db_loop_execs
-        for loop_exec in loop_execs:
-            if (loop_execs is not None) and (loop_execs != ""):
+        value = opm_process_value.db_value
+        if value is not None:
+            if value.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(value, childNode)
+            elif value.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(value, childNode)
+            elif value.vtType == 'loop_exec':
                 childNode = ElementTree.SubElement(node, 'loopExec')
-                self.getDao('loop_exec').toXML(loop_exec, childNode)
+                self.getDao('loop_exec').toXML(value, childNode)
         
         return node
 
@@ -5666,161 +6163,181 @@ class XMLDAOListBase(dict):
         if daos is not None:
             dict.update(self, daos)
 
-        if 'opm_process_id_effect' not in self:
-            self['opm_process_id_effect'] = DBOpmProcessIdEffectXMLDAOBase(self)
-        if 'vistrailVariable' not in self:
-            self['vistrailVariable'] = DBVistrailVariableXMLDAOBase(self)
-        if 'prov_agent' not in self:
-            self['prov_agent'] = DBProvAgentXMLDAOBase(self)
         if 'opm_was_generated_by' not in self:
             self['opm_was_generated_by'] = DBOpmWasGeneratedByXMLDAOBase(self)
-        if 'opm_accounts' not in self:
-            self['opm_accounts'] = DBOpmAccountsXMLDAOBase(self)
-        if 'ref_prov_agent' not in self:
-            self['ref_prov_agent'] = DBRefProvAgentXMLDAOBase(self)
-        if 'portSpec' not in self:
-            self['portSpec'] = DBPortSpecXMLDAOBase(self)
-        if 'module' not in self:
-            self['module'] = DBModuleXMLDAOBase(self)
-        if 'module_descriptor' not in self:
-            self['module_descriptor'] = DBModuleDescriptorXMLDAOBase(self)
-        if 'tag' not in self:
-            self['tag'] = DBTagXMLDAOBase(self)
-        if 'opm_role' not in self:
-            self['opm_role'] = DBOpmRoleXMLDAOBase(self)
-        if 'prov_document' not in self:
-            self['prov_document'] = DBProvDocumentXMLDAOBase(self)
+        if 'config_key' not in self:
+            self['config_key'] = DBConfigKeyXMLDAOBase(self)
+        if 'mashup_alias' not in self:
+            self['mashup_alias'] = DBMashupAliasXMLDAOBase(self)
+        if 'group' not in self:
+            self['group'] = DBGroupXMLDAOBase(self)
+        if 'opm_was_controlled_by' not in self:
+            self['opm_was_controlled_by'] = DBOpmWasControlledByXMLDAOBase(self)
+        if 'add' not in self:
+            self['add'] = DBAddXMLDAOBase(self)
+        if 'prov_generation' not in self:
+            self['prov_generation'] = DBProvGenerationXMLDAOBase(self)
+        if 'opm_used' not in self:
+            self['opm_used'] = DBOpmUsedXMLDAOBase(self)
+        if 'opm_artifact_id_cause' not in self:
+            self['opm_artifact_id_cause'] = DBOpmArtifactIdCauseXMLDAOBase(self)
+        if 'ref_prov_entity' not in self:
+            self['ref_prov_entity'] = DBRefProvEntityXMLDAOBase(self)
+        if 'vt_connection' not in self:
+            self['vt_connection'] = DBVtConnectionXMLDAOBase(self)
         if 'opm_account' not in self:
             self['opm_account'] = DBOpmAccountXMLDAOBase(self)
-        if 'opm_processes' not in self:
-            self['opm_processes'] = DBOpmProcessesXMLDAOBase(self)
-        if 'ref_prov_activity' not in self:
-            self['ref_prov_activity'] = DBRefProvActivityXMLDAOBase(self)
-        if 'opm_account_id' not in self:
-            self['opm_account_id'] = DBOpmAccountIdXMLDAOBase(self)
+        if 'group_exec' not in self:
+            self['group_exec'] = DBGroupExecXMLDAOBase(self)
+        if 'opm_agent_id' not in self:
+            self['opm_agent_id'] = DBOpmAgentIdXMLDAOBase(self)
+        if 'parameter' not in self:
+            self['parameter'] = DBParameterXMLDAOBase(self)
+        if 'vistrail' not in self:
+            self['vistrail'] = DBVistrailXMLDAOBase(self)
+        if 'opm_artifact_value' not in self:
+            self['opm_artifact_value'] = DBOpmArtifactValueXMLDAOBase(self)
+        if 'config_str' not in self:
+            self['config_str'] = DBConfigStrXMLDAOBase(self)
+        if 'startup' not in self:
+            self['startup'] = DBStartupXMLDAOBase(self)
+        if 'module' not in self:
+            self['module'] = DBModuleXMLDAOBase(self)
         if 'port' not in self:
             self['port'] = DBPortXMLDAOBase(self)
+        if 'opm_agents' not in self:
+            self['opm_agents'] = DBOpmAgentsXMLDAOBase(self)
+        if 'opm_dependencies' not in self:
+            self['opm_dependencies'] = DBOpmDependenciesXMLDAOBase(self)
+        if 'pe_function' not in self:
+            self['pe_function'] = DBPEFunctionXMLDAOBase(self)
+        if 'workflow' not in self:
+            self['workflow'] = DBWorkflowXMLDAOBase(self)
+        if 'mashup_action' not in self:
+            self['mashup_action'] = DBMashupActionXMLDAOBase(self)
+        if 'configuration' not in self:
+            self['configuration'] = DBConfigurationXMLDAOBase(self)
+        if 'change' not in self:
+            self['change'] = DBChangeXMLDAOBase(self)
+        if 'package' not in self:
+            self['package'] = DBPackageXMLDAOBase(self)
+        if 'loop_exec' not in self:
+            self['loop_exec'] = DBLoopExecXMLDAOBase(self)
+        if 'connection' not in self:
+            self['connection'] = DBConnectionXMLDAOBase(self)
+        if 'config_bool' not in self:
+            self['config_bool'] = DBConfigBoolXMLDAOBase(self)
+        if 'action' not in self:
+            self['action'] = DBActionXMLDAOBase(self)
+        if 'startup_package' not in self:
+            self['startup_package'] = DBStartupPackageXMLDAOBase(self)
+        if 'config_int' not in self:
+            self['config_int'] = DBConfigIntXMLDAOBase(self)
+        if 'opm_process_id_effect' not in self:
+            self['opm_process_id_effect'] = DBOpmProcessIdEffectXMLDAOBase(self)
         if 'ref_prov_plan' not in self:
             self['ref_prov_plan'] = DBRefProvPlanXMLDAOBase(self)
+        if 'opm_accounts' not in self:
+            self['opm_accounts'] = DBOpmAccountsXMLDAOBase(self)
+        if 'ref_prov_agent' not in self:
+            self['ref_prov_agent'] = DBRefProvAgentXMLDAOBase(self)
+        if 'portSpec' not in self:
+            self['portSpec'] = DBPortSpecXMLDAOBase(self)
+        if 'enabled_packages' not in self:
+            self['enabled_packages'] = DBEnabledPackagesXMLDAOBase(self)
         if 'opm_artifact' not in self:
             self['opm_artifact'] = DBOpmArtifactXMLDAOBase(self)
-        if 'group' not in self:
-            self['group'] = DBGroupXMLDAOBase(self)
         if 'log' not in self:
             self['log'] = DBLogXMLDAOBase(self)
-        if 'mashup_alias' not in self:
-            self['mashup_alias'] = DBMashupAliasXMLDAOBase(self)
-        if 'opm_agents' not in self:
-            self['opm_agents'] = DBOpmAgentsXMLDAOBase(self)
-        if 'mashup' not in self:
-            self['mashup'] = DBMashupXMLDAOBase(self)
         if 'opm_process_id_cause' not in self:
             self['opm_process_id_cause'] = DBOpmProcessIdCauseXMLDAOBase(self)
-        if 'prov_generation' not in self:
-            self['prov_generation'] = DBProvGenerationXMLDAOBase(self)
-        if 'portSpecItem' not in self:
-            self['portSpecItem'] = DBPortSpecItemXMLDAOBase(self)
-        if 'machine' not in self:
-            self['machine'] = DBMachineXMLDAOBase(self)
-        if 'add' not in self:
-            self['add'] = DBAddXMLDAOBase(self)
-        if 'other' not in self:
-            self['other'] = DBOtherXMLDAOBase(self)
-        if 'location' not in self:
-            self['location'] = DBLocationXMLDAOBase(self)
-        if 'opm_overlaps' not in self:
-            self['opm_overlaps'] = DBOpmOverlapsXMLDAOBase(self)
+        if 'opm_artifacts' not in self:
+            self['opm_artifacts'] = DBOpmArtifactsXMLDAOBase(self)
         if 'pe_parameter' not in self:
             self['pe_parameter'] = DBPEParameterXMLDAOBase(self)
-        if 'opm_dependencies' not in self:
-            self['opm_dependencies'] = DBOpmDependenciesXMLDAOBase(self)
-        if 'parameter' not in self:
-            self['parameter'] = DBParameterXMLDAOBase(self)
-        if 'opm_used' not in self:
-            self['opm_used'] = DBOpmUsedXMLDAOBase(self)
-        if 'plugin_data' not in self:
-            self['plugin_data'] = DBPluginDataXMLDAOBase(self)
+        if 'workflow_exec' not in self:
+            self['workflow_exec'] = DBWorkflowExecXMLDAOBase(self)
+        if 'location' not in self:
+            self['location'] = DBLocationXMLDAOBase(self)
         if 'function' not in self:
             self['function'] = DBFunctionXMLDAOBase(self)
         if 'actionAnnotation' not in self:
             self['actionAnnotation'] = DBActionAnnotationXMLDAOBase(self)
-        if 'abstraction' not in self:
-            self['abstraction'] = DBAbstractionXMLDAOBase(self)
-        if 'workflow' not in self:
-            self['workflow'] = DBWorkflowXMLDAOBase(self)
-        if 'opm_artifact_id_cause' not in self:
-            self['opm_artifact_id_cause'] = DBOpmArtifactIdCauseXMLDAOBase(self)
-        if 'ref_prov_entity' not in self:
-            self['ref_prov_entity'] = DBRefProvEntityXMLDAOBase(self)
         if 'prov_activity' not in self:
             self['prov_activity'] = DBProvActivityXMLDAOBase(self)
-        if 'mashup_action' not in self:
-            self['mashup_action'] = DBMashupActionXMLDAOBase(self)
         if 'prov_usage' not in self:
             self['prov_usage'] = DBProvUsageXMLDAOBase(self)
-        if 'opm_artifact_value' not in self:
-            self['opm_artifact_value'] = DBOpmArtifactValueXMLDAOBase(self)
         if 'opm_artifact_id_effect' not in self:
             self['opm_artifact_id_effect'] = DBOpmArtifactIdEffectXMLDAOBase(self)
         if 'opm_graph' not in self:
             self['opm_graph'] = DBOpmGraphXMLDAOBase(self)
+        if 'is_part_of' not in self:
+            self['is_part_of'] = DBIsPartOfXMLDAOBase(self)
+        if 'opm_was_derived_from' not in self:
+            self['opm_was_derived_from'] = DBOpmWasDerivedFromXMLDAOBase(self)
+        if 'plugin_data' not in self:
+            self['plugin_data'] = DBPluginDataXMLDAOBase(self)
+        if 'delete' not in self:
+            self['delete'] = DBDeleteXMLDAOBase(self)
+        if 'vistrailVariable' not in self:
+            self['vistrailVariable'] = DBVistrailVariableXMLDAOBase(self)
+        if 'opm_overlaps' not in self:
+            self['opm_overlaps'] = DBOpmOverlapsXMLDAOBase(self)
+        if 'opm_was_triggered_by' not in self:
+            self['opm_was_triggered_by'] = DBOpmWasTriggeredByXMLDAOBase(self)
+        if 'module_descriptor' not in self:
+            self['module_descriptor'] = DBModuleDescriptorXMLDAOBase(self)
+        if 'tag' not in self:
+            self['tag'] = DBTagXMLDAOBase(self)
+        if 'opm_role' not in self:
+            self['opm_role'] = DBOpmRoleXMLDAOBase(self)
+        if 'prov_document' not in self:
+            self['prov_document'] = DBProvDocumentXMLDAOBase(self)
+        if 'opm_processes' not in self:
+            self['opm_processes'] = DBOpmProcessesXMLDAOBase(self)
+        if 'opm_account_id' not in self:
+            self['opm_account_id'] = DBOpmAccountIdXMLDAOBase(self)
+        if 'portSpecItem' not in self:
+            self['portSpecItem'] = DBPortSpecItemXMLDAOBase(self)
+        if 'mashup_component' not in self:
+            self['mashup_component'] = DBMashupComponentXMLDAOBase(self)
+        if 'mashup' not in self:
+            self['mashup'] = DBMashupXMLDAOBase(self)
+        if 'machine' not in self:
+            self['machine'] = DBMachineXMLDAOBase(self)
+        if 'config_float' not in self:
+            self['config_float'] = DBConfigFloatXMLDAOBase(self)
+        if 'other' not in self:
+            self['other'] = DBOtherXMLDAOBase(self)
+        if 'ref_prov_activity' not in self:
+            self['ref_prov_activity'] = DBRefProvActivityXMLDAOBase(self)
+        if 'abstraction' not in self:
+            self['abstraction'] = DBAbstractionXMLDAOBase(self)
+        if 'prov_agent' not in self:
+            self['prov_agent'] = DBProvAgentXMLDAOBase(self)
         if 'mashuptrail' not in self:
             self['mashuptrail'] = DBMashuptrailXMLDAOBase(self)
         if 'registry' not in self:
             self['registry'] = DBRegistryXMLDAOBase(self)
-        if 'vt_connection' not in self:
-            self['vt_connection'] = DBVtConnectionXMLDAOBase(self)
-        if 'mashup_component' not in self:
-            self['mashup_component'] = DBMashupComponentXMLDAOBase(self)
+        if 'opm_agent' not in self:
+            self['opm_agent'] = DBOpmAgentXMLDAOBase(self)
         if 'prov_entity' not in self:
             self['prov_entity'] = DBProvEntityXMLDAOBase(self)
         if 'annotation' not in self:
             self['annotation'] = DBAnnotationXMLDAOBase(self)
-        if 'change' not in self:
-            self['change'] = DBChangeXMLDAOBase(self)
-        if 'opm_was_derived_from' not in self:
-            self['opm_was_derived_from'] = DBOpmWasDerivedFromXMLDAOBase(self)
-        if 'opm_artifacts' not in self:
-            self['opm_artifacts'] = DBOpmArtifactsXMLDAOBase(self)
-        if 'opm_was_controlled_by' not in self:
-            self['opm_was_controlled_by'] = DBOpmWasControlledByXMLDAOBase(self)
-        if 'opm_agent_id' not in self:
-            self['opm_agent_id'] = DBOpmAgentIdXMLDAOBase(self)
-        if 'group_exec' not in self:
-            self['group_exec'] = DBGroupExecXMLDAOBase(self)
         if 'opm_time' not in self:
             self['opm_time'] = DBOpmTimeXMLDAOBase(self)
-        if 'package' not in self:
-            self['package'] = DBPackageXMLDAOBase(self)
-        if 'workflow_exec' not in self:
-            self['workflow_exec'] = DBWorkflowExecXMLDAOBase(self)
         if 'parameter_exploration' not in self:
             self['parameter_exploration'] = DBParameterExplorationXMLDAOBase(self)
-        if 'loop_exec' not in self:
-            self['loop_exec'] = DBLoopExecXMLDAOBase(self)
-        if 'opm_was_triggered_by' not in self:
-            self['opm_was_triggered_by'] = DBOpmWasTriggeredByXMLDAOBase(self)
         if 'mashup_actionAnnotation' not in self:
             self['mashup_actionAnnotation'] = DBMashupActionAnnotationXMLDAOBase(self)
-        if 'connection' not in self:
-            self['connection'] = DBConnectionXMLDAOBase(self)
         if 'opm_process' not in self:
             self['opm_process'] = DBOpmProcessXMLDAOBase(self)
-        if 'is_part_of' not in self:
-            self['is_part_of'] = DBIsPartOfXMLDAOBase(self)
-        if 'pe_function' not in self:
-            self['pe_function'] = DBPEFunctionXMLDAOBase(self)
-        if 'opm_process_value' not in self:
-            self['opm_process_value'] = DBOpmProcessValueXMLDAOBase(self)
-        if 'action' not in self:
-            self['action'] = DBActionXMLDAOBase(self)
-        if 'opm_agent' not in self:
-            self['opm_agent'] = DBOpmAgentXMLDAOBase(self)
-        if 'delete' not in self:
-            self['delete'] = DBDeleteXMLDAOBase(self)
-        if 'prov_association' not in self:
-            self['prov_association'] = DBProvAssociationXMLDAOBase(self)
-        if 'vistrail' not in self:
-            self['vistrail'] = DBVistrailXMLDAOBase(self)
+        if 'disabled_packages' not in self:
+            self['disabled_packages'] = DBDisabledPackagesXMLDAOBase(self)
         if 'module_exec' not in self:
             self['module_exec'] = DBModuleExecXMLDAOBase(self)
+        if 'prov_association' not in self:
+            self['prov_association'] = DBProvAssociationXMLDAOBase(self)
+        if 'opm_process_value' not in self:
+            self['opm_process_value'] = DBOpmProcessValueXMLDAOBase(self)
diff --git a/vistrails/db/versions/v1_0_3/persistence/xml/xml_dao.py b/vistrails/db/versions/v1_0_3/persistence/xml/xml_dao.py
index dea8449..dc29f8f 100644
--- a/vistrails/db/versions/v1_0_3/persistence/xml/xml_dao.py
+++ b/vistrails/db/versions/v1_0_3/persistence/xml/xml_dao.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from datetime import date, datetime
-from time import strptime
+
+from vistrails.core.system import strftime, time_strptime
 
 class XMLDAO:
     def __init__(self):
@@ -73,9 +77,9 @@ class XMLDAO:
                         else:
                             return 0
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     def convertToStr(self, value, type):
@@ -83,7 +87,7 @@ class XMLDAO:
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
diff --git a/vistrails/db/versions/v1_0_3/schemas/sql/vistrails.sql b/vistrails/db/versions/v1_0_3/schemas/sql/vistrails.sql
index b3031dd..fc92198 100644
--- a/vistrails/db/versions/v1_0_3/schemas/sql/vistrails.sql
+++ b/vistrails/db/versions/v1_0_3/schemas/sql/vistrails.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
@@ -45,64 +46,87 @@ CREATE TABLE thumbnail(
 
 -- generated automatically by auto_dao.py
 
-CREATE TABLE vistrail_variable(
+CREATE TABLE mashup_alias(
+    id int,
     name varchar(255),
-    uuid char(36),
-    package varchar(255),
-    module varchar(255),
-    namespace varchar(255),
-    value varchar(8191),
     parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE port_spec(
+CREATE TABLE group_tbl(
     id int,
+    cache int,
     name varchar(255),
-    type varchar(255),
-    optional int,
-    sort_key int,
-    min_conns int,
-    max_conns int,
+    namespace varchar(255),
+    package varchar(511),
+    version varchar(255),
     parent_type char(32),
     entity_id int,
     entity_type char(16),
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE module(
+CREATE TABLE add_tbl(
     id int,
-    cache int,
-    name varchar(255),
-    namespace varchar(255),
-    package varchar(511),
-    version varchar(255),
+    what varchar(255),
+    object_id int,
+    par_obj_id int,
+    par_obj_type char(16),
+    action_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE group_exec(
+    id int,
+    ts_start datetime,
+    ts_end datetime,
+    cached int,
+    module_id int,
+    group_name varchar(255),
+    group_type varchar(255),
+    completed int,
+    error varchar(1023),
+    machine_id int,
     parent_type char(32),
     entity_id int,
     entity_type char(16),
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE module_descriptor(
+CREATE TABLE parameter(
     id int,
+    pos int,
     name varchar(255),
-    package varchar(255),
-    namespace varchar(255),
-    package_version varchar(255),
-    version varchar(255),
-    base_descriptor_id int,
-    parent_id int,
+    type varchar(255),
+    val mediumtext,
+    alias varchar(255),
+    parent_type char(32),
     entity_id int,
-    entity_type char(16)
+    entity_type char(16),
+    parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE tag(
+CREATE TABLE vistrail(
+    id int not null auto_increment primary key,
+    entity_type char(16),
+    version char(16),
+    name varchar(255),
+    last_modified datetime
+) engine=InnoDB;
+
+CREATE TABLE module(
     id int,
+    cache int,
     name varchar(255),
-    parent_id int,
+    namespace varchar(255),
+    package varchar(511),
+    version varchar(255),
+    parent_type char(32),
     entity_id int,
-    entity_type char(16)
+    entity_type char(16),
+    parent_id int
 ) engine=InnoDB;
 
 CREATE TABLE port(
@@ -118,107 +142,116 @@ CREATE TABLE port(
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE group_tbl(
+CREATE TABLE pe_function(
     id int,
-    cache int,
-    name varchar(255),
-    namespace varchar(255),
-    package varchar(511),
-    version varchar(255),
+    module_id int,
+    port_name varchar(255),
+    is_alias int,
     parent_type char(32),
+    parent_id int,
     entity_id int,
-    entity_type char(16),
-    parent_id int
+    entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE log_tbl(
+CREATE TABLE workflow(
     id int not null auto_increment primary key,
+    entity_id int,
     entity_type char(16),
-    version char(16),
     name varchar(255),
+    version char(16),
     last_modified datetime,
-    vistrail_id int
+    vistrail_id int,
+    parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE mashup_alias(
+CREATE TABLE mashup_action(
     id int,
-    name varchar(255),
+    prev_id int,
+    date datetime,
+    user varchar(255),
     parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE mashup(
+CREATE TABLE change_tbl(
     id int,
+    what varchar(255),
+    old_obj_id int,
+    new_obj_id int,
+    par_obj_id int,
+    par_obj_type char(16),
+    action_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE package(
+    id int not null auto_increment primary key,
     name varchar(255),
-    version int,
-    type varchar(255),
-    vtid int,
-    layout mediumtext,
-    geometry mediumtext,
-    has_seq int,
+    identifier varchar(1023),
+    codepath varchar(1023),
+    load_configuration int,
+    version varchar(255),
+    description varchar(1023),
     parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE port_spec_item(
+CREATE TABLE loop_exec(
     id int,
-    pos int,
-    module varchar(255),
-    package varchar(255),
-    namespace varchar(255),
-    label varchar(4095),
-    _default varchar(4095),
-    _values mediumtext,
-    entry_type varchar(255),
-    parent_id int,
+    ts_start datetime,
+    ts_end datetime,
+    iteration int,
+    completed int,
+    error varchar(1023),
+    parent_type char(32),
     entity_id int,
-    entity_type char(16)
+    entity_type char(16),
+    parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE machine(
+CREATE TABLE connection_tbl(
     id int,
-    name varchar(255),
-    os varchar(255),
-    architecture varchar(255),
-    processor varchar(255),
-    ram bigint,
-    vt_id int,
-    log_id int,
+    parent_type char(32),
     entity_id int,
-    entity_type char(16)
+    entity_type char(16),
+    parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE add_tbl(
+CREATE TABLE action(
     id int,
-    what varchar(255),
-    object_id int,
-    par_obj_id int,
-    par_obj_type char(16),
-    action_id int,
+    prev_id int,
+    date datetime,
+    session int,
+    user varchar(255),
+    parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE other(
+CREATE TABLE port_spec(
     id int,
-    okey varchar(255),
-    value varchar(255),
+    name varchar(255),
+    type varchar(255),
+    optional int,
+    sort_key int,
+    min_conns int,
+    max_conns int,
     parent_type char(32),
     entity_id int,
     entity_type char(16),
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE location(
-    id int,
-    x DECIMAL(18,12),
-    y DECIMAL(18,12),
-    parent_type char(32),
-    entity_id int,
+CREATE TABLE log_tbl(
+    id int not null auto_increment primary key,
     entity_type char(16),
-    parent_id int
+    version char(16),
+    name varchar(255),
+    last_modified datetime,
+    vistrail_id int
 ) engine=InnoDB;
 
 CREATE TABLE pe_parameter(
@@ -233,22 +266,28 @@ CREATE TABLE pe_parameter(
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE parameter(
+CREATE TABLE workflow_exec(
     id int,
-    pos int,
+    user varchar(255),
+    ip varchar(255),
+    session int,
+    vt_version varchar(255),
+    ts_start datetime,
+    ts_end datetime,
+    parent_id int,
+    parent_type varchar(255),
+    parent_version int,
+    completed int,
     name varchar(255),
-    type varchar(255),
-    val mediumtext,
-    alias varchar(255),
-    parent_type char(32),
+    log_id int,
     entity_id int,
-    entity_type char(16),
-    parent_id int
+    entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE plugin_data(
+CREATE TABLE location(
     id int,
-    data varchar(8191),
+    x DECIMAL(18,12),
+    y DECIMAL(18,12),
     parent_type char(32),
     entity_id int,
     entity_type char(16),
@@ -277,57 +316,72 @@ CREATE TABLE action_annotation(
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE abstraction(
+CREATE TABLE plugin_data(
     id int,
-    cache int,
-    name varchar(255),
-    namespace varchar(255),
-    package varchar(511),
-    version varchar(255),
-    internal_version varchar(255),
+    data varchar(8191),
     parent_type char(32),
     entity_id int,
     entity_type char(16),
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE workflow(
-    id int not null auto_increment primary key,
+CREATE TABLE delete_tbl(
+    id int,
+    what varchar(255),
+    object_id int,
+    par_obj_id int,
+    par_obj_type char(16),
+    action_id int,
     entity_id int,
-    entity_type char(16),
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE vistrail_variable(
     name varchar(255),
-    version char(16),
-    last_modified datetime,
-    vistrail_id int,
-    parent_id int
+    uuid char(36),
+    package varchar(255),
+    module varchar(255),
+    namespace varchar(255),
+    value varchar(8191),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE mashup_action(
+CREATE TABLE module_descriptor(
     id int,
-    prev_id int,
-    date datetime,
-    user varchar(255),
+    name varchar(255),
+    package varchar(255),
+    namespace varchar(255),
+    package_version varchar(255),
+    version varchar(255),
+    base_descriptor_id int,
     parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE mashuptrail(
-    id int not null auto_increment primary key,
-    name char(36),
-    version char(16),
-    vt_version int,
-    last_modified datetime,
+CREATE TABLE tag(
+    id int,
+    name varchar(255),
+    parent_id int,
+    entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE registry(
-    id int not null auto_increment primary key,
-    entity_type char(16),
-    version char(16),
-    root_descriptor_id int,
-    name varchar(255),
-    last_modified datetime
+CREATE TABLE port_spec_item(
+    id int,
+    pos int,
+    module varchar(255),
+    package varchar(255),
+    namespace varchar(255),
+    label varchar(4095),
+    _default varchar(4095),
+    _values mediumtext,
+    entry_type varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
 ) engine=InnoDB;
 
 CREATE TABLE mashup_component(
@@ -353,163 +407,110 @@ CREATE TABLE mashup_component(
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE annotation(
+CREATE TABLE mashup(
     id int,
-    akey varchar(255),
-    value mediumtext,
-    parent_type char(32),
+    name varchar(255),
+    version int,
+    type varchar(255),
+    vtid int,
+    layout mediumtext,
+    geometry mediumtext,
+    has_seq int,
+    parent_id int,
     entity_id int,
-    entity_type char(16),
-    parent_id int
+    entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE change_tbl(
+CREATE TABLE machine(
     id int,
-    what varchar(255),
-    old_obj_id int,
-    new_obj_id int,
-    par_obj_id int,
-    par_obj_type char(16),
-    action_id int,
+    name varchar(255),
+    os varchar(255),
+    architecture varchar(255),
+    processor varchar(255),
+    ram bigint,
+    vt_id int,
+    log_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE group_exec(
+CREATE TABLE other(
     id int,
-    ts_start datetime,
-    ts_end datetime,
-    cached int,
-    module_id int,
-    group_name varchar(255),
-    group_type varchar(255),
-    completed int,
-    error varchar(1023),
-    machine_id int,
+    okey varchar(255),
+    value varchar(255),
     parent_type char(32),
     entity_id int,
     entity_type char(16),
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE package(
-    id int not null auto_increment primary key,
+CREATE TABLE abstraction(
+    id int,
+    cache int,
     name varchar(255),
-    identifier varchar(1023),
-    codepath varchar(1023),
-    load_configuration int,
+    namespace varchar(255),
+    package varchar(511),
     version varchar(255),
-    description varchar(1023),
-    parent_id int,
+    internal_version varchar(255),
+    parent_type char(32),
     entity_id int,
-    entity_type char(16)
+    entity_type char(16),
+    parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE workflow_exec(
-    id int,
-    user varchar(255),
-    ip varchar(255),
-    session int,
-    vt_version varchar(255),
-    ts_start datetime,
-    ts_end datetime,
-    parent_id int,
-    parent_type varchar(255),
-    parent_version int,
-    completed int,
-    name varchar(255),
-    log_id int,
-    entity_id int,
+CREATE TABLE mashuptrail(
+    id int not null auto_increment primary key,
+    name char(36),
+    version char(16),
+    vt_version int,
+    last_modified datetime,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE parameter_exploration(
-    id int,
-    action_id int,
+CREATE TABLE registry(
+    id int not null auto_increment primary key,
+    entity_type char(16),
+    version char(16),
+    root_descriptor_id int,
     name varchar(255),
-    date datetime,
-    user varchar(255),
-    dims varchar(255),
-    layout varchar(255),
-    parent_id int,
-    entity_id int,
-    entity_type char(16)
+    last_modified datetime
 ) engine=InnoDB;
 
-CREATE TABLE loop_exec(
+CREATE TABLE annotation(
     id int,
-    ts_start datetime,
-    ts_end datetime,
-    iteration int,
-    completed int,
-    error varchar(1023),
+    akey varchar(255),
+    value mediumtext,
     parent_type char(32),
     entity_id int,
     entity_type char(16),
     parent_id int
 ) engine=InnoDB;
 
-CREATE TABLE mashup_action_annotation(
+CREATE TABLE parameter_exploration(
     id int,
-    akey varchar(255),
-    value varchar(8191),
     action_id int,
+    name varchar(255),
     date datetime,
     user varchar(255),
+    dims varchar(255),
+    layout varchar(255),
     parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE connection_tbl(
-    id int,
-    parent_type char(32),
-    entity_id int,
-    entity_type char(16),
-    parent_id int
-) engine=InnoDB;
-
-CREATE TABLE pe_function(
-    id int,
-    module_id int,
-    port_name varchar(255),
-    is_alias int,
-    parent_type char(32),
-    parent_id int,
-    entity_id int,
-    entity_type char(16)
-) engine=InnoDB;
-
-CREATE TABLE action(
+CREATE TABLE mashup_action_annotation(
     id int,
-    prev_id int,
+    akey varchar(255),
+    value varchar(8191),
+    action_id int,
     date datetime,
-    session int,
     user varchar(255),
     parent_id int,
     entity_id int,
     entity_type char(16)
 ) engine=InnoDB;
 
-CREATE TABLE delete_tbl(
-    id int,
-    what varchar(255),
-    object_id int,
-    par_obj_id int,
-    par_obj_type char(16),
-    action_id int,
-    entity_id int,
-    entity_type char(16)
-) engine=InnoDB;
-
-CREATE TABLE vistrail(
-    id int not null auto_increment primary key,
-    entity_type char(16),
-    version char(16),
-    name varchar(255),
-    last_modified datetime
-) engine=InnoDB;
-
 CREATE TABLE module_exec(
     id int,
     ts_start datetime,
diff --git a/vistrails/db/versions/v1_0_3/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v1_0_3/schemas/sql/vistrails_drop.sql
index 5fc87bb..a5333d4 100644
--- a/vistrails/db/versions/v1_0_3/schemas/sql/vistrails_drop.sql
+++ b/vistrails/db/versions/v1_0_3/schemas/sql/vistrails_drop.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
@@ -39,4 +40,4 @@ DROP TABLE IF EXISTS thumbnail;
 
 -- genereated automatically by generate.py
 
-DROP TABLE IF EXISTS vistrail_variable, port_spec, module, module_descriptor, tag, port, group_tbl, log_tbl, mashup_alias, mashup, port_spec_item, machine, add_tbl, other, location, pe_parameter, parameter, plugin_data, function, action_annotation, abstraction, workflow, mashup_action, mashuptrail, registry, mashup_component, annotation, change_tbl, group_exec, package, workflow_exec, parameter_exploration, loop_exec, mashup_action_annotation, connection_tbl, pe_function, action, delete_ [...]
+DROP TABLE IF EXISTS mashup_alias, group_tbl, add_tbl, group_exec, parameter, vistrail, module, port, pe_function, workflow, mashup_action, change_tbl, package, loop_exec, connection_tbl, action, port_spec, log_tbl, pe_parameter, workflow_exec, location, function, action_annotation, plugin_data, delete_tbl, vistrail_variable, module_descriptor, tag, port_spec_item, mashup_component, mashup, machine, other, abstraction, mashuptrail, registry, annotation, parameter_exploration, mashup_acti [...]
diff --git a/vistrails/db/versions/v1_0_3/schemas/xml/log.xsd b/vistrails/db/versions/v1_0_3/schemas/xml/log.xsd
index effdfa5..d3739f7 100644
--- a/vistrails/db/versions/v1_0_3/schemas/xml/log.xsd
+++ b/vistrails/db/versions/v1_0_3/schemas/xml/log.xsd
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_3/schemas/xml/vistrail.xsd b/vistrails/db/versions/v1_0_3/schemas/xml/vistrail.xsd
index 06a88d4..b44f35e 100644
--- a/vistrails/db/versions/v1_0_3/schemas/xml/vistrail.xsd
+++ b/vistrails/db/versions/v1_0_3/schemas/xml/vistrail.xsd
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_3/schemas/xml/vtlink.xsd b/vistrails/db/versions/v1_0_3/schemas/xml/vtlink.xsd
index 011b59c..3453317 100644
--- a/vistrails/db/versions/v1_0_3/schemas/xml/vtlink.xsd
+++ b/vistrails/db/versions/v1_0_3/schemas/xml/vtlink.xsd
@@ -1,5 +1,6 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
 ## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
@@ -7,28 +8,28 @@
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_3/schemas/xml/workflow.xsd b/vistrails/db/versions/v1_0_3/schemas/xml/workflow.xsd
index 840847f..fe74e24 100644
--- a/vistrails/db/versions/v1_0_3/schemas/xml/workflow.xsd
+++ b/vistrails/db/versions/v1_0_3/schemas/xml/workflow.xsd
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/db/versions/v1_0_3/specs/all.xml b/vistrails/db/versions/v1_0_3/specs/all.xml
index 40df0ef..56deaba 100644
--- a/vistrails/db/versions/v1_0_3/specs/all.xml
+++ b/vistrails/db/versions/v1_0_3/specs/all.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -3821,4 +3822,186 @@
     </property>
   </object>
 
+  <!--++++++++++++++++++++++++++-->
+  <!-- STARTUP +++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="startup">
+    <layout>
+      <xml name="startup" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <property ref="true" object="configuration" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="enabled_packages" type="list" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>    
+
+    <property ref="true" object="disabled_packages" type="list" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>    
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ENABLED_PACKAGES ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="enabled_packages">
+    <layout>
+      <xml name="packages" nodeType="xs:element"/>
+    </layout>
+  
+    <property name="package" ref="true" object="startup_package" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- DISABLED_PACKAGES +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="disabled_packages">
+    <layout>
+      <xml name="disabledpackages" nodeType="xs:element"/>
+    </layout>
+  
+    <property name="package" ref="true" object="startup_package" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- STARTUP_PACKAGE +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="startup_package">
+    <layout>
+      <xml name="package" nodeType="xs:element"/>
+    </layout>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property ref="true" object="configuration" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element" name="configuration"/>
+    </property>    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIGURATION +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="configuration">
+    <layout>
+      <xml name="configuration" nodeType="xs:element"/>
+    </layout>
+
+    <property ref="true" object="config_key" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml name="key" nodeType="xs:element"/>
+    </property>    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_KEY ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_key">
+    <layout>
+      <xml name="key" nodeType="xs:element"/>
+    </layout>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <choice name="value" type="object" mapping="one-to-one">
+      <property ref="true" object="config_str">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_int">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_float">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_bool">
+	<xml nodeType="xs:element"/>
+      </property>
+      
+      <property ref="true" object="configuration">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_STR ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_str">
+    <layout>
+      <xml name="str" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_INT ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_int">
+    <layout>
+      <xml name="int" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_FLOAT ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_float">
+    <layout>
+      <xml name="float" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="float">
+      <xml nodeType="xs:attribute" type="xs:float"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_BOOL +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_bool">
+    <layout>
+      <xml name="bool" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
 </objects>
diff --git a/vistrails/db/versions/v1_0_3/translate/__init__.py b/vistrails/db/versions/v1_0_3/translate/__init__.py
index aee1abc..fe71b86 100644
--- a/vistrails/db/versions/v1_0_3/translate/__init__.py
+++ b/vistrails/db/versions/v1_0_3/translate/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 version = '1.0.3'
diff --git a/vistrails/db/versions/v1_0_3/translate/v1_0_2.py b/vistrails/db/versions/v1_0_3/translate/v1_0_2.py
index a16c5d1..948e8de 100644
--- a/vistrails/db/versions/v1_0_3/translate/v1_0_2.py
+++ b/vistrails/db/versions/v1_0_3/translate/v1_0_2.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.db.versions.v1_0_3.domain import DBVistrail, DBVistrailVariable, \
                                       DBWorkflow, DBLog, DBRegistry, \
                                       DBAdd, DBChange, DBDelete, \
@@ -43,10 +46,12 @@ from vistrails.db.versions.v1_0_3.domain import DBVistrail, DBVistrailVariable,
                                       DBActionAnnotation
 
 from vistrails.db.services.vistrail import materializeWorkflow
-from xml.dom.minidom import parseString
-from itertools import izip
 
+import os
+from itertools import izip
+from ast import literal_eval
 import unittest
+from xml.dom.minidom import parseString
 
 id_scope = None
 
@@ -58,7 +63,7 @@ def update_portSpec(old_obj, translate_dict):
         for sig in sigstring[1:-1].split(','):
             sigs.append(sig.split(':', 2))
     # not great to use eval...
-    defaults = eval(old_obj.db_defaults) if old_obj.db_defaults else []
+    defaults = literal_eval(old_obj.db_defaults) if old_obj.db_defaults else []
     if isinstance(defaults, basestring):
         defaults = (defaults,)
     else:
@@ -67,7 +72,7 @@ def update_portSpec(old_obj, translate_dict):
         except TypeError:
             defaults = (defaults,)
     # not great to use eval...
-    labels = eval(old_obj.db_labels) if old_obj.db_labels else []
+    labels = literal_eval(old_obj.db_labels) if old_obj.db_labels else []
     if isinstance(labels, basestring):
         labels = (labels,)
     else:
@@ -122,7 +127,7 @@ def createParameterExploration(action_id, xmlString, vistrail):
         striplen = len("<paramexps>")
         xmlString = xmlString[striplen:-(striplen+1)].strip()
         xmlDoc = parseString(xmlString).documentElement
-    except:
+    except Exception:
         return None
     # we need the pipeline to look up function/paramater id:s
     pipeline = materializeWorkflow(vistrail, action_id)
@@ -231,7 +236,7 @@ def translateVistrail(_vistrail):
         new_annotations = []
         for a in old_obj.db_annotations:
             if a.db_key == '__vistrail_vars__':
-                for name, data in dict(eval(a.db_value)).iteritems():
+                for name, data in dict(literal_eval(a.db_value)).iteritems():
                     uuid, identifier, value = data
                     package, module, namespace = identifier
                     var = DBVistrailVariable(name, uuid, package, module, 
@@ -315,7 +320,7 @@ class TestTranslate(unittest.TestCase):
         pes = vistrail.db_get_parameter_explorations()
         self.assertEqual(len(pes), 1)
         funs = pes[0].db_functions
-        self.assertEqual(set([f.db_port_name for f in funs]),
+        self.assertEqual(set(f.db_port_name for f in funs),
                          set(['SetCoefficients', 'SetBackgroundWidget']))
         parameters = funs[0].db_parameters
         self.assertEqual(len(parameters), 10)
@@ -333,10 +338,8 @@ class TestTranslate(unittest.TestCase):
         self.assertEqual(len(visvars), 2)
         self.assertNotEqual(visvars[0].db_name, visvars[1].db_name)
 
+
 if __name__ == '__main__':
-    from vistrails.gui.application import start_application
-    v = start_application({'interactiveMode': False,
-                           'nologger': True,
-                           'singleInstance': False,
-                           'fixedSpreadsheetCells': True})
+    import vistrails.core.application
+    vistrails.core.application.init()
     unittest.main()
diff --git a/vistrails/db/versions/v1_0_3/translate/v1_0_4.py b/vistrails/db/versions/v1_0_3/translate/v1_0_4.py
new file mode 100644
index 0000000..dfaeab2
--- /dev/null
+++ b/vistrails/db/versions/v1_0_3/translate/v1_0_4.py
@@ -0,0 +1,106 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from vistrails.db.versions.v1_0_3.domain import DBVistrail, DBAnnotation, \
+                                      DBWorkflow, DBLog, DBRegistry, \
+                                      DBPortSpec, DBAdd, DBChange, DBDelete
+from vistrails.core import debug
+from vistrails.core.system import get_elementtree_library
+ElementTree = get_elementtree_library()
+
+id_scope = None
+
+def translateVistrail(_vistrail):
+    """ Translate new DBVistrailVariable based vistrail variables to old
+         annotation based type """
+    global id_scope
+    
+    def update_workflow(old_obj, trans_dict):
+        return DBWorkflow.update_version(old_obj.db_workflow, 
+                                         trans_dict, DBWorkflow())
+
+    def update_operations(old_obj, trans_dict):
+        new_ops = []
+        for obj in old_obj.db_operations:
+            if obj.vtType == 'delete':
+                new_ops.append(DBDelete.update_version(obj, trans_dict))
+            elif obj.vtType == 'add':
+                new_op = DBAdd.update_version(obj, trans_dict)
+                new_ops.append(new_op)
+            elif obj.vtType == 'change':
+                new_op = DBChange.update_version(obj, trans_dict)
+                new_ops.append(new_op)
+        return new_ops
+
+    vistrail = DBVistrail()
+    id_scope = vistrail.idScope
+
+    translate_dict = {'DBAction': {'operations': update_operations},
+                      'DBGroup': {'workflow': update_workflow}
+                      }
+
+    if _vistrail.db_controlParameters:
+        debug.warning(("Vistrail contains %s control parameters that "
+                      "cannot be converted") % len(_vistrail.db_controlParameters))
+    vistrail = DBVistrail.update_version(_vistrail, translate_dict, vistrail)
+
+    vistrail.db_version = '1.0.3'
+    return vistrail
+
+def translateWorkflow(_workflow):
+    def update_workflow(old_obj, translate_dict):
+        return DBWorkflow.update_version(old_obj.db_workflow, translate_dict)
+    translate_dict = {'DBGroup': {'workflow': update_workflow}}
+    workflow = DBWorkflow.update_version(_workflow, translate_dict)
+
+    workflow.db_version = '1.0.3'
+    return workflow
+
+def translateLog(_log):
+    translate_dict = {}
+    log = DBLog.update_version(_log, translate_dict)
+    log.db_version = '1.0.3'
+    return log
+
+def translateRegistry(_registry):
+    global id_scope
+    translate_dict = {}
+    registry = DBRegistry()
+    id_scope = registry.idScope
+    vistrail = DBRegistry.update_version(_registry, translate_dict, registry)
+    registry.db_version = '1.0.3'
+    return registry
diff --git a/vistrails/db/versions/v1_0_4/__init__.py b/vistrails/db/versions/v1_0_4/__init__.py
new file mode 100644
index 0000000..c59e2e5
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/__init__.py
@@ -0,0 +1,39 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+version = '1.0.4'
diff --git a/vistrails/db/versions/v1_0_4/domain/__init__.py b/vistrails/db/versions/v1_0_4/domain/__init__.py
new file mode 100644
index 0000000..40b3fbf
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/__init__.py
@@ -0,0 +1,44 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from auto_gen import *
+from registry import DBRegistry
+from workflow import DBWorkflow
+from vistrail import DBVistrail
+from log import DBLog
+from id_scope import IdScope
diff --git a/vistrails/db/versions/v1_0_4/domain/auto_gen.py b/vistrails/db/versions/v1_0_4/domain/auto_gen.py
new file mode 100644
index 0000000..21eceac
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/auto_gen.py
@@ -0,0 +1,18687 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""generated automatically by auto_dao.py"""
+
+from __future__ import division
+
+import copy
+
+class DBOpmWasGeneratedBy(object):
+
+    vtType = 'opm_was_generated_by'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmWasGeneratedBy.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmWasGeneratedBy()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmWasGeneratedBy()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmArtifactIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmArtifactIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmProcessIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmProcessIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
+        self.is_dirty = True
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
+        self.is_dirty = True
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
+    
+
+
+class DBConfigKey(object):
+
+    vtType = 'config_key'
+
+    def __init__(self, value=None, name=None):
+        self.db_deleted_value = []
+        self._db_value = value
+        self._db_name = name
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfigKey.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigKey(name=self._db_name)
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigKey()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            if obj.vtType == 'config_str':
+                new_obj.db_add_value(DBConfigStr.update_version(obj, trans_dict))
+            elif obj.vtType == 'config_int':
+                new_obj.db_add_value(DBConfigInt.update_version(obj, trans_dict))
+            elif obj.vtType == 'config_float':
+                new_obj.db_add_value(DBConfigFloat.update_version(obj, trans_dict))
+            elif obj.vtType == 'config_bool':
+                new_obj.db_add_value(DBConfigBool.update_version(obj, trans_dict))
+            elif obj.vtType == 'configuration':
+                new_obj.db_add_value(DBConfiguration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                if obj.vtType == 'config_str':
+                    n_obj = DBConfigStr.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'config_int':
+                    n_obj = DBConfigInt.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'config_float':
+                    n_obj = DBConfigFloat.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'config_bool':
+                    n_obj = DBConfigBool.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'configuration':
+                    n_obj = DBConfiguration.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_value)
+        if remove:
+            self.db_deleted_value = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def getPrimaryKey(self):
+        return self._db_name
+
+class DBMashupAlias(object):
+
+    vtType = 'mashup_alias'
+
+    def __init__(self, id=None, name=None, component=None):
+        self._db_id = id
+        self._db_name = name
+        self.db_deleted_component = []
+        self._db_component = component
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashupAlias.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashupAlias(id=self._db_id,
+                           name=self._db_name)
+        if self._db_component is not None:
+            cp._db_component = self._db_component.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMashupAlias()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'component' in class_dict:
+            res = class_dict['component'](old_obj, trans_dict)
+            new_obj.db_component = res
+        elif hasattr(old_obj, 'db_component') and old_obj.db_component is not None:
+            obj = old_obj.db_component
+            new_obj.db_add_component(DBMashupComponent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_component') and hasattr(new_obj, 'db_deleted_component'):
+            for obj in old_obj.db_deleted_component:
+                n_obj = DBMashupComponent.update_version(obj, trans_dict)
+                new_obj.db_deleted_component.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_component is not None:
+            children.extend(self._db_component.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_component = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_component)
+        if remove:
+            self.db_deleted_component = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_component is not None and self._db_component.has_changes():
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_component(self):
+        return self._db_component
+    def __set_db_component(self, component):
+        self._db_component = component
+        self.is_dirty = True
+    db_component = property(__get_db_component, __set_db_component)
+    def db_add_component(self, component):
+        self._db_component = component
+    def db_change_component(self, component):
+        self._db_component = component
+    def db_delete_component(self, component):
+        if not self.is_new:
+            self.db_deleted_component.append(self._db_component)
+        self._db_component = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBGroup(object):
+
+    vtType = 'group'
+
+    def __init__(self, id=None, workflow=None, cache=None, name=None, namespace=None, package=None, version=None, location=None, functions=None, annotations=None, controlParameters=None):
+        self._db_id = id
+        self.db_deleted_workflow = []
+        self._db_workflow = workflow
+        self._db_cache = cache
+        self._db_name = name
+        self._db_namespace = namespace
+        self._db_package = package
+        self._db_version = version
+        self.db_deleted_location = []
+        self._db_location = location
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
+        else:
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_controlParameters = []
+        self.db_controlParameters_id_index = {}
+        self.db_controlParameters_name_index = {}
+        if controlParameters is None:
+            self._db_controlParameters = []
+        else:
+            self._db_controlParameters = controlParameters
+            for v in self._db_controlParameters:
+                self.db_controlParameters_id_index[v.db_id] = v
+                self.db_controlParameters_name_index[v.db_name] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBGroup.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBGroup(id=self._db_id,
+                     cache=self._db_cache,
+                     name=self._db_name,
+                     namespace=self._db_namespace,
+                     package=self._db_package,
+                     version=self._db_version)
+        if self._db_workflow is not None:
+            cp._db_workflow = self._db_workflow.do_copy()
+        if self._db_location is not None:
+            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
+        if self._db_functions is None:
+            cp._db_functions = []
+        else:
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_controlParameters is None:
+            cp._db_controlParameters = []
+        else:
+            cp._db_controlParameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_controlParameters]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_controlParameters_id_index = dict((v.db_id, v) for v in cp._db_controlParameters)
+        cp.db_controlParameters_name_index = dict((v.db_name, v) for v in cp._db_controlParameters)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBGroup()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'workflow' in class_dict:
+            res = class_dict['workflow'](old_obj, trans_dict)
+            new_obj.db_workflow = res
+        elif hasattr(old_obj, 'db_workflow') and old_obj.db_workflow is not None:
+            obj = old_obj.db_workflow
+            new_obj.db_add_workflow(DBWorkflow.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_workflow') and hasattr(new_obj, 'db_deleted_workflow'):
+            for obj in old_obj.db_deleted_workflow:
+                n_obj = DBWorkflow.update_version(obj, trans_dict)
+                new_obj.db_deleted_workflow.append(n_obj)
+        if 'cache' in class_dict:
+            res = class_dict['cache'](old_obj, trans_dict)
+            new_obj.db_cache = res
+        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
+            new_obj.db_cache = old_obj.db_cache
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'location' in class_dict:
+            res = class_dict['location'](old_obj, trans_dict)
+            new_obj.db_location = res
+        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
+            obj = old_obj.db_location
+            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
+            for obj in old_obj.db_deleted_location:
+                n_obj = DBLocation.update_version(obj, trans_dict)
+                new_obj.db_deleted_location.append(n_obj)
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'controlParameters' in class_dict:
+            res = class_dict['controlParameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_controlParameter(obj)
+        elif hasattr(old_obj, 'db_controlParameters') and old_obj.db_controlParameters is not None:
+            for obj in old_obj.db_controlParameters:
+                new_obj.db_add_controlParameter(DBControlParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_controlParameters') and hasattr(new_obj, 'db_deleted_controlParameters'):
+            for obj in old_obj.db_deleted_controlParameters:
+                n_obj = DBControlParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_controlParameters.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_location is not None:
+            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_location = None
+        to_del = []
+        for child in self.db_functions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_function(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_controlParameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_controlParameter(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_workflow)
+        children.extend(self.db_deleted_location)
+        children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_controlParameters)
+        if remove:
+            self.db_deleted_workflow = []
+            self.db_deleted_location = []
+            self.db_deleted_functions = []
+            self.db_deleted_annotations = []
+            self.db_deleted_controlParameters = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_workflow is not None and self._db_workflow.has_changes():
+            return True
+        if self._db_location is not None and self._db_location.has_changes():
+            return True
+        for child in self._db_functions:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_controlParameters:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_workflow(self):
+        return self._db_workflow
+    def __set_db_workflow(self, workflow):
+        self._db_workflow = workflow
+        self.is_dirty = True
+    db_workflow = property(__get_db_workflow, __set_db_workflow)
+    def db_add_workflow(self, workflow):
+        self._db_workflow = workflow
+    def db_change_workflow(self, workflow):
+        self._db_workflow = workflow
+    def db_delete_workflow(self, workflow):
+        if not self.is_new:
+            self.db_deleted_workflow.append(self._db_workflow)
+        self._db_workflow = None
+    
+    def __get_db_cache(self):
+        return self._db_cache
+    def __set_db_cache(self, cache):
+        self._db_cache = cache
+        self.is_dirty = True
+    db_cache = property(__get_db_cache, __set_db_cache)
+    def db_add_cache(self, cache):
+        self._db_cache = cache
+    def db_change_cache(self, cache):
+        self._db_cache = cache
+    def db_delete_cache(self, cache):
+        self._db_cache = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_location(self):
+        return self._db_location
+    def __set_db_location(self, location):
+        self._db_location = location
+        self.is_dirty = True
+    db_location = property(__get_db_location, __set_db_location)
+    def db_add_location(self, location):
+        self._db_location = location
+    def db_change_location(self, location):
+        self._db_location = location
+    def db_delete_location(self, location):
+        if not self.is_new:
+            self.db_deleted_location.append(self._db_location)
+        self._db_location = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
+        self.is_dirty = True
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
+        self.is_dirty = True
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
+                found = True
+                break
+        if not found:
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
+        self.is_dirty = True
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
+                break
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
+        return None
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_controlParameters(self):
+        return self._db_controlParameters
+    def __set_db_controlParameters(self, controlParameters):
+        self._db_controlParameters = controlParameters
+        self.is_dirty = True
+    db_controlParameters = property(__get_db_controlParameters, __set_db_controlParameters)
+    def db_get_controlParameters(self):
+        return self._db_controlParameters
+    def db_add_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_change_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                self._db_controlParameters[i] = controlParameter
+                found = True
+                break
+        if not found:
+            self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_delete_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                if not self._db_controlParameters[i].is_new:
+                    self.db_deleted_controlParameters.append(self._db_controlParameters[i])
+                del self._db_controlParameters[i]
+                break
+        del self.db_controlParameters_id_index[controlParameter.db_id]
+        del self.db_controlParameters_name_index[controlParameter.db_name]
+    def db_get_controlParameter(self, key):
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == key:
+                return self._db_controlParameters[i]
+        return None
+    def db_get_controlParameter_by_id(self, key):
+        return self.db_controlParameters_id_index[key]
+    def db_has_controlParameter_with_id(self, key):
+        return key in self.db_controlParameters_id_index
+    def db_get_controlParameter_by_name(self, key):
+        return self.db_controlParameters_name_index[key]
+    def db_has_controlParameter_with_name(self, key):
+        return key in self.db_controlParameters_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmWasControlledBy(object):
+
+    vtType = 'opm_was_controlled_by'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, starts=None, ends=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_starts = []
+        if starts is None:
+            self._db_starts = []
+        else:
+            self._db_starts = starts
+        self.db_deleted_ends = []
+        if ends is None:
+            self._db_ends = []
+        else:
+            self._db_ends = ends
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmWasControlledBy.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmWasControlledBy()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_starts is None:
+            cp._db_starts = []
+        else:
+            cp._db_starts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_starts]
+        if self._db_ends is None:
+            cp._db_ends = []
+        else:
+            cp._db_ends = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_ends]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmWasControlledBy()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmAgentId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmAgentId.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'starts' in class_dict:
+            res = class_dict['starts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_start(obj)
+        elif hasattr(old_obj, 'db_starts') and old_obj.db_starts is not None:
+            for obj in old_obj.db_starts:
+                new_obj.db_add_start(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_starts') and hasattr(new_obj, 'db_deleted_starts'):
+            for obj in old_obj.db_deleted_starts:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_starts.append(n_obj)
+        if 'ends' in class_dict:
+            res = class_dict['ends'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_end(obj)
+        elif hasattr(old_obj, 'db_ends') and old_obj.db_ends is not None:
+            for obj in old_obj.db_ends:
+                new_obj.db_add_end(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_ends') and hasattr(new_obj, 'db_deleted_ends'):
+            for obj in old_obj.db_deleted_ends:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_ends.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_starts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_start(child)
+        to_del = []
+        for child in self.db_ends:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_end(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_starts)
+        children.extend(self.db_deleted_ends)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_starts = []
+            self.db_deleted_ends = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_starts:
+            if child.has_changes():
+                return True
+        for child in self._db_ends:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
+        self.is_dirty = True
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_starts(self):
+        return self._db_starts
+    def __set_db_starts(self, starts):
+        self._db_starts = starts
+        self.is_dirty = True
+    db_starts = property(__get_db_starts, __set_db_starts)
+    def db_get_starts(self):
+        return self._db_starts
+    def db_add_start(self, start):
+        self.is_dirty = True
+        self._db_starts.append(start)
+    def db_change_start(self, start):
+        self.is_dirty = True
+        self._db_starts.append(start)
+    def db_delete_start(self, start):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_start(self, key):
+        return None
+    
+    def __get_db_ends(self):
+        return self._db_ends
+    def __set_db_ends(self, ends):
+        self._db_ends = ends
+        self.is_dirty = True
+    db_ends = property(__get_db_ends, __set_db_ends)
+    def db_get_ends(self):
+        return self._db_ends
+    def db_add_end(self, end):
+        self.is_dirty = True
+        self._db_ends.append(end)
+    def db_change_end(self, end):
+        self.is_dirty = True
+        self._db_ends.append(end)
+    def db_delete_end(self, end):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_end(self, key):
+        return None
+    
+
+
+class DBAdd(object):
+
+    vtType = 'add'
+
+    def __init__(self, data=None, id=None, what=None, objectId=None, parentObjId=None, parentObjType=None):
+        self.db_deleted_data = []
+        self._db_data = data
+        self._db_id = id
+        self._db_what = what
+        self._db_objectId = objectId
+        self._db_parentObjId = parentObjId
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBAdd.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBAdd(id=self._db_id,
+                   what=self._db_what,
+                   objectId=self._db_objectId,
+                   parentObjId=self._db_parentObjId,
+                   parentObjType=self._db_parentObjType)
+        if self._db_data is not None:
+            cp._db_data = self._db_data.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_objectId') and (self._db_what, self._db_objectId) in id_remap:
+                cp._db_objectId = id_remap[(self._db_what, self._db_objectId)]
+            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
+                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBAdd()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'data' in class_dict:
+            res = class_dict['data'](old_obj, trans_dict)
+            new_obj.db_data = res
+        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
+            obj = old_obj.db_data
+            if obj.vtType == 'module':
+                new_obj.db_add_data(DBModule.update_version(obj, trans_dict))
+            elif obj.vtType == 'location':
+                new_obj.db_add_data(DBLocation.update_version(obj, trans_dict))
+            elif obj.vtType == 'annotation':
+                new_obj.db_add_data(DBAnnotation.update_version(obj, trans_dict))
+            elif obj.vtType == 'controlParameter':
+                new_obj.db_add_data(DBControlParameter.update_version(obj, trans_dict))
+            elif obj.vtType == 'function':
+                new_obj.db_add_data(DBFunction.update_version(obj, trans_dict))
+            elif obj.vtType == 'connection':
+                new_obj.db_add_data(DBConnection.update_version(obj, trans_dict))
+            elif obj.vtType == 'port':
+                new_obj.db_add_data(DBPort.update_version(obj, trans_dict))
+            elif obj.vtType == 'parameter':
+                new_obj.db_add_data(DBParameter.update_version(obj, trans_dict))
+            elif obj.vtType == 'portSpec':
+                new_obj.db_add_data(DBPortSpec.update_version(obj, trans_dict))
+            elif obj.vtType == 'abstraction':
+                new_obj.db_add_data(DBAbstraction.update_version(obj, trans_dict))
+            elif obj.vtType == 'group':
+                new_obj.db_add_data(DBGroup.update_version(obj, trans_dict))
+            elif obj.vtType == 'other':
+                new_obj.db_add_data(DBOther.update_version(obj, trans_dict))
+            elif obj.vtType == 'plugin_data':
+                new_obj.db_add_data(DBPluginData.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_data') and hasattr(new_obj, 'db_deleted_data'):
+            for obj in old_obj.db_deleted_data:
+                if obj.vtType == 'module':
+                    n_obj = DBModule.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'location':
+                    n_obj = DBLocation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'annotation':
+                    n_obj = DBAnnotation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'controlParameter':
+                    n_obj = DBControlParameter.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'function':
+                    n_obj = DBFunction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'connection':
+                    n_obj = DBConnection.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'port':
+                    n_obj = DBPort.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'parameter':
+                    n_obj = DBParameter.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'portSpec':
+                    n_obj = DBPortSpec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'abstraction':
+                    n_obj = DBAbstraction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'group':
+                    n_obj = DBGroup.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'other':
+                    n_obj = DBOther.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'plugin_data':
+                    n_obj = DBPluginData.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'what' in class_dict:
+            res = class_dict['what'](old_obj, trans_dict)
+            new_obj.db_what = res
+        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
+            new_obj.db_what = old_obj.db_what
+        if 'objectId' in class_dict:
+            res = class_dict['objectId'](old_obj, trans_dict)
+            new_obj.db_objectId = res
+        elif hasattr(old_obj, 'db_objectId') and old_obj.db_objectId is not None:
+            new_obj.db_objectId = old_obj.db_objectId
+        if 'parentObjId' in class_dict:
+            res = class_dict['parentObjId'](old_obj, trans_dict)
+            new_obj.db_parentObjId = res
+        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
+            new_obj.db_parentObjId = old_obj.db_parentObjId
+        if 'parentObjType' in class_dict:
+            res = class_dict['parentObjType'](old_obj, trans_dict)
+            new_obj.db_parentObjType = res
+        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
+            new_obj.db_parentObjType = old_obj.db_parentObjType
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_data is not None:
+            children.extend(self._db_data.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_data = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_data)
+        if remove:
+            self.db_deleted_data = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_data is not None and self._db_data.has_changes():
+            return True
+        return False
+    def __get_db_data(self):
+        return self._db_data
+    def __set_db_data(self, data):
+        self._db_data = data
+        self.is_dirty = True
+    db_data = property(__get_db_data, __set_db_data)
+    def db_add_data(self, data):
+        self._db_data = data
+    def db_change_data(self, data):
+        self._db_data = data
+    def db_delete_data(self, data):
+        if not self.is_new:
+            self.db_deleted_data.append(self._db_data)
+        self._db_data = None
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_what(self):
+        return self._db_what
+    def __set_db_what(self, what):
+        self._db_what = what
+        self.is_dirty = True
+    db_what = property(__get_db_what, __set_db_what)
+    def db_add_what(self, what):
+        self._db_what = what
+    def db_change_what(self, what):
+        self._db_what = what
+    def db_delete_what(self, what):
+        self._db_what = None
+    
+    def __get_db_objectId(self):
+        return self._db_objectId
+    def __set_db_objectId(self, objectId):
+        self._db_objectId = objectId
+        self.is_dirty = True
+    db_objectId = property(__get_db_objectId, __set_db_objectId)
+    def db_add_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_change_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_delete_objectId(self, objectId):
+        self._db_objectId = None
+    
+    def __get_db_parentObjId(self):
+        return self._db_parentObjId
+    def __set_db_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+        self.is_dirty = True
+    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
+    def db_add_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_change_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_delete_parentObjId(self, parentObjId):
+        self._db_parentObjId = None
+    
+    def __get_db_parentObjType(self):
+        return self._db_parentObjType
+    def __set_db_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
+    def db_add_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_change_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_delete_parentObjType(self, parentObjType):
+        self._db_parentObjType = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvGeneration(object):
+
+    vtType = 'prov_generation'
+
+    def __init__(self, prov_entity=None, prov_activity=None, prov_role=None):
+        self.db_deleted_prov_entity = []
+        self._db_prov_entity = prov_entity
+        self.db_deleted_prov_activity = []
+        self._db_prov_activity = prov_activity
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvGeneration.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvGeneration(prov_role=self._db_prov_role)
+        if self._db_prov_entity is not None:
+            cp._db_prov_entity = self._db_prov_entity.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_activity is not None:
+            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvGeneration()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_entity' in class_dict:
+            res = class_dict['prov_entity'](old_obj, trans_dict)
+            new_obj.db_prov_entity = res
+        elif hasattr(old_obj, 'db_prov_entity') and old_obj.db_prov_entity is not None:
+            obj = old_obj.db_prov_entity
+            new_obj.db_add_prov_entity(DBRefProvEntity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_entity') and hasattr(new_obj, 'db_deleted_prov_entity'):
+            for obj in old_obj.db_deleted_prov_entity:
+                n_obj = DBRefProvEntity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_entity.append(n_obj)
+        if 'prov_activity' in class_dict:
+            res = class_dict['prov_activity'](old_obj, trans_dict)
+            new_obj.db_prov_activity = res
+        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
+            obj = old_obj.db_prov_activity
+            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
+            for obj in old_obj.db_deleted_prov_activity:
+                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activity.append(n_obj)
+        if 'prov_role' in class_dict:
+            res = class_dict['prov_role'](old_obj, trans_dict)
+            new_obj.db_prov_role = res
+        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
+            new_obj.db_prov_role = old_obj.db_prov_role
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_prov_entity is not None:
+            children.extend(self._db_prov_entity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_entity = None
+        if self._db_prov_activity is not None:
+            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_activity = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_prov_entity)
+        children.extend(self.db_deleted_prov_activity)
+        if remove:
+            self.db_deleted_prov_entity = []
+            self.db_deleted_prov_activity = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_prov_entity is not None and self._db_prov_entity.has_changes():
+            return True
+        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
+            return True
+        return False
+    def __get_db_prov_entity(self):
+        return self._db_prov_entity
+    def __set_db_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+        self.is_dirty = True
+    db_prov_entity = property(__get_db_prov_entity, __set_db_prov_entity)
+    def db_add_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_change_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_delete_prov_entity(self, prov_entity):
+        if not self.is_new:
+            self.db_deleted_prov_entity.append(self._db_prov_entity)
+        self._db_prov_entity = None
+    
+    def __get_db_prov_activity(self):
+        return self._db_prov_activity
+    def __set_db_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+        self.is_dirty = True
+    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
+    def db_add_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        if not self.is_new:
+            self.db_deleted_prov_activity.append(self._db_prov_activity)
+        self._db_prov_activity = None
+    
+    def __get_db_prov_role(self):
+        return self._db_prov_role
+    def __set_db_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
+    def db_add_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_change_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_delete_prov_role(self, prov_role):
+        self._db_prov_role = None
+    
+
+
+class DBOpmUsed(object):
+
+    vtType = 'opm_used'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmUsed.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmUsed()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmUsed()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmArtifactIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmArtifactIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
+        self.is_dirty = True
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
+        self.is_dirty = True
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
+    
+
+
+class DBOpmArtifactIdCause(object):
+
+    vtType = 'opm_artifact_id_cause'
+
+    def __init__(self, id=None):
+        self._db_id = id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmArtifactIdCause.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmArtifactIdCause(id=self._db_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_artifact', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_artifact', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmArtifactIdCause()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBRefProvEntity(object):
+
+    vtType = 'ref_prov_entity'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBRefProvEntity.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBRefProvEntity(prov_ref=self._db_prov_ref)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_entity', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_entity', self._db_prov_ref)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRefProvEntity()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
+    
+
+
+class DBVtConnection(object):
+
+    vtType = 'vt_connection'
+
+    def __init__(self, id=None, vt_source=None, vt_dest=None, vt_source_port=None, vt_dest_port=None, vt_source_signature=None, vt_dest_signature=None):
+        self._db_id = id
+        self._db_vt_source = vt_source
+        self._db_vt_dest = vt_dest
+        self._db_vt_source_port = vt_source_port
+        self._db_vt_dest_port = vt_dest_port
+        self._db_vt_source_signature = vt_source_signature
+        self._db_vt_dest_signature = vt_dest_signature
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBVtConnection.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBVtConnection(id=self._db_id,
+                            vt_source=self._db_vt_source,
+                            vt_dest=self._db_vt_dest,
+                            vt_source_port=self._db_vt_source_port,
+                            vt_dest_port=self._db_vt_dest_port,
+                            vt_source_signature=self._db_vt_source_signature,
+                            vt_dest_signature=self._db_vt_dest_signature)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBVtConnection()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'vt_source' in class_dict:
+            res = class_dict['vt_source'](old_obj, trans_dict)
+            new_obj.db_vt_source = res
+        elif hasattr(old_obj, 'db_vt_source') and old_obj.db_vt_source is not None:
+            new_obj.db_vt_source = old_obj.db_vt_source
+        if 'vt_dest' in class_dict:
+            res = class_dict['vt_dest'](old_obj, trans_dict)
+            new_obj.db_vt_dest = res
+        elif hasattr(old_obj, 'db_vt_dest') and old_obj.db_vt_dest is not None:
+            new_obj.db_vt_dest = old_obj.db_vt_dest
+        if 'vt_source_port' in class_dict:
+            res = class_dict['vt_source_port'](old_obj, trans_dict)
+            new_obj.db_vt_source_port = res
+        elif hasattr(old_obj, 'db_vt_source_port') and old_obj.db_vt_source_port is not None:
+            new_obj.db_vt_source_port = old_obj.db_vt_source_port
+        if 'vt_dest_port' in class_dict:
+            res = class_dict['vt_dest_port'](old_obj, trans_dict)
+            new_obj.db_vt_dest_port = res
+        elif hasattr(old_obj, 'db_vt_dest_port') and old_obj.db_vt_dest_port is not None:
+            new_obj.db_vt_dest_port = old_obj.db_vt_dest_port
+        if 'vt_source_signature' in class_dict:
+            res = class_dict['vt_source_signature'](old_obj, trans_dict)
+            new_obj.db_vt_source_signature = res
+        elif hasattr(old_obj, 'db_vt_source_signature') and old_obj.db_vt_source_signature is not None:
+            new_obj.db_vt_source_signature = old_obj.db_vt_source_signature
+        if 'vt_dest_signature' in class_dict:
+            res = class_dict['vt_dest_signature'](old_obj, trans_dict)
+            new_obj.db_vt_dest_signature = res
+        elif hasattr(old_obj, 'db_vt_dest_signature') and old_obj.db_vt_dest_signature is not None:
+            new_obj.db_vt_dest_signature = old_obj.db_vt_dest_signature
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_vt_source(self):
+        return self._db_vt_source
+    def __set_db_vt_source(self, vt_source):
+        self._db_vt_source = vt_source
+        self.is_dirty = True
+    db_vt_source = property(__get_db_vt_source, __set_db_vt_source)
+    def db_add_vt_source(self, vt_source):
+        self._db_vt_source = vt_source
+    def db_change_vt_source(self, vt_source):
+        self._db_vt_source = vt_source
+    def db_delete_vt_source(self, vt_source):
+        self._db_vt_source = None
+    
+    def __get_db_vt_dest(self):
+        return self._db_vt_dest
+    def __set_db_vt_dest(self, vt_dest):
+        self._db_vt_dest = vt_dest
+        self.is_dirty = True
+    db_vt_dest = property(__get_db_vt_dest, __set_db_vt_dest)
+    def db_add_vt_dest(self, vt_dest):
+        self._db_vt_dest = vt_dest
+    def db_change_vt_dest(self, vt_dest):
+        self._db_vt_dest = vt_dest
+    def db_delete_vt_dest(self, vt_dest):
+        self._db_vt_dest = None
+    
+    def __get_db_vt_source_port(self):
+        return self._db_vt_source_port
+    def __set_db_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = vt_source_port
+        self.is_dirty = True
+    db_vt_source_port = property(__get_db_vt_source_port, __set_db_vt_source_port)
+    def db_add_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = vt_source_port
+    def db_change_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = vt_source_port
+    def db_delete_vt_source_port(self, vt_source_port):
+        self._db_vt_source_port = None
+    
+    def __get_db_vt_dest_port(self):
+        return self._db_vt_dest_port
+    def __set_db_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = vt_dest_port
+        self.is_dirty = True
+    db_vt_dest_port = property(__get_db_vt_dest_port, __set_db_vt_dest_port)
+    def db_add_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = vt_dest_port
+    def db_change_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = vt_dest_port
+    def db_delete_vt_dest_port(self, vt_dest_port):
+        self._db_vt_dest_port = None
+    
+    def __get_db_vt_source_signature(self):
+        return self._db_vt_source_signature
+    def __set_db_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = vt_source_signature
+        self.is_dirty = True
+    db_vt_source_signature = property(__get_db_vt_source_signature, __set_db_vt_source_signature)
+    def db_add_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = vt_source_signature
+    def db_change_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = vt_source_signature
+    def db_delete_vt_source_signature(self, vt_source_signature):
+        self._db_vt_source_signature = None
+    
+    def __get_db_vt_dest_signature(self):
+        return self._db_vt_dest_signature
+    def __set_db_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = vt_dest_signature
+        self.is_dirty = True
+    db_vt_dest_signature = property(__get_db_vt_dest_signature, __set_db_vt_dest_signature)
+    def db_add_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = vt_dest_signature
+    def db_change_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = vt_dest_signature
+    def db_delete_vt_dest_signature(self, vt_dest_signature):
+        self._db_vt_dest_signature = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmAccount(object):
+
+    vtType = 'opm_account'
+
+    def __init__(self, id=None, value=None):
+        self._db_id = id
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAccount.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAccount(id=self._db_id,
+                          value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAccount()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBGroupExec(object):
+
+    vtType = 'group_exec'
+
+    def __init__(self, item_execs=None, id=None, ts_start=None, ts_end=None, cached=None, module_id=None, group_name=None, group_type=None, completed=None, error=None, machine_id=None, annotations=None):
+        self.db_deleted_item_execs = []
+        self.db_item_execs_id_index = {}
+        if item_execs is None:
+            self._db_item_execs = []
+        else:
+            self._db_item_execs = item_execs
+            for v in self._db_item_execs:
+                self.db_item_execs_id_index[v.db_id] = v
+        self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_cached = cached
+        self._db_module_id = module_id
+        self._db_group_name = group_name
+        self._db_group_type = group_type
+        self._db_completed = completed
+        self._db_error = error
+        self._db_machine_id = machine_id
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBGroupExec.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBGroupExec(id=self._db_id,
+                         ts_start=self._db_ts_start,
+                         ts_end=self._db_ts_end,
+                         cached=self._db_cached,
+                         module_id=self._db_module_id,
+                         group_name=self._db_group_name,
+                         group_type=self._db_group_type,
+                         completed=self._db_completed,
+                         error=self._db_error,
+                         machine_id=self._db_machine_id)
+        if self._db_item_execs is None:
+            cp._db_item_execs = []
+        else:
+            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
+                cp._db_module_id = id_remap[('module', self._db_module_id)]
+            if hasattr(self, 'db_machine_id') and ('machine', self._db_machine_id) in id_remap:
+                cp._db_machine_id = id_remap[('machine', self._db_machine_id)]
+        
+        # recreate indices and set flags
+        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBGroupExec()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'item_execs' in class_dict:
+            res = class_dict['item_execs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_item_exec(obj)
+        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
+            for obj in old_obj.db_item_execs:
+                if obj.vtType == 'module_exec':
+                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'group_exec':
+                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'loop_exec':
+                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
+            for obj in old_obj.db_deleted_item_execs:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'cached' in class_dict:
+            res = class_dict['cached'](old_obj, trans_dict)
+            new_obj.db_cached = res
+        elif hasattr(old_obj, 'db_cached') and old_obj.db_cached is not None:
+            new_obj.db_cached = old_obj.db_cached
+        if 'module_id' in class_dict:
+            res = class_dict['module_id'](old_obj, trans_dict)
+            new_obj.db_module_id = res
+        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
+            new_obj.db_module_id = old_obj.db_module_id
+        if 'group_name' in class_dict:
+            res = class_dict['group_name'](old_obj, trans_dict)
+            new_obj.db_group_name = res
+        elif hasattr(old_obj, 'db_group_name') and old_obj.db_group_name is not None:
+            new_obj.db_group_name = old_obj.db_group_name
+        if 'group_type' in class_dict:
+            res = class_dict['group_type'](old_obj, trans_dict)
+            new_obj.db_group_type = res
+        elif hasattr(old_obj, 'db_group_type') and old_obj.db_group_type is not None:
+            new_obj.db_group_type = old_obj.db_group_type
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'error' in class_dict:
+            res = class_dict['error'](old_obj, trans_dict)
+            new_obj.db_error = res
+        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
+            new_obj.db_error = old_obj.db_error
+        if 'machine_id' in class_dict:
+            res = class_dict['machine_id'](old_obj, trans_dict)
+            new_obj.db_machine_id = res
+        elif hasattr(old_obj, 'db_machine_id') and old_obj.db_machine_id is not None:
+            new_obj.db_machine_id = old_obj.db_machine_id
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_item_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_item_exec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_item_execs)
+        if remove:
+            self.db_deleted_annotations = []
+            self.db_deleted_item_execs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_item_execs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_item_execs(self):
+        return self._db_item_execs
+    def __set_db_item_execs(self, item_execs):
+        self._db_item_execs = item_execs
+        self.is_dirty = True
+    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
+    def db_get_item_execs(self):
+        return self._db_item_execs
+    def db_add_item_exec(self, item_exec):
+        self.is_dirty = True
+        self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_change_item_exec(self, item_exec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                self._db_item_execs[i] = item_exec
+                found = True
+                break
+        if not found:
+            self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_delete_item_exec(self, item_exec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                if not self._db_item_execs[i].is_new:
+                    self.db_deleted_item_execs.append(self._db_item_execs[i])
+                del self._db_item_execs[i]
+                break
+        del self.db_item_execs_id_index[item_exec.db_id]
+    def db_get_item_exec(self, key):
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == key:
+                return self._db_item_execs[i]
+        return None
+    def db_get_item_exec_by_id(self, key):
+        return self.db_item_execs_id_index[key]
+    def db_has_item_exec_with_id(self, key):
+        return key in self.db_item_execs_id_index
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_cached(self):
+        return self._db_cached
+    def __set_db_cached(self, cached):
+        self._db_cached = cached
+        self.is_dirty = True
+    db_cached = property(__get_db_cached, __set_db_cached)
+    def db_add_cached(self, cached):
+        self._db_cached = cached
+    def db_change_cached(self, cached):
+        self._db_cached = cached
+    def db_delete_cached(self, cached):
+        self._db_cached = None
+    
+    def __get_db_module_id(self):
+        return self._db_module_id
+    def __set_db_module_id(self, module_id):
+        self._db_module_id = module_id
+        self.is_dirty = True
+    db_module_id = property(__get_db_module_id, __set_db_module_id)
+    def db_add_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_change_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_delete_module_id(self, module_id):
+        self._db_module_id = None
+    
+    def __get_db_group_name(self):
+        return self._db_group_name
+    def __set_db_group_name(self, group_name):
+        self._db_group_name = group_name
+        self.is_dirty = True
+    db_group_name = property(__get_db_group_name, __set_db_group_name)
+    def db_add_group_name(self, group_name):
+        self._db_group_name = group_name
+    def db_change_group_name(self, group_name):
+        self._db_group_name = group_name
+    def db_delete_group_name(self, group_name):
+        self._db_group_name = None
+    
+    def __get_db_group_type(self):
+        return self._db_group_type
+    def __set_db_group_type(self, group_type):
+        self._db_group_type = group_type
+        self.is_dirty = True
+    db_group_type = property(__get_db_group_type, __set_db_group_type)
+    def db_add_group_type(self, group_type):
+        self._db_group_type = group_type
+    def db_change_group_type(self, group_type):
+        self._db_group_type = group_type
+    def db_delete_group_type(self, group_type):
+        self._db_group_type = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_error(self):
+        return self._db_error
+    def __set_db_error(self, error):
+        self._db_error = error
+        self.is_dirty = True
+    db_error = property(__get_db_error, __set_db_error)
+    def db_add_error(self, error):
+        self._db_error = error
+    def db_change_error(self, error):
+        self._db_error = error
+    def db_delete_error(self, error):
+        self._db_error = None
+    
+    def __get_db_machine_id(self):
+        return self._db_machine_id
+    def __set_db_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+        self.is_dirty = True
+    db_machine_id = property(__get_db_machine_id, __set_db_machine_id)
+    def db_add_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_change_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_delete_machine_id(self, machine_id):
+        self._db_machine_id = None
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmAgentId(object):
+
+    vtType = 'opm_agent_id'
+
+    def __init__(self, id=None):
+        self._db_id = id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAgentId.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAgentId(id=self._db_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_agent', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_agent', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAgentId()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBParameter(object):
+
+    vtType = 'parameter'
+
+    def __init__(self, id=None, pos=None, name=None, type=None, val=None, alias=None):
+        self._db_id = id
+        self._db_pos = pos
+        self._db_name = name
+        self._db_type = type
+        self._db_val = val
+        self._db_alias = alias
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBParameter.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBParameter(id=self._db_id,
+                         pos=self._db_pos,
+                         name=self._db_name,
+                         type=self._db_type,
+                         val=self._db_val,
+                         alias=self._db_alias)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBParameter()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'val' in class_dict:
+            res = class_dict['val'](old_obj, trans_dict)
+            new_obj.db_val = res
+        elif hasattr(old_obj, 'db_val') and old_obj.db_val is not None:
+            new_obj.db_val = old_obj.db_val
+        if 'alias' in class_dict:
+            res = class_dict['alias'](old_obj, trans_dict)
+            new_obj.db_alias = res
+        elif hasattr(old_obj, 'db_alias') and old_obj.db_alias is not None:
+            new_obj.db_alias = old_obj.db_alias
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
+        self.is_dirty = True
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_val(self):
+        return self._db_val
+    def __set_db_val(self, val):
+        self._db_val = val
+        self.is_dirty = True
+    db_val = property(__get_db_val, __set_db_val)
+    def db_add_val(self, val):
+        self._db_val = val
+    def db_change_val(self, val):
+        self._db_val = val
+    def db_delete_val(self, val):
+        self._db_val = None
+    
+    def __get_db_alias(self):
+        return self._db_alias
+    def __set_db_alias(self, alias):
+        self._db_alias = alias
+        self.is_dirty = True
+    db_alias = property(__get_db_alias, __set_db_alias)
+    def db_add_alias(self, alias):
+        self._db_alias = alias
+    def db_change_alias(self, alias):
+        self._db_alias = alias
+    def db_delete_alias(self, alias):
+        self._db_alias = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBVistrail(object):
+
+    vtType = 'vistrail'
+
+    def __init__(self, id=None, entity_type=None, version=None, name=None, last_modified=None, actions=None, tags=None, annotations=None, controlParameters=None, vistrailVariables=None, parameter_explorations=None, actionAnnotations=None):
+        self._db_id = id
+        self._db_entity_type = entity_type
+        self._db_version = version
+        self._db_name = name
+        self._db_last_modified = last_modified
+        self.db_deleted_actions = []
+        self.db_actions_id_index = {}
+        if actions is None:
+            self._db_actions = []
+        else:
+            self._db_actions = actions
+            for v in self._db_actions:
+                self.db_actions_id_index[v.db_id] = v
+        self.db_deleted_tags = []
+        self.db_tags_id_index = {}
+        self.db_tags_name_index = {}
+        if tags is None:
+            self._db_tags = []
+        else:
+            self._db_tags = tags
+            for v in self._db_tags:
+                self.db_tags_id_index[v.db_id] = v
+                self.db_tags_name_index[v.db_name] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_controlParameters = []
+        self.db_controlParameters_id_index = {}
+        self.db_controlParameters_name_index = {}
+        if controlParameters is None:
+            self._db_controlParameters = []
+        else:
+            self._db_controlParameters = controlParameters
+            for v in self._db_controlParameters:
+                self.db_controlParameters_id_index[v.db_id] = v
+                self.db_controlParameters_name_index[v.db_name] = v
+        self.db_deleted_vistrailVariables = []
+        self.db_vistrailVariables_name_index = {}
+        self.db_vistrailVariables_uuid_index = {}
+        if vistrailVariables is None:
+            self._db_vistrailVariables = []
+        else:
+            self._db_vistrailVariables = vistrailVariables
+            for v in self._db_vistrailVariables:
+                self.db_vistrailVariables_name_index[v.db_name] = v
+                self.db_vistrailVariables_uuid_index[v.db_uuid] = v
+        self.db_deleted_parameter_explorations = []
+        self.db_parameter_explorations_id_index = {}
+        if parameter_explorations is None:
+            self._db_parameter_explorations = []
+        else:
+            self._db_parameter_explorations = parameter_explorations
+            for v in self._db_parameter_explorations:
+                self.db_parameter_explorations_id_index[v.db_id] = v
+        self.db_deleted_actionAnnotations = []
+        self.db_actionAnnotations_id_index = {}
+        self.db_actionAnnotations_action_id_index = {}
+        self.db_actionAnnotations_key_index = {}
+        if actionAnnotations is None:
+            self._db_actionAnnotations = []
+        else:
+            self._db_actionAnnotations = actionAnnotations
+            for v in self._db_actionAnnotations:
+                self.db_actionAnnotations_id_index[v.db_id] = v
+                self.db_actionAnnotations_action_id_index[(v.db_action_id,v.db_key)] = v
+                self.db_actionAnnotations_key_index[(v.db_key,v.db_value)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBVistrail.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBVistrail(id=self._db_id,
+                        entity_type=self._db_entity_type,
+                        version=self._db_version,
+                        name=self._db_name,
+                        last_modified=self._db_last_modified)
+        if self._db_actions is None:
+            cp._db_actions = []
+        else:
+            cp._db_actions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actions]
+        if self._db_tags is None:
+            cp._db_tags = []
+        else:
+            cp._db_tags = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_tags]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_controlParameters is None:
+            cp._db_controlParameters = []
+        else:
+            cp._db_controlParameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_controlParameters]
+        if self._db_vistrailVariables is None:
+            cp._db_vistrailVariables = []
+        else:
+            cp._db_vistrailVariables = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_vistrailVariables]
+        if self._db_parameter_explorations is None:
+            cp._db_parameter_explorations = []
+        else:
+            cp._db_parameter_explorations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameter_explorations]
+        if self._db_actionAnnotations is None:
+            cp._db_actionAnnotations = []
+        else:
+            cp._db_actionAnnotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actionAnnotations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_actions_id_index = dict((v.db_id, v) for v in cp._db_actions)
+        cp.db_tags_id_index = dict((v.db_id, v) for v in cp._db_tags)
+        cp.db_tags_name_index = dict((v.db_name, v) for v in cp._db_tags)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_controlParameters_id_index = dict((v.db_id, v) for v in cp._db_controlParameters)
+        cp.db_controlParameters_name_index = dict((v.db_name, v) for v in cp._db_controlParameters)
+        cp.db_vistrailVariables_name_index = dict((v.db_name, v) for v in cp._db_vistrailVariables)
+        cp.db_vistrailVariables_uuid_index = dict((v.db_uuid, v) for v in cp._db_vistrailVariables)
+        cp.db_parameter_explorations_id_index = dict((v.db_id, v) for v in cp._db_parameter_explorations)
+        cp.db_actionAnnotations_id_index = dict((v.db_id, v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_action_id_index = dict(((v.db_action_id,v.db_key), v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_key_index = dict(((v.db_key,v.db_value), v) for v in cp._db_actionAnnotations)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBVistrail()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'actions' in class_dict:
+            res = class_dict['actions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_action(obj)
+        elif hasattr(old_obj, 'db_actions') and old_obj.db_actions is not None:
+            for obj in old_obj.db_actions:
+                new_obj.db_add_action(DBAction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actions') and hasattr(new_obj, 'db_deleted_actions'):
+            for obj in old_obj.db_deleted_actions:
+                n_obj = DBAction.update_version(obj, trans_dict)
+                new_obj.db_deleted_actions.append(n_obj)
+        if 'tags' in class_dict:
+            res = class_dict['tags'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_tag(obj)
+        elif hasattr(old_obj, 'db_tags') and old_obj.db_tags is not None:
+            for obj in old_obj.db_tags:
+                new_obj.db_add_tag(DBTag.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_tags') and hasattr(new_obj, 'db_deleted_tags'):
+            for obj in old_obj.db_deleted_tags:
+                n_obj = DBTag.update_version(obj, trans_dict)
+                new_obj.db_deleted_tags.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'controlParameters' in class_dict:
+            res = class_dict['controlParameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_controlParameter(obj)
+        elif hasattr(old_obj, 'db_controlParameters') and old_obj.db_controlParameters is not None:
+            for obj in old_obj.db_controlParameters:
+                new_obj.db_add_controlParameter(DBControlParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_controlParameters') and hasattr(new_obj, 'db_deleted_controlParameters'):
+            for obj in old_obj.db_deleted_controlParameters:
+                n_obj = DBControlParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_controlParameters.append(n_obj)
+        if 'vistrailVariables' in class_dict:
+            res = class_dict['vistrailVariables'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_vistrailVariable(obj)
+        elif hasattr(old_obj, 'db_vistrailVariables') and old_obj.db_vistrailVariables is not None:
+            for obj in old_obj.db_vistrailVariables:
+                new_obj.db_add_vistrailVariable(DBVistrailVariable.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_vistrailVariables') and hasattr(new_obj, 'db_deleted_vistrailVariables'):
+            for obj in old_obj.db_deleted_vistrailVariables:
+                n_obj = DBVistrailVariable.update_version(obj, trans_dict)
+                new_obj.db_deleted_vistrailVariables.append(n_obj)
+        if 'parameter_explorations' in class_dict:
+            res = class_dict['parameter_explorations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_parameter_exploration(obj)
+        elif hasattr(old_obj, 'db_parameter_explorations') and old_obj.db_parameter_explorations is not None:
+            for obj in old_obj.db_parameter_explorations:
+                new_obj.db_add_parameter_exploration(DBParameterExploration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_parameter_explorations') and hasattr(new_obj, 'db_deleted_parameter_explorations'):
+            for obj in old_obj.db_deleted_parameter_explorations:
+                n_obj = DBParameterExploration.update_version(obj, trans_dict)
+                new_obj.db_deleted_parameter_explorations.append(n_obj)
+        if 'actionAnnotations' in class_dict:
+            res = class_dict['actionAnnotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_actionAnnotation(obj)
+        elif hasattr(old_obj, 'db_actionAnnotations') and old_obj.db_actionAnnotations is not None:
+            for obj in old_obj.db_actionAnnotations:
+                new_obj.db_add_actionAnnotation(DBActionAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actionAnnotations') and hasattr(new_obj, 'db_deleted_actionAnnotations'):
+            for obj in old_obj.db_deleted_actionAnnotations:
+                n_obj = DBActionAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_actionAnnotations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_actions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_action(child)
+        to_del = []
+        for child in self.db_tags:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_tag(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_controlParameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_controlParameter(child)
+        to_del = []
+        for child in self.db_vistrailVariables:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_vistrailVariable(child)
+        to_del = []
+        for child in self.db_parameter_explorations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_parameter_exploration(child)
+        to_del = []
+        for child in self.db_actionAnnotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_actionAnnotation(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_actions)
+        children.extend(self.db_deleted_tags)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_controlParameters)
+        children.extend(self.db_deleted_vistrailVariables)
+        children.extend(self.db_deleted_parameter_explorations)
+        children.extend(self.db_deleted_actionAnnotations)
+        if remove:
+            self.db_deleted_actions = []
+            self.db_deleted_tags = []
+            self.db_deleted_annotations = []
+            self.db_deleted_controlParameters = []
+            self.db_deleted_vistrailVariables = []
+            self.db_deleted_parameter_explorations = []
+            self.db_deleted_actionAnnotations = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_actions:
+            if child.has_changes():
+                return True
+        for child in self._db_tags:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_controlParameters:
+            if child.has_changes():
+                return True
+        for child in self._db_vistrailVariables:
+            if child.has_changes():
+                return True
+        for child in self._db_parameter_explorations:
+            if child.has_changes():
+                return True
+        for child in self._db_actionAnnotations:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+        self.is_dirty = True
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_actions(self):
+        return self._db_actions
+    def __set_db_actions(self, actions):
+        self._db_actions = actions
+        self.is_dirty = True
+    db_actions = property(__get_db_actions, __set_db_actions)
+    def db_get_actions(self):
+        return self._db_actions
+    def db_add_action(self, action):
+        self.is_dirty = True
+        self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_change_action(self, action):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                self._db_actions[i] = action
+                found = True
+                break
+        if not found:
+            self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_delete_action(self, action):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                if not self._db_actions[i].is_new:
+                    self.db_deleted_actions.append(self._db_actions[i])
+                del self._db_actions[i]
+                break
+        del self.db_actions_id_index[action.db_id]
+    def db_get_action(self, key):
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == key:
+                return self._db_actions[i]
+        return None
+    def db_get_action_by_id(self, key):
+        return self.db_actions_id_index[key]
+    def db_has_action_with_id(self, key):
+        return key in self.db_actions_id_index
+    
+    def __get_db_tags(self):
+        return self._db_tags
+    def __set_db_tags(self, tags):
+        self._db_tags = tags
+        self.is_dirty = True
+    db_tags = property(__get_db_tags, __set_db_tags)
+    def db_get_tags(self):
+        return self._db_tags
+    def db_add_tag(self, tag):
+        self.is_dirty = True
+        self._db_tags.append(tag)
+        self.db_tags_id_index[tag.db_id] = tag
+        self.db_tags_name_index[tag.db_name] = tag
+    def db_change_tag(self, tag):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_tags)):
+            if self._db_tags[i].db_id == tag.db_id:
+                self._db_tags[i] = tag
+                found = True
+                break
+        if not found:
+            self._db_tags.append(tag)
+        self.db_tags_id_index[tag.db_id] = tag
+        self.db_tags_name_index[tag.db_name] = tag
+    def db_delete_tag(self, tag):
+        self.is_dirty = True
+        for i in xrange(len(self._db_tags)):
+            if self._db_tags[i].db_id == tag.db_id:
+                if not self._db_tags[i].is_new:
+                    self.db_deleted_tags.append(self._db_tags[i])
+                del self._db_tags[i]
+                break
+        del self.db_tags_id_index[tag.db_id]
+        del self.db_tags_name_index[tag.db_name]
+    def db_get_tag(self, key):
+        for i in xrange(len(self._db_tags)):
+            if self._db_tags[i].db_id == key:
+                return self._db_tags[i]
+        return None
+    def db_get_tag_by_id(self, key):
+        return self.db_tags_id_index[key]
+    def db_has_tag_with_id(self, key):
+        return key in self.db_tags_id_index
+    def db_get_tag_by_name(self, key):
+        return self.db_tags_name_index[key]
+    def db_has_tag_with_name(self, key):
+        return key in self.db_tags_name_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_controlParameters(self):
+        return self._db_controlParameters
+    def __set_db_controlParameters(self, controlParameters):
+        self._db_controlParameters = controlParameters
+        self.is_dirty = True
+    db_controlParameters = property(__get_db_controlParameters, __set_db_controlParameters)
+    def db_get_controlParameters(self):
+        return self._db_controlParameters
+    def db_add_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_change_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                self._db_controlParameters[i] = controlParameter
+                found = True
+                break
+        if not found:
+            self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_delete_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                if not self._db_controlParameters[i].is_new:
+                    self.db_deleted_controlParameters.append(self._db_controlParameters[i])
+                del self._db_controlParameters[i]
+                break
+        del self.db_controlParameters_id_index[controlParameter.db_id]
+        del self.db_controlParameters_name_index[controlParameter.db_name]
+    def db_get_controlParameter(self, key):
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == key:
+                return self._db_controlParameters[i]
+        return None
+    def db_get_controlParameter_by_id(self, key):
+        return self.db_controlParameters_id_index[key]
+    def db_has_controlParameter_with_id(self, key):
+        return key in self.db_controlParameters_id_index
+    def db_get_controlParameter_by_name(self, key):
+        return self.db_controlParameters_name_index[key]
+    def db_has_controlParameter_with_name(self, key):
+        return key in self.db_controlParameters_name_index
+    
+    def __get_db_vistrailVariables(self):
+        return self._db_vistrailVariables
+    def __set_db_vistrailVariables(self, vistrailVariables):
+        self._db_vistrailVariables = vistrailVariables
+        self.is_dirty = True
+    db_vistrailVariables = property(__get_db_vistrailVariables, __set_db_vistrailVariables)
+    def db_get_vistrailVariables(self):
+        return self._db_vistrailVariables
+    def db_add_vistrailVariable(self, vistrailVariable):
+        self.is_dirty = True
+        self._db_vistrailVariables.append(vistrailVariable)
+        self.db_vistrailVariables_name_index[vistrailVariable.db_name] = vistrailVariable
+        self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid] = vistrailVariable
+    def db_change_vistrailVariable(self, vistrailVariable):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_vistrailVariables)):
+            if self._db_vistrailVariables[i].db_name == vistrailVariable.db_name:
+                self._db_vistrailVariables[i] = vistrailVariable
+                found = True
+                break
+        if not found:
+            self._db_vistrailVariables.append(vistrailVariable)
+        self.db_vistrailVariables_name_index[vistrailVariable.db_name] = vistrailVariable
+        self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid] = vistrailVariable
+    def db_delete_vistrailVariable(self, vistrailVariable):
+        self.is_dirty = True
+        for i in xrange(len(self._db_vistrailVariables)):
+            if self._db_vistrailVariables[i].db_name == vistrailVariable.db_name:
+                if not self._db_vistrailVariables[i].is_new:
+                    self.db_deleted_vistrailVariables.append(self._db_vistrailVariables[i])
+                del self._db_vistrailVariables[i]
+                break
+        del self.db_vistrailVariables_name_index[vistrailVariable.db_name]
+        del self.db_vistrailVariables_uuid_index[vistrailVariable.db_uuid]
+    def db_get_vistrailVariable(self, key):
+        for i in xrange(len(self._db_vistrailVariables)):
+            if self._db_vistrailVariables[i].db_name == key:
+                return self._db_vistrailVariables[i]
+        return None
+    def db_get_vistrailVariable_by_name(self, key):
+        return self.db_vistrailVariables_name_index[key]
+    def db_has_vistrailVariable_with_name(self, key):
+        return key in self.db_vistrailVariables_name_index
+    def db_get_vistrailVariable_by_uuid(self, key):
+        return self.db_vistrailVariables_uuid_index[key]
+    def db_has_vistrailVariable_with_uuid(self, key):
+        return key in self.db_vistrailVariables_uuid_index
+    
+    def __get_db_parameter_explorations(self):
+        return self._db_parameter_explorations
+    def __set_db_parameter_explorations(self, parameter_explorations):
+        self._db_parameter_explorations = parameter_explorations
+        self.is_dirty = True
+    db_parameter_explorations = property(__get_db_parameter_explorations, __set_db_parameter_explorations)
+    def db_get_parameter_explorations(self):
+        return self._db_parameter_explorations
+    def db_add_parameter_exploration(self, parameter_exploration):
+        self.is_dirty = True
+        self._db_parameter_explorations.append(parameter_exploration)
+        self.db_parameter_explorations_id_index[parameter_exploration.db_id] = parameter_exploration
+    def db_change_parameter_exploration(self, parameter_exploration):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_parameter_explorations)):
+            if self._db_parameter_explorations[i].db_id == parameter_exploration.db_id:
+                self._db_parameter_explorations[i] = parameter_exploration
+                found = True
+                break
+        if not found:
+            self._db_parameter_explorations.append(parameter_exploration)
+        self.db_parameter_explorations_id_index[parameter_exploration.db_id] = parameter_exploration
+    def db_delete_parameter_exploration(self, parameter_exploration):
+        self.is_dirty = True
+        for i in xrange(len(self._db_parameter_explorations)):
+            if self._db_parameter_explorations[i].db_id == parameter_exploration.db_id:
+                if not self._db_parameter_explorations[i].is_new:
+                    self.db_deleted_parameter_explorations.append(self._db_parameter_explorations[i])
+                del self._db_parameter_explorations[i]
+                break
+        del self.db_parameter_explorations_id_index[parameter_exploration.db_id]
+    def db_get_parameter_exploration(self, key):
+        for i in xrange(len(self._db_parameter_explorations)):
+            if self._db_parameter_explorations[i].db_id == key:
+                return self._db_parameter_explorations[i]
+        return None
+    def db_get_parameter_exploration_by_id(self, key):
+        return self.db_parameter_explorations_id_index[key]
+    def db_has_parameter_exploration_with_id(self, key):
+        return key in self.db_parameter_explorations_id_index
+    
+    def __get_db_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def __set_db_actionAnnotations(self, actionAnnotations):
+        self._db_actionAnnotations = actionAnnotations
+        self.is_dirty = True
+    db_actionAnnotations = property(__get_db_actionAnnotations, __set_db_actionAnnotations)
+    def db_get_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def db_add_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_change_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                self._db_actionAnnotations[i] = actionAnnotation
+                found = True
+                break
+        if not found:
+            self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_delete_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                if not self._db_actionAnnotations[i].is_new:
+                    self.db_deleted_actionAnnotations.append(self._db_actionAnnotations[i])
+                del self._db_actionAnnotations[i]
+                break
+        del self.db_actionAnnotations_id_index[actionAnnotation.db_id]
+        del self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)]
+        try:
+            del self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)]
+        except KeyError:
+            pass
+    def db_get_actionAnnotation(self, key):
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == key:
+                return self._db_actionAnnotations[i]
+        return None
+    def db_get_actionAnnotation_by_id(self, key):
+        return self.db_actionAnnotations_id_index[key]
+    def db_has_actionAnnotation_with_id(self, key):
+        return key in self.db_actionAnnotations_id_index
+    def db_get_actionAnnotation_by_action_id(self, key):
+        return self.db_actionAnnotations_action_id_index[key]
+    def db_has_actionAnnotation_with_action_id(self, key):
+        return key in self.db_actionAnnotations_action_id_index
+    def db_get_actionAnnotation_by_key(self, key):
+        return self.db_actionAnnotations_key_index[key]
+    def db_has_actionAnnotation_with_key(self, key):
+        return key in self.db_actionAnnotations_key_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmArtifactValue(object):
+
+    vtType = 'opm_artifact_value'
+
+    def __init__(self, value=None):
+        self.db_deleted_value = []
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmArtifactValue.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmArtifactValue()
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmArtifactValue()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            if obj.vtType == 'portSpec':
+                new_obj.db_add_value(DBPortSpec.update_version(obj, trans_dict))
+            elif obj.vtType == 'function':
+                new_obj.db_add_value(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                if obj.vtType == 'portSpec':
+                    n_obj = DBPortSpec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'function':
+                    n_obj = DBFunction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_value)
+        if remove:
+            self.db_deleted_value = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+
+
+class DBConfigStr(object):
+
+    vtType = 'config_str'
+
+    def __init__(self, value=None):
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfigStr.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigStr(value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigStr()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBStartup(object):
+
+    vtType = 'startup'
+
+    def __init__(self, version=None, configuration=None, enabled_packages=None, disabled_packages=None):
+        self._db_version = version
+        self.db_deleted_configuration = []
+        self._db_configuration = configuration
+        self.db_deleted_enabled_packages = []
+        self._db_enabled_packages = enabled_packages
+        self.db_deleted_disabled_packages = []
+        self._db_disabled_packages = disabled_packages
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBStartup.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBStartup(version=self._db_version)
+        if self._db_configuration is not None:
+            cp._db_configuration = self._db_configuration.do_copy(new_ids, id_scope, id_remap)
+        if self._db_enabled_packages is not None:
+            cp._db_enabled_packages = self._db_enabled_packages.do_copy(new_ids, id_scope, id_remap)
+        if self._db_disabled_packages is not None:
+            cp._db_disabled_packages = self._db_disabled_packages.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBStartup()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'configuration' in class_dict:
+            res = class_dict['configuration'](old_obj, trans_dict)
+            new_obj.db_configuration = res
+        elif hasattr(old_obj, 'db_configuration') and old_obj.db_configuration is not None:
+            obj = old_obj.db_configuration
+            new_obj.db_add_configuration(DBConfiguration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_configuration') and hasattr(new_obj, 'db_deleted_configuration'):
+            for obj in old_obj.db_deleted_configuration:
+                n_obj = DBConfiguration.update_version(obj, trans_dict)
+                new_obj.db_deleted_configuration.append(n_obj)
+        if 'enabled_packages' in class_dict:
+            res = class_dict['enabled_packages'](old_obj, trans_dict)
+            new_obj.db_enabled_packages = res
+        elif hasattr(old_obj, 'db_enabled_packages') and old_obj.db_enabled_packages is not None:
+            obj = old_obj.db_enabled_packages
+            new_obj.db_add_enabled_packages(DBEnabledPackages.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_enabled_packages') and hasattr(new_obj, 'db_deleted_enabled_packages'):
+            for obj in old_obj.db_deleted_enabled_packages:
+                n_obj = DBEnabledPackages.update_version(obj, trans_dict)
+                new_obj.db_deleted_enabled_packages.append(n_obj)
+        if 'disabled_packages' in class_dict:
+            res = class_dict['disabled_packages'](old_obj, trans_dict)
+            new_obj.db_disabled_packages = res
+        elif hasattr(old_obj, 'db_disabled_packages') and old_obj.db_disabled_packages is not None:
+            obj = old_obj.db_disabled_packages
+            new_obj.db_add_disabled_packages(DBDisabledPackages.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_disabled_packages') and hasattr(new_obj, 'db_deleted_disabled_packages'):
+            for obj in old_obj.db_deleted_disabled_packages:
+                n_obj = DBDisabledPackages.update_version(obj, trans_dict)
+                new_obj.db_deleted_disabled_packages.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_configuration is not None:
+            children.extend(self._db_configuration.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_configuration = None
+        if self._db_enabled_packages is not None:
+            children.extend(self._db_enabled_packages.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_enabled_packages = None
+        if self._db_disabled_packages is not None:
+            children.extend(self._db_disabled_packages.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_disabled_packages = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_configuration)
+        children.extend(self.db_deleted_enabled_packages)
+        children.extend(self.db_deleted_disabled_packages)
+        if remove:
+            self.db_deleted_configuration = []
+            self.db_deleted_enabled_packages = []
+            self.db_deleted_disabled_packages = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_configuration is not None and self._db_configuration.has_changes():
+            return True
+        if self._db_enabled_packages is not None and self._db_enabled_packages.has_changes():
+            return True
+        if self._db_disabled_packages is not None and self._db_disabled_packages.has_changes():
+            return True
+        return False
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_configuration(self):
+        return self._db_configuration
+    def __set_db_configuration(self, configuration):
+        self._db_configuration = configuration
+        self.is_dirty = True
+    db_configuration = property(__get_db_configuration, __set_db_configuration)
+    def db_add_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_change_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_delete_configuration(self, configuration):
+        if not self.is_new:
+            self.db_deleted_configuration.append(self._db_configuration)
+        self._db_configuration = None
+    
+    def __get_db_enabled_packages(self):
+        return self._db_enabled_packages
+    def __set_db_enabled_packages(self, enabled_packages):
+        self._db_enabled_packages = enabled_packages
+        self.is_dirty = True
+    db_enabled_packages = property(__get_db_enabled_packages, __set_db_enabled_packages)
+    def db_add_enabled_packages(self, enabled_packages):
+        self._db_enabled_packages = enabled_packages
+    def db_change_enabled_packages(self, enabled_packages):
+        self._db_enabled_packages = enabled_packages
+    def db_delete_enabled_packages(self, enabled_packages):
+        if not self.is_new:
+            self.db_deleted_enabled_packages.append(self._db_enabled_packages)
+        self._db_enabled_packages = None
+    
+    def __get_db_disabled_packages(self):
+        return self._db_disabled_packages
+    def __set_db_disabled_packages(self, disabled_packages):
+        self._db_disabled_packages = disabled_packages
+        self.is_dirty = True
+    db_disabled_packages = property(__get_db_disabled_packages, __set_db_disabled_packages)
+    def db_add_disabled_packages(self, disabled_packages):
+        self._db_disabled_packages = disabled_packages
+    def db_change_disabled_packages(self, disabled_packages):
+        self._db_disabled_packages = disabled_packages
+    def db_delete_disabled_packages(self, disabled_packages):
+        if not self.is_new:
+            self.db_deleted_disabled_packages.append(self._db_disabled_packages)
+        self._db_disabled_packages = None
+    
+
+
+class DBModule(object):
+
+    vtType = 'module'
+
+    def __init__(self, id=None, cache=None, name=None, namespace=None, package=None, version=None, location=None, functions=None, annotations=None, controlParameters=None, portSpecs=None):
+        self._db_id = id
+        self._db_cache = cache
+        self._db_name = name
+        self._db_namespace = namespace
+        self._db_package = package
+        self._db_version = version
+        self.db_deleted_location = []
+        self._db_location = location
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
+        else:
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_controlParameters = []
+        self.db_controlParameters_id_index = {}
+        self.db_controlParameters_name_index = {}
+        if controlParameters is None:
+            self._db_controlParameters = []
+        else:
+            self._db_controlParameters = controlParameters
+            for v in self._db_controlParameters:
+                self.db_controlParameters_id_index[v.db_id] = v
+                self.db_controlParameters_name_index[v.db_name] = v
+        self.db_deleted_portSpecs = []
+        self.db_portSpecs_id_index = {}
+        self.db_portSpecs_name_index = {}
+        if portSpecs is None:
+            self._db_portSpecs = []
+        else:
+            self._db_portSpecs = portSpecs
+            for v in self._db_portSpecs:
+                self.db_portSpecs_id_index[v.db_id] = v
+                self.db_portSpecs_name_index[(v.db_name,v.db_type)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBModule.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBModule(id=self._db_id,
+                      cache=self._db_cache,
+                      name=self._db_name,
+                      namespace=self._db_namespace,
+                      package=self._db_package,
+                      version=self._db_version)
+        if self._db_location is not None:
+            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
+        if self._db_functions is None:
+            cp._db_functions = []
+        else:
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_controlParameters is None:
+            cp._db_controlParameters = []
+        else:
+            cp._db_controlParameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_controlParameters]
+        if self._db_portSpecs is None:
+            cp._db_portSpecs = []
+        else:
+            cp._db_portSpecs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_controlParameters_id_index = dict((v.db_id, v) for v in cp._db_controlParameters)
+        cp.db_controlParameters_name_index = dict((v.db_name, v) for v in cp._db_controlParameters)
+        cp.db_portSpecs_id_index = dict((v.db_id, v) for v in cp._db_portSpecs)
+        cp.db_portSpecs_name_index = dict(((v.db_name,v.db_type), v) for v in cp._db_portSpecs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBModule()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'cache' in class_dict:
+            res = class_dict['cache'](old_obj, trans_dict)
+            new_obj.db_cache = res
+        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
+            new_obj.db_cache = old_obj.db_cache
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'location' in class_dict:
+            res = class_dict['location'](old_obj, trans_dict)
+            new_obj.db_location = res
+        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
+            obj = old_obj.db_location
+            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
+            for obj in old_obj.db_deleted_location:
+                n_obj = DBLocation.update_version(obj, trans_dict)
+                new_obj.db_deleted_location.append(n_obj)
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'controlParameters' in class_dict:
+            res = class_dict['controlParameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_controlParameter(obj)
+        elif hasattr(old_obj, 'db_controlParameters') and old_obj.db_controlParameters is not None:
+            for obj in old_obj.db_controlParameters:
+                new_obj.db_add_controlParameter(DBControlParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_controlParameters') and hasattr(new_obj, 'db_deleted_controlParameters'):
+            for obj in old_obj.db_deleted_controlParameters:
+                n_obj = DBControlParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_controlParameters.append(n_obj)
+        if 'portSpecs' in class_dict:
+            res = class_dict['portSpecs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_portSpec(obj)
+        elif hasattr(old_obj, 'db_portSpecs') and old_obj.db_portSpecs is not None:
+            for obj in old_obj.db_portSpecs:
+                new_obj.db_add_portSpec(DBPortSpec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_portSpecs') and hasattr(new_obj, 'db_deleted_portSpecs'):
+            for obj in old_obj.db_deleted_portSpecs:
+                n_obj = DBPortSpec.update_version(obj, trans_dict)
+                new_obj.db_deleted_portSpecs.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_location is not None:
+            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_location = None
+        to_del = []
+        for child in self.db_functions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_function(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_controlParameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_controlParameter(child)
+        to_del = []
+        for child in self.db_portSpecs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_portSpec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_location)
+        children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_controlParameters)
+        children.extend(self.db_deleted_portSpecs)
+        if remove:
+            self.db_deleted_location = []
+            self.db_deleted_functions = []
+            self.db_deleted_annotations = []
+            self.db_deleted_controlParameters = []
+            self.db_deleted_portSpecs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_location is not None and self._db_location.has_changes():
+            return True
+        for child in self._db_functions:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_controlParameters:
+            if child.has_changes():
+                return True
+        for child in self._db_portSpecs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_cache(self):
+        return self._db_cache
+    def __set_db_cache(self, cache):
+        self._db_cache = cache
+        self.is_dirty = True
+    db_cache = property(__get_db_cache, __set_db_cache)
+    def db_add_cache(self, cache):
+        self._db_cache = cache
+    def db_change_cache(self, cache):
+        self._db_cache = cache
+    def db_delete_cache(self, cache):
+        self._db_cache = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_location(self):
+        return self._db_location
+    def __set_db_location(self, location):
+        self._db_location = location
+        self.is_dirty = True
+    db_location = property(__get_db_location, __set_db_location)
+    def db_add_location(self, location):
+        self._db_location = location
+    def db_change_location(self, location):
+        self._db_location = location
+    def db_delete_location(self, location):
+        if not self.is_new:
+            self.db_deleted_location.append(self._db_location)
+        self._db_location = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
+        self.is_dirty = True
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
+        self.is_dirty = True
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
+                found = True
+                break
+        if not found:
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
+        self.is_dirty = True
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
+                break
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
+        return None
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_controlParameters(self):
+        return self._db_controlParameters
+    def __set_db_controlParameters(self, controlParameters):
+        self._db_controlParameters = controlParameters
+        self.is_dirty = True
+    db_controlParameters = property(__get_db_controlParameters, __set_db_controlParameters)
+    def db_get_controlParameters(self):
+        return self._db_controlParameters
+    def db_add_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_change_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                self._db_controlParameters[i] = controlParameter
+                found = True
+                break
+        if not found:
+            self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_delete_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                if not self._db_controlParameters[i].is_new:
+                    self.db_deleted_controlParameters.append(self._db_controlParameters[i])
+                del self._db_controlParameters[i]
+                break
+        del self.db_controlParameters_id_index[controlParameter.db_id]
+        del self.db_controlParameters_name_index[controlParameter.db_name]
+    def db_get_controlParameter(self, key):
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == key:
+                return self._db_controlParameters[i]
+        return None
+    def db_get_controlParameter_by_id(self, key):
+        return self.db_controlParameters_id_index[key]
+    def db_has_controlParameter_with_id(self, key):
+        return key in self.db_controlParameters_id_index
+    def db_get_controlParameter_by_name(self, key):
+        return self.db_controlParameters_name_index[key]
+    def db_has_controlParameter_with_name(self, key):
+        return key in self.db_controlParameters_name_index
+    
+    def __get_db_portSpecs(self):
+        return self._db_portSpecs
+    def __set_db_portSpecs(self, portSpecs):
+        self._db_portSpecs = portSpecs
+        self.is_dirty = True
+    db_portSpecs = property(__get_db_portSpecs, __set_db_portSpecs)
+    def db_get_portSpecs(self):
+        return self._db_portSpecs
+    def db_add_portSpec(self, portSpec):
+        self.is_dirty = True
+        self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_change_portSpec(self, portSpec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                self._db_portSpecs[i] = portSpec
+                found = True
+                break
+        if not found:
+            self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_delete_portSpec(self, portSpec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                if not self._db_portSpecs[i].is_new:
+                    self.db_deleted_portSpecs.append(self._db_portSpecs[i])
+                del self._db_portSpecs[i]
+                break
+        del self.db_portSpecs_id_index[portSpec.db_id]
+        del self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)]
+    def db_get_portSpec(self, key):
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == key:
+                return self._db_portSpecs[i]
+        return None
+    def db_get_portSpec_by_id(self, key):
+        return self.db_portSpecs_id_index[key]
+    def db_has_portSpec_with_id(self, key):
+        return key in self.db_portSpecs_id_index
+    def db_get_portSpec_by_name(self, key):
+        return self.db_portSpecs_name_index[key]
+    def db_has_portSpec_with_name(self, key):
+        return key in self.db_portSpecs_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBPort(object):
+
+    vtType = 'port'
+
+    def __init__(self, id=None, type=None, moduleId=None, moduleName=None, name=None, signature=None):
+        self._db_id = id
+        self._db_type = type
+        self._db_moduleId = moduleId
+        self._db_moduleName = moduleName
+        self._db_name = name
+        self._db_signature = signature
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPort.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPort(id=self._db_id,
+                    type=self._db_type,
+                    moduleId=self._db_moduleId,
+                    moduleName=self._db_moduleName,
+                    name=self._db_name,
+                    signature=self._db_signature)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_moduleId') and ('module', self._db_moduleId) in id_remap:
+                cp._db_moduleId = id_remap[('module', self._db_moduleId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPort()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'moduleId' in class_dict:
+            res = class_dict['moduleId'](old_obj, trans_dict)
+            new_obj.db_moduleId = res
+        elif hasattr(old_obj, 'db_moduleId') and old_obj.db_moduleId is not None:
+            new_obj.db_moduleId = old_obj.db_moduleId
+        if 'moduleName' in class_dict:
+            res = class_dict['moduleName'](old_obj, trans_dict)
+            new_obj.db_moduleName = res
+        elif hasattr(old_obj, 'db_moduleName') and old_obj.db_moduleName is not None:
+            new_obj.db_moduleName = old_obj.db_moduleName
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'signature' in class_dict:
+            res = class_dict['signature'](old_obj, trans_dict)
+            new_obj.db_signature = res
+        elif hasattr(old_obj, 'db_signature') and old_obj.db_signature is not None:
+            new_obj.db_signature = old_obj.db_signature
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_moduleId(self):
+        return self._db_moduleId
+    def __set_db_moduleId(self, moduleId):
+        self._db_moduleId = moduleId
+        self.is_dirty = True
+    db_moduleId = property(__get_db_moduleId, __set_db_moduleId)
+    def db_add_moduleId(self, moduleId):
+        self._db_moduleId = moduleId
+    def db_change_moduleId(self, moduleId):
+        self._db_moduleId = moduleId
+    def db_delete_moduleId(self, moduleId):
+        self._db_moduleId = None
+    
+    def __get_db_moduleName(self):
+        return self._db_moduleName
+    def __set_db_moduleName(self, moduleName):
+        self._db_moduleName = moduleName
+        self.is_dirty = True
+    db_moduleName = property(__get_db_moduleName, __set_db_moduleName)
+    def db_add_moduleName(self, moduleName):
+        self._db_moduleName = moduleName
+    def db_change_moduleName(self, moduleName):
+        self._db_moduleName = moduleName
+    def db_delete_moduleName(self, moduleName):
+        self._db_moduleName = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_signature(self):
+        return self._db_signature
+    def __set_db_signature(self, signature):
+        self._db_signature = signature
+        self.is_dirty = True
+    db_signature = property(__get_db_signature, __set_db_signature)
+    def db_add_signature(self, signature):
+        self._db_signature = signature
+    def db_change_signature(self, signature):
+        self._db_signature = signature
+    def db_delete_signature(self, signature):
+        self._db_signature = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmAgents(object):
+
+    vtType = 'opm_agents'
+
+    def __init__(self, agents=None):
+        self.db_deleted_agents = []
+        self.db_agents_id_index = {}
+        if agents is None:
+            self._db_agents = []
+        else:
+            self._db_agents = agents
+            for v in self._db_agents:
+                self.db_agents_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAgents.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAgents()
+        if self._db_agents is None:
+            cp._db_agents = []
+        else:
+            cp._db_agents = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_agents]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_agents_id_index = dict((v.db_id, v) for v in cp._db_agents)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAgents()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'agents' in class_dict:
+            res = class_dict['agents'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_agent(obj)
+        elif hasattr(old_obj, 'db_agents') and old_obj.db_agents is not None:
+            for obj in old_obj.db_agents:
+                new_obj.db_add_agent(DBOpmAgent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_agents') and hasattr(new_obj, 'db_deleted_agents'):
+            for obj in old_obj.db_deleted_agents:
+                n_obj = DBOpmAgent.update_version(obj, trans_dict)
+                new_obj.db_deleted_agents.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_agents:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_agent(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_agents)
+        if remove:
+            self.db_deleted_agents = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_agents:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_agents(self):
+        return self._db_agents
+    def __set_db_agents(self, agents):
+        self._db_agents = agents
+        self.is_dirty = True
+    db_agents = property(__get_db_agents, __set_db_agents)
+    def db_get_agents(self):
+        return self._db_agents
+    def db_add_agent(self, agent):
+        self.is_dirty = True
+        self._db_agents.append(agent)
+        self.db_agents_id_index[agent.db_id] = agent
+    def db_change_agent(self, agent):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_agents)):
+            if self._db_agents[i].db_id == agent.db_id:
+                self._db_agents[i] = agent
+                found = True
+                break
+        if not found:
+            self._db_agents.append(agent)
+        self.db_agents_id_index[agent.db_id] = agent
+    def db_delete_agent(self, agent):
+        self.is_dirty = True
+        for i in xrange(len(self._db_agents)):
+            if self._db_agents[i].db_id == agent.db_id:
+                if not self._db_agents[i].is_new:
+                    self.db_deleted_agents.append(self._db_agents[i])
+                del self._db_agents[i]
+                break
+        del self.db_agents_id_index[agent.db_id]
+    def db_get_agent(self, key):
+        for i in xrange(len(self._db_agents)):
+            if self._db_agents[i].db_id == key:
+                return self._db_agents[i]
+        return None
+    def db_get_agent_by_id(self, key):
+        return self.db_agents_id_index[key]
+    def db_has_agent_with_id(self, key):
+        return key in self.db_agents_id_index
+    
+
+
+class DBOpmDependencies(object):
+
+    vtType = 'opm_dependencies'
+
+    def __init__(self, dependencys=None):
+        self.db_deleted_dependencys = []
+        if dependencys is None:
+            self._db_dependencys = []
+        else:
+            self._db_dependencys = dependencys
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmDependencies.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmDependencies()
+        if self._db_dependencys is None:
+            cp._db_dependencys = []
+        else:
+            cp._db_dependencys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_dependencys]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmDependencies()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'dependencys' in class_dict:
+            res = class_dict['dependencys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_dependency(obj)
+        elif hasattr(old_obj, 'db_dependencys') and old_obj.db_dependencys is not None:
+            for obj in old_obj.db_dependencys:
+                if obj.vtType == 'opm_used':
+                    new_obj.db_add_dependency(DBOpmUsed.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_generated_by':
+                    new_obj.db_add_dependency(DBOpmWasGeneratedBy.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_triggered_by':
+                    new_obj.db_add_dependency(DBOpmWasTriggeredBy.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_derived_from':
+                    new_obj.db_add_dependency(DBOpmWasDerivedFrom.update_version(obj, trans_dict))
+                elif obj.vtType == 'opm_was_controlled_by':
+                    new_obj.db_add_dependency(DBOpmWasControlledBy.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_dependencys') and hasattr(new_obj, 'db_deleted_dependencys'):
+            for obj in old_obj.db_deleted_dependencys:
+                if obj.vtType == 'opm_used':
+                    n_obj = DBOpmUsed.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_generated_by':
+                    n_obj = DBOpmWasGeneratedBy.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_triggered_by':
+                    n_obj = DBOpmWasTriggeredBy.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_derived_from':
+                    n_obj = DBOpmWasDerivedFrom.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+                elif obj.vtType == 'opm_was_controlled_by':
+                    n_obj = DBOpmWasControlledBy.update_version(obj, trans_dict)
+                    new_obj.db_deleted_dependencys.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_dependencys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_dependency(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_dependencys)
+        if remove:
+            self.db_deleted_dependencys = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_dependencys:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_dependencys(self):
+        return self._db_dependencys
+    def __set_db_dependencys(self, dependencys):
+        self._db_dependencys = dependencys
+        self.is_dirty = True
+    db_dependencys = property(__get_db_dependencys, __set_db_dependencys)
+    def db_get_dependencys(self):
+        return self._db_dependencys
+    def db_add_dependency(self, dependency):
+        self.is_dirty = True
+        self._db_dependencys.append(dependency)
+    def db_change_dependency(self, dependency):
+        self.is_dirty = True
+        self._db_dependencys.append(dependency)
+    def db_delete_dependency(self, dependency):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_dependency(self, key):
+        return None
+    
+
+
+class DBPEFunction(object):
+
+    vtType = 'pe_function'
+
+    def __init__(self, id=None, module_id=None, port_name=None, is_alias=None, parameters=None):
+        self._db_id = id
+        self._db_module_id = module_id
+        self._db_port_name = port_name
+        self._db_is_alias = is_alias
+        self.db_deleted_parameters = []
+        self.db_parameters_id_index = {}
+        if parameters is None:
+            self._db_parameters = []
+        else:
+            self._db_parameters = parameters
+            for v in self._db_parameters:
+                self.db_parameters_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPEFunction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPEFunction(id=self._db_id,
+                          module_id=self._db_module_id,
+                          port_name=self._db_port_name,
+                          is_alias=self._db_is_alias)
+        if self._db_parameters is None:
+            cp._db_parameters = []
+        else:
+            cp._db_parameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameters]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
+                cp._db_module_id = id_remap[('module', self._db_module_id)]
+        
+        # recreate indices and set flags
+        cp.db_parameters_id_index = dict((v.db_id, v) for v in cp._db_parameters)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPEFunction()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'module_id' in class_dict:
+            res = class_dict['module_id'](old_obj, trans_dict)
+            new_obj.db_module_id = res
+        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
+            new_obj.db_module_id = old_obj.db_module_id
+        if 'port_name' in class_dict:
+            res = class_dict['port_name'](old_obj, trans_dict)
+            new_obj.db_port_name = res
+        elif hasattr(old_obj, 'db_port_name') and old_obj.db_port_name is not None:
+            new_obj.db_port_name = old_obj.db_port_name
+        if 'is_alias' in class_dict:
+            res = class_dict['is_alias'](old_obj, trans_dict)
+            new_obj.db_is_alias = res
+        elif hasattr(old_obj, 'db_is_alias') and old_obj.db_is_alias is not None:
+            new_obj.db_is_alias = old_obj.db_is_alias
+        if 'parameters' in class_dict:
+            res = class_dict['parameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_parameter(obj)
+        elif hasattr(old_obj, 'db_parameters') and old_obj.db_parameters is not None:
+            for obj in old_obj.db_parameters:
+                new_obj.db_add_parameter(DBPEParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_parameters') and hasattr(new_obj, 'db_deleted_parameters'):
+            for obj in old_obj.db_deleted_parameters:
+                n_obj = DBPEParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_parameters.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_parameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_parameter(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_parameters)
+        if remove:
+            self.db_deleted_parameters = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_parameters:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_module_id(self):
+        return self._db_module_id
+    def __set_db_module_id(self, module_id):
+        self._db_module_id = module_id
+        self.is_dirty = True
+    db_module_id = property(__get_db_module_id, __set_db_module_id)
+    def db_add_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_change_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_delete_module_id(self, module_id):
+        self._db_module_id = None
+    
+    def __get_db_port_name(self):
+        return self._db_port_name
+    def __set_db_port_name(self, port_name):
+        self._db_port_name = port_name
+        self.is_dirty = True
+    db_port_name = property(__get_db_port_name, __set_db_port_name)
+    def db_add_port_name(self, port_name):
+        self._db_port_name = port_name
+    def db_change_port_name(self, port_name):
+        self._db_port_name = port_name
+    def db_delete_port_name(self, port_name):
+        self._db_port_name = None
+    
+    def __get_db_is_alias(self):
+        return self._db_is_alias
+    def __set_db_is_alias(self, is_alias):
+        self._db_is_alias = is_alias
+        self.is_dirty = True
+    db_is_alias = property(__get_db_is_alias, __set_db_is_alias)
+    def db_add_is_alias(self, is_alias):
+        self._db_is_alias = is_alias
+    def db_change_is_alias(self, is_alias):
+        self._db_is_alias = is_alias
+    def db_delete_is_alias(self, is_alias):
+        self._db_is_alias = None
+    
+    def __get_db_parameters(self):
+        return self._db_parameters
+    def __set_db_parameters(self, parameters):
+        self._db_parameters = parameters
+        self.is_dirty = True
+    db_parameters = property(__get_db_parameters, __set_db_parameters)
+    def db_get_parameters(self):
+        return self._db_parameters
+    def db_add_parameter(self, parameter):
+        self.is_dirty = True
+        self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_change_parameter(self, parameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                self._db_parameters[i] = parameter
+                found = True
+                break
+        if not found:
+            self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_delete_parameter(self, parameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                if not self._db_parameters[i].is_new:
+                    self.db_deleted_parameters.append(self._db_parameters[i])
+                del self._db_parameters[i]
+                break
+        del self.db_parameters_id_index[parameter.db_id]
+    def db_get_parameter(self, key):
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == key:
+                return self._db_parameters[i]
+        return None
+    def db_get_parameter_by_id(self, key):
+        return self.db_parameters_id_index[key]
+    def db_has_parameter_with_id(self, key):
+        return key in self.db_parameters_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBWorkflow(object):
+
+    vtType = 'workflow'
+
+    def __init__(self, modules=None, id=None, entity_type=None, name=None, version=None, last_modified=None, connections=None, annotations=None, plugin_datas=None, others=None, vistrail_id=None):
+        self.db_deleted_modules = []
+        self.db_modules_id_index = {}
+        if modules is None:
+            self._db_modules = []
+        else:
+            self._db_modules = modules
+            for v in self._db_modules:
+                self.db_modules_id_index[v.db_id] = v
+        self._db_id = id
+        self._db_entity_type = entity_type
+        self._db_name = name
+        self._db_version = version
+        self._db_last_modified = last_modified
+        self.db_deleted_connections = []
+        self.db_connections_id_index = {}
+        if connections is None:
+            self._db_connections = []
+        else:
+            self._db_connections = connections
+            for v in self._db_connections:
+                self.db_connections_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+        self.db_deleted_plugin_datas = []
+        self.db_plugin_datas_id_index = {}
+        if plugin_datas is None:
+            self._db_plugin_datas = []
+        else:
+            self._db_plugin_datas = plugin_datas
+            for v in self._db_plugin_datas:
+                self.db_plugin_datas_id_index[v.db_id] = v
+        self.db_deleted_others = []
+        self.db_others_id_index = {}
+        if others is None:
+            self._db_others = []
+        else:
+            self._db_others = others
+            for v in self._db_others:
+                self.db_others_id_index[v.db_id] = v
+        self._db_vistrail_id = vistrail_id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBWorkflow.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBWorkflow(id=self._db_id,
+                        entity_type=self._db_entity_type,
+                        name=self._db_name,
+                        version=self._db_version,
+                        last_modified=self._db_last_modified,
+                        vistrail_id=self._db_vistrail_id)
+        if self._db_modules is None:
+            cp._db_modules = []
+        else:
+            cp._db_modules = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_modules]
+        if self._db_connections is None:
+            cp._db_connections = []
+        else:
+            cp._db_connections = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_connections]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_plugin_datas is None:
+            cp._db_plugin_datas = []
+        else:
+            cp._db_plugin_datas = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_plugin_datas]
+        if self._db_others is None:
+            cp._db_others = []
+        else:
+            cp._db_others = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_others]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_vistrail_id') and ('vistrail', self._db_vistrail_id) in id_remap:
+                cp._db_vistrail_id = id_remap[('vistrail', self._db_vistrail_id)]
+        
+        # recreate indices and set flags
+        cp.db_modules_id_index = dict((v.db_id, v) for v in cp._db_modules)
+        cp.db_connections_id_index = dict((v.db_id, v) for v in cp._db_connections)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_plugin_datas_id_index = dict((v.db_id, v) for v in cp._db_plugin_datas)
+        cp.db_others_id_index = dict((v.db_id, v) for v in cp._db_others)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBWorkflow()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'modules' in class_dict:
+            res = class_dict['modules'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_module(obj)
+        elif hasattr(old_obj, 'db_modules') and old_obj.db_modules is not None:
+            for obj in old_obj.db_modules:
+                if obj.vtType == 'module':
+                    new_obj.db_add_module(DBModule.update_version(obj, trans_dict))
+                elif obj.vtType == 'abstraction':
+                    new_obj.db_add_module(DBAbstraction.update_version(obj, trans_dict))
+                elif obj.vtType == 'group':
+                    new_obj.db_add_module(DBGroup.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_modules') and hasattr(new_obj, 'db_deleted_modules'):
+            for obj in old_obj.db_deleted_modules:
+                if obj.vtType == 'module':
+                    n_obj = DBModule.update_version(obj, trans_dict)
+                    new_obj.db_deleted_modules.append(n_obj)
+                elif obj.vtType == 'abstraction':
+                    n_obj = DBAbstraction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_modules.append(n_obj)
+                elif obj.vtType == 'group':
+                    n_obj = DBGroup.update_version(obj, trans_dict)
+                    new_obj.db_deleted_modules.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'connections' in class_dict:
+            res = class_dict['connections'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_connection(obj)
+        elif hasattr(old_obj, 'db_connections') and old_obj.db_connections is not None:
+            for obj in old_obj.db_connections:
+                new_obj.db_add_connection(DBConnection.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_connections') and hasattr(new_obj, 'db_deleted_connections'):
+            for obj in old_obj.db_deleted_connections:
+                n_obj = DBConnection.update_version(obj, trans_dict)
+                new_obj.db_deleted_connections.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'plugin_datas' in class_dict:
+            res = class_dict['plugin_datas'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_plugin_data(obj)
+        elif hasattr(old_obj, 'db_plugin_datas') and old_obj.db_plugin_datas is not None:
+            for obj in old_obj.db_plugin_datas:
+                new_obj.db_add_plugin_data(DBPluginData.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_plugin_datas') and hasattr(new_obj, 'db_deleted_plugin_datas'):
+            for obj in old_obj.db_deleted_plugin_datas:
+                n_obj = DBPluginData.update_version(obj, trans_dict)
+                new_obj.db_deleted_plugin_datas.append(n_obj)
+        if 'others' in class_dict:
+            res = class_dict['others'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_other(obj)
+        elif hasattr(old_obj, 'db_others') and old_obj.db_others is not None:
+            for obj in old_obj.db_others:
+                new_obj.db_add_other(DBOther.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_others') and hasattr(new_obj, 'db_deleted_others'):
+            for obj in old_obj.db_deleted_others:
+                n_obj = DBOther.update_version(obj, trans_dict)
+                new_obj.db_deleted_others.append(n_obj)
+        if 'vistrail_id' in class_dict:
+            res = class_dict['vistrail_id'](old_obj, trans_dict)
+            new_obj.db_vistrail_id = res
+        elif hasattr(old_obj, 'db_vistrail_id') and old_obj.db_vistrail_id is not None:
+            new_obj.db_vistrail_id = old_obj.db_vistrail_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_connections:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_connection(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_plugin_datas:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_plugin_data(child)
+        to_del = []
+        for child in self.db_others:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_other(child)
+        to_del = []
+        for child in self.db_modules:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_module(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_connections)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_plugin_datas)
+        children.extend(self.db_deleted_others)
+        children.extend(self.db_deleted_modules)
+        if remove:
+            self.db_deleted_connections = []
+            self.db_deleted_annotations = []
+            self.db_deleted_plugin_datas = []
+            self.db_deleted_others = []
+            self.db_deleted_modules = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_connections:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_plugin_datas:
+            if child.has_changes():
+                return True
+        for child in self._db_others:
+            if child.has_changes():
+                return True
+        for child in self._db_modules:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_modules(self):
+        return self._db_modules
+    def __set_db_modules(self, modules):
+        self._db_modules = modules
+        self.is_dirty = True
+    db_modules = property(__get_db_modules, __set_db_modules)
+    def db_get_modules(self):
+        return self._db_modules
+    def db_add_module(self, module):
+        self.is_dirty = True
+        self._db_modules.append(module)
+        self.db_modules_id_index[module.db_id] = module
+    def db_change_module(self, module):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_modules)):
+            if self._db_modules[i].db_id == module.db_id:
+                self._db_modules[i] = module
+                found = True
+                break
+        if not found:
+            self._db_modules.append(module)
+        self.db_modules_id_index[module.db_id] = module
+    def db_delete_module(self, module):
+        self.is_dirty = True
+        for i in xrange(len(self._db_modules)):
+            if self._db_modules[i].db_id == module.db_id:
+                if not self._db_modules[i].is_new:
+                    self.db_deleted_modules.append(self._db_modules[i])
+                del self._db_modules[i]
+                break
+        del self.db_modules_id_index[module.db_id]
+    def db_get_module(self, key):
+        for i in xrange(len(self._db_modules)):
+            if self._db_modules[i].db_id == key:
+                return self._db_modules[i]
+        return None
+    def db_get_module_by_id(self, key):
+        return self.db_modules_id_index[key]
+    def db_has_module_with_id(self, key):
+        return key in self.db_modules_id_index
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+        self.is_dirty = True
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_connections(self):
+        return self._db_connections
+    def __set_db_connections(self, connections):
+        self._db_connections = connections
+        self.is_dirty = True
+    db_connections = property(__get_db_connections, __set_db_connections)
+    def db_get_connections(self):
+        return self._db_connections
+    def db_add_connection(self, connection):
+        self.is_dirty = True
+        self._db_connections.append(connection)
+        self.db_connections_id_index[connection.db_id] = connection
+    def db_change_connection(self, connection):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_connections)):
+            if self._db_connections[i].db_id == connection.db_id:
+                self._db_connections[i] = connection
+                found = True
+                break
+        if not found:
+            self._db_connections.append(connection)
+        self.db_connections_id_index[connection.db_id] = connection
+    def db_delete_connection(self, connection):
+        self.is_dirty = True
+        for i in xrange(len(self._db_connections)):
+            if self._db_connections[i].db_id == connection.db_id:
+                if not self._db_connections[i].is_new:
+                    self.db_deleted_connections.append(self._db_connections[i])
+                del self._db_connections[i]
+                break
+        del self.db_connections_id_index[connection.db_id]
+    def db_get_connection(self, key):
+        for i in xrange(len(self._db_connections)):
+            if self._db_connections[i].db_id == key:
+                return self._db_connections[i]
+        return None
+    def db_get_connection_by_id(self, key):
+        return self.db_connections_id_index[key]
+    def db_has_connection_with_id(self, key):
+        return key in self.db_connections_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    
+    def __get_db_plugin_datas(self):
+        return self._db_plugin_datas
+    def __set_db_plugin_datas(self, plugin_datas):
+        self._db_plugin_datas = plugin_datas
+        self.is_dirty = True
+    db_plugin_datas = property(__get_db_plugin_datas, __set_db_plugin_datas)
+    def db_get_plugin_datas(self):
+        return self._db_plugin_datas
+    def db_add_plugin_data(self, plugin_data):
+        self.is_dirty = True
+        self._db_plugin_datas.append(plugin_data)
+        self.db_plugin_datas_id_index[plugin_data.db_id] = plugin_data
+    def db_change_plugin_data(self, plugin_data):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_plugin_datas)):
+            if self._db_plugin_datas[i].db_id == plugin_data.db_id:
+                self._db_plugin_datas[i] = plugin_data
+                found = True
+                break
+        if not found:
+            self._db_plugin_datas.append(plugin_data)
+        self.db_plugin_datas_id_index[plugin_data.db_id] = plugin_data
+    def db_delete_plugin_data(self, plugin_data):
+        self.is_dirty = True
+        for i in xrange(len(self._db_plugin_datas)):
+            if self._db_plugin_datas[i].db_id == plugin_data.db_id:
+                if not self._db_plugin_datas[i].is_new:
+                    self.db_deleted_plugin_datas.append(self._db_plugin_datas[i])
+                del self._db_plugin_datas[i]
+                break
+        del self.db_plugin_datas_id_index[plugin_data.db_id]
+    def db_get_plugin_data(self, key):
+        for i in xrange(len(self._db_plugin_datas)):
+            if self._db_plugin_datas[i].db_id == key:
+                return self._db_plugin_datas[i]
+        return None
+    def db_get_plugin_data_by_id(self, key):
+        return self.db_plugin_datas_id_index[key]
+    def db_has_plugin_data_with_id(self, key):
+        return key in self.db_plugin_datas_id_index
+    
+    def __get_db_others(self):
+        return self._db_others
+    def __set_db_others(self, others):
+        self._db_others = others
+        self.is_dirty = True
+    db_others = property(__get_db_others, __set_db_others)
+    def db_get_others(self):
+        return self._db_others
+    def db_add_other(self, other):
+        self.is_dirty = True
+        self._db_others.append(other)
+        self.db_others_id_index[other.db_id] = other
+    def db_change_other(self, other):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_others)):
+            if self._db_others[i].db_id == other.db_id:
+                self._db_others[i] = other
+                found = True
+                break
+        if not found:
+            self._db_others.append(other)
+        self.db_others_id_index[other.db_id] = other
+    def db_delete_other(self, other):
+        self.is_dirty = True
+        for i in xrange(len(self._db_others)):
+            if self._db_others[i].db_id == other.db_id:
+                if not self._db_others[i].is_new:
+                    self.db_deleted_others.append(self._db_others[i])
+                del self._db_others[i]
+                break
+        del self.db_others_id_index[other.db_id]
+    def db_get_other(self, key):
+        for i in xrange(len(self._db_others)):
+            if self._db_others[i].db_id == key:
+                return self._db_others[i]
+        return None
+    def db_get_other_by_id(self, key):
+        return self.db_others_id_index[key]
+    def db_has_other_with_id(self, key):
+        return key in self.db_others_id_index
+    
+    def __get_db_vistrail_id(self):
+        return self._db_vistrail_id
+    def __set_db_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+        self.is_dirty = True
+    db_vistrail_id = property(__get_db_vistrail_id, __set_db_vistrail_id)
+    def db_add_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_change_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_delete_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBMashupAction(object):
+
+    vtType = 'mashup_action'
+
+    def __init__(self, id=None, prevId=None, date=None, user=None, mashup=None):
+        self._db_id = id
+        self._db_prevId = prevId
+        self._db_date = date
+        self._db_user = user
+        self.db_deleted_mashup = []
+        self._db_mashup = mashup
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashupAction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashupAction(id=self._db_id,
+                            prevId=self._db_prevId,
+                            date=self._db_date,
+                            user=self._db_user)
+        if self._db_mashup is not None:
+            cp._db_mashup = self._db_mashup.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prevId') and ('mashup_action', self._db_prevId) in id_remap:
+                cp._db_prevId = id_remap[('mashup_action', self._db_prevId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMashupAction()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'prevId' in class_dict:
+            res = class_dict['prevId'](old_obj, trans_dict)
+            new_obj.db_prevId = res
+        elif hasattr(old_obj, 'db_prevId') and old_obj.db_prevId is not None:
+            new_obj.db_prevId = old_obj.db_prevId
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'mashup' in class_dict:
+            res = class_dict['mashup'](old_obj, trans_dict)
+            new_obj.db_mashup = res
+        elif hasattr(old_obj, 'db_mashup') and old_obj.db_mashup is not None:
+            obj = old_obj.db_mashup
+            new_obj.db_add_mashup(DBMashup.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_mashup') and hasattr(new_obj, 'db_deleted_mashup'):
+            for obj in old_obj.db_deleted_mashup:
+                n_obj = DBMashup.update_version(obj, trans_dict)
+                new_obj.db_deleted_mashup.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_mashup is not None:
+            children.extend(self._db_mashup.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_mashup = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_mashup)
+        if remove:
+            self.db_deleted_mashup = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_mashup is not None and self._db_mashup.has_changes():
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_prevId(self):
+        return self._db_prevId
+    def __set_db_prevId(self, prevId):
+        self._db_prevId = prevId
+        self.is_dirty = True
+    db_prevId = property(__get_db_prevId, __set_db_prevId)
+    def db_add_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_change_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_delete_prevId(self, prevId):
+        self._db_prevId = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
+        self.is_dirty = True
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def __get_db_mashup(self):
+        return self._db_mashup
+    def __set_db_mashup(self, mashup):
+        self._db_mashup = mashup
+        self.is_dirty = True
+    db_mashup = property(__get_db_mashup, __set_db_mashup)
+    def db_add_mashup(self, mashup):
+        self._db_mashup = mashup
+    def db_change_mashup(self, mashup):
+        self._db_mashup = mashup
+    def db_delete_mashup(self, mashup):
+        if not self.is_new:
+            self.db_deleted_mashup.append(self._db_mashup)
+        self._db_mashup = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBConfiguration(object):
+
+    vtType = 'configuration'
+
+    def __init__(self, config_keys=None):
+        self.db_deleted_config_keys = []
+        self.db_config_keys_name_index = {}
+        if config_keys is None:
+            self._db_config_keys = []
+        else:
+            self._db_config_keys = config_keys
+            for v in self._db_config_keys:
+                self.db_config_keys_name_index[v.db_name] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfiguration.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfiguration()
+        if self._db_config_keys is None:
+            cp._db_config_keys = []
+        else:
+            cp._db_config_keys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_config_keys]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_config_keys_name_index = dict((v.db_name, v) for v in cp._db_config_keys)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfiguration()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'config_keys' in class_dict:
+            res = class_dict['config_keys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_config_key(obj)
+        elif hasattr(old_obj, 'db_config_keys') and old_obj.db_config_keys is not None:
+            for obj in old_obj.db_config_keys:
+                new_obj.db_add_config_key(DBConfigKey.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_config_keys') and hasattr(new_obj, 'db_deleted_config_keys'):
+            for obj in old_obj.db_deleted_config_keys:
+                n_obj = DBConfigKey.update_version(obj, trans_dict)
+                new_obj.db_deleted_config_keys.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_config_keys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_config_key(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_config_keys)
+        if remove:
+            self.db_deleted_config_keys = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_config_keys:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_config_keys(self):
+        return self._db_config_keys
+    def __set_db_config_keys(self, config_keys):
+        self._db_config_keys = config_keys
+        self.is_dirty = True
+    db_config_keys = property(__get_db_config_keys, __set_db_config_keys)
+    def db_get_config_keys(self):
+        return self._db_config_keys
+    def db_add_config_key(self, config_key):
+        self.is_dirty = True
+        self._db_config_keys.append(config_key)
+        self.db_config_keys_name_index[config_key.db_name] = config_key
+    def db_change_config_key(self, config_key):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_config_keys)):
+            if self._db_config_keys[i].db_name == config_key.db_name:
+                self._db_config_keys[i] = config_key
+                found = True
+                break
+        if not found:
+            self._db_config_keys.append(config_key)
+        self.db_config_keys_name_index[config_key.db_name] = config_key
+    def db_delete_config_key(self, config_key):
+        self.is_dirty = True
+        for i in xrange(len(self._db_config_keys)):
+            if self._db_config_keys[i].db_name == config_key.db_name:
+                if not self._db_config_keys[i].is_new:
+                    self.db_deleted_config_keys.append(self._db_config_keys[i])
+                del self._db_config_keys[i]
+                break
+        del self.db_config_keys_name_index[config_key.db_name]
+    def db_get_config_key(self, key):
+        for i in xrange(len(self._db_config_keys)):
+            if self._db_config_keys[i].db_name == key:
+                return self._db_config_keys[i]
+        return None
+    def db_get_config_key_by_name(self, key):
+        return self.db_config_keys_name_index[key]
+    def db_has_config_key_with_name(self, key):
+        return key in self.db_config_keys_name_index
+    
+
+
+class DBChange(object):
+
+    vtType = 'change'
+
+    def __init__(self, data=None, id=None, what=None, oldObjId=None, newObjId=None, parentObjId=None, parentObjType=None):
+        self.db_deleted_data = []
+        self._db_data = data
+        self._db_id = id
+        self._db_what = what
+        self._db_oldObjId = oldObjId
+        self._db_newObjId = newObjId
+        self._db_parentObjId = parentObjId
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBChange.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBChange(id=self._db_id,
+                      what=self._db_what,
+                      oldObjId=self._db_oldObjId,
+                      newObjId=self._db_newObjId,
+                      parentObjId=self._db_parentObjId,
+                      parentObjType=self._db_parentObjType)
+        if self._db_data is not None:
+            cp._db_data = self._db_data.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_oldObjId') and (self._db_what, self._db_oldObjId) in id_remap:
+                cp._db_oldObjId = id_remap[(self._db_what, self._db_oldObjId)]
+            if hasattr(self, 'db_newObjId') and (self._db_what, self._db_newObjId) in id_remap:
+                cp._db_newObjId = id_remap[(self._db_what, self._db_newObjId)]
+            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
+                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBChange()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'data' in class_dict:
+            res = class_dict['data'](old_obj, trans_dict)
+            new_obj.db_data = res
+        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
+            obj = old_obj.db_data
+            if obj.vtType == 'module':
+                new_obj.db_add_data(DBModule.update_version(obj, trans_dict))
+            elif obj.vtType == 'location':
+                new_obj.db_add_data(DBLocation.update_version(obj, trans_dict))
+            elif obj.vtType == 'annotation':
+                new_obj.db_add_data(DBAnnotation.update_version(obj, trans_dict))
+            elif obj.vtType == 'controlParameter':
+                new_obj.db_add_data(DBControlParameter.update_version(obj, trans_dict))
+            elif obj.vtType == 'function':
+                new_obj.db_add_data(DBFunction.update_version(obj, trans_dict))
+            elif obj.vtType == 'connection':
+                new_obj.db_add_data(DBConnection.update_version(obj, trans_dict))
+            elif obj.vtType == 'port':
+                new_obj.db_add_data(DBPort.update_version(obj, trans_dict))
+            elif obj.vtType == 'parameter':
+                new_obj.db_add_data(DBParameter.update_version(obj, trans_dict))
+            elif obj.vtType == 'portSpec':
+                new_obj.db_add_data(DBPortSpec.update_version(obj, trans_dict))
+            elif obj.vtType == 'abstraction':
+                new_obj.db_add_data(DBAbstraction.update_version(obj, trans_dict))
+            elif obj.vtType == 'group':
+                new_obj.db_add_data(DBGroup.update_version(obj, trans_dict))
+            elif obj.vtType == 'other':
+                new_obj.db_add_data(DBOther.update_version(obj, trans_dict))
+            elif obj.vtType == 'plugin_data':
+                new_obj.db_add_data(DBPluginData.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_data') and hasattr(new_obj, 'db_deleted_data'):
+            for obj in old_obj.db_deleted_data:
+                if obj.vtType == 'module':
+                    n_obj = DBModule.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'location':
+                    n_obj = DBLocation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'annotation':
+                    n_obj = DBAnnotation.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'controlParameter':
+                    n_obj = DBControlParameter.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'function':
+                    n_obj = DBFunction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'connection':
+                    n_obj = DBConnection.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'port':
+                    n_obj = DBPort.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'parameter':
+                    n_obj = DBParameter.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'portSpec':
+                    n_obj = DBPortSpec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'abstraction':
+                    n_obj = DBAbstraction.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'group':
+                    n_obj = DBGroup.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'other':
+                    n_obj = DBOther.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+                elif obj.vtType == 'plugin_data':
+                    n_obj = DBPluginData.update_version(obj, trans_dict)
+                    new_obj.db_deleted_data.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'what' in class_dict:
+            res = class_dict['what'](old_obj, trans_dict)
+            new_obj.db_what = res
+        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
+            new_obj.db_what = old_obj.db_what
+        if 'oldObjId' in class_dict:
+            res = class_dict['oldObjId'](old_obj, trans_dict)
+            new_obj.db_oldObjId = res
+        elif hasattr(old_obj, 'db_oldObjId') and old_obj.db_oldObjId is not None:
+            new_obj.db_oldObjId = old_obj.db_oldObjId
+        if 'newObjId' in class_dict:
+            res = class_dict['newObjId'](old_obj, trans_dict)
+            new_obj.db_newObjId = res
+        elif hasattr(old_obj, 'db_newObjId') and old_obj.db_newObjId is not None:
+            new_obj.db_newObjId = old_obj.db_newObjId
+        if 'parentObjId' in class_dict:
+            res = class_dict['parentObjId'](old_obj, trans_dict)
+            new_obj.db_parentObjId = res
+        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
+            new_obj.db_parentObjId = old_obj.db_parentObjId
+        if 'parentObjType' in class_dict:
+            res = class_dict['parentObjType'](old_obj, trans_dict)
+            new_obj.db_parentObjType = res
+        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
+            new_obj.db_parentObjType = old_obj.db_parentObjType
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_data is not None:
+            children.extend(self._db_data.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_data = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_data)
+        if remove:
+            self.db_deleted_data = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_data is not None and self._db_data.has_changes():
+            return True
+        return False
+    def __get_db_data(self):
+        return self._db_data
+    def __set_db_data(self, data):
+        self._db_data = data
+        self.is_dirty = True
+    db_data = property(__get_db_data, __set_db_data)
+    def db_add_data(self, data):
+        self._db_data = data
+    def db_change_data(self, data):
+        self._db_data = data
+    def db_delete_data(self, data):
+        if not self.is_new:
+            self.db_deleted_data.append(self._db_data)
+        self._db_data = None
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_what(self):
+        return self._db_what
+    def __set_db_what(self, what):
+        self._db_what = what
+        self.is_dirty = True
+    db_what = property(__get_db_what, __set_db_what)
+    def db_add_what(self, what):
+        self._db_what = what
+    def db_change_what(self, what):
+        self._db_what = what
+    def db_delete_what(self, what):
+        self._db_what = None
+    
+    def __get_db_oldObjId(self):
+        return self._db_oldObjId
+    def __set_db_oldObjId(self, oldObjId):
+        self._db_oldObjId = oldObjId
+        self.is_dirty = True
+    db_oldObjId = property(__get_db_oldObjId, __set_db_oldObjId)
+    def db_add_oldObjId(self, oldObjId):
+        self._db_oldObjId = oldObjId
+    def db_change_oldObjId(self, oldObjId):
+        self._db_oldObjId = oldObjId
+    def db_delete_oldObjId(self, oldObjId):
+        self._db_oldObjId = None
+    
+    def __get_db_newObjId(self):
+        return self._db_newObjId
+    def __set_db_newObjId(self, newObjId):
+        self._db_newObjId = newObjId
+        self.is_dirty = True
+    db_newObjId = property(__get_db_newObjId, __set_db_newObjId)
+    def db_add_newObjId(self, newObjId):
+        self._db_newObjId = newObjId
+    def db_change_newObjId(self, newObjId):
+        self._db_newObjId = newObjId
+    def db_delete_newObjId(self, newObjId):
+        self._db_newObjId = None
+    
+    def __get_db_parentObjId(self):
+        return self._db_parentObjId
+    def __set_db_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+        self.is_dirty = True
+    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
+    def db_add_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_change_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_delete_parentObjId(self, parentObjId):
+        self._db_parentObjId = None
+    
+    def __get_db_parentObjType(self):
+        return self._db_parentObjType
+    def __set_db_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
+    def db_add_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_change_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_delete_parentObjType(self, parentObjType):
+        self._db_parentObjType = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBPackage(object):
+
+    vtType = 'package'
+
+    def __init__(self, id=None, name=None, identifier=None, codepath=None, load_configuration=None, version=None, description=None, module_descriptors=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_identifier = identifier
+        self._db_codepath = codepath
+        self._db_load_configuration = load_configuration
+        self._db_version = version
+        self._db_description = description
+        self.db_deleted_module_descriptors = []
+        self.db_module_descriptors_id_index = {}
+        self.db_module_descriptors_name_index = {}
+        if module_descriptors is None:
+            self._db_module_descriptors = []
+        else:
+            self._db_module_descriptors = module_descriptors
+            for v in self._db_module_descriptors:
+                self.db_module_descriptors_id_index[v.db_id] = v
+                self.db_module_descriptors_name_index[(v.db_name,v.db_namespace,v.db_version)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPackage.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPackage(id=self._db_id,
+                       name=self._db_name,
+                       identifier=self._db_identifier,
+                       codepath=self._db_codepath,
+                       load_configuration=self._db_load_configuration,
+                       version=self._db_version,
+                       description=self._db_description)
+        if self._db_module_descriptors is None:
+            cp._db_module_descriptors = []
+        else:
+            cp._db_module_descriptors = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_module_descriptors]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_module_descriptors_id_index = dict((v.db_id, v) for v in cp._db_module_descriptors)
+        cp.db_module_descriptors_name_index = dict(((v.db_name,v.db_namespace,v.db_version), v) for v in cp._db_module_descriptors)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPackage()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'identifier' in class_dict:
+            res = class_dict['identifier'](old_obj, trans_dict)
+            new_obj.db_identifier = res
+        elif hasattr(old_obj, 'db_identifier') and old_obj.db_identifier is not None:
+            new_obj.db_identifier = old_obj.db_identifier
+        if 'codepath' in class_dict:
+            res = class_dict['codepath'](old_obj, trans_dict)
+            new_obj.db_codepath = res
+        elif hasattr(old_obj, 'db_codepath') and old_obj.db_codepath is not None:
+            new_obj.db_codepath = old_obj.db_codepath
+        if 'load_configuration' in class_dict:
+            res = class_dict['load_configuration'](old_obj, trans_dict)
+            new_obj.db_load_configuration = res
+        elif hasattr(old_obj, 'db_load_configuration') and old_obj.db_load_configuration is not None:
+            new_obj.db_load_configuration = old_obj.db_load_configuration
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'description' in class_dict:
+            res = class_dict['description'](old_obj, trans_dict)
+            new_obj.db_description = res
+        elif hasattr(old_obj, 'db_description') and old_obj.db_description is not None:
+            new_obj.db_description = old_obj.db_description
+        if 'module_descriptors' in class_dict:
+            res = class_dict['module_descriptors'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_module_descriptor(obj)
+        elif hasattr(old_obj, 'db_module_descriptors') and old_obj.db_module_descriptors is not None:
+            for obj in old_obj.db_module_descriptors:
+                new_obj.db_add_module_descriptor(DBModuleDescriptor.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_module_descriptors') and hasattr(new_obj, 'db_deleted_module_descriptors'):
+            for obj in old_obj.db_deleted_module_descriptors:
+                n_obj = DBModuleDescriptor.update_version(obj, trans_dict)
+                new_obj.db_deleted_module_descriptors.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_module_descriptors:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_module_descriptor(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_module_descriptors)
+        if remove:
+            self.db_deleted_module_descriptors = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_module_descriptors:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_identifier(self):
+        return self._db_identifier
+    def __set_db_identifier(self, identifier):
+        self._db_identifier = identifier
+        self.is_dirty = True
+    db_identifier = property(__get_db_identifier, __set_db_identifier)
+    def db_add_identifier(self, identifier):
+        self._db_identifier = identifier
+    def db_change_identifier(self, identifier):
+        self._db_identifier = identifier
+    def db_delete_identifier(self, identifier):
+        self._db_identifier = None
+    
+    def __get_db_codepath(self):
+        return self._db_codepath
+    def __set_db_codepath(self, codepath):
+        self._db_codepath = codepath
+        self.is_dirty = True
+    db_codepath = property(__get_db_codepath, __set_db_codepath)
+    def db_add_codepath(self, codepath):
+        self._db_codepath = codepath
+    def db_change_codepath(self, codepath):
+        self._db_codepath = codepath
+    def db_delete_codepath(self, codepath):
+        self._db_codepath = None
+    
+    def __get_db_load_configuration(self):
+        return self._db_load_configuration
+    def __set_db_load_configuration(self, load_configuration):
+        self._db_load_configuration = load_configuration
+        self.is_dirty = True
+    db_load_configuration = property(__get_db_load_configuration, __set_db_load_configuration)
+    def db_add_load_configuration(self, load_configuration):
+        self._db_load_configuration = load_configuration
+    def db_change_load_configuration(self, load_configuration):
+        self._db_load_configuration = load_configuration
+    def db_delete_load_configuration(self, load_configuration):
+        self._db_load_configuration = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_description(self):
+        return self._db_description
+    def __set_db_description(self, description):
+        self._db_description = description
+        self.is_dirty = True
+    db_description = property(__get_db_description, __set_db_description)
+    def db_add_description(self, description):
+        self._db_description = description
+    def db_change_description(self, description):
+        self._db_description = description
+    def db_delete_description(self, description):
+        self._db_description = None
+    
+    def __get_db_module_descriptors(self):
+        return self._db_module_descriptors
+    def __set_db_module_descriptors(self, module_descriptors):
+        self._db_module_descriptors = module_descriptors
+        self.is_dirty = True
+    db_module_descriptors = property(__get_db_module_descriptors, __set_db_module_descriptors)
+    def db_get_module_descriptors(self):
+        return self._db_module_descriptors
+    def db_add_module_descriptor(self, module_descriptor):
+        self.is_dirty = True
+        self._db_module_descriptors.append(module_descriptor)
+        self.db_module_descriptors_id_index[module_descriptor.db_id] = module_descriptor
+        self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)] = module_descriptor
+    def db_change_module_descriptor(self, module_descriptor):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_module_descriptors)):
+            if self._db_module_descriptors[i].db_id == module_descriptor.db_id:
+                self._db_module_descriptors[i] = module_descriptor
+                found = True
+                break
+        if not found:
+            self._db_module_descriptors.append(module_descriptor)
+        self.db_module_descriptors_id_index[module_descriptor.db_id] = module_descriptor
+        self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)] = module_descriptor
+    def db_delete_module_descriptor(self, module_descriptor):
+        self.is_dirty = True
+        for i in xrange(len(self._db_module_descriptors)):
+            if self._db_module_descriptors[i].db_id == module_descriptor.db_id:
+                if not self._db_module_descriptors[i].is_new:
+                    self.db_deleted_module_descriptors.append(self._db_module_descriptors[i])
+                del self._db_module_descriptors[i]
+                break
+        del self.db_module_descriptors_id_index[module_descriptor.db_id]
+        del self.db_module_descriptors_name_index[(module_descriptor.db_name,module_descriptor.db_namespace,module_descriptor.db_version)]
+    def db_get_module_descriptor(self, key):
+        for i in xrange(len(self._db_module_descriptors)):
+            if self._db_module_descriptors[i].db_id == key:
+                return self._db_module_descriptors[i]
+        return None
+    def db_get_module_descriptor_by_id(self, key):
+        return self.db_module_descriptors_id_index[key]
+    def db_has_module_descriptor_with_id(self, key):
+        return key in self.db_module_descriptors_id_index
+    def db_get_module_descriptor_by_name(self, key):
+        return self.db_module_descriptors_name_index[key]
+    def db_has_module_descriptor_with_name(self, key):
+        return key in self.db_module_descriptors_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBLoopExec(object):
+
+    vtType = 'loop_exec'
+
+    def __init__(self, id=None, ts_start=None, ts_end=None, loop_iterations=None):
+        self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self.db_deleted_loop_iterations = []
+        self.db_loop_iterations_id_index = {}
+        if loop_iterations is None:
+            self._db_loop_iterations = []
+        else:
+            self._db_loop_iterations = loop_iterations
+            for v in self._db_loop_iterations:
+                self.db_loop_iterations_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBLoopExec.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBLoopExec(id=self._db_id,
+                        ts_start=self._db_ts_start,
+                        ts_end=self._db_ts_end)
+        if self._db_loop_iterations is None:
+            cp._db_loop_iterations = []
+        else:
+            cp._db_loop_iterations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_loop_iterations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_loop_iterations_id_index = dict((v.db_id, v) for v in cp._db_loop_iterations)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBLoopExec()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'loop_iterations' in class_dict:
+            res = class_dict['loop_iterations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_loop_iteration(obj)
+        elif hasattr(old_obj, 'db_loop_iterations') and old_obj.db_loop_iterations is not None:
+            for obj in old_obj.db_loop_iterations:
+                new_obj.db_add_loop_iteration(DBLoopIteration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_loop_iterations') and hasattr(new_obj, 'db_deleted_loop_iterations'):
+            for obj in old_obj.db_deleted_loop_iterations:
+                n_obj = DBLoopIteration.update_version(obj, trans_dict)
+                new_obj.db_deleted_loop_iterations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_loop_iterations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_loop_iteration(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_loop_iterations)
+        if remove:
+            self.db_deleted_loop_iterations = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_loop_iterations:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_loop_iterations(self):
+        return self._db_loop_iterations
+    def __set_db_loop_iterations(self, loop_iterations):
+        self._db_loop_iterations = loop_iterations
+        self.is_dirty = True
+    db_loop_iterations = property(__get_db_loop_iterations, __set_db_loop_iterations)
+    def db_get_loop_iterations(self):
+        return self._db_loop_iterations
+    def db_add_loop_iteration(self, loop_iteration):
+        self.is_dirty = True
+        self._db_loop_iterations.append(loop_iteration)
+        self.db_loop_iterations_id_index[loop_iteration.db_id] = loop_iteration
+    def db_change_loop_iteration(self, loop_iteration):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_loop_iterations)):
+            if self._db_loop_iterations[i].db_id == loop_iteration.db_id:
+                self._db_loop_iterations[i] = loop_iteration
+                found = True
+                break
+        if not found:
+            self._db_loop_iterations.append(loop_iteration)
+        self.db_loop_iterations_id_index[loop_iteration.db_id] = loop_iteration
+    def db_delete_loop_iteration(self, loop_iteration):
+        self.is_dirty = True
+        for i in xrange(len(self._db_loop_iterations)):
+            if self._db_loop_iterations[i].db_id == loop_iteration.db_id:
+                if not self._db_loop_iterations[i].is_new:
+                    self.db_deleted_loop_iterations.append(self._db_loop_iterations[i])
+                del self._db_loop_iterations[i]
+                break
+        del self.db_loop_iterations_id_index[loop_iteration.db_id]
+    def db_get_loop_iteration(self, key):
+        for i in xrange(len(self._db_loop_iterations)):
+            if self._db_loop_iterations[i].db_id == key:
+                return self._db_loop_iterations[i]
+        return None
+    def db_get_loop_iteration_by_id(self, key):
+        return self.db_loop_iterations_id_index[key]
+    def db_has_loop_iteration_with_id(self, key):
+        return key in self.db_loop_iterations_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBConnection(object):
+
+    vtType = 'connection'
+
+    def __init__(self, id=None, ports=None):
+        self._db_id = id
+        self.db_deleted_ports = []
+        self.db_ports_id_index = {}
+        self.db_ports_type_index = {}
+        if ports is None:
+            self._db_ports = []
+        else:
+            self._db_ports = ports
+            for v in self._db_ports:
+                self.db_ports_id_index[v.db_id] = v
+                self.db_ports_type_index[v.db_type] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConnection.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConnection(id=self._db_id)
+        if self._db_ports is None:
+            cp._db_ports = []
+        else:
+            cp._db_ports = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_ports]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_ports_id_index = dict((v.db_id, v) for v in cp._db_ports)
+        cp.db_ports_type_index = dict((v.db_type, v) for v in cp._db_ports)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConnection()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ports' in class_dict:
+            res = class_dict['ports'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_port(obj)
+        elif hasattr(old_obj, 'db_ports') and old_obj.db_ports is not None:
+            for obj in old_obj.db_ports:
+                new_obj.db_add_port(DBPort.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_ports') and hasattr(new_obj, 'db_deleted_ports'):
+            for obj in old_obj.db_deleted_ports:
+                n_obj = DBPort.update_version(obj, trans_dict)
+                new_obj.db_deleted_ports.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_ports:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_port(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_ports)
+        if remove:
+            self.db_deleted_ports = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_ports:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_ports(self):
+        return self._db_ports
+    def __set_db_ports(self, ports):
+        self._db_ports = ports
+        self.is_dirty = True
+    db_ports = property(__get_db_ports, __set_db_ports)
+    def db_get_ports(self):
+        return self._db_ports
+    def db_add_port(self, port):
+        self.is_dirty = True
+        self._db_ports.append(port)
+        self.db_ports_id_index[port.db_id] = port
+        self.db_ports_type_index[port.db_type] = port
+    def db_change_port(self, port):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_ports)):
+            if self._db_ports[i].db_id == port.db_id:
+                self._db_ports[i] = port
+                found = True
+                break
+        if not found:
+            self._db_ports.append(port)
+        self.db_ports_id_index[port.db_id] = port
+        self.db_ports_type_index[port.db_type] = port
+    def db_delete_port(self, port):
+        self.is_dirty = True
+        for i in xrange(len(self._db_ports)):
+            if self._db_ports[i].db_id == port.db_id:
+                if not self._db_ports[i].is_new:
+                    self.db_deleted_ports.append(self._db_ports[i])
+                del self._db_ports[i]
+                break
+        del self.db_ports_id_index[port.db_id]
+        del self.db_ports_type_index[port.db_type]
+    def db_get_port(self, key):
+        for i in xrange(len(self._db_ports)):
+            if self._db_ports[i].db_id == key:
+                return self._db_ports[i]
+        return None
+    def db_get_port_by_id(self, key):
+        return self.db_ports_id_index[key]
+    def db_has_port_with_id(self, key):
+        return key in self.db_ports_id_index
+    def db_get_port_by_type(self, key):
+        return self.db_ports_type_index[key]
+    def db_has_port_with_type(self, key):
+        return key in self.db_ports_type_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBConfigBool(object):
+
+    vtType = 'config_bool'
+
+    def __init__(self, value=None):
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfigBool.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigBool(value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigBool()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBAction(object):
+
+    vtType = 'action'
+
+    def __init__(self, operations=None, id=None, prevId=None, date=None, session=None, user=None, annotations=None):
+        self.db_deleted_operations = []
+        self.db_operations_id_index = {}
+        if operations is None:
+            self._db_operations = []
+        else:
+            self._db_operations = operations
+            for v in self._db_operations:
+                self.db_operations_id_index[v.db_id] = v
+        self._db_id = id
+        self._db_prevId = prevId
+        self._db_date = date
+        self._db_session = session
+        self._db_user = user
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBAction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBAction(id=self._db_id,
+                      prevId=self._db_prevId,
+                      date=self._db_date,
+                      session=self._db_session,
+                      user=self._db_user)
+        if self._db_operations is None:
+            cp._db_operations = []
+        else:
+            cp._db_operations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_operations]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prevId') and ('action', self._db_prevId) in id_remap:
+                cp._db_prevId = id_remap[('action', self._db_prevId)]
+        
+        # recreate indices and set flags
+        cp.db_operations_id_index = dict((v.db_id, v) for v in cp._db_operations)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBAction()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'operations' in class_dict:
+            res = class_dict['operations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_operation(obj)
+        elif hasattr(old_obj, 'db_operations') and old_obj.db_operations is not None:
+            for obj in old_obj.db_operations:
+                if obj.vtType == 'add':
+                    new_obj.db_add_operation(DBAdd.update_version(obj, trans_dict))
+                elif obj.vtType == 'delete':
+                    new_obj.db_add_operation(DBDelete.update_version(obj, trans_dict))
+                elif obj.vtType == 'change':
+                    new_obj.db_add_operation(DBChange.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_operations') and hasattr(new_obj, 'db_deleted_operations'):
+            for obj in old_obj.db_deleted_operations:
+                if obj.vtType == 'add':
+                    n_obj = DBAdd.update_version(obj, trans_dict)
+                    new_obj.db_deleted_operations.append(n_obj)
+                elif obj.vtType == 'delete':
+                    n_obj = DBDelete.update_version(obj, trans_dict)
+                    new_obj.db_deleted_operations.append(n_obj)
+                elif obj.vtType == 'change':
+                    n_obj = DBChange.update_version(obj, trans_dict)
+                    new_obj.db_deleted_operations.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'prevId' in class_dict:
+            res = class_dict['prevId'](old_obj, trans_dict)
+            new_obj.db_prevId = res
+        elif hasattr(old_obj, 'db_prevId') and old_obj.db_prevId is not None:
+            new_obj.db_prevId = old_obj.db_prevId
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'session' in class_dict:
+            res = class_dict['session'](old_obj, trans_dict)
+            new_obj.db_session = res
+        elif hasattr(old_obj, 'db_session') and old_obj.db_session is not None:
+            new_obj.db_session = old_obj.db_session
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_operations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_operation(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_operations)
+        if remove:
+            self.db_deleted_annotations = []
+            self.db_deleted_operations = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_operations:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_operations(self):
+        return self._db_operations
+    def __set_db_operations(self, operations):
+        self._db_operations = operations
+        self.is_dirty = True
+    db_operations = property(__get_db_operations, __set_db_operations)
+    def db_get_operations(self):
+        return self._db_operations
+    def db_add_operation(self, operation):
+        self.is_dirty = True
+        self._db_operations.append(operation)
+        self.db_operations_id_index[operation.db_id] = operation
+    def db_change_operation(self, operation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_operations)):
+            if self._db_operations[i].db_id == operation.db_id:
+                self._db_operations[i] = operation
+                found = True
+                break
+        if not found:
+            self._db_operations.append(operation)
+        self.db_operations_id_index[operation.db_id] = operation
+    def db_delete_operation(self, operation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_operations)):
+            if self._db_operations[i].db_id == operation.db_id:
+                if not self._db_operations[i].is_new:
+                    self.db_deleted_operations.append(self._db_operations[i])
+                del self._db_operations[i]
+                break
+        del self.db_operations_id_index[operation.db_id]
+    def db_get_operation(self, key):
+        for i in xrange(len(self._db_operations)):
+            if self._db_operations[i].db_id == key:
+                return self._db_operations[i]
+        return None
+    def db_get_operation_by_id(self, key):
+        return self.db_operations_id_index[key]
+    def db_has_operation_with_id(self, key):
+        return key in self.db_operations_id_index
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_prevId(self):
+        return self._db_prevId
+    def __set_db_prevId(self, prevId):
+        self._db_prevId = prevId
+        self.is_dirty = True
+    db_prevId = property(__get_db_prevId, __set_db_prevId)
+    def db_add_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_change_prevId(self, prevId):
+        self._db_prevId = prevId
+    def db_delete_prevId(self, prevId):
+        self._db_prevId = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
+        self.is_dirty = True
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_session(self):
+        return self._db_session
+    def __set_db_session(self, session):
+        self._db_session = session
+        self.is_dirty = True
+    db_session = property(__get_db_session, __set_db_session)
+    def db_add_session(self, session):
+        self._db_session = session
+    def db_change_session(self, session):
+        self._db_session = session
+    def db_delete_session(self, session):
+        self._db_session = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBStartupPackage(object):
+
+    vtType = 'startup_package'
+
+    def __init__(self, name=None, configuration=None):
+        self._db_name = name
+        self.db_deleted_configuration = []
+        self._db_configuration = configuration
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBStartupPackage.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBStartupPackage(name=self._db_name)
+        if self._db_configuration is not None:
+            cp._db_configuration = self._db_configuration.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBStartupPackage()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'configuration' in class_dict:
+            res = class_dict['configuration'](old_obj, trans_dict)
+            new_obj.db_configuration = res
+        elif hasattr(old_obj, 'db_configuration') and old_obj.db_configuration is not None:
+            obj = old_obj.db_configuration
+            new_obj.db_add_configuration(DBConfiguration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_configuration') and hasattr(new_obj, 'db_deleted_configuration'):
+            for obj in old_obj.db_deleted_configuration:
+                n_obj = DBConfiguration.update_version(obj, trans_dict)
+                new_obj.db_deleted_configuration.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_configuration is not None:
+            children.extend(self._db_configuration.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_configuration = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_configuration)
+        if remove:
+            self.db_deleted_configuration = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_configuration is not None and self._db_configuration.has_changes():
+            return True
+        return False
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_configuration(self):
+        return self._db_configuration
+    def __set_db_configuration(self, configuration):
+        self._db_configuration = configuration
+        self.is_dirty = True
+    db_configuration = property(__get_db_configuration, __set_db_configuration)
+    def db_add_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_change_configuration(self, configuration):
+        self._db_configuration = configuration
+    def db_delete_configuration(self, configuration):
+        if not self.is_new:
+            self.db_deleted_configuration.append(self._db_configuration)
+        self._db_configuration = None
+    
+
+
+class DBConfigInt(object):
+
+    vtType = 'config_int'
+
+    def __init__(self, value=None):
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfigInt.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigInt(value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigInt()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBOpmProcessIdEffect(object):
+
+    vtType = 'opm_process_id_effect'
+
+    def __init__(self, id=None):
+        self._db_id = id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmProcessIdEffect.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmProcessIdEffect(id=self._db_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_process', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_process', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmProcessIdEffect()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBRefProvPlan(object):
+
+    vtType = 'ref_prov_plan'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBRefProvPlan.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBRefProvPlan(prov_ref=self._db_prov_ref)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_entity', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_entity', self._db_prov_ref)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRefProvPlan()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
+    
+
+
+class DBOpmAccounts(object):
+
+    vtType = 'opm_accounts'
+
+    def __init__(self, accounts=None, opm_overlapss=None):
+        self.db_deleted_accounts = []
+        self.db_accounts_id_index = {}
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+            for v in self._db_accounts:
+                self.db_accounts_id_index[v.db_id] = v
+        self.db_deleted_opm_overlapss = []
+        if opm_overlapss is None:
+            self._db_opm_overlapss = []
+        else:
+            self._db_opm_overlapss = opm_overlapss
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAccounts.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAccounts()
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_overlapss is None:
+            cp._db_opm_overlapss = []
+        else:
+            cp._db_opm_overlapss = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_overlapss]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_accounts_id_index = dict((v.db_id, v) for v in cp._db_accounts)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAccounts()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccount.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccount.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_overlapss' in class_dict:
+            res = class_dict['opm_overlapss'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_overlaps(obj)
+        elif hasattr(old_obj, 'db_opm_overlapss') and old_obj.db_opm_overlapss is not None:
+            for obj in old_obj.db_opm_overlapss:
+                new_obj.db_add_opm_overlaps(DBOpmOverlaps.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_overlapss') and hasattr(new_obj, 'db_deleted_opm_overlapss'):
+            for obj in old_obj.db_deleted_opm_overlapss:
+                n_obj = DBOpmOverlaps.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_overlapss.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_overlapss:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_overlaps(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_overlapss)
+        if remove:
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_overlapss = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_overlapss:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+        self.db_accounts_id_index[account.db_id] = account
+    def db_change_account(self, account):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_accounts)):
+            if self._db_accounts[i].db_id == account.db_id:
+                self._db_accounts[i] = account
+                found = True
+                break
+        if not found:
+            self._db_accounts.append(account)
+        self.db_accounts_id_index[account.db_id] = account
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        for i in xrange(len(self._db_accounts)):
+            if self._db_accounts[i].db_id == account.db_id:
+                if not self._db_accounts[i].is_new:
+                    self.db_deleted_accounts.append(self._db_accounts[i])
+                del self._db_accounts[i]
+                break
+        del self.db_accounts_id_index[account.db_id]
+    def db_get_account(self, key):
+        for i in xrange(len(self._db_accounts)):
+            if self._db_accounts[i].db_id == key:
+                return self._db_accounts[i]
+        return None
+    def db_get_account_by_id(self, key):
+        return self.db_accounts_id_index[key]
+    def db_has_account_with_id(self, key):
+        return key in self.db_accounts_id_index
+    
+    def __get_db_opm_overlapss(self):
+        return self._db_opm_overlapss
+    def __set_db_opm_overlapss(self, opm_overlapss):
+        self._db_opm_overlapss = opm_overlapss
+        self.is_dirty = True
+    db_opm_overlapss = property(__get_db_opm_overlapss, __set_db_opm_overlapss)
+    def db_get_opm_overlapss(self):
+        return self._db_opm_overlapss
+    def db_add_opm_overlaps(self, opm_overlaps):
+        self.is_dirty = True
+        self._db_opm_overlapss.append(opm_overlaps)
+    def db_change_opm_overlaps(self, opm_overlaps):
+        self.is_dirty = True
+        self._db_opm_overlapss.append(opm_overlaps)
+    def db_delete_opm_overlaps(self, opm_overlaps):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_overlaps(self, key):
+        return None
+    
+
+
+class DBRefProvAgent(object):
+
+    vtType = 'ref_prov_agent'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBRefProvAgent.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBRefProvAgent(prov_ref=self._db_prov_ref)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_agent', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_agent', self._db_prov_ref)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRefProvAgent()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
+    
+
+
+class DBPortSpec(object):
+
+    vtType = 'portSpec'
+
+    def __init__(self, id=None, name=None, type=None, optional=None, depth=None, sort_key=None, portSpecItems=None, min_conns=None, max_conns=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_type = type
+        self._db_optional = optional
+        self._db_depth = depth
+        self._db_sort_key = sort_key
+        self.db_deleted_portSpecItems = []
+        self.db_portSpecItems_id_index = {}
+        if portSpecItems is None:
+            self._db_portSpecItems = []
+        else:
+            self._db_portSpecItems = portSpecItems
+            for v in self._db_portSpecItems:
+                self.db_portSpecItems_id_index[v.db_id] = v
+        self._db_min_conns = min_conns
+        self._db_max_conns = max_conns
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPortSpec.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPortSpec(id=self._db_id,
+                        name=self._db_name,
+                        type=self._db_type,
+                        optional=self._db_optional,
+                        depth=self._db_depth,
+                        sort_key=self._db_sort_key,
+                        min_conns=self._db_min_conns,
+                        max_conns=self._db_max_conns)
+        if self._db_portSpecItems is None:
+            cp._db_portSpecItems = []
+        else:
+            cp._db_portSpecItems = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecItems]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_portSpecItems_id_index = dict((v.db_id, v) for v in cp._db_portSpecItems)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPortSpec()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'optional' in class_dict:
+            res = class_dict['optional'](old_obj, trans_dict)
+            new_obj.db_optional = res
+        elif hasattr(old_obj, 'db_optional') and old_obj.db_optional is not None:
+            new_obj.db_optional = old_obj.db_optional
+        if 'depth' in class_dict:
+            res = class_dict['depth'](old_obj, trans_dict)
+            new_obj.db_depth = res
+        elif hasattr(old_obj, 'db_depth') and old_obj.db_depth is not None:
+            new_obj.db_depth = old_obj.db_depth
+        if 'sort_key' in class_dict:
+            res = class_dict['sort_key'](old_obj, trans_dict)
+            new_obj.db_sort_key = res
+        elif hasattr(old_obj, 'db_sort_key') and old_obj.db_sort_key is not None:
+            new_obj.db_sort_key = old_obj.db_sort_key
+        if 'portSpecItems' in class_dict:
+            res = class_dict['portSpecItems'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_portSpecItem(obj)
+        elif hasattr(old_obj, 'db_portSpecItems') and old_obj.db_portSpecItems is not None:
+            for obj in old_obj.db_portSpecItems:
+                new_obj.db_add_portSpecItem(DBPortSpecItem.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_portSpecItems') and hasattr(new_obj, 'db_deleted_portSpecItems'):
+            for obj in old_obj.db_deleted_portSpecItems:
+                n_obj = DBPortSpecItem.update_version(obj, trans_dict)
+                new_obj.db_deleted_portSpecItems.append(n_obj)
+        if 'min_conns' in class_dict:
+            res = class_dict['min_conns'](old_obj, trans_dict)
+            new_obj.db_min_conns = res
+        elif hasattr(old_obj, 'db_min_conns') and old_obj.db_min_conns is not None:
+            new_obj.db_min_conns = old_obj.db_min_conns
+        if 'max_conns' in class_dict:
+            res = class_dict['max_conns'](old_obj, trans_dict)
+            new_obj.db_max_conns = res
+        elif hasattr(old_obj, 'db_max_conns') and old_obj.db_max_conns is not None:
+            new_obj.db_max_conns = old_obj.db_max_conns
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if not for_action:
+            for child in self.db_portSpecItems:
+                children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_portSpecItems)
+        if remove:
+            self.db_deleted_portSpecItems = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_portSpecItems:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_optional(self):
+        return self._db_optional
+    def __set_db_optional(self, optional):
+        self._db_optional = optional
+        self.is_dirty = True
+    db_optional = property(__get_db_optional, __set_db_optional)
+    def db_add_optional(self, optional):
+        self._db_optional = optional
+    def db_change_optional(self, optional):
+        self._db_optional = optional
+    def db_delete_optional(self, optional):
+        self._db_optional = None
+    
+    def __get_db_depth(self):
+        return self._db_depth
+    def __set_db_depth(self, depth):
+        self._db_depth = depth
+        self.is_dirty = True
+    db_depth = property(__get_db_depth, __set_db_depth)
+    def db_add_depth(self, depth):
+        self._db_depth = depth
+    def db_change_depth(self, depth):
+        self._db_depth = depth
+    def db_delete_depth(self, depth):
+        self._db_depth = None
+    
+    def __get_db_sort_key(self):
+        return self._db_sort_key
+    def __set_db_sort_key(self, sort_key):
+        self._db_sort_key = sort_key
+        self.is_dirty = True
+    db_sort_key = property(__get_db_sort_key, __set_db_sort_key)
+    def db_add_sort_key(self, sort_key):
+        self._db_sort_key = sort_key
+    def db_change_sort_key(self, sort_key):
+        self._db_sort_key = sort_key
+    def db_delete_sort_key(self, sort_key):
+        self._db_sort_key = None
+    
+    def __get_db_portSpecItems(self):
+        return self._db_portSpecItems
+    def __set_db_portSpecItems(self, portSpecItems):
+        self._db_portSpecItems = portSpecItems
+        self.is_dirty = True
+    db_portSpecItems = property(__get_db_portSpecItems, __set_db_portSpecItems)
+    def db_get_portSpecItems(self):
+        return self._db_portSpecItems
+    def db_add_portSpecItem(self, portSpecItem):
+        self.is_dirty = True
+        self._db_portSpecItems.append(portSpecItem)
+        self.db_portSpecItems_id_index[portSpecItem.db_id] = portSpecItem
+    def db_change_portSpecItem(self, portSpecItem):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_portSpecItems)):
+            if self._db_portSpecItems[i].db_id == portSpecItem.db_id:
+                self._db_portSpecItems[i] = portSpecItem
+                found = True
+                break
+        if not found:
+            self._db_portSpecItems.append(portSpecItem)
+        self.db_portSpecItems_id_index[portSpecItem.db_id] = portSpecItem
+    def db_delete_portSpecItem(self, portSpecItem):
+        self.is_dirty = True
+        for i in xrange(len(self._db_portSpecItems)):
+            if self._db_portSpecItems[i].db_id == portSpecItem.db_id:
+                if not self._db_portSpecItems[i].is_new:
+                    self.db_deleted_portSpecItems.append(self._db_portSpecItems[i])
+                del self._db_portSpecItems[i]
+                break
+        del self.db_portSpecItems_id_index[portSpecItem.db_id]
+    def db_get_portSpecItem(self, key):
+        for i in xrange(len(self._db_portSpecItems)):
+            if self._db_portSpecItems[i].db_id == key:
+                return self._db_portSpecItems[i]
+        return None
+    def db_get_portSpecItem_by_id(self, key):
+        return self.db_portSpecItems_id_index[key]
+    def db_has_portSpecItem_with_id(self, key):
+        return key in self.db_portSpecItems_id_index
+    
+    def __get_db_min_conns(self):
+        return self._db_min_conns
+    def __set_db_min_conns(self, min_conns):
+        self._db_min_conns = min_conns
+        self.is_dirty = True
+    db_min_conns = property(__get_db_min_conns, __set_db_min_conns)
+    def db_add_min_conns(self, min_conns):
+        self._db_min_conns = min_conns
+    def db_change_min_conns(self, min_conns):
+        self._db_min_conns = min_conns
+    def db_delete_min_conns(self, min_conns):
+        self._db_min_conns = None
+    
+    def __get_db_max_conns(self):
+        return self._db_max_conns
+    def __set_db_max_conns(self, max_conns):
+        self._db_max_conns = max_conns
+        self.is_dirty = True
+    db_max_conns = property(__get_db_max_conns, __set_db_max_conns)
+    def db_add_max_conns(self, max_conns):
+        self._db_max_conns = max_conns
+    def db_change_max_conns(self, max_conns):
+        self._db_max_conns = max_conns
+    def db_delete_max_conns(self, max_conns):
+        self._db_max_conns = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBEnabledPackages(object):
+
+    vtType = 'enabled_packages'
+
+    def __init__(self, packages=None):
+        self.db_deleted_packages = []
+        self.db_packages_name_index = {}
+        if packages is None:
+            self._db_packages = []
+        else:
+            self._db_packages = packages
+            for v in self._db_packages:
+                self.db_packages_name_index[v.db_name] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBEnabledPackages.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBEnabledPackages()
+        if self._db_packages is None:
+            cp._db_packages = []
+        else:
+            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_packages_name_index = dict((v.db_name, v) for v in cp._db_packages)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBEnabledPackages()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'packages' in class_dict:
+            res = class_dict['packages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_package(obj)
+        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
+            for obj in old_obj.db_packages:
+                new_obj.db_add_package(DBStartupPackage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
+            for obj in old_obj.db_deleted_packages:
+                n_obj = DBStartupPackage.update_version(obj, trans_dict)
+                new_obj.db_deleted_packages.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_packages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_package(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_packages)
+        if remove:
+            self.db_deleted_packages = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_packages:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_packages(self):
+        return self._db_packages
+    def __set_db_packages(self, packages):
+        self._db_packages = packages
+        self.is_dirty = True
+    db_packages = property(__get_db_packages, __set_db_packages)
+    def db_get_packages(self):
+        return self._db_packages
+    def db_add_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_change_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_delete_package(self, package):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_package(self, key):
+        return None
+    def db_get_package_by_name(self, key):
+        return self.db_packages_name_index[key]
+    def db_has_package_with_name(self, key):
+        return key in self.db_packages_name_index
+    
+
+
+class DBOpmArtifact(object):
+
+    vtType = 'opm_artifact'
+
+    def __init__(self, id=None, value=None, accounts=None):
+        self._db_id = id
+        self.db_deleted_value = []
+        self._db_value = value
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmArtifact.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmArtifact(id=self._db_id)
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmArtifact()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            new_obj.db_add_value(DBOpmArtifactValue.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                n_obj = DBOpmArtifactValue.update_version(obj, trans_dict)
+                new_obj.db_deleted_value.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_value)
+        children.extend(self.db_deleted_accounts)
+        if remove:
+            self.db_deleted_value = []
+            self.db_deleted_accounts = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBLog(object):
+
+    vtType = 'log'
+
+    def __init__(self, id=None, entity_type=None, version=None, name=None, last_modified=None, workflow_execs=None, vistrail_id=None):
+        self._db_id = id
+        self._db_entity_type = entity_type
+        self._db_version = version
+        self._db_name = name
+        self._db_last_modified = last_modified
+        self.db_deleted_workflow_execs = []
+        self.db_workflow_execs_id_index = {}
+        if workflow_execs is None:
+            self._db_workflow_execs = []
+        else:
+            self._db_workflow_execs = workflow_execs
+            for v in self._db_workflow_execs:
+                self.db_workflow_execs_id_index[v.db_id] = v
+        self._db_vistrail_id = vistrail_id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBLog.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBLog(id=self._db_id,
+                   entity_type=self._db_entity_type,
+                   version=self._db_version,
+                   name=self._db_name,
+                   last_modified=self._db_last_modified,
+                   vistrail_id=self._db_vistrail_id)
+        if self._db_workflow_execs is None:
+            cp._db_workflow_execs = []
+        else:
+            cp._db_workflow_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_workflow_execs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_vistrail_id') and ('vistrail', self._db_vistrail_id) in id_remap:
+                cp._db_vistrail_id = id_remap[('vistrail', self._db_vistrail_id)]
+        
+        # recreate indices and set flags
+        cp.db_workflow_execs_id_index = dict((v.db_id, v) for v in cp._db_workflow_execs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBLog()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'workflow_execs' in class_dict:
+            res = class_dict['workflow_execs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_workflow_exec(obj)
+        elif hasattr(old_obj, 'db_workflow_execs') and old_obj.db_workflow_execs is not None:
+            for obj in old_obj.db_workflow_execs:
+                new_obj.db_add_workflow_exec(DBWorkflowExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_workflow_execs') and hasattr(new_obj, 'db_deleted_workflow_execs'):
+            for obj in old_obj.db_deleted_workflow_execs:
+                n_obj = DBWorkflowExec.update_version(obj, trans_dict)
+                new_obj.db_deleted_workflow_execs.append(n_obj)
+        if 'vistrail_id' in class_dict:
+            res = class_dict['vistrail_id'](old_obj, trans_dict)
+            new_obj.db_vistrail_id = res
+        elif hasattr(old_obj, 'db_vistrail_id') and old_obj.db_vistrail_id is not None:
+            new_obj.db_vistrail_id = old_obj.db_vistrail_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_workflow_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_workflow_exec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_workflow_execs)
+        if remove:
+            self.db_deleted_workflow_execs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_workflow_execs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+        self.is_dirty = True
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_workflow_execs(self):
+        return self._db_workflow_execs
+    def __set_db_workflow_execs(self, workflow_execs):
+        self._db_workflow_execs = workflow_execs
+        self.is_dirty = True
+    db_workflow_execs = property(__get_db_workflow_execs, __set_db_workflow_execs)
+    def db_get_workflow_execs(self):
+        return self._db_workflow_execs
+    def db_add_workflow_exec(self, workflow_exec):
+        self.is_dirty = True
+        self._db_workflow_execs.append(workflow_exec)
+        self.db_workflow_execs_id_index[workflow_exec.db_id] = workflow_exec
+    def db_change_workflow_exec(self, workflow_exec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_workflow_execs)):
+            if self._db_workflow_execs[i].db_id == workflow_exec.db_id:
+                self._db_workflow_execs[i] = workflow_exec
+                found = True
+                break
+        if not found:
+            self._db_workflow_execs.append(workflow_exec)
+        self.db_workflow_execs_id_index[workflow_exec.db_id] = workflow_exec
+    def db_delete_workflow_exec(self, workflow_exec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_workflow_execs)):
+            if self._db_workflow_execs[i].db_id == workflow_exec.db_id:
+                if not self._db_workflow_execs[i].is_new:
+                    self.db_deleted_workflow_execs.append(self._db_workflow_execs[i])
+                del self._db_workflow_execs[i]
+                break
+        del self.db_workflow_execs_id_index[workflow_exec.db_id]
+    def db_get_workflow_exec(self, key):
+        for i in xrange(len(self._db_workflow_execs)):
+            if self._db_workflow_execs[i].db_id == key:
+                return self._db_workflow_execs[i]
+        return None
+    def db_get_workflow_exec_by_id(self, key):
+        return self.db_workflow_execs_id_index[key]
+    def db_has_workflow_exec_with_id(self, key):
+        return key in self.db_workflow_execs_id_index
+    
+    def __get_db_vistrail_id(self):
+        return self._db_vistrail_id
+    def __set_db_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+        self.is_dirty = True
+    db_vistrail_id = property(__get_db_vistrail_id, __set_db_vistrail_id)
+    def db_add_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_change_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = vistrail_id
+    def db_delete_vistrail_id(self, vistrail_id):
+        self._db_vistrail_id = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBLoopIteration(object):
+
+    vtType = 'loop_iteration'
+
+    def __init__(self, item_execs=None, id=None, ts_start=None, ts_end=None, iteration=None, completed=None, error=None):
+        self.db_deleted_item_execs = []
+        self.db_item_execs_id_index = {}
+        if item_execs is None:
+            self._db_item_execs = []
+        else:
+            self._db_item_execs = item_execs
+            for v in self._db_item_execs:
+                self.db_item_execs_id_index[v.db_id] = v
+        self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_iteration = iteration
+        self._db_completed = completed
+        self._db_error = error
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBLoopIteration.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBLoopIteration(id=self._db_id,
+                             ts_start=self._db_ts_start,
+                             ts_end=self._db_ts_end,
+                             iteration=self._db_iteration,
+                             completed=self._db_completed,
+                             error=self._db_error)
+        if self._db_item_execs is None:
+            cp._db_item_execs = []
+        else:
+            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBLoopIteration()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'item_execs' in class_dict:
+            res = class_dict['item_execs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_item_exec(obj)
+        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
+            for obj in old_obj.db_item_execs:
+                if obj.vtType == 'module_exec':
+                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'group_exec':
+                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'loop_exec':
+                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
+            for obj in old_obj.db_deleted_item_execs:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'iteration' in class_dict:
+            res = class_dict['iteration'](old_obj, trans_dict)
+            new_obj.db_iteration = res
+        elif hasattr(old_obj, 'db_iteration') and old_obj.db_iteration is not None:
+            new_obj.db_iteration = old_obj.db_iteration
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'error' in class_dict:
+            res = class_dict['error'](old_obj, trans_dict)
+            new_obj.db_error = res
+        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
+            new_obj.db_error = old_obj.db_error
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_item_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_item_exec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_item_execs)
+        if remove:
+            self.db_deleted_item_execs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_item_execs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_item_execs(self):
+        return self._db_item_execs
+    def __set_db_item_execs(self, item_execs):
+        self._db_item_execs = item_execs
+        self.is_dirty = True
+    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
+    def db_get_item_execs(self):
+        return self._db_item_execs
+    def db_add_item_exec(self, item_exec):
+        self.is_dirty = True
+        self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_change_item_exec(self, item_exec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                self._db_item_execs[i] = item_exec
+                found = True
+                break
+        if not found:
+            self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_delete_item_exec(self, item_exec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                if not self._db_item_execs[i].is_new:
+                    self.db_deleted_item_execs.append(self._db_item_execs[i])
+                del self._db_item_execs[i]
+                break
+        del self.db_item_execs_id_index[item_exec.db_id]
+    def db_get_item_exec(self, key):
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == key:
+                return self._db_item_execs[i]
+        return None
+    def db_get_item_exec_by_id(self, key):
+        return self.db_item_execs_id_index[key]
+    def db_has_item_exec_with_id(self, key):
+        return key in self.db_item_execs_id_index
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_iteration(self):
+        return self._db_iteration
+    def __set_db_iteration(self, iteration):
+        self._db_iteration = iteration
+        self.is_dirty = True
+    db_iteration = property(__get_db_iteration, __set_db_iteration)
+    def db_add_iteration(self, iteration):
+        self._db_iteration = iteration
+    def db_change_iteration(self, iteration):
+        self._db_iteration = iteration
+    def db_delete_iteration(self, iteration):
+        self._db_iteration = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_error(self):
+        return self._db_error
+    def __set_db_error(self, error):
+        self._db_error = error
+        self.is_dirty = True
+    db_error = property(__get_db_error, __set_db_error)
+    def db_add_error(self, error):
+        self._db_error = error
+    def db_change_error(self, error):
+        self._db_error = error
+    def db_delete_error(self, error):
+        self._db_error = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmProcessIdCause(object):
+
+    vtType = 'opm_process_id_cause'
+
+    def __init__(self, id=None):
+        self._db_id = id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmProcessIdCause.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmProcessIdCause(id=self._db_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_process', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_process', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmProcessIdCause()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBOpmArtifacts(object):
+
+    vtType = 'opm_artifacts'
+
+    def __init__(self, artifacts=None):
+        self.db_deleted_artifacts = []
+        self.db_artifacts_id_index = {}
+        if artifacts is None:
+            self._db_artifacts = []
+        else:
+            self._db_artifacts = artifacts
+            for v in self._db_artifacts:
+                self.db_artifacts_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmArtifacts.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmArtifacts()
+        if self._db_artifacts is None:
+            cp._db_artifacts = []
+        else:
+            cp._db_artifacts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_artifacts]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_artifacts_id_index = dict((v.db_id, v) for v in cp._db_artifacts)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmArtifacts()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'artifacts' in class_dict:
+            res = class_dict['artifacts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_artifact(obj)
+        elif hasattr(old_obj, 'db_artifacts') and old_obj.db_artifacts is not None:
+            for obj in old_obj.db_artifacts:
+                new_obj.db_add_artifact(DBOpmArtifact.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_artifacts') and hasattr(new_obj, 'db_deleted_artifacts'):
+            for obj in old_obj.db_deleted_artifacts:
+                n_obj = DBOpmArtifact.update_version(obj, trans_dict)
+                new_obj.db_deleted_artifacts.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_artifacts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_artifact(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_artifacts)
+        if remove:
+            self.db_deleted_artifacts = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_artifacts:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_artifacts(self):
+        return self._db_artifacts
+    def __set_db_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+        self.is_dirty = True
+    db_artifacts = property(__get_db_artifacts, __set_db_artifacts)
+    def db_get_artifacts(self):
+        return self._db_artifacts
+    def db_add_artifact(self, artifact):
+        self.is_dirty = True
+        self._db_artifacts.append(artifact)
+        self.db_artifacts_id_index[artifact.db_id] = artifact
+    def db_change_artifact(self, artifact):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_artifacts)):
+            if self._db_artifacts[i].db_id == artifact.db_id:
+                self._db_artifacts[i] = artifact
+                found = True
+                break
+        if not found:
+            self._db_artifacts.append(artifact)
+        self.db_artifacts_id_index[artifact.db_id] = artifact
+    def db_delete_artifact(self, artifact):
+        self.is_dirty = True
+        for i in xrange(len(self._db_artifacts)):
+            if self._db_artifacts[i].db_id == artifact.db_id:
+                if not self._db_artifacts[i].is_new:
+                    self.db_deleted_artifacts.append(self._db_artifacts[i])
+                del self._db_artifacts[i]
+                break
+        del self.db_artifacts_id_index[artifact.db_id]
+    def db_get_artifact(self, key):
+        for i in xrange(len(self._db_artifacts)):
+            if self._db_artifacts[i].db_id == key:
+                return self._db_artifacts[i]
+        return None
+    def db_get_artifact_by_id(self, key):
+        return self.db_artifacts_id_index[key]
+    def db_has_artifact_with_id(self, key):
+        return key in self.db_artifacts_id_index
+    
+
+
+class DBPEParameter(object):
+
+    vtType = 'pe_parameter'
+
+    def __init__(self, id=None, pos=None, interpolator=None, value=None, dimension=None):
+        self._db_id = id
+        self._db_pos = pos
+        self._db_interpolator = interpolator
+        self._db_value = value
+        self._db_dimension = dimension
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPEParameter.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPEParameter(id=self._db_id,
+                           pos=self._db_pos,
+                           interpolator=self._db_interpolator,
+                           value=self._db_value,
+                           dimension=self._db_dimension)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPEParameter()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'interpolator' in class_dict:
+            res = class_dict['interpolator'](old_obj, trans_dict)
+            new_obj.db_interpolator = res
+        elif hasattr(old_obj, 'db_interpolator') and old_obj.db_interpolator is not None:
+            new_obj.db_interpolator = old_obj.db_interpolator
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'dimension' in class_dict:
+            res = class_dict['dimension'](old_obj, trans_dict)
+            new_obj.db_dimension = res
+        elif hasattr(old_obj, 'db_dimension') and old_obj.db_dimension is not None:
+            new_obj.db_dimension = old_obj.db_dimension
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
+        self.is_dirty = True
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
+    
+    def __get_db_interpolator(self):
+        return self._db_interpolator
+    def __set_db_interpolator(self, interpolator):
+        self._db_interpolator = interpolator
+        self.is_dirty = True
+    db_interpolator = property(__get_db_interpolator, __set_db_interpolator)
+    def db_add_interpolator(self, interpolator):
+        self._db_interpolator = interpolator
+    def db_change_interpolator(self, interpolator):
+        self._db_interpolator = interpolator
+    def db_delete_interpolator(self, interpolator):
+        self._db_interpolator = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_dimension(self):
+        return self._db_dimension
+    def __set_db_dimension(self, dimension):
+        self._db_dimension = dimension
+        self.is_dirty = True
+    db_dimension = property(__get_db_dimension, __set_db_dimension)
+    def db_add_dimension(self, dimension):
+        self._db_dimension = dimension
+    def db_change_dimension(self, dimension):
+        self._db_dimension = dimension
+    def db_delete_dimension(self, dimension):
+        self._db_dimension = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBWorkflowExec(object):
+
+    vtType = 'workflow_exec'
+
+    def __init__(self, item_execs=None, id=None, user=None, ip=None, session=None, vt_version=None, ts_start=None, ts_end=None, parent_id=None, parent_type=None, parent_version=None, completed=None, name=None, annotations=None, machines=None):
+        self.db_deleted_item_execs = []
+        self.db_item_execs_id_index = {}
+        if item_execs is None:
+            self._db_item_execs = []
+        else:
+            self._db_item_execs = item_execs
+            for v in self._db_item_execs:
+                self.db_item_execs_id_index[v.db_id] = v
+        self._db_id = id
+        self._db_user = user
+        self._db_ip = ip
+        self._db_session = session
+        self._db_vt_version = vt_version
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_parent_id = parent_id
+        self._db_parent_type = parent_type
+        self._db_parent_version = parent_version
+        self._db_completed = completed
+        self._db_name = name
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+        self.db_deleted_machines = []
+        self.db_machines_id_index = {}
+        if machines is None:
+            self._db_machines = []
+        else:
+            self._db_machines = machines
+            for v in self._db_machines:
+                self.db_machines_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBWorkflowExec.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBWorkflowExec(id=self._db_id,
+                            user=self._db_user,
+                            ip=self._db_ip,
+                            session=self._db_session,
+                            vt_version=self._db_vt_version,
+                            ts_start=self._db_ts_start,
+                            ts_end=self._db_ts_end,
+                            parent_id=self._db_parent_id,
+                            parent_type=self._db_parent_type,
+                            parent_version=self._db_parent_version,
+                            completed=self._db_completed,
+                            name=self._db_name)
+        if self._db_item_execs is None:
+            cp._db_item_execs = []
+        else:
+            cp._db_item_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_item_execs]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_machines is None:
+            cp._db_machines = []
+        else:
+            cp._db_machines = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_machines]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_item_execs_id_index = dict((v.db_id, v) for v in cp._db_item_execs)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_machines_id_index = dict((v.db_id, v) for v in cp._db_machines)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBWorkflowExec()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'item_execs' in class_dict:
+            res = class_dict['item_execs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_item_exec(obj)
+        elif hasattr(old_obj, 'db_item_execs') and old_obj.db_item_execs is not None:
+            for obj in old_obj.db_item_execs:
+                if obj.vtType == 'module_exec':
+                    new_obj.db_add_item_exec(DBModuleExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'group_exec':
+                    new_obj.db_add_item_exec(DBGroupExec.update_version(obj, trans_dict))
+                elif obj.vtType == 'loop_exec':
+                    new_obj.db_add_item_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_item_execs') and hasattr(new_obj, 'db_deleted_item_execs'):
+            for obj in old_obj.db_deleted_item_execs:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_item_execs.append(n_obj)
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'ip' in class_dict:
+            res = class_dict['ip'](old_obj, trans_dict)
+            new_obj.db_ip = res
+        elif hasattr(old_obj, 'db_ip') and old_obj.db_ip is not None:
+            new_obj.db_ip = old_obj.db_ip
+        if 'session' in class_dict:
+            res = class_dict['session'](old_obj, trans_dict)
+            new_obj.db_session = res
+        elif hasattr(old_obj, 'db_session') and old_obj.db_session is not None:
+            new_obj.db_session = old_obj.db_session
+        if 'vt_version' in class_dict:
+            res = class_dict['vt_version'](old_obj, trans_dict)
+            new_obj.db_vt_version = res
+        elif hasattr(old_obj, 'db_vt_version') and old_obj.db_vt_version is not None:
+            new_obj.db_vt_version = old_obj.db_vt_version
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'parent_id' in class_dict:
+            res = class_dict['parent_id'](old_obj, trans_dict)
+            new_obj.db_parent_id = res
+        elif hasattr(old_obj, 'db_parent_id') and old_obj.db_parent_id is not None:
+            new_obj.db_parent_id = old_obj.db_parent_id
+        if 'parent_type' in class_dict:
+            res = class_dict['parent_type'](old_obj, trans_dict)
+            new_obj.db_parent_type = res
+        elif hasattr(old_obj, 'db_parent_type') and old_obj.db_parent_type is not None:
+            new_obj.db_parent_type = old_obj.db_parent_type
+        if 'parent_version' in class_dict:
+            res = class_dict['parent_version'](old_obj, trans_dict)
+            new_obj.db_parent_version = res
+        elif hasattr(old_obj, 'db_parent_version') and old_obj.db_parent_version is not None:
+            new_obj.db_parent_version = old_obj.db_parent_version
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'machines' in class_dict:
+            res = class_dict['machines'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_machine(obj)
+        elif hasattr(old_obj, 'db_machines') and old_obj.db_machines is not None:
+            for obj in old_obj.db_machines:
+                new_obj.db_add_machine(DBMachine.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_machines') and hasattr(new_obj, 'db_deleted_machines'):
+            for obj in old_obj.db_deleted_machines:
+                n_obj = DBMachine.update_version(obj, trans_dict)
+                new_obj.db_deleted_machines.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_machines:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_machine(child)
+        to_del = []
+        for child in self.db_item_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_item_exec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_machines)
+        children.extend(self.db_deleted_item_execs)
+        if remove:
+            self.db_deleted_annotations = []
+            self.db_deleted_machines = []
+            self.db_deleted_item_execs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_machines:
+            if child.has_changes():
+                return True
+        for child in self._db_item_execs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_item_execs(self):
+        return self._db_item_execs
+    def __set_db_item_execs(self, item_execs):
+        self._db_item_execs = item_execs
+        self.is_dirty = True
+    db_item_execs = property(__get_db_item_execs, __set_db_item_execs)
+    def db_get_item_execs(self):
+        return self._db_item_execs
+    def db_add_item_exec(self, item_exec):
+        self.is_dirty = True
+        self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_change_item_exec(self, item_exec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                self._db_item_execs[i] = item_exec
+                found = True
+                break
+        if not found:
+            self._db_item_execs.append(item_exec)
+        self.db_item_execs_id_index[item_exec.db_id] = item_exec
+    def db_delete_item_exec(self, item_exec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == item_exec.db_id:
+                if not self._db_item_execs[i].is_new:
+                    self.db_deleted_item_execs.append(self._db_item_execs[i])
+                del self._db_item_execs[i]
+                break
+        del self.db_item_execs_id_index[item_exec.db_id]
+    def db_get_item_exec(self, key):
+        for i in xrange(len(self._db_item_execs)):
+            if self._db_item_execs[i].db_id == key:
+                return self._db_item_execs[i]
+        return None
+    def db_get_item_exec_by_id(self, key):
+        return self.db_item_execs_id_index[key]
+    def db_has_item_exec_with_id(self, key):
+        return key in self.db_item_execs_id_index
+    
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def __get_db_ip(self):
+        return self._db_ip
+    def __set_db_ip(self, ip):
+        self._db_ip = ip
+        self.is_dirty = True
+    db_ip = property(__get_db_ip, __set_db_ip)
+    def db_add_ip(self, ip):
+        self._db_ip = ip
+    def db_change_ip(self, ip):
+        self._db_ip = ip
+    def db_delete_ip(self, ip):
+        self._db_ip = None
+    
+    def __get_db_session(self):
+        return self._db_session
+    def __set_db_session(self, session):
+        self._db_session = session
+        self.is_dirty = True
+    db_session = property(__get_db_session, __set_db_session)
+    def db_add_session(self, session):
+        self._db_session = session
+    def db_change_session(self, session):
+        self._db_session = session
+    def db_delete_session(self, session):
+        self._db_session = None
+    
+    def __get_db_vt_version(self):
+        return self._db_vt_version
+    def __set_db_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+        self.is_dirty = True
+    db_vt_version = property(__get_db_vt_version, __set_db_vt_version)
+    def db_add_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_change_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_delete_vt_version(self, vt_version):
+        self._db_vt_version = None
+    
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_parent_id(self):
+        return self._db_parent_id
+    def __set_db_parent_id(self, parent_id):
+        self._db_parent_id = parent_id
+        self.is_dirty = True
+    db_parent_id = property(__get_db_parent_id, __set_db_parent_id)
+    def db_add_parent_id(self, parent_id):
+        self._db_parent_id = parent_id
+    def db_change_parent_id(self, parent_id):
+        self._db_parent_id = parent_id
+    def db_delete_parent_id(self, parent_id):
+        self._db_parent_id = None
+    
+    def __get_db_parent_type(self):
+        return self._db_parent_type
+    def __set_db_parent_type(self, parent_type):
+        self._db_parent_type = parent_type
+        self.is_dirty = True
+    db_parent_type = property(__get_db_parent_type, __set_db_parent_type)
+    def db_add_parent_type(self, parent_type):
+        self._db_parent_type = parent_type
+    def db_change_parent_type(self, parent_type):
+        self._db_parent_type = parent_type
+    def db_delete_parent_type(self, parent_type):
+        self._db_parent_type = None
+    
+    def __get_db_parent_version(self):
+        return self._db_parent_version
+    def __set_db_parent_version(self, parent_version):
+        self._db_parent_version = parent_version
+        self.is_dirty = True
+    db_parent_version = property(__get_db_parent_version, __set_db_parent_version)
+    def db_add_parent_version(self, parent_version):
+        self._db_parent_version = parent_version
+    def db_change_parent_version(self, parent_version):
+        self._db_parent_version = parent_version
+    def db_delete_parent_version(self, parent_version):
+        self._db_parent_version = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    
+    def __get_db_machines(self):
+        return self._db_machines
+    def __set_db_machines(self, machines):
+        self._db_machines = machines
+        self.is_dirty = True
+    db_machines = property(__get_db_machines, __set_db_machines)
+    def db_get_machines(self):
+        return self._db_machines
+    def db_add_machine(self, machine):
+        self.is_dirty = True
+        self._db_machines.append(machine)
+        self.db_machines_id_index[machine.db_id] = machine
+    def db_change_machine(self, machine):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_machines)):
+            if self._db_machines[i].db_id == machine.db_id:
+                self._db_machines[i] = machine
+                found = True
+                break
+        if not found:
+            self._db_machines.append(machine)
+        self.db_machines_id_index[machine.db_id] = machine
+    def db_delete_machine(self, machine):
+        self.is_dirty = True
+        for i in xrange(len(self._db_machines)):
+            if self._db_machines[i].db_id == machine.db_id:
+                if not self._db_machines[i].is_new:
+                    self.db_deleted_machines.append(self._db_machines[i])
+                del self._db_machines[i]
+                break
+        del self.db_machines_id_index[machine.db_id]
+    def db_get_machine(self, key):
+        for i in xrange(len(self._db_machines)):
+            if self._db_machines[i].db_id == key:
+                return self._db_machines[i]
+        return None
+    def db_get_machine_by_id(self, key):
+        return self.db_machines_id_index[key]
+    def db_has_machine_with_id(self, key):
+        return key in self.db_machines_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBLocation(object):
+
+    vtType = 'location'
+
+    def __init__(self, id=None, x=None, y=None):
+        self._db_id = id
+        self._db_x = x
+        self._db_y = y
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBLocation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBLocation(id=self._db_id,
+                        x=self._db_x,
+                        y=self._db_y)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBLocation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'x' in class_dict:
+            res = class_dict['x'](old_obj, trans_dict)
+            new_obj.db_x = res
+        elif hasattr(old_obj, 'db_x') and old_obj.db_x is not None:
+            new_obj.db_x = old_obj.db_x
+        if 'y' in class_dict:
+            res = class_dict['y'](old_obj, trans_dict)
+            new_obj.db_y = res
+        elif hasattr(old_obj, 'db_y') and old_obj.db_y is not None:
+            new_obj.db_y = old_obj.db_y
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_x(self):
+        return self._db_x
+    def __set_db_x(self, x):
+        self._db_x = x
+        self.is_dirty = True
+    db_x = property(__get_db_x, __set_db_x)
+    def db_add_x(self, x):
+        self._db_x = x
+    def db_change_x(self, x):
+        self._db_x = x
+    def db_delete_x(self, x):
+        self._db_x = None
+    
+    def __get_db_y(self):
+        return self._db_y
+    def __set_db_y(self, y):
+        self._db_y = y
+        self.is_dirty = True
+    db_y = property(__get_db_y, __set_db_y)
+    def db_add_y(self, y):
+        self._db_y = y
+    def db_change_y(self, y):
+        self._db_y = y
+    def db_delete_y(self, y):
+        self._db_y = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBFunction(object):
+
+    vtType = 'function'
+
+    def __init__(self, id=None, pos=None, name=None, parameters=None):
+        self._db_id = id
+        self._db_pos = pos
+        self._db_name = name
+        self.db_deleted_parameters = []
+        self.db_parameters_id_index = {}
+        if parameters is None:
+            self._db_parameters = []
+        else:
+            self._db_parameters = parameters
+            for v in self._db_parameters:
+                self.db_parameters_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBFunction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBFunction(id=self._db_id,
+                        pos=self._db_pos,
+                        name=self._db_name)
+        if self._db_parameters is None:
+            cp._db_parameters = []
+        else:
+            cp._db_parameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_parameters]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_parameters_id_index = dict((v.db_id, v) for v in cp._db_parameters)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBFunction()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'parameters' in class_dict:
+            res = class_dict['parameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_parameter(obj)
+        elif hasattr(old_obj, 'db_parameters') and old_obj.db_parameters is not None:
+            for obj in old_obj.db_parameters:
+                new_obj.db_add_parameter(DBParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_parameters') and hasattr(new_obj, 'db_deleted_parameters'):
+            for obj in old_obj.db_deleted_parameters:
+                n_obj = DBParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_parameters.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_parameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_parameter(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_parameters)
+        if remove:
+            self.db_deleted_parameters = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_parameters:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
+        self.is_dirty = True
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_parameters(self):
+        return self._db_parameters
+    def __set_db_parameters(self, parameters):
+        self._db_parameters = parameters
+        self.is_dirty = True
+    db_parameters = property(__get_db_parameters, __set_db_parameters)
+    def db_get_parameters(self):
+        return self._db_parameters
+    def db_add_parameter(self, parameter):
+        self.is_dirty = True
+        self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_change_parameter(self, parameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                self._db_parameters[i] = parameter
+                found = True
+                break
+        if not found:
+            self._db_parameters.append(parameter)
+        self.db_parameters_id_index[parameter.db_id] = parameter
+    def db_delete_parameter(self, parameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == parameter.db_id:
+                if not self._db_parameters[i].is_new:
+                    self.db_deleted_parameters.append(self._db_parameters[i])
+                del self._db_parameters[i]
+                break
+        del self.db_parameters_id_index[parameter.db_id]
+    def db_get_parameter(self, key):
+        for i in xrange(len(self._db_parameters)):
+            if self._db_parameters[i].db_id == key:
+                return self._db_parameters[i]
+        return None
+    def db_get_parameter_by_id(self, key):
+        return self.db_parameters_id_index[key]
+    def db_has_parameter_with_id(self, key):
+        return key in self.db_parameters_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBActionAnnotation(object):
+
+    vtType = 'actionAnnotation'
+
+    def __init__(self, id=None, key=None, value=None, action_id=None, date=None, user=None):
+        self._db_id = id
+        self._db_key = key
+        self._db_value = value
+        self._db_action_id = action_id
+        self._db_date = date
+        self._db_user = user
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBActionAnnotation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBActionAnnotation(id=self._db_id,
+                                key=self._db_key,
+                                value=self._db_value,
+                                action_id=self._db_action_id,
+                                date=self._db_date,
+                                user=self._db_user)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_action_id') and ('action', self._db_action_id) in id_remap:
+                cp._db_action_id = id_remap[('action', self._db_action_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBActionAnnotation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'action_id' in class_dict:
+            res = class_dict['action_id'](old_obj, trans_dict)
+            new_obj.db_action_id = res
+        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
+            new_obj.db_action_id = old_obj.db_action_id
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
+        self.is_dirty = True
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_action_id(self):
+        return self._db_action_id
+    def __set_db_action_id(self, action_id):
+        self._db_action_id = action_id
+        self.is_dirty = True
+    db_action_id = property(__get_db_action_id, __set_db_action_id)
+    def db_add_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_change_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_delete_action_id(self, action_id):
+        self._db_action_id = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
+        self.is_dirty = True
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvActivity(object):
+
+    vtType = 'prov_activity'
+
+    def __init__(self, id=None, startTime=None, endTime=None, vt_id=None, vt_type=None, vt_cached=None, vt_completed=None, vt_machine_id=None, vt_error=None, is_part_of=None):
+        self._db_id = id
+        self._db_startTime = startTime
+        self._db_endTime = endTime
+        self._db_vt_id = vt_id
+        self._db_vt_type = vt_type
+        self._db_vt_cached = vt_cached
+        self._db_vt_completed = vt_completed
+        self._db_vt_machine_id = vt_machine_id
+        self._db_vt_error = vt_error
+        self.db_deleted_is_part_of = []
+        self._db_is_part_of = is_part_of
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvActivity.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvActivity(id=self._db_id,
+                            startTime=self._db_startTime,
+                            endTime=self._db_endTime,
+                            vt_id=self._db_vt_id,
+                            vt_type=self._db_vt_type,
+                            vt_cached=self._db_vt_cached,
+                            vt_completed=self._db_vt_completed,
+                            vt_machine_id=self._db_vt_machine_id,
+                            vt_error=self._db_vt_error)
+        if self._db_is_part_of is not None:
+            cp._db_is_part_of = self._db_is_part_of.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvActivity()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'startTime' in class_dict:
+            res = class_dict['startTime'](old_obj, trans_dict)
+            new_obj.db_startTime = res
+        elif hasattr(old_obj, 'db_startTime') and old_obj.db_startTime is not None:
+            new_obj.db_startTime = old_obj.db_startTime
+        if 'endTime' in class_dict:
+            res = class_dict['endTime'](old_obj, trans_dict)
+            new_obj.db_endTime = res
+        elif hasattr(old_obj, 'db_endTime') and old_obj.db_endTime is not None:
+            new_obj.db_endTime = old_obj.db_endTime
+        if 'vt_id' in class_dict:
+            res = class_dict['vt_id'](old_obj, trans_dict)
+            new_obj.db_vt_id = res
+        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
+            new_obj.db_vt_id = old_obj.db_vt_id
+        if 'vt_type' in class_dict:
+            res = class_dict['vt_type'](old_obj, trans_dict)
+            new_obj.db_vt_type = res
+        elif hasattr(old_obj, 'db_vt_type') and old_obj.db_vt_type is not None:
+            new_obj.db_vt_type = old_obj.db_vt_type
+        if 'vt_cached' in class_dict:
+            res = class_dict['vt_cached'](old_obj, trans_dict)
+            new_obj.db_vt_cached = res
+        elif hasattr(old_obj, 'db_vt_cached') and old_obj.db_vt_cached is not None:
+            new_obj.db_vt_cached = old_obj.db_vt_cached
+        if 'vt_completed' in class_dict:
+            res = class_dict['vt_completed'](old_obj, trans_dict)
+            new_obj.db_vt_completed = res
+        elif hasattr(old_obj, 'db_vt_completed') and old_obj.db_vt_completed is not None:
+            new_obj.db_vt_completed = old_obj.db_vt_completed
+        if 'vt_machine_id' in class_dict:
+            res = class_dict['vt_machine_id'](old_obj, trans_dict)
+            new_obj.db_vt_machine_id = res
+        elif hasattr(old_obj, 'db_vt_machine_id') and old_obj.db_vt_machine_id is not None:
+            new_obj.db_vt_machine_id = old_obj.db_vt_machine_id
+        if 'vt_error' in class_dict:
+            res = class_dict['vt_error'](old_obj, trans_dict)
+            new_obj.db_vt_error = res
+        elif hasattr(old_obj, 'db_vt_error') and old_obj.db_vt_error is not None:
+            new_obj.db_vt_error = old_obj.db_vt_error
+        if 'is_part_of' in class_dict:
+            res = class_dict['is_part_of'](old_obj, trans_dict)
+            new_obj.db_is_part_of = res
+        elif hasattr(old_obj, 'db_is_part_of') and old_obj.db_is_part_of is not None:
+            obj = old_obj.db_is_part_of
+            new_obj.db_add_is_part_of(DBIsPartOf.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_is_part_of') and hasattr(new_obj, 'db_deleted_is_part_of'):
+            for obj in old_obj.db_deleted_is_part_of:
+                n_obj = DBIsPartOf.update_version(obj, trans_dict)
+                new_obj.db_deleted_is_part_of.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_is_part_of is not None:
+            children.extend(self._db_is_part_of.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_is_part_of = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_is_part_of)
+        if remove:
+            self.db_deleted_is_part_of = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_is_part_of is not None and self._db_is_part_of.has_changes():
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_startTime(self):
+        return self._db_startTime
+    def __set_db_startTime(self, startTime):
+        self._db_startTime = startTime
+        self.is_dirty = True
+    db_startTime = property(__get_db_startTime, __set_db_startTime)
+    def db_add_startTime(self, startTime):
+        self._db_startTime = startTime
+    def db_change_startTime(self, startTime):
+        self._db_startTime = startTime
+    def db_delete_startTime(self, startTime):
+        self._db_startTime = None
+    
+    def __get_db_endTime(self):
+        return self._db_endTime
+    def __set_db_endTime(self, endTime):
+        self._db_endTime = endTime
+        self.is_dirty = True
+    db_endTime = property(__get_db_endTime, __set_db_endTime)
+    def db_add_endTime(self, endTime):
+        self._db_endTime = endTime
+    def db_change_endTime(self, endTime):
+        self._db_endTime = endTime
+    def db_delete_endTime(self, endTime):
+        self._db_endTime = None
+    
+    def __get_db_vt_id(self):
+        return self._db_vt_id
+    def __set_db_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+        self.is_dirty = True
+    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
+    def db_add_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_change_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_delete_vt_id(self, vt_id):
+        self._db_vt_id = None
+    
+    def __get_db_vt_type(self):
+        return self._db_vt_type
+    def __set_db_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+        self.is_dirty = True
+    db_vt_type = property(__get_db_vt_type, __set_db_vt_type)
+    def db_add_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+    def db_change_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+    def db_delete_vt_type(self, vt_type):
+        self._db_vt_type = None
+    
+    def __get_db_vt_cached(self):
+        return self._db_vt_cached
+    def __set_db_vt_cached(self, vt_cached):
+        self._db_vt_cached = vt_cached
+        self.is_dirty = True
+    db_vt_cached = property(__get_db_vt_cached, __set_db_vt_cached)
+    def db_add_vt_cached(self, vt_cached):
+        self._db_vt_cached = vt_cached
+    def db_change_vt_cached(self, vt_cached):
+        self._db_vt_cached = vt_cached
+    def db_delete_vt_cached(self, vt_cached):
+        self._db_vt_cached = None
+    
+    def __get_db_vt_completed(self):
+        return self._db_vt_completed
+    def __set_db_vt_completed(self, vt_completed):
+        self._db_vt_completed = vt_completed
+        self.is_dirty = True
+    db_vt_completed = property(__get_db_vt_completed, __set_db_vt_completed)
+    def db_add_vt_completed(self, vt_completed):
+        self._db_vt_completed = vt_completed
+    def db_change_vt_completed(self, vt_completed):
+        self._db_vt_completed = vt_completed
+    def db_delete_vt_completed(self, vt_completed):
+        self._db_vt_completed = None
+    
+    def __get_db_vt_machine_id(self):
+        return self._db_vt_machine_id
+    def __set_db_vt_machine_id(self, vt_machine_id):
+        self._db_vt_machine_id = vt_machine_id
+        self.is_dirty = True
+    db_vt_machine_id = property(__get_db_vt_machine_id, __set_db_vt_machine_id)
+    def db_add_vt_machine_id(self, vt_machine_id):
+        self._db_vt_machine_id = vt_machine_id
+    def db_change_vt_machine_id(self, vt_machine_id):
+        self._db_vt_machine_id = vt_machine_id
+    def db_delete_vt_machine_id(self, vt_machine_id):
+        self._db_vt_machine_id = None
+    
+    def __get_db_vt_error(self):
+        return self._db_vt_error
+    def __set_db_vt_error(self, vt_error):
+        self._db_vt_error = vt_error
+        self.is_dirty = True
+    db_vt_error = property(__get_db_vt_error, __set_db_vt_error)
+    def db_add_vt_error(self, vt_error):
+        self._db_vt_error = vt_error
+    def db_change_vt_error(self, vt_error):
+        self._db_vt_error = vt_error
+    def db_delete_vt_error(self, vt_error):
+        self._db_vt_error = None
+    
+    def __get_db_is_part_of(self):
+        return self._db_is_part_of
+    def __set_db_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+        self.is_dirty = True
+    db_is_part_of = property(__get_db_is_part_of, __set_db_is_part_of)
+    def db_add_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_change_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_delete_is_part_of(self, is_part_of):
+        if not self.is_new:
+            self.db_deleted_is_part_of.append(self._db_is_part_of)
+        self._db_is_part_of = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvUsage(object):
+
+    vtType = 'prov_usage'
+
+    def __init__(self, prov_activity=None, prov_entity=None, prov_role=None):
+        self.db_deleted_prov_activity = []
+        self._db_prov_activity = prov_activity
+        self.db_deleted_prov_entity = []
+        self._db_prov_entity = prov_entity
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvUsage.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvUsage(prov_role=self._db_prov_role)
+        if self._db_prov_activity is not None:
+            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_entity is not None:
+            cp._db_prov_entity = self._db_prov_entity.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvUsage()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_activity' in class_dict:
+            res = class_dict['prov_activity'](old_obj, trans_dict)
+            new_obj.db_prov_activity = res
+        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
+            obj = old_obj.db_prov_activity
+            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
+            for obj in old_obj.db_deleted_prov_activity:
+                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activity.append(n_obj)
+        if 'prov_entity' in class_dict:
+            res = class_dict['prov_entity'](old_obj, trans_dict)
+            new_obj.db_prov_entity = res
+        elif hasattr(old_obj, 'db_prov_entity') and old_obj.db_prov_entity is not None:
+            obj = old_obj.db_prov_entity
+            new_obj.db_add_prov_entity(DBRefProvEntity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_entity') and hasattr(new_obj, 'db_deleted_prov_entity'):
+            for obj in old_obj.db_deleted_prov_entity:
+                n_obj = DBRefProvEntity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_entity.append(n_obj)
+        if 'prov_role' in class_dict:
+            res = class_dict['prov_role'](old_obj, trans_dict)
+            new_obj.db_prov_role = res
+        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
+            new_obj.db_prov_role = old_obj.db_prov_role
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_prov_activity is not None:
+            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_activity = None
+        if self._db_prov_entity is not None:
+            children.extend(self._db_prov_entity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_entity = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_prov_activity)
+        children.extend(self.db_deleted_prov_entity)
+        if remove:
+            self.db_deleted_prov_activity = []
+            self.db_deleted_prov_entity = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
+            return True
+        if self._db_prov_entity is not None and self._db_prov_entity.has_changes():
+            return True
+        return False
+    def __get_db_prov_activity(self):
+        return self._db_prov_activity
+    def __set_db_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+        self.is_dirty = True
+    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
+    def db_add_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        if not self.is_new:
+            self.db_deleted_prov_activity.append(self._db_prov_activity)
+        self._db_prov_activity = None
+    
+    def __get_db_prov_entity(self):
+        return self._db_prov_entity
+    def __set_db_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+        self.is_dirty = True
+    db_prov_entity = property(__get_db_prov_entity, __set_db_prov_entity)
+    def db_add_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_change_prov_entity(self, prov_entity):
+        self._db_prov_entity = prov_entity
+    def db_delete_prov_entity(self, prov_entity):
+        if not self.is_new:
+            self.db_deleted_prov_entity.append(self._db_prov_entity)
+        self._db_prov_entity = None
+    
+    def __get_db_prov_role(self):
+        return self._db_prov_role
+    def __set_db_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
+    def db_add_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_change_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_delete_prov_role(self, prov_role):
+        self._db_prov_role = None
+    
+
+
+class DBOpmArtifactIdEffect(object):
+
+    vtType = 'opm_artifact_id_effect'
+
+    def __init__(self, id=None):
+        self._db_id = id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmArtifactIdEffect.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmArtifactIdEffect(id=self._db_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_artifact', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_artifact', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmArtifactIdEffect()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBOpmGraph(object):
+
+    vtType = 'opm_graph'
+
+    def __init__(self, accounts=None, processes=None, artifacts=None, agents=None, dependencies=None):
+        self.db_deleted_accounts = []
+        self._db_accounts = accounts
+        self.db_deleted_processes = []
+        self._db_processes = processes
+        self.db_deleted_artifacts = []
+        self._db_artifacts = artifacts
+        self.db_deleted_agents = []
+        self._db_agents = agents
+        self.db_deleted_dependencies = []
+        self._db_dependencies = dependencies
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmGraph.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmGraph()
+        if self._db_accounts is not None:
+            cp._db_accounts = self._db_accounts.do_copy(new_ids, id_scope, id_remap)
+        if self._db_processes is not None:
+            cp._db_processes = self._db_processes.do_copy(new_ids, id_scope, id_remap)
+        if self._db_artifacts is not None:
+            cp._db_artifacts = self._db_artifacts.do_copy(new_ids, id_scope, id_remap)
+        if self._db_agents is not None:
+            cp._db_agents = self._db_agents.do_copy(new_ids, id_scope, id_remap)
+        if self._db_dependencies is not None:
+            cp._db_dependencies = self._db_dependencies.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmGraph()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            new_obj.db_accounts = res
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            obj = old_obj.db_accounts
+            new_obj.db_add_accounts(DBOpmAccounts.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccounts.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'processes' in class_dict:
+            res = class_dict['processes'](old_obj, trans_dict)
+            new_obj.db_processes = res
+        elif hasattr(old_obj, 'db_processes') and old_obj.db_processes is not None:
+            obj = old_obj.db_processes
+            new_obj.db_add_processes(DBOpmProcesses.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_processes') and hasattr(new_obj, 'db_deleted_processes'):
+            for obj in old_obj.db_deleted_processes:
+                n_obj = DBOpmProcesses.update_version(obj, trans_dict)
+                new_obj.db_deleted_processes.append(n_obj)
+        if 'artifacts' in class_dict:
+            res = class_dict['artifacts'](old_obj, trans_dict)
+            new_obj.db_artifacts = res
+        elif hasattr(old_obj, 'db_artifacts') and old_obj.db_artifacts is not None:
+            obj = old_obj.db_artifacts
+            new_obj.db_add_artifacts(DBOpmArtifacts.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_artifacts') and hasattr(new_obj, 'db_deleted_artifacts'):
+            for obj in old_obj.db_deleted_artifacts:
+                n_obj = DBOpmArtifacts.update_version(obj, trans_dict)
+                new_obj.db_deleted_artifacts.append(n_obj)
+        if 'agents' in class_dict:
+            res = class_dict['agents'](old_obj, trans_dict)
+            new_obj.db_agents = res
+        elif hasattr(old_obj, 'db_agents') and old_obj.db_agents is not None:
+            obj = old_obj.db_agents
+            new_obj.db_add_agents(DBOpmAgents.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_agents') and hasattr(new_obj, 'db_deleted_agents'):
+            for obj in old_obj.db_deleted_agents:
+                n_obj = DBOpmAgents.update_version(obj, trans_dict)
+                new_obj.db_deleted_agents.append(n_obj)
+        if 'dependencies' in class_dict:
+            res = class_dict['dependencies'](old_obj, trans_dict)
+            new_obj.db_dependencies = res
+        elif hasattr(old_obj, 'db_dependencies') and old_obj.db_dependencies is not None:
+            obj = old_obj.db_dependencies
+            new_obj.db_add_dependencies(DBOpmDependencies.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_dependencies') and hasattr(new_obj, 'db_deleted_dependencies'):
+            for obj in old_obj.db_deleted_dependencies:
+                n_obj = DBOpmDependencies.update_version(obj, trans_dict)
+                new_obj.db_deleted_dependencies.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_accounts is not None:
+            children.extend(self._db_accounts.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_accounts = None
+        if self._db_processes is not None:
+            children.extend(self._db_processes.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_processes = None
+        if self._db_artifacts is not None:
+            children.extend(self._db_artifacts.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_artifacts = None
+        if self._db_agents is not None:
+            children.extend(self._db_agents.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_agents = None
+        if self._db_dependencies is not None:
+            children.extend(self._db_dependencies.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_dependencies = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_processes)
+        children.extend(self.db_deleted_artifacts)
+        children.extend(self.db_deleted_agents)
+        children.extend(self.db_deleted_dependencies)
+        if remove:
+            self.db_deleted_accounts = []
+            self.db_deleted_processes = []
+            self.db_deleted_artifacts = []
+            self.db_deleted_agents = []
+            self.db_deleted_dependencies = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_accounts is not None and self._db_accounts.has_changes():
+            return True
+        if self._db_processes is not None and self._db_processes.has_changes():
+            return True
+        if self._db_artifacts is not None and self._db_artifacts.has_changes():
+            return True
+        if self._db_agents is not None and self._db_agents.has_changes():
+            return True
+        if self._db_dependencies is not None and self._db_dependencies.has_changes():
+            return True
+        return False
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_add_accounts(self, accounts):
+        self._db_accounts = accounts
+    def db_change_accounts(self, accounts):
+        self._db_accounts = accounts
+    def db_delete_accounts(self, accounts):
+        if not self.is_new:
+            self.db_deleted_accounts.append(self._db_accounts)
+        self._db_accounts = None
+    
+    def __get_db_processes(self):
+        return self._db_processes
+    def __set_db_processes(self, processes):
+        self._db_processes = processes
+        self.is_dirty = True
+    db_processes = property(__get_db_processes, __set_db_processes)
+    def db_add_processes(self, processes):
+        self._db_processes = processes
+    def db_change_processes(self, processes):
+        self._db_processes = processes
+    def db_delete_processes(self, processes):
+        if not self.is_new:
+            self.db_deleted_processes.append(self._db_processes)
+        self._db_processes = None
+    
+    def __get_db_artifacts(self):
+        return self._db_artifacts
+    def __set_db_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+        self.is_dirty = True
+    db_artifacts = property(__get_db_artifacts, __set_db_artifacts)
+    def db_add_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+    def db_change_artifacts(self, artifacts):
+        self._db_artifacts = artifacts
+    def db_delete_artifacts(self, artifacts):
+        if not self.is_new:
+            self.db_deleted_artifacts.append(self._db_artifacts)
+        self._db_artifacts = None
+    
+    def __get_db_agents(self):
+        return self._db_agents
+    def __set_db_agents(self, agents):
+        self._db_agents = agents
+        self.is_dirty = True
+    db_agents = property(__get_db_agents, __set_db_agents)
+    def db_add_agents(self, agents):
+        self._db_agents = agents
+    def db_change_agents(self, agents):
+        self._db_agents = agents
+    def db_delete_agents(self, agents):
+        if not self.is_new:
+            self.db_deleted_agents.append(self._db_agents)
+        self._db_agents = None
+    
+    def __get_db_dependencies(self):
+        return self._db_dependencies
+    def __set_db_dependencies(self, dependencies):
+        self._db_dependencies = dependencies
+        self.is_dirty = True
+    db_dependencies = property(__get_db_dependencies, __set_db_dependencies)
+    def db_add_dependencies(self, dependencies):
+        self._db_dependencies = dependencies
+    def db_change_dependencies(self, dependencies):
+        self._db_dependencies = dependencies
+    def db_delete_dependencies(self, dependencies):
+        if not self.is_new:
+            self.db_deleted_dependencies.append(self._db_dependencies)
+        self._db_dependencies = None
+    
+
+
+class DBIsPartOf(object):
+
+    vtType = 'is_part_of'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBIsPartOf.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBIsPartOf(prov_ref=self._db_prov_ref)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBIsPartOf()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
+    
+
+
+class DBOpmWasDerivedFrom(object):
+
+    vtType = 'opm_was_derived_from'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmWasDerivedFrom.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmWasDerivedFrom()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmWasDerivedFrom()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmArtifactIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmArtifactIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmArtifactIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmArtifactIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
+        self.is_dirty = True
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
+        self.is_dirty = True
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
+    
+
+
+class DBControlParameter(object):
+
+    vtType = 'controlParameter'
+
+    def __init__(self, id=None, name=None, value=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBControlParameter.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBControlParameter(id=self._db_id,
+                                name=self._db_name,
+                                value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBControlParameter()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBPluginData(object):
+
+    vtType = 'plugin_data'
+
+    def __init__(self, id=None, data=None):
+        self._db_id = id
+        self._db_data = data
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPluginData.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPluginData(id=self._db_id,
+                          data=self._db_data)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPluginData()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'data' in class_dict:
+            res = class_dict['data'](old_obj, trans_dict)
+            new_obj.db_data = res
+        elif hasattr(old_obj, 'db_data') and old_obj.db_data is not None:
+            new_obj.db_data = old_obj.db_data
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_data(self):
+        return self._db_data
+    def __set_db_data(self, data):
+        self._db_data = data
+        self.is_dirty = True
+    db_data = property(__get_db_data, __set_db_data)
+    def db_add_data(self, data):
+        self._db_data = data
+    def db_change_data(self, data):
+        self._db_data = data
+    def db_delete_data(self, data):
+        self._db_data = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBDelete(object):
+
+    vtType = 'delete'
+
+    def __init__(self, id=None, what=None, objectId=None, parentObjId=None, parentObjType=None):
+        self._db_id = id
+        self._db_what = what
+        self._db_objectId = objectId
+        self._db_parentObjId = parentObjId
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBDelete.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBDelete(id=self._db_id,
+                      what=self._db_what,
+                      objectId=self._db_objectId,
+                      parentObjId=self._db_parentObjId,
+                      parentObjType=self._db_parentObjType)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_objectId') and (self._db_what, self._db_objectId) in id_remap:
+                cp._db_objectId = id_remap[(self._db_what, self._db_objectId)]
+            if hasattr(self, 'db_parentObjId') and (self._db_parentObjType, self._db_parentObjId) in id_remap:
+                cp._db_parentObjId = id_remap[(self._db_parentObjType, self._db_parentObjId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBDelete()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'what' in class_dict:
+            res = class_dict['what'](old_obj, trans_dict)
+            new_obj.db_what = res
+        elif hasattr(old_obj, 'db_what') and old_obj.db_what is not None:
+            new_obj.db_what = old_obj.db_what
+        if 'objectId' in class_dict:
+            res = class_dict['objectId'](old_obj, trans_dict)
+            new_obj.db_objectId = res
+        elif hasattr(old_obj, 'db_objectId') and old_obj.db_objectId is not None:
+            new_obj.db_objectId = old_obj.db_objectId
+        if 'parentObjId' in class_dict:
+            res = class_dict['parentObjId'](old_obj, trans_dict)
+            new_obj.db_parentObjId = res
+        elif hasattr(old_obj, 'db_parentObjId') and old_obj.db_parentObjId is not None:
+            new_obj.db_parentObjId = old_obj.db_parentObjId
+        if 'parentObjType' in class_dict:
+            res = class_dict['parentObjType'](old_obj, trans_dict)
+            new_obj.db_parentObjType = res
+        elif hasattr(old_obj, 'db_parentObjType') and old_obj.db_parentObjType is not None:
+            new_obj.db_parentObjType = old_obj.db_parentObjType
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_what(self):
+        return self._db_what
+    def __set_db_what(self, what):
+        self._db_what = what
+        self.is_dirty = True
+    db_what = property(__get_db_what, __set_db_what)
+    def db_add_what(self, what):
+        self._db_what = what
+    def db_change_what(self, what):
+        self._db_what = what
+    def db_delete_what(self, what):
+        self._db_what = None
+    
+    def __get_db_objectId(self):
+        return self._db_objectId
+    def __set_db_objectId(self, objectId):
+        self._db_objectId = objectId
+        self.is_dirty = True
+    db_objectId = property(__get_db_objectId, __set_db_objectId)
+    def db_add_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_change_objectId(self, objectId):
+        self._db_objectId = objectId
+    def db_delete_objectId(self, objectId):
+        self._db_objectId = None
+    
+    def __get_db_parentObjId(self):
+        return self._db_parentObjId
+    def __set_db_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+        self.is_dirty = True
+    db_parentObjId = property(__get_db_parentObjId, __set_db_parentObjId)
+    def db_add_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_change_parentObjId(self, parentObjId):
+        self._db_parentObjId = parentObjId
+    def db_delete_parentObjId(self, parentObjId):
+        self._db_parentObjId = None
+    
+    def __get_db_parentObjType(self):
+        return self._db_parentObjType
+    def __set_db_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+        self.is_dirty = True
+    db_parentObjType = property(__get_db_parentObjType, __set_db_parentObjType)
+    def db_add_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_change_parentObjType(self, parentObjType):
+        self._db_parentObjType = parentObjType
+    def db_delete_parentObjType(self, parentObjType):
+        self._db_parentObjType = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBVistrailVariable(object):
+
+    vtType = 'vistrailVariable'
+
+    def __init__(self, name=None, uuid=None, package=None, module=None, namespace=None, value=None):
+        self._db_name = name
+        self._db_uuid = uuid
+        self._db_package = package
+        self._db_module = module
+        self._db_namespace = namespace
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBVistrailVariable.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBVistrailVariable(name=self._db_name,
+                                uuid=self._db_uuid,
+                                package=self._db_package,
+                                module=self._db_module,
+                                namespace=self._db_namespace,
+                                value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBVistrailVariable()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'uuid' in class_dict:
+            res = class_dict['uuid'](old_obj, trans_dict)
+            new_obj.db_uuid = res
+        elif hasattr(old_obj, 'db_uuid') and old_obj.db_uuid is not None:
+            new_obj.db_uuid = old_obj.db_uuid
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'module' in class_dict:
+            res = class_dict['module'](old_obj, trans_dict)
+            new_obj.db_module = res
+        elif hasattr(old_obj, 'db_module') and old_obj.db_module is not None:
+            new_obj.db_module = old_obj.db_module
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_uuid(self):
+        return self._db_uuid
+    def __set_db_uuid(self, uuid):
+        self._db_uuid = uuid
+        self.is_dirty = True
+    db_uuid = property(__get_db_uuid, __set_db_uuid)
+    def db_add_uuid(self, uuid):
+        self._db_uuid = uuid
+    def db_change_uuid(self, uuid):
+        self._db_uuid = uuid
+    def db_delete_uuid(self, uuid):
+        self._db_uuid = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_module(self):
+        return self._db_module
+    def __set_db_module(self, module):
+        self._db_module = module
+        self.is_dirty = True
+    db_module = property(__get_db_module, __set_db_module)
+    def db_add_module(self, module):
+        self._db_module = module
+    def db_change_module(self, module):
+        self._db_module = module
+    def db_delete_module(self, module):
+        self._db_module = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def getPrimaryKey(self):
+        return self._db_name
+
+class DBOpmOverlaps(object):
+
+    vtType = 'opm_overlaps'
+
+    def __init__(self, opm_account_ids=None):
+        self.db_deleted_opm_account_ids = []
+        if opm_account_ids is None:
+            self._db_opm_account_ids = []
+        else:
+            self._db_opm_account_ids = opm_account_ids
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmOverlaps.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmOverlaps()
+        if self._db_opm_account_ids is None:
+            cp._db_opm_account_ids = []
+        else:
+            cp._db_opm_account_ids = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_account_ids]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmOverlaps()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'opm_account_ids' in class_dict:
+            res = class_dict['opm_account_ids'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_account_id(obj)
+        elif hasattr(old_obj, 'db_opm_account_ids') and old_obj.db_opm_account_ids is not None:
+            for obj in old_obj.db_opm_account_ids:
+                new_obj.db_add_opm_account_id(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_account_ids') and hasattr(new_obj, 'db_deleted_opm_account_ids'):
+            for obj in old_obj.db_deleted_opm_account_ids:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_account_ids.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_opm_account_ids:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_account_id(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_opm_account_ids)
+        if remove:
+            self.db_deleted_opm_account_ids = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_opm_account_ids:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_opm_account_ids(self):
+        return self._db_opm_account_ids
+    def __set_db_opm_account_ids(self, opm_account_ids):
+        self._db_opm_account_ids = opm_account_ids
+        self.is_dirty = True
+    db_opm_account_ids = property(__get_db_opm_account_ids, __set_db_opm_account_ids)
+    def db_get_opm_account_ids(self):
+        return self._db_opm_account_ids
+    def db_add_opm_account_id(self, opm_account_id):
+        self.is_dirty = True
+        self._db_opm_account_ids.append(opm_account_id)
+    def db_change_opm_account_id(self, opm_account_id):
+        self.is_dirty = True
+        self._db_opm_account_ids.append(opm_account_id)
+    def db_delete_opm_account_id(self, opm_account_id):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_account_id(self, key):
+        return None
+    
+
+
+class DBOpmWasTriggeredBy(object):
+
+    vtType = 'opm_was_triggered_by'
+
+    def __init__(self, effect=None, role=None, cause=None, accounts=None, opm_times=None):
+        self.db_deleted_effect = []
+        self._db_effect = effect
+        self.db_deleted_role = []
+        self._db_role = role
+        self.db_deleted_cause = []
+        self._db_cause = cause
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.db_deleted_opm_times = []
+        if opm_times is None:
+            self._db_opm_times = []
+        else:
+            self._db_opm_times = opm_times
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmWasTriggeredBy.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmWasTriggeredBy()
+        if self._db_effect is not None:
+            cp._db_effect = self._db_effect.do_copy(new_ids, id_scope, id_remap)
+        if self._db_role is not None:
+            cp._db_role = self._db_role.do_copy(new_ids, id_scope, id_remap)
+        if self._db_cause is not None:
+            cp._db_cause = self._db_cause.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        if self._db_opm_times is None:
+            cp._db_opm_times = []
+        else:
+            cp._db_opm_times = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_opm_times]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmWasTriggeredBy()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'effect' in class_dict:
+            res = class_dict['effect'](old_obj, trans_dict)
+            new_obj.db_effect = res
+        elif hasattr(old_obj, 'db_effect') and old_obj.db_effect is not None:
+            obj = old_obj.db_effect
+            new_obj.db_add_effect(DBOpmProcessIdEffect.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_effect') and hasattr(new_obj, 'db_deleted_effect'):
+            for obj in old_obj.db_deleted_effect:
+                n_obj = DBOpmProcessIdEffect.update_version(obj, trans_dict)
+                new_obj.db_deleted_effect.append(n_obj)
+        if 'role' in class_dict:
+            res = class_dict['role'](old_obj, trans_dict)
+            new_obj.db_role = res
+        elif hasattr(old_obj, 'db_role') and old_obj.db_role is not None:
+            obj = old_obj.db_role
+            new_obj.db_add_role(DBOpmRole.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_role') and hasattr(new_obj, 'db_deleted_role'):
+            for obj in old_obj.db_deleted_role:
+                n_obj = DBOpmRole.update_version(obj, trans_dict)
+                new_obj.db_deleted_role.append(n_obj)
+        if 'cause' in class_dict:
+            res = class_dict['cause'](old_obj, trans_dict)
+            new_obj.db_cause = res
+        elif hasattr(old_obj, 'db_cause') and old_obj.db_cause is not None:
+            obj = old_obj.db_cause
+            new_obj.db_add_cause(DBOpmProcessIdCause.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_cause') and hasattr(new_obj, 'db_deleted_cause'):
+            for obj in old_obj.db_deleted_cause:
+                n_obj = DBOpmProcessIdCause.update_version(obj, trans_dict)
+                new_obj.db_deleted_cause.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        if 'opm_times' in class_dict:
+            res = class_dict['opm_times'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_opm_time(obj)
+        elif hasattr(old_obj, 'db_opm_times') and old_obj.db_opm_times is not None:
+            for obj in old_obj.db_opm_times:
+                new_obj.db_add_opm_time(DBOpmTime.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_opm_times') and hasattr(new_obj, 'db_deleted_opm_times'):
+            for obj in old_obj.db_deleted_opm_times:
+                n_obj = DBOpmTime.update_version(obj, trans_dict)
+                new_obj.db_deleted_opm_times.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_effect is not None:
+            children.extend(self._db_effect.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_effect = None
+        if self._db_role is not None:
+            children.extend(self._db_role.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_role = None
+        if self._db_cause is not None:
+            children.extend(self._db_cause.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_cause = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        to_del = []
+        for child in self.db_opm_times:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_opm_time(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_effect)
+        children.extend(self.db_deleted_role)
+        children.extend(self.db_deleted_cause)
+        children.extend(self.db_deleted_accounts)
+        children.extend(self.db_deleted_opm_times)
+        if remove:
+            self.db_deleted_effect = []
+            self.db_deleted_role = []
+            self.db_deleted_cause = []
+            self.db_deleted_accounts = []
+            self.db_deleted_opm_times = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_effect is not None and self._db_effect.has_changes():
+            return True
+        if self._db_role is not None and self._db_role.has_changes():
+            return True
+        if self._db_cause is not None and self._db_cause.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        for child in self._db_opm_times:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_effect(self):
+        return self._db_effect
+    def __set_db_effect(self, effect):
+        self._db_effect = effect
+        self.is_dirty = True
+    db_effect = property(__get_db_effect, __set_db_effect)
+    def db_add_effect(self, effect):
+        self._db_effect = effect
+    def db_change_effect(self, effect):
+        self._db_effect = effect
+    def db_delete_effect(self, effect):
+        if not self.is_new:
+            self.db_deleted_effect.append(self._db_effect)
+        self._db_effect = None
+    
+    def __get_db_role(self):
+        return self._db_role
+    def __set_db_role(self, role):
+        self._db_role = role
+        self.is_dirty = True
+    db_role = property(__get_db_role, __set_db_role)
+    def db_add_role(self, role):
+        self._db_role = role
+    def db_change_role(self, role):
+        self._db_role = role
+    def db_delete_role(self, role):
+        if not self.is_new:
+            self.db_deleted_role.append(self._db_role)
+        self._db_role = None
+    
+    def __get_db_cause(self):
+        return self._db_cause
+    def __set_db_cause(self, cause):
+        self._db_cause = cause
+        self.is_dirty = True
+    db_cause = property(__get_db_cause, __set_db_cause)
+    def db_add_cause(self, cause):
+        self._db_cause = cause
+    def db_change_cause(self, cause):
+        self._db_cause = cause
+    def db_delete_cause(self, cause):
+        if not self.is_new:
+            self.db_deleted_cause.append(self._db_cause)
+        self._db_cause = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def __get_db_opm_times(self):
+        return self._db_opm_times
+    def __set_db_opm_times(self, opm_times):
+        self._db_opm_times = opm_times
+        self.is_dirty = True
+    db_opm_times = property(__get_db_opm_times, __set_db_opm_times)
+    def db_get_opm_times(self):
+        return self._db_opm_times
+    def db_add_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_change_opm_time(self, opm_time):
+        self.is_dirty = True
+        self._db_opm_times.append(opm_time)
+    def db_delete_opm_time(self, opm_time):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_opm_time(self, key):
+        return None
+    
+
+
+class DBModuleDescriptor(object):
+
+    vtType = 'module_descriptor'
+
+    def __init__(self, id=None, name=None, package=None, namespace=None, package_version=None, version=None, base_descriptor_id=None, portSpecs=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_package = package
+        self._db_namespace = namespace
+        self._db_package_version = package_version
+        self._db_version = version
+        self._db_base_descriptor_id = base_descriptor_id
+        self.db_deleted_portSpecs = []
+        self.db_portSpecs_id_index = {}
+        self.db_portSpecs_name_index = {}
+        if portSpecs is None:
+            self._db_portSpecs = []
+        else:
+            self._db_portSpecs = portSpecs
+            for v in self._db_portSpecs:
+                self.db_portSpecs_id_index[v.db_id] = v
+                self.db_portSpecs_name_index[(v.db_name,v.db_type)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBModuleDescriptor.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBModuleDescriptor(id=self._db_id,
+                                name=self._db_name,
+                                package=self._db_package,
+                                namespace=self._db_namespace,
+                                package_version=self._db_package_version,
+                                version=self._db_version,
+                                base_descriptor_id=self._db_base_descriptor_id)
+        if self._db_portSpecs is None:
+            cp._db_portSpecs = []
+        else:
+            cp._db_portSpecs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_portSpecs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_base_descriptor_id') and ('module_descriptor', self._db_base_descriptor_id) in id_remap:
+                cp._db_base_descriptor_id = id_remap[('module_descriptor', self._db_base_descriptor_id)]
+        
+        # recreate indices and set flags
+        cp.db_portSpecs_id_index = dict((v.db_id, v) for v in cp._db_portSpecs)
+        cp.db_portSpecs_name_index = dict(((v.db_name,v.db_type), v) for v in cp._db_portSpecs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBModuleDescriptor()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package_version' in class_dict:
+            res = class_dict['package_version'](old_obj, trans_dict)
+            new_obj.db_package_version = res
+        elif hasattr(old_obj, 'db_package_version') and old_obj.db_package_version is not None:
+            new_obj.db_package_version = old_obj.db_package_version
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'base_descriptor_id' in class_dict:
+            res = class_dict['base_descriptor_id'](old_obj, trans_dict)
+            new_obj.db_base_descriptor_id = res
+        elif hasattr(old_obj, 'db_base_descriptor_id') and old_obj.db_base_descriptor_id is not None:
+            new_obj.db_base_descriptor_id = old_obj.db_base_descriptor_id
+        if 'portSpecs' in class_dict:
+            res = class_dict['portSpecs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_portSpec(obj)
+        elif hasattr(old_obj, 'db_portSpecs') and old_obj.db_portSpecs is not None:
+            for obj in old_obj.db_portSpecs:
+                new_obj.db_add_portSpec(DBPortSpec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_portSpecs') and hasattr(new_obj, 'db_deleted_portSpecs'):
+            for obj in old_obj.db_deleted_portSpecs:
+                n_obj = DBPortSpec.update_version(obj, trans_dict)
+                new_obj.db_deleted_portSpecs.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_portSpecs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_portSpec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_portSpecs)
+        if remove:
+            self.db_deleted_portSpecs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_portSpecs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_package_version(self):
+        return self._db_package_version
+    def __set_db_package_version(self, package_version):
+        self._db_package_version = package_version
+        self.is_dirty = True
+    db_package_version = property(__get_db_package_version, __set_db_package_version)
+    def db_add_package_version(self, package_version):
+        self._db_package_version = package_version
+    def db_change_package_version(self, package_version):
+        self._db_package_version = package_version
+    def db_delete_package_version(self, package_version):
+        self._db_package_version = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_base_descriptor_id(self):
+        return self._db_base_descriptor_id
+    def __set_db_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = base_descriptor_id
+        self.is_dirty = True
+    db_base_descriptor_id = property(__get_db_base_descriptor_id, __set_db_base_descriptor_id)
+    def db_add_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = base_descriptor_id
+    def db_change_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = base_descriptor_id
+    def db_delete_base_descriptor_id(self, base_descriptor_id):
+        self._db_base_descriptor_id = None
+    
+    def __get_db_portSpecs(self):
+        return self._db_portSpecs
+    def __set_db_portSpecs(self, portSpecs):
+        self._db_portSpecs = portSpecs
+        self.is_dirty = True
+    db_portSpecs = property(__get_db_portSpecs, __set_db_portSpecs)
+    def db_get_portSpecs(self):
+        return self._db_portSpecs
+    def db_add_portSpec(self, portSpec):
+        self.is_dirty = True
+        self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_change_portSpec(self, portSpec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                self._db_portSpecs[i] = portSpec
+                found = True
+                break
+        if not found:
+            self._db_portSpecs.append(portSpec)
+        self.db_portSpecs_id_index[portSpec.db_id] = portSpec
+        self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)] = portSpec
+    def db_delete_portSpec(self, portSpec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == portSpec.db_id:
+                if not self._db_portSpecs[i].is_new:
+                    self.db_deleted_portSpecs.append(self._db_portSpecs[i])
+                del self._db_portSpecs[i]
+                break
+        del self.db_portSpecs_id_index[portSpec.db_id]
+        del self.db_portSpecs_name_index[(portSpec.db_name,portSpec.db_type)]
+    def db_get_portSpec(self, key):
+        for i in xrange(len(self._db_portSpecs)):
+            if self._db_portSpecs[i].db_id == key:
+                return self._db_portSpecs[i]
+        return None
+    def db_get_portSpec_by_id(self, key):
+        return self.db_portSpecs_id_index[key]
+    def db_has_portSpec_with_id(self, key):
+        return key in self.db_portSpecs_id_index
+    def db_get_portSpec_by_name(self, key):
+        return self.db_portSpecs_name_index[key]
+    def db_has_portSpec_with_name(self, key):
+        return key in self.db_portSpecs_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBTag(object):
+
+    vtType = 'tag'
+
+    def __init__(self, id=None, name=None):
+        self._db_id = id
+        self._db_name = name
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBTag.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBTag(id=self._db_id,
+                   name=self._db_name)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('action', self._db_id) in id_remap:
+                cp._db_id = id_remap[('action', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBTag()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmRole(object):
+
+    vtType = 'opm_role'
+
+    def __init__(self, value=None):
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmRole.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmRole(value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmRole()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBProvDocument(object):
+
+    vtType = 'prov_document'
+
+    def __init__(self, prov_entitys=None, prov_activitys=None, prov_agents=None, vt_connections=None, prov_usages=None, prov_generations=None, prov_associations=None):
+        self.db_deleted_prov_entitys = []
+        self.db_prov_entitys_id_index = {}
+        if prov_entitys is None:
+            self._db_prov_entitys = []
+        else:
+            self._db_prov_entitys = prov_entitys
+            for v in self._db_prov_entitys:
+                self.db_prov_entitys_id_index[v.db_id] = v
+        self.db_deleted_prov_activitys = []
+        self.db_prov_activitys_id_index = {}
+        if prov_activitys is None:
+            self._db_prov_activitys = []
+        else:
+            self._db_prov_activitys = prov_activitys
+            for v in self._db_prov_activitys:
+                self.db_prov_activitys_id_index[v.db_id] = v
+        self.db_deleted_prov_agents = []
+        self.db_prov_agents_id_index = {}
+        if prov_agents is None:
+            self._db_prov_agents = []
+        else:
+            self._db_prov_agents = prov_agents
+            for v in self._db_prov_agents:
+                self.db_prov_agents_id_index[v.db_id] = v
+        self.db_deleted_vt_connections = []
+        self.db_vt_connections_id_index = {}
+        if vt_connections is None:
+            self._db_vt_connections = []
+        else:
+            self._db_vt_connections = vt_connections
+            for v in self._db_vt_connections:
+                self.db_vt_connections_id_index[v.db_id] = v
+        self.db_deleted_prov_usages = []
+        if prov_usages is None:
+            self._db_prov_usages = []
+        else:
+            self._db_prov_usages = prov_usages
+        self.db_deleted_prov_generations = []
+        if prov_generations is None:
+            self._db_prov_generations = []
+        else:
+            self._db_prov_generations = prov_generations
+        self.db_deleted_prov_associations = []
+        if prov_associations is None:
+            self._db_prov_associations = []
+        else:
+            self._db_prov_associations = prov_associations
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvDocument.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvDocument()
+        if self._db_prov_entitys is None:
+            cp._db_prov_entitys = []
+        else:
+            cp._db_prov_entitys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_entitys]
+        if self._db_prov_activitys is None:
+            cp._db_prov_activitys = []
+        else:
+            cp._db_prov_activitys = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_activitys]
+        if self._db_prov_agents is None:
+            cp._db_prov_agents = []
+        else:
+            cp._db_prov_agents = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_agents]
+        if self._db_vt_connections is None:
+            cp._db_vt_connections = []
+        else:
+            cp._db_vt_connections = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_vt_connections]
+        if self._db_prov_usages is None:
+            cp._db_prov_usages = []
+        else:
+            cp._db_prov_usages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_usages]
+        if self._db_prov_generations is None:
+            cp._db_prov_generations = []
+        else:
+            cp._db_prov_generations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_generations]
+        if self._db_prov_associations is None:
+            cp._db_prov_associations = []
+        else:
+            cp._db_prov_associations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_prov_associations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_prov_entitys_id_index = dict((v.db_id, v) for v in cp._db_prov_entitys)
+        cp.db_prov_activitys_id_index = dict((v.db_id, v) for v in cp._db_prov_activitys)
+        cp.db_prov_agents_id_index = dict((v.db_id, v) for v in cp._db_prov_agents)
+        cp.db_vt_connections_id_index = dict((v.db_id, v) for v in cp._db_vt_connections)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvDocument()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_entitys' in class_dict:
+            res = class_dict['prov_entitys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_entity(obj)
+        elif hasattr(old_obj, 'db_prov_entitys') and old_obj.db_prov_entitys is not None:
+            for obj in old_obj.db_prov_entitys:
+                new_obj.db_add_prov_entity(DBProvEntity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_entitys') and hasattr(new_obj, 'db_deleted_prov_entitys'):
+            for obj in old_obj.db_deleted_prov_entitys:
+                n_obj = DBProvEntity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_entitys.append(n_obj)
+        if 'prov_activitys' in class_dict:
+            res = class_dict['prov_activitys'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_activity(obj)
+        elif hasattr(old_obj, 'db_prov_activitys') and old_obj.db_prov_activitys is not None:
+            for obj in old_obj.db_prov_activitys:
+                new_obj.db_add_prov_activity(DBProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activitys') and hasattr(new_obj, 'db_deleted_prov_activitys'):
+            for obj in old_obj.db_deleted_prov_activitys:
+                n_obj = DBProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activitys.append(n_obj)
+        if 'prov_agents' in class_dict:
+            res = class_dict['prov_agents'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_agent(obj)
+        elif hasattr(old_obj, 'db_prov_agents') and old_obj.db_prov_agents is not None:
+            for obj in old_obj.db_prov_agents:
+                new_obj.db_add_prov_agent(DBProvAgent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_agents') and hasattr(new_obj, 'db_deleted_prov_agents'):
+            for obj in old_obj.db_deleted_prov_agents:
+                n_obj = DBProvAgent.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_agents.append(n_obj)
+        if 'vt_connections' in class_dict:
+            res = class_dict['vt_connections'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_vt_connection(obj)
+        elif hasattr(old_obj, 'db_vt_connections') and old_obj.db_vt_connections is not None:
+            for obj in old_obj.db_vt_connections:
+                new_obj.db_add_vt_connection(DBVtConnection.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_vt_connections') and hasattr(new_obj, 'db_deleted_vt_connections'):
+            for obj in old_obj.db_deleted_vt_connections:
+                n_obj = DBVtConnection.update_version(obj, trans_dict)
+                new_obj.db_deleted_vt_connections.append(n_obj)
+        if 'prov_usages' in class_dict:
+            res = class_dict['prov_usages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_usage(obj)
+        elif hasattr(old_obj, 'db_prov_usages') and old_obj.db_prov_usages is not None:
+            for obj in old_obj.db_prov_usages:
+                new_obj.db_add_prov_usage(DBProvUsage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_usages') and hasattr(new_obj, 'db_deleted_prov_usages'):
+            for obj in old_obj.db_deleted_prov_usages:
+                n_obj = DBProvUsage.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_usages.append(n_obj)
+        if 'prov_generations' in class_dict:
+            res = class_dict['prov_generations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_generation(obj)
+        elif hasattr(old_obj, 'db_prov_generations') and old_obj.db_prov_generations is not None:
+            for obj in old_obj.db_prov_generations:
+                new_obj.db_add_prov_generation(DBProvGeneration.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_generations') and hasattr(new_obj, 'db_deleted_prov_generations'):
+            for obj in old_obj.db_deleted_prov_generations:
+                n_obj = DBProvGeneration.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_generations.append(n_obj)
+        if 'prov_associations' in class_dict:
+            res = class_dict['prov_associations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_prov_association(obj)
+        elif hasattr(old_obj, 'db_prov_associations') and old_obj.db_prov_associations is not None:
+            for obj in old_obj.db_prov_associations:
+                new_obj.db_add_prov_association(DBProvAssociation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_associations') and hasattr(new_obj, 'db_deleted_prov_associations'):
+            for obj in old_obj.db_deleted_prov_associations:
+                n_obj = DBProvAssociation.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_associations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_prov_entitys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_entity(child)
+        to_del = []
+        for child in self.db_prov_activitys:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_activity(child)
+        to_del = []
+        for child in self.db_prov_agents:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_agent(child)
+        to_del = []
+        for child in self.db_vt_connections:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_vt_connection(child)
+        to_del = []
+        for child in self.db_prov_usages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_usage(child)
+        to_del = []
+        for child in self.db_prov_generations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_generation(child)
+        to_del = []
+        for child in self.db_prov_associations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_prov_association(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_prov_entitys)
+        children.extend(self.db_deleted_prov_activitys)
+        children.extend(self.db_deleted_prov_agents)
+        children.extend(self.db_deleted_vt_connections)
+        children.extend(self.db_deleted_prov_usages)
+        children.extend(self.db_deleted_prov_generations)
+        children.extend(self.db_deleted_prov_associations)
+        if remove:
+            self.db_deleted_prov_entitys = []
+            self.db_deleted_prov_activitys = []
+            self.db_deleted_prov_agents = []
+            self.db_deleted_vt_connections = []
+            self.db_deleted_prov_usages = []
+            self.db_deleted_prov_generations = []
+            self.db_deleted_prov_associations = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_prov_entitys:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_activitys:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_agents:
+            if child.has_changes():
+                return True
+        for child in self._db_vt_connections:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_usages:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_generations:
+            if child.has_changes():
+                return True
+        for child in self._db_prov_associations:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_prov_entitys(self):
+        return self._db_prov_entitys
+    def __set_db_prov_entitys(self, prov_entitys):
+        self._db_prov_entitys = prov_entitys
+        self.is_dirty = True
+    db_prov_entitys = property(__get_db_prov_entitys, __set_db_prov_entitys)
+    def db_get_prov_entitys(self):
+        return self._db_prov_entitys
+    def db_add_prov_entity(self, prov_entity):
+        self.is_dirty = True
+        self._db_prov_entitys.append(prov_entity)
+        self.db_prov_entitys_id_index[prov_entity.db_id] = prov_entity
+    def db_change_prov_entity(self, prov_entity):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_prov_entitys)):
+            if self._db_prov_entitys[i].db_id == prov_entity.db_id:
+                self._db_prov_entitys[i] = prov_entity
+                found = True
+                break
+        if not found:
+            self._db_prov_entitys.append(prov_entity)
+        self.db_prov_entitys_id_index[prov_entity.db_id] = prov_entity
+    def db_delete_prov_entity(self, prov_entity):
+        self.is_dirty = True
+        for i in xrange(len(self._db_prov_entitys)):
+            if self._db_prov_entitys[i].db_id == prov_entity.db_id:
+                if not self._db_prov_entitys[i].is_new:
+                    self.db_deleted_prov_entitys.append(self._db_prov_entitys[i])
+                del self._db_prov_entitys[i]
+                break
+        del self.db_prov_entitys_id_index[prov_entity.db_id]
+    def db_get_prov_entity(self, key):
+        for i in xrange(len(self._db_prov_entitys)):
+            if self._db_prov_entitys[i].db_id == key:
+                return self._db_prov_entitys[i]
+        return None
+    def db_get_prov_entity_by_id(self, key):
+        return self.db_prov_entitys_id_index[key]
+    def db_has_prov_entity_with_id(self, key):
+        return key in self.db_prov_entitys_id_index
+    
+    def __get_db_prov_activitys(self):
+        return self._db_prov_activitys
+    def __set_db_prov_activitys(self, prov_activitys):
+        self._db_prov_activitys = prov_activitys
+        self.is_dirty = True
+    db_prov_activitys = property(__get_db_prov_activitys, __set_db_prov_activitys)
+    def db_get_prov_activitys(self):
+        return self._db_prov_activitys
+    def db_add_prov_activity(self, prov_activity):
+        self.is_dirty = True
+        self._db_prov_activitys.append(prov_activity)
+        self.db_prov_activitys_id_index[prov_activity.db_id] = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_prov_activitys)):
+            if self._db_prov_activitys[i].db_id == prov_activity.db_id:
+                self._db_prov_activitys[i] = prov_activity
+                found = True
+                break
+        if not found:
+            self._db_prov_activitys.append(prov_activity)
+        self.db_prov_activitys_id_index[prov_activity.db_id] = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        self.is_dirty = True
+        for i in xrange(len(self._db_prov_activitys)):
+            if self._db_prov_activitys[i].db_id == prov_activity.db_id:
+                if not self._db_prov_activitys[i].is_new:
+                    self.db_deleted_prov_activitys.append(self._db_prov_activitys[i])
+                del self._db_prov_activitys[i]
+                break
+        del self.db_prov_activitys_id_index[prov_activity.db_id]
+    def db_get_prov_activity(self, key):
+        for i in xrange(len(self._db_prov_activitys)):
+            if self._db_prov_activitys[i].db_id == key:
+                return self._db_prov_activitys[i]
+        return None
+    def db_get_prov_activity_by_id(self, key):
+        return self.db_prov_activitys_id_index[key]
+    def db_has_prov_activity_with_id(self, key):
+        return key in self.db_prov_activitys_id_index
+    
+    def __get_db_prov_agents(self):
+        return self._db_prov_agents
+    def __set_db_prov_agents(self, prov_agents):
+        self._db_prov_agents = prov_agents
+        self.is_dirty = True
+    db_prov_agents = property(__get_db_prov_agents, __set_db_prov_agents)
+    def db_get_prov_agents(self):
+        return self._db_prov_agents
+    def db_add_prov_agent(self, prov_agent):
+        self.is_dirty = True
+        self._db_prov_agents.append(prov_agent)
+        self.db_prov_agents_id_index[prov_agent.db_id] = prov_agent
+    def db_change_prov_agent(self, prov_agent):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_prov_agents)):
+            if self._db_prov_agents[i].db_id == prov_agent.db_id:
+                self._db_prov_agents[i] = prov_agent
+                found = True
+                break
+        if not found:
+            self._db_prov_agents.append(prov_agent)
+        self.db_prov_agents_id_index[prov_agent.db_id] = prov_agent
+    def db_delete_prov_agent(self, prov_agent):
+        self.is_dirty = True
+        for i in xrange(len(self._db_prov_agents)):
+            if self._db_prov_agents[i].db_id == prov_agent.db_id:
+                if not self._db_prov_agents[i].is_new:
+                    self.db_deleted_prov_agents.append(self._db_prov_agents[i])
+                del self._db_prov_agents[i]
+                break
+        del self.db_prov_agents_id_index[prov_agent.db_id]
+    def db_get_prov_agent(self, key):
+        for i in xrange(len(self._db_prov_agents)):
+            if self._db_prov_agents[i].db_id == key:
+                return self._db_prov_agents[i]
+        return None
+    def db_get_prov_agent_by_id(self, key):
+        return self.db_prov_agents_id_index[key]
+    def db_has_prov_agent_with_id(self, key):
+        return key in self.db_prov_agents_id_index
+    
+    def __get_db_vt_connections(self):
+        return self._db_vt_connections
+    def __set_db_vt_connections(self, vt_connections):
+        self._db_vt_connections = vt_connections
+        self.is_dirty = True
+    db_vt_connections = property(__get_db_vt_connections, __set_db_vt_connections)
+    def db_get_vt_connections(self):
+        return self._db_vt_connections
+    def db_add_vt_connection(self, vt_connection):
+        self.is_dirty = True
+        self._db_vt_connections.append(vt_connection)
+        self.db_vt_connections_id_index[vt_connection.db_id] = vt_connection
+    def db_change_vt_connection(self, vt_connection):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_vt_connections)):
+            if self._db_vt_connections[i].db_id == vt_connection.db_id:
+                self._db_vt_connections[i] = vt_connection
+                found = True
+                break
+        if not found:
+            self._db_vt_connections.append(vt_connection)
+        self.db_vt_connections_id_index[vt_connection.db_id] = vt_connection
+    def db_delete_vt_connection(self, vt_connection):
+        self.is_dirty = True
+        for i in xrange(len(self._db_vt_connections)):
+            if self._db_vt_connections[i].db_id == vt_connection.db_id:
+                if not self._db_vt_connections[i].is_new:
+                    self.db_deleted_vt_connections.append(self._db_vt_connections[i])
+                del self._db_vt_connections[i]
+                break
+        del self.db_vt_connections_id_index[vt_connection.db_id]
+    def db_get_vt_connection(self, key):
+        for i in xrange(len(self._db_vt_connections)):
+            if self._db_vt_connections[i].db_id == key:
+                return self._db_vt_connections[i]
+        return None
+    def db_get_vt_connection_by_id(self, key):
+        return self.db_vt_connections_id_index[key]
+    def db_has_vt_connection_with_id(self, key):
+        return key in self.db_vt_connections_id_index
+    
+    def __get_db_prov_usages(self):
+        return self._db_prov_usages
+    def __set_db_prov_usages(self, prov_usages):
+        self._db_prov_usages = prov_usages
+        self.is_dirty = True
+    db_prov_usages = property(__get_db_prov_usages, __set_db_prov_usages)
+    def db_get_prov_usages(self):
+        return self._db_prov_usages
+    def db_add_prov_usage(self, prov_usage):
+        self.is_dirty = True
+        self._db_prov_usages.append(prov_usage)
+    def db_change_prov_usage(self, prov_usage):
+        self.is_dirty = True
+        self._db_prov_usages.append(prov_usage)
+    def db_delete_prov_usage(self, prov_usage):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_prov_usage(self, key):
+        return None
+    
+    def __get_db_prov_generations(self):
+        return self._db_prov_generations
+    def __set_db_prov_generations(self, prov_generations):
+        self._db_prov_generations = prov_generations
+        self.is_dirty = True
+    db_prov_generations = property(__get_db_prov_generations, __set_db_prov_generations)
+    def db_get_prov_generations(self):
+        return self._db_prov_generations
+    def db_add_prov_generation(self, prov_generation):
+        self.is_dirty = True
+        self._db_prov_generations.append(prov_generation)
+    def db_change_prov_generation(self, prov_generation):
+        self.is_dirty = True
+        self._db_prov_generations.append(prov_generation)
+    def db_delete_prov_generation(self, prov_generation):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_prov_generation(self, key):
+        return None
+    
+    def __get_db_prov_associations(self):
+        return self._db_prov_associations
+    def __set_db_prov_associations(self, prov_associations):
+        self._db_prov_associations = prov_associations
+        self.is_dirty = True
+    db_prov_associations = property(__get_db_prov_associations, __set_db_prov_associations)
+    def db_get_prov_associations(self):
+        return self._db_prov_associations
+    def db_add_prov_association(self, prov_association):
+        self.is_dirty = True
+        self._db_prov_associations.append(prov_association)
+    def db_change_prov_association(self, prov_association):
+        self.is_dirty = True
+        self._db_prov_associations.append(prov_association)
+    def db_delete_prov_association(self, prov_association):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_prov_association(self, key):
+        return None
+    
+
+
+class DBOpmProcesses(object):
+
+    vtType = 'opm_processes'
+
+    def __init__(self, processs=None):
+        self.db_deleted_processs = []
+        self.db_processs_id_index = {}
+        if processs is None:
+            self._db_processs = []
+        else:
+            self._db_processs = processs
+            for v in self._db_processs:
+                self.db_processs_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmProcesses.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmProcesses()
+        if self._db_processs is None:
+            cp._db_processs = []
+        else:
+            cp._db_processs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_processs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_processs_id_index = dict((v.db_id, v) for v in cp._db_processs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmProcesses()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'processs' in class_dict:
+            res = class_dict['processs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_process(obj)
+        elif hasattr(old_obj, 'db_processs') and old_obj.db_processs is not None:
+            for obj in old_obj.db_processs:
+                new_obj.db_add_process(DBOpmProcess.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_processs') and hasattr(new_obj, 'db_deleted_processs'):
+            for obj in old_obj.db_deleted_processs:
+                n_obj = DBOpmProcess.update_version(obj, trans_dict)
+                new_obj.db_deleted_processs.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_processs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_process(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_processs)
+        if remove:
+            self.db_deleted_processs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_processs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_processs(self):
+        return self._db_processs
+    def __set_db_processs(self, processs):
+        self._db_processs = processs
+        self.is_dirty = True
+    db_processs = property(__get_db_processs, __set_db_processs)
+    def db_get_processs(self):
+        return self._db_processs
+    def db_add_process(self, process):
+        self.is_dirty = True
+        self._db_processs.append(process)
+        self.db_processs_id_index[process.db_id] = process
+    def db_change_process(self, process):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_processs)):
+            if self._db_processs[i].db_id == process.db_id:
+                self._db_processs[i] = process
+                found = True
+                break
+        if not found:
+            self._db_processs.append(process)
+        self.db_processs_id_index[process.db_id] = process
+    def db_delete_process(self, process):
+        self.is_dirty = True
+        for i in xrange(len(self._db_processs)):
+            if self._db_processs[i].db_id == process.db_id:
+                if not self._db_processs[i].is_new:
+                    self.db_deleted_processs.append(self._db_processs[i])
+                del self._db_processs[i]
+                break
+        del self.db_processs_id_index[process.db_id]
+    def db_get_process(self, key):
+        for i in xrange(len(self._db_processs)):
+            if self._db_processs[i].db_id == key:
+                return self._db_processs[i]
+        return None
+    def db_get_process_by_id(self, key):
+        return self.db_processs_id_index[key]
+    def db_has_process_with_id(self, key):
+        return key in self.db_processs_id_index
+    
+
+
+class DBOpmAccountId(object):
+
+    vtType = 'opm_account_id'
+
+    def __init__(self, id=None):
+        self._db_id = id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAccountId.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAccountId(id=self._db_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_id') and ('opm_account', self._db_id) in id_remap:
+                cp._db_id = id_remap[('opm_account', self._db_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAccountId()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+
+
+class DBPortSpecItem(object):
+
+    vtType = 'portSpecItem'
+
+    def __init__(self, id=None, pos=None, module=None, package=None, namespace=None, label=None, default=None, values=None, entry_type=None):
+        self._db_id = id
+        self._db_pos = pos
+        self._db_module = module
+        self._db_package = package
+        self._db_namespace = namespace
+        self._db_label = label
+        self._db_default = default
+        self._db_values = values
+        self._db_entry_type = entry_type
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBPortSpecItem.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBPortSpecItem(id=self._db_id,
+                            pos=self._db_pos,
+                            module=self._db_module,
+                            package=self._db_package,
+                            namespace=self._db_namespace,
+                            label=self._db_label,
+                            default=self._db_default,
+                            values=self._db_values,
+                            entry_type=self._db_entry_type)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBPortSpecItem()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'module' in class_dict:
+            res = class_dict['module'](old_obj, trans_dict)
+            new_obj.db_module = res
+        elif hasattr(old_obj, 'db_module') and old_obj.db_module is not None:
+            new_obj.db_module = old_obj.db_module
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'label' in class_dict:
+            res = class_dict['label'](old_obj, trans_dict)
+            new_obj.db_label = res
+        elif hasattr(old_obj, 'db_label') and old_obj.db_label is not None:
+            new_obj.db_label = old_obj.db_label
+        if 'default' in class_dict:
+            res = class_dict['default'](old_obj, trans_dict)
+            new_obj.db_default = res
+        elif hasattr(old_obj, 'db_default') and old_obj.db_default is not None:
+            new_obj.db_default = old_obj.db_default
+        if 'values' in class_dict:
+            res = class_dict['values'](old_obj, trans_dict)
+            new_obj.db_values = res
+        elif hasattr(old_obj, 'db_values') and old_obj.db_values is not None:
+            new_obj.db_values = old_obj.db_values
+        if 'entry_type' in class_dict:
+            res = class_dict['entry_type'](old_obj, trans_dict)
+            new_obj.db_entry_type = res
+        elif hasattr(old_obj, 'db_entry_type') and old_obj.db_entry_type is not None:
+            new_obj.db_entry_type = old_obj.db_entry_type
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
+        self.is_dirty = True
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
+    
+    def __get_db_module(self):
+        return self._db_module
+    def __set_db_module(self, module):
+        self._db_module = module
+        self.is_dirty = True
+    db_module = property(__get_db_module, __set_db_module)
+    def db_add_module(self, module):
+        self._db_module = module
+    def db_change_module(self, module):
+        self._db_module = module
+    def db_delete_module(self, module):
+        self._db_module = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_label(self):
+        return self._db_label
+    def __set_db_label(self, label):
+        self._db_label = label
+        self.is_dirty = True
+    db_label = property(__get_db_label, __set_db_label)
+    def db_add_label(self, label):
+        self._db_label = label
+    def db_change_label(self, label):
+        self._db_label = label
+    def db_delete_label(self, label):
+        self._db_label = None
+    
+    def __get_db_default(self):
+        return self._db_default
+    def __set_db_default(self, default):
+        self._db_default = default
+        self.is_dirty = True
+    db_default = property(__get_db_default, __set_db_default)
+    def db_add_default(self, default):
+        self._db_default = default
+    def db_change_default(self, default):
+        self._db_default = default
+    def db_delete_default(self, default):
+        self._db_default = None
+    
+    def __get_db_values(self):
+        return self._db_values
+    def __set_db_values(self, values):
+        self._db_values = values
+        self.is_dirty = True
+    db_values = property(__get_db_values, __set_db_values)
+    def db_add_values(self, values):
+        self._db_values = values
+    def db_change_values(self, values):
+        self._db_values = values
+    def db_delete_values(self, values):
+        self._db_values = None
+    
+    def __get_db_entry_type(self):
+        return self._db_entry_type
+    def __set_db_entry_type(self, entry_type):
+        self._db_entry_type = entry_type
+        self.is_dirty = True
+    db_entry_type = property(__get_db_entry_type, __set_db_entry_type)
+    def db_add_entry_type(self, entry_type):
+        self._db_entry_type = entry_type
+    def db_change_entry_type(self, entry_type):
+        self._db_entry_type = entry_type
+    def db_delete_entry_type(self, entry_type):
+        self._db_entry_type = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBMashupComponent(object):
+
+    vtType = 'mashup_component'
+
+    def __init__(self, id=None, vtid=None, vttype=None, vtparent_type=None, vtparent_id=None, vtpos=None, vtmid=None, pos=None, type=None, val=None, minVal=None, maxVal=None, stepSize=None, strvaluelist=None, widget=None, seq=None, parent=None):
+        self._db_id = id
+        self._db_vtid = vtid
+        self._db_vttype = vttype
+        self._db_vtparent_type = vtparent_type
+        self._db_vtparent_id = vtparent_id
+        self._db_vtpos = vtpos
+        self._db_vtmid = vtmid
+        self._db_pos = pos
+        self._db_type = type
+        self._db_val = val
+        self._db_minVal = minVal
+        self._db_maxVal = maxVal
+        self._db_stepSize = stepSize
+        self._db_strvaluelist = strvaluelist
+        self._db_widget = widget
+        self._db_seq = seq
+        self._db_parent = parent
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashupComponent.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashupComponent(id=self._db_id,
+                               vtid=self._db_vtid,
+                               vttype=self._db_vttype,
+                               vtparent_type=self._db_vtparent_type,
+                               vtparent_id=self._db_vtparent_id,
+                               vtpos=self._db_vtpos,
+                               vtmid=self._db_vtmid,
+                               pos=self._db_pos,
+                               type=self._db_type,
+                               val=self._db_val,
+                               minVal=self._db_minVal,
+                               maxVal=self._db_maxVal,
+                               stepSize=self._db_stepSize,
+                               strvaluelist=self._db_strvaluelist,
+                               widget=self._db_widget,
+                               seq=self._db_seq,
+                               parent=self._db_parent)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMashupComponent()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'vtid' in class_dict:
+            res = class_dict['vtid'](old_obj, trans_dict)
+            new_obj.db_vtid = res
+        elif hasattr(old_obj, 'db_vtid') and old_obj.db_vtid is not None:
+            new_obj.db_vtid = old_obj.db_vtid
+        if 'vttype' in class_dict:
+            res = class_dict['vttype'](old_obj, trans_dict)
+            new_obj.db_vttype = res
+        elif hasattr(old_obj, 'db_vttype') and old_obj.db_vttype is not None:
+            new_obj.db_vttype = old_obj.db_vttype
+        if 'vtparent_type' in class_dict:
+            res = class_dict['vtparent_type'](old_obj, trans_dict)
+            new_obj.db_vtparent_type = res
+        elif hasattr(old_obj, 'db_vtparent_type') and old_obj.db_vtparent_type is not None:
+            new_obj.db_vtparent_type = old_obj.db_vtparent_type
+        if 'vtparent_id' in class_dict:
+            res = class_dict['vtparent_id'](old_obj, trans_dict)
+            new_obj.db_vtparent_id = res
+        elif hasattr(old_obj, 'db_vtparent_id') and old_obj.db_vtparent_id is not None:
+            new_obj.db_vtparent_id = old_obj.db_vtparent_id
+        if 'vtpos' in class_dict:
+            res = class_dict['vtpos'](old_obj, trans_dict)
+            new_obj.db_vtpos = res
+        elif hasattr(old_obj, 'db_vtpos') and old_obj.db_vtpos is not None:
+            new_obj.db_vtpos = old_obj.db_vtpos
+        if 'vtmid' in class_dict:
+            res = class_dict['vtmid'](old_obj, trans_dict)
+            new_obj.db_vtmid = res
+        elif hasattr(old_obj, 'db_vtmid') and old_obj.db_vtmid is not None:
+            new_obj.db_vtmid = old_obj.db_vtmid
+        if 'pos' in class_dict:
+            res = class_dict['pos'](old_obj, trans_dict)
+            new_obj.db_pos = res
+        elif hasattr(old_obj, 'db_pos') and old_obj.db_pos is not None:
+            new_obj.db_pos = old_obj.db_pos
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'val' in class_dict:
+            res = class_dict['val'](old_obj, trans_dict)
+            new_obj.db_val = res
+        elif hasattr(old_obj, 'db_val') and old_obj.db_val is not None:
+            new_obj.db_val = old_obj.db_val
+        if 'minVal' in class_dict:
+            res = class_dict['minVal'](old_obj, trans_dict)
+            new_obj.db_minVal = res
+        elif hasattr(old_obj, 'db_minVal') and old_obj.db_minVal is not None:
+            new_obj.db_minVal = old_obj.db_minVal
+        if 'maxVal' in class_dict:
+            res = class_dict['maxVal'](old_obj, trans_dict)
+            new_obj.db_maxVal = res
+        elif hasattr(old_obj, 'db_maxVal') and old_obj.db_maxVal is not None:
+            new_obj.db_maxVal = old_obj.db_maxVal
+        if 'stepSize' in class_dict:
+            res = class_dict['stepSize'](old_obj, trans_dict)
+            new_obj.db_stepSize = res
+        elif hasattr(old_obj, 'db_stepSize') and old_obj.db_stepSize is not None:
+            new_obj.db_stepSize = old_obj.db_stepSize
+        if 'strvaluelist' in class_dict:
+            res = class_dict['strvaluelist'](old_obj, trans_dict)
+            new_obj.db_strvaluelist = res
+        elif hasattr(old_obj, 'db_strvaluelist') and old_obj.db_strvaluelist is not None:
+            new_obj.db_strvaluelist = old_obj.db_strvaluelist
+        if 'widget' in class_dict:
+            res = class_dict['widget'](old_obj, trans_dict)
+            new_obj.db_widget = res
+        elif hasattr(old_obj, 'db_widget') and old_obj.db_widget is not None:
+            new_obj.db_widget = old_obj.db_widget
+        if 'seq' in class_dict:
+            res = class_dict['seq'](old_obj, trans_dict)
+            new_obj.db_seq = res
+        elif hasattr(old_obj, 'db_seq') and old_obj.db_seq is not None:
+            new_obj.db_seq = old_obj.db_seq
+        if 'parent' in class_dict:
+            res = class_dict['parent'](old_obj, trans_dict)
+            new_obj.db_parent = res
+        elif hasattr(old_obj, 'db_parent') and old_obj.db_parent is not None:
+            new_obj.db_parent = old_obj.db_parent
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_vtid(self):
+        return self._db_vtid
+    def __set_db_vtid(self, vtid):
+        self._db_vtid = vtid
+        self.is_dirty = True
+    db_vtid = property(__get_db_vtid, __set_db_vtid)
+    def db_add_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_change_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_delete_vtid(self, vtid):
+        self._db_vtid = None
+    
+    def __get_db_vttype(self):
+        return self._db_vttype
+    def __set_db_vttype(self, vttype):
+        self._db_vttype = vttype
+        self.is_dirty = True
+    db_vttype = property(__get_db_vttype, __set_db_vttype)
+    def db_add_vttype(self, vttype):
+        self._db_vttype = vttype
+    def db_change_vttype(self, vttype):
+        self._db_vttype = vttype
+    def db_delete_vttype(self, vttype):
+        self._db_vttype = None
+    
+    def __get_db_vtparent_type(self):
+        return self._db_vtparent_type
+    def __set_db_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = vtparent_type
+        self.is_dirty = True
+    db_vtparent_type = property(__get_db_vtparent_type, __set_db_vtparent_type)
+    def db_add_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = vtparent_type
+    def db_change_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = vtparent_type
+    def db_delete_vtparent_type(self, vtparent_type):
+        self._db_vtparent_type = None
+    
+    def __get_db_vtparent_id(self):
+        return self._db_vtparent_id
+    def __set_db_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = vtparent_id
+        self.is_dirty = True
+    db_vtparent_id = property(__get_db_vtparent_id, __set_db_vtparent_id)
+    def db_add_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = vtparent_id
+    def db_change_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = vtparent_id
+    def db_delete_vtparent_id(self, vtparent_id):
+        self._db_vtparent_id = None
+    
+    def __get_db_vtpos(self):
+        return self._db_vtpos
+    def __set_db_vtpos(self, vtpos):
+        self._db_vtpos = vtpos
+        self.is_dirty = True
+    db_vtpos = property(__get_db_vtpos, __set_db_vtpos)
+    def db_add_vtpos(self, vtpos):
+        self._db_vtpos = vtpos
+    def db_change_vtpos(self, vtpos):
+        self._db_vtpos = vtpos
+    def db_delete_vtpos(self, vtpos):
+        self._db_vtpos = None
+    
+    def __get_db_vtmid(self):
+        return self._db_vtmid
+    def __set_db_vtmid(self, vtmid):
+        self._db_vtmid = vtmid
+        self.is_dirty = True
+    db_vtmid = property(__get_db_vtmid, __set_db_vtmid)
+    def db_add_vtmid(self, vtmid):
+        self._db_vtmid = vtmid
+    def db_change_vtmid(self, vtmid):
+        self._db_vtmid = vtmid
+    def db_delete_vtmid(self, vtmid):
+        self._db_vtmid = None
+    
+    def __get_db_pos(self):
+        return self._db_pos
+    def __set_db_pos(self, pos):
+        self._db_pos = pos
+        self.is_dirty = True
+    db_pos = property(__get_db_pos, __set_db_pos)
+    def db_add_pos(self, pos):
+        self._db_pos = pos
+    def db_change_pos(self, pos):
+        self._db_pos = pos
+    def db_delete_pos(self, pos):
+        self._db_pos = None
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_val(self):
+        return self._db_val
+    def __set_db_val(self, val):
+        self._db_val = val
+        self.is_dirty = True
+    db_val = property(__get_db_val, __set_db_val)
+    def db_add_val(self, val):
+        self._db_val = val
+    def db_change_val(self, val):
+        self._db_val = val
+    def db_delete_val(self, val):
+        self._db_val = None
+    
+    def __get_db_minVal(self):
+        return self._db_minVal
+    def __set_db_minVal(self, minVal):
+        self._db_minVal = minVal
+        self.is_dirty = True
+    db_minVal = property(__get_db_minVal, __set_db_minVal)
+    def db_add_minVal(self, minVal):
+        self._db_minVal = minVal
+    def db_change_minVal(self, minVal):
+        self._db_minVal = minVal
+    def db_delete_minVal(self, minVal):
+        self._db_minVal = None
+    
+    def __get_db_maxVal(self):
+        return self._db_maxVal
+    def __set_db_maxVal(self, maxVal):
+        self._db_maxVal = maxVal
+        self.is_dirty = True
+    db_maxVal = property(__get_db_maxVal, __set_db_maxVal)
+    def db_add_maxVal(self, maxVal):
+        self._db_maxVal = maxVal
+    def db_change_maxVal(self, maxVal):
+        self._db_maxVal = maxVal
+    def db_delete_maxVal(self, maxVal):
+        self._db_maxVal = None
+    
+    def __get_db_stepSize(self):
+        return self._db_stepSize
+    def __set_db_stepSize(self, stepSize):
+        self._db_stepSize = stepSize
+        self.is_dirty = True
+    db_stepSize = property(__get_db_stepSize, __set_db_stepSize)
+    def db_add_stepSize(self, stepSize):
+        self._db_stepSize = stepSize
+    def db_change_stepSize(self, stepSize):
+        self._db_stepSize = stepSize
+    def db_delete_stepSize(self, stepSize):
+        self._db_stepSize = None
+    
+    def __get_db_strvaluelist(self):
+        return self._db_strvaluelist
+    def __set_db_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = strvaluelist
+        self.is_dirty = True
+    db_strvaluelist = property(__get_db_strvaluelist, __set_db_strvaluelist)
+    def db_add_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = strvaluelist
+    def db_change_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = strvaluelist
+    def db_delete_strvaluelist(self, strvaluelist):
+        self._db_strvaluelist = None
+    
+    def __get_db_widget(self):
+        return self._db_widget
+    def __set_db_widget(self, widget):
+        self._db_widget = widget
+        self.is_dirty = True
+    db_widget = property(__get_db_widget, __set_db_widget)
+    def db_add_widget(self, widget):
+        self._db_widget = widget
+    def db_change_widget(self, widget):
+        self._db_widget = widget
+    def db_delete_widget(self, widget):
+        self._db_widget = None
+    
+    def __get_db_seq(self):
+        return self._db_seq
+    def __set_db_seq(self, seq):
+        self._db_seq = seq
+        self.is_dirty = True
+    db_seq = property(__get_db_seq, __set_db_seq)
+    def db_add_seq(self, seq):
+        self._db_seq = seq
+    def db_change_seq(self, seq):
+        self._db_seq = seq
+    def db_delete_seq(self, seq):
+        self._db_seq = None
+    
+    def __get_db_parent(self):
+        return self._db_parent
+    def __set_db_parent(self, parent):
+        self._db_parent = parent
+        self.is_dirty = True
+    db_parent = property(__get_db_parent, __set_db_parent)
+    def db_add_parent(self, parent):
+        self._db_parent = parent
+    def db_change_parent(self, parent):
+        self._db_parent = parent
+    def db_delete_parent(self, parent):
+        self._db_parent = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBMashup(object):
+
+    vtType = 'mashup'
+
+    def __init__(self, id=None, name=None, version=None, aliases=None, type=None, vtid=None, layout=None, geometry=None, has_seq=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_version = version
+        self.db_deleted_aliases = []
+        self.db_aliases_id_index = {}
+        if aliases is None:
+            self._db_aliases = []
+        else:
+            self._db_aliases = aliases
+            for v in self._db_aliases:
+                self.db_aliases_id_index[v.db_id] = v
+        self._db_type = type
+        self._db_vtid = vtid
+        self._db_layout = layout
+        self._db_geometry = geometry
+        self._db_has_seq = has_seq
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashup.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashup(id=self._db_id,
+                      name=self._db_name,
+                      version=self._db_version,
+                      type=self._db_type,
+                      vtid=self._db_vtid,
+                      layout=self._db_layout,
+                      geometry=self._db_geometry,
+                      has_seq=self._db_has_seq)
+        if self._db_aliases is None:
+            cp._db_aliases = []
+        else:
+            cp._db_aliases = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_aliases]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_vtid') and ('vistrail', self._db_vtid) in id_remap:
+                cp._db_vtid = id_remap[('vistrail', self._db_vtid)]
+        
+        # recreate indices and set flags
+        cp.db_aliases_id_index = dict((v.db_id, v) for v in cp._db_aliases)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMashup()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'aliases' in class_dict:
+            res = class_dict['aliases'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_alias(obj)
+        elif hasattr(old_obj, 'db_aliases') and old_obj.db_aliases is not None:
+            for obj in old_obj.db_aliases:
+                new_obj.db_add_alias(DBMashupAlias.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_aliases') and hasattr(new_obj, 'db_deleted_aliases'):
+            for obj in old_obj.db_deleted_aliases:
+                n_obj = DBMashupAlias.update_version(obj, trans_dict)
+                new_obj.db_deleted_aliases.append(n_obj)
+        if 'type' in class_dict:
+            res = class_dict['type'](old_obj, trans_dict)
+            new_obj.db_type = res
+        elif hasattr(old_obj, 'db_type') and old_obj.db_type is not None:
+            new_obj.db_type = old_obj.db_type
+        if 'vtid' in class_dict:
+            res = class_dict['vtid'](old_obj, trans_dict)
+            new_obj.db_vtid = res
+        elif hasattr(old_obj, 'db_vtid') and old_obj.db_vtid is not None:
+            new_obj.db_vtid = old_obj.db_vtid
+        if 'layout' in class_dict:
+            res = class_dict['layout'](old_obj, trans_dict)
+            new_obj.db_layout = res
+        elif hasattr(old_obj, 'db_layout') and old_obj.db_layout is not None:
+            new_obj.db_layout = old_obj.db_layout
+        if 'geometry' in class_dict:
+            res = class_dict['geometry'](old_obj, trans_dict)
+            new_obj.db_geometry = res
+        elif hasattr(old_obj, 'db_geometry') and old_obj.db_geometry is not None:
+            new_obj.db_geometry = old_obj.db_geometry
+        if 'has_seq' in class_dict:
+            res = class_dict['has_seq'](old_obj, trans_dict)
+            new_obj.db_has_seq = res
+        elif hasattr(old_obj, 'db_has_seq') and old_obj.db_has_seq is not None:
+            new_obj.db_has_seq = old_obj.db_has_seq
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_aliases:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_alias(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_aliases)
+        if remove:
+            self.db_deleted_aliases = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_aliases:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_aliases(self):
+        return self._db_aliases
+    def __set_db_aliases(self, aliases):
+        self._db_aliases = aliases
+        self.is_dirty = True
+    db_aliases = property(__get_db_aliases, __set_db_aliases)
+    def db_get_aliases(self):
+        return self._db_aliases
+    def db_add_alias(self, alias):
+        self.is_dirty = True
+        self._db_aliases.append(alias)
+        self.db_aliases_id_index[alias.db_id] = alias
+    def db_change_alias(self, alias):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_aliases)):
+            if self._db_aliases[i].db_id == alias.db_id:
+                self._db_aliases[i] = alias
+                found = True
+                break
+        if not found:
+            self._db_aliases.append(alias)
+        self.db_aliases_id_index[alias.db_id] = alias
+    def db_delete_alias(self, alias):
+        self.is_dirty = True
+        for i in xrange(len(self._db_aliases)):
+            if self._db_aliases[i].db_id == alias.db_id:
+                if not self._db_aliases[i].is_new:
+                    self.db_deleted_aliases.append(self._db_aliases[i])
+                del self._db_aliases[i]
+                break
+        del self.db_aliases_id_index[alias.db_id]
+    def db_get_alias(self, key):
+        for i in xrange(len(self._db_aliases)):
+            if self._db_aliases[i].db_id == key:
+                return self._db_aliases[i]
+        return None
+    def db_get_alias_by_id(self, key):
+        return self.db_aliases_id_index[key]
+    def db_has_alias_with_id(self, key):
+        return key in self.db_aliases_id_index
+    
+    def __get_db_type(self):
+        return self._db_type
+    def __set_db_type(self, type):
+        self._db_type = type
+        self.is_dirty = True
+    db_type = property(__get_db_type, __set_db_type)
+    def db_add_type(self, type):
+        self._db_type = type
+    def db_change_type(self, type):
+        self._db_type = type
+    def db_delete_type(self, type):
+        self._db_type = None
+    
+    def __get_db_vtid(self):
+        return self._db_vtid
+    def __set_db_vtid(self, vtid):
+        self._db_vtid = vtid
+        self.is_dirty = True
+    db_vtid = property(__get_db_vtid, __set_db_vtid)
+    def db_add_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_change_vtid(self, vtid):
+        self._db_vtid = vtid
+    def db_delete_vtid(self, vtid):
+        self._db_vtid = None
+    
+    def __get_db_layout(self):
+        return self._db_layout
+    def __set_db_layout(self, layout):
+        self._db_layout = layout
+        self.is_dirty = True
+    db_layout = property(__get_db_layout, __set_db_layout)
+    def db_add_layout(self, layout):
+        self._db_layout = layout
+    def db_change_layout(self, layout):
+        self._db_layout = layout
+    def db_delete_layout(self, layout):
+        self._db_layout = None
+    
+    def __get_db_geometry(self):
+        return self._db_geometry
+    def __set_db_geometry(self, geometry):
+        self._db_geometry = geometry
+        self.is_dirty = True
+    db_geometry = property(__get_db_geometry, __set_db_geometry)
+    def db_add_geometry(self, geometry):
+        self._db_geometry = geometry
+    def db_change_geometry(self, geometry):
+        self._db_geometry = geometry
+    def db_delete_geometry(self, geometry):
+        self._db_geometry = None
+    
+    def __get_db_has_seq(self):
+        return self._db_has_seq
+    def __set_db_has_seq(self, has_seq):
+        self._db_has_seq = has_seq
+        self.is_dirty = True
+    db_has_seq = property(__get_db_has_seq, __set_db_has_seq)
+    def db_add_has_seq(self, has_seq):
+        self._db_has_seq = has_seq
+    def db_change_has_seq(self, has_seq):
+        self._db_has_seq = has_seq
+    def db_delete_has_seq(self, has_seq):
+        self._db_has_seq = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBMachine(object):
+
+    vtType = 'machine'
+
+    def __init__(self, id=None, name=None, os=None, architecture=None, processor=None, ram=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_os = os
+        self._db_architecture = architecture
+        self._db_processor = processor
+        self._db_ram = ram
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMachine.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMachine(id=self._db_id,
+                       name=self._db_name,
+                       os=self._db_os,
+                       architecture=self._db_architecture,
+                       processor=self._db_processor,
+                       ram=self._db_ram)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_vistrailId') and ('vistrail', self._db_vistrailId) in id_remap:
+                cp._db_vistrailId = id_remap[('vistrail', self._db_vistrailId)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMachine()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'os' in class_dict:
+            res = class_dict['os'](old_obj, trans_dict)
+            new_obj.db_os = res
+        elif hasattr(old_obj, 'db_os') and old_obj.db_os is not None:
+            new_obj.db_os = old_obj.db_os
+        if 'architecture' in class_dict:
+            res = class_dict['architecture'](old_obj, trans_dict)
+            new_obj.db_architecture = res
+        elif hasattr(old_obj, 'db_architecture') and old_obj.db_architecture is not None:
+            new_obj.db_architecture = old_obj.db_architecture
+        if 'processor' in class_dict:
+            res = class_dict['processor'](old_obj, trans_dict)
+            new_obj.db_processor = res
+        elif hasattr(old_obj, 'db_processor') and old_obj.db_processor is not None:
+            new_obj.db_processor = old_obj.db_processor
+        if 'ram' in class_dict:
+            res = class_dict['ram'](old_obj, trans_dict)
+            new_obj.db_ram = res
+        elif hasattr(old_obj, 'db_ram') and old_obj.db_ram is not None:
+            new_obj.db_ram = old_obj.db_ram
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_os(self):
+        return self._db_os
+    def __set_db_os(self, os):
+        self._db_os = os
+        self.is_dirty = True
+    db_os = property(__get_db_os, __set_db_os)
+    def db_add_os(self, os):
+        self._db_os = os
+    def db_change_os(self, os):
+        self._db_os = os
+    def db_delete_os(self, os):
+        self._db_os = None
+    
+    def __get_db_architecture(self):
+        return self._db_architecture
+    def __set_db_architecture(self, architecture):
+        self._db_architecture = architecture
+        self.is_dirty = True
+    db_architecture = property(__get_db_architecture, __set_db_architecture)
+    def db_add_architecture(self, architecture):
+        self._db_architecture = architecture
+    def db_change_architecture(self, architecture):
+        self._db_architecture = architecture
+    def db_delete_architecture(self, architecture):
+        self._db_architecture = None
+    
+    def __get_db_processor(self):
+        return self._db_processor
+    def __set_db_processor(self, processor):
+        self._db_processor = processor
+        self.is_dirty = True
+    db_processor = property(__get_db_processor, __set_db_processor)
+    def db_add_processor(self, processor):
+        self._db_processor = processor
+    def db_change_processor(self, processor):
+        self._db_processor = processor
+    def db_delete_processor(self, processor):
+        self._db_processor = None
+    
+    def __get_db_ram(self):
+        return self._db_ram
+    def __set_db_ram(self, ram):
+        self._db_ram = ram
+        self.is_dirty = True
+    db_ram = property(__get_db_ram, __set_db_ram)
+    def db_add_ram(self, ram):
+        self._db_ram = ram
+    def db_change_ram(self, ram):
+        self._db_ram = ram
+    def db_delete_ram(self, ram):
+        self._db_ram = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBConfigFloat(object):
+
+    vtType = 'config_float'
+
+    def __init__(self, value=None):
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBConfigFloat.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBConfigFloat(value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBConfigFloat()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+
+
+class DBOther(object):
+
+    vtType = 'other'
+
+    def __init__(self, id=None, key=None, value=None):
+        self._db_id = id
+        self._db_key = key
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOther.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOther(id=self._db_id,
+                     key=self._db_key,
+                     value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOther()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
+        self.is_dirty = True
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBRefProvActivity(object):
+
+    vtType = 'ref_prov_activity'
+
+    def __init__(self, prov_ref=None):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBRefProvActivity.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBRefProvActivity(prov_ref=self._db_prov_ref)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_prov_ref') and ('prov_activity', self._db_prov_ref) in id_remap:
+                cp._db_prov_ref = id_remap[('prov_activity', self._db_prov_ref)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRefProvActivity()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_ref' in class_dict:
+            res = class_dict['prov_ref'](old_obj, trans_dict)
+            new_obj.db_prov_ref = res
+        elif hasattr(old_obj, 'db_prov_ref') and old_obj.db_prov_ref is not None:
+            new_obj.db_prov_ref = old_obj.db_prov_ref
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_prov_ref(self):
+        return self._db_prov_ref
+    def __set_db_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+        self.is_dirty = True
+    db_prov_ref = property(__get_db_prov_ref, __set_db_prov_ref)
+    def db_add_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_change_prov_ref(self, prov_ref):
+        self._db_prov_ref = prov_ref
+    def db_delete_prov_ref(self, prov_ref):
+        self._db_prov_ref = None
+    
+
+
+class DBAbstraction(object):
+
+    vtType = 'abstraction'
+
+    def __init__(self, id=None, cache=None, name=None, namespace=None, package=None, version=None, internal_version=None, location=None, functions=None, annotations=None, controlParameters=None):
+        self._db_id = id
+        self._db_cache = cache
+        self._db_name = name
+        self._db_namespace = namespace
+        self._db_package = package
+        self._db_version = version
+        self._db_internal_version = internal_version
+        self.db_deleted_location = []
+        self._db_location = location
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
+        else:
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_controlParameters = []
+        self.db_controlParameters_id_index = {}
+        self.db_controlParameters_name_index = {}
+        if controlParameters is None:
+            self._db_controlParameters = []
+        else:
+            self._db_controlParameters = controlParameters
+            for v in self._db_controlParameters:
+                self.db_controlParameters_id_index[v.db_id] = v
+                self.db_controlParameters_name_index[v.db_name] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBAbstraction.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBAbstraction(id=self._db_id,
+                           cache=self._db_cache,
+                           name=self._db_name,
+                           namespace=self._db_namespace,
+                           package=self._db_package,
+                           version=self._db_version,
+                           internal_version=self._db_internal_version)
+        if self._db_location is not None:
+            cp._db_location = self._db_location.do_copy(new_ids, id_scope, id_remap)
+        if self._db_functions is None:
+            cp._db_functions = []
+        else:
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_controlParameters is None:
+            cp._db_controlParameters = []
+        else:
+            cp._db_controlParameters = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_controlParameters]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_controlParameters_id_index = dict((v.db_id, v) for v in cp._db_controlParameters)
+        cp.db_controlParameters_name_index = dict((v.db_name, v) for v in cp._db_controlParameters)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBAbstraction()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'cache' in class_dict:
+            res = class_dict['cache'](old_obj, trans_dict)
+            new_obj.db_cache = res
+        elif hasattr(old_obj, 'db_cache') and old_obj.db_cache is not None:
+            new_obj.db_cache = old_obj.db_cache
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'namespace' in class_dict:
+            res = class_dict['namespace'](old_obj, trans_dict)
+            new_obj.db_namespace = res
+        elif hasattr(old_obj, 'db_namespace') and old_obj.db_namespace is not None:
+            new_obj.db_namespace = old_obj.db_namespace
+        if 'package' in class_dict:
+            res = class_dict['package'](old_obj, trans_dict)
+            new_obj.db_package = res
+        elif hasattr(old_obj, 'db_package') and old_obj.db_package is not None:
+            new_obj.db_package = old_obj.db_package
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'internal_version' in class_dict:
+            res = class_dict['internal_version'](old_obj, trans_dict)
+            new_obj.db_internal_version = res
+        elif hasattr(old_obj, 'db_internal_version') and old_obj.db_internal_version is not None:
+            new_obj.db_internal_version = old_obj.db_internal_version
+        if 'location' in class_dict:
+            res = class_dict['location'](old_obj, trans_dict)
+            new_obj.db_location = res
+        elif hasattr(old_obj, 'db_location') and old_obj.db_location is not None:
+            obj = old_obj.db_location
+            new_obj.db_add_location(DBLocation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_location') and hasattr(new_obj, 'db_deleted_location'):
+            for obj in old_obj.db_deleted_location:
+                n_obj = DBLocation.update_version(obj, trans_dict)
+                new_obj.db_deleted_location.append(n_obj)
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'controlParameters' in class_dict:
+            res = class_dict['controlParameters'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_controlParameter(obj)
+        elif hasattr(old_obj, 'db_controlParameters') and old_obj.db_controlParameters is not None:
+            for obj in old_obj.db_controlParameters:
+                new_obj.db_add_controlParameter(DBControlParameter.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_controlParameters') and hasattr(new_obj, 'db_deleted_controlParameters'):
+            for obj in old_obj.db_deleted_controlParameters:
+                n_obj = DBControlParameter.update_version(obj, trans_dict)
+                new_obj.db_deleted_controlParameters.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_location is not None:
+            children.extend(self._db_location.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_location = None
+        to_del = []
+        for child in self.db_functions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_function(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_controlParameters:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_controlParameter(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_location)
+        children.extend(self.db_deleted_functions)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_controlParameters)
+        if remove:
+            self.db_deleted_location = []
+            self.db_deleted_functions = []
+            self.db_deleted_annotations = []
+            self.db_deleted_controlParameters = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_location is not None and self._db_location.has_changes():
+            return True
+        for child in self._db_functions:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_controlParameters:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_cache(self):
+        return self._db_cache
+    def __set_db_cache(self, cache):
+        self._db_cache = cache
+        self.is_dirty = True
+    db_cache = property(__get_db_cache, __set_db_cache)
+    def db_add_cache(self, cache):
+        self._db_cache = cache
+    def db_change_cache(self, cache):
+        self._db_cache = cache
+    def db_delete_cache(self, cache):
+        self._db_cache = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_namespace(self):
+        return self._db_namespace
+    def __set_db_namespace(self, namespace):
+        self._db_namespace = namespace
+        self.is_dirty = True
+    db_namespace = property(__get_db_namespace, __set_db_namespace)
+    def db_add_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_change_namespace(self, namespace):
+        self._db_namespace = namespace
+    def db_delete_namespace(self, namespace):
+        self._db_namespace = None
+    
+    def __get_db_package(self):
+        return self._db_package
+    def __set_db_package(self, package):
+        self._db_package = package
+        self.is_dirty = True
+    db_package = property(__get_db_package, __set_db_package)
+    def db_add_package(self, package):
+        self._db_package = package
+    def db_change_package(self, package):
+        self._db_package = package
+    def db_delete_package(self, package):
+        self._db_package = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_internal_version(self):
+        return self._db_internal_version
+    def __set_db_internal_version(self, internal_version):
+        self._db_internal_version = internal_version
+        self.is_dirty = True
+    db_internal_version = property(__get_db_internal_version, __set_db_internal_version)
+    def db_add_internal_version(self, internal_version):
+        self._db_internal_version = internal_version
+    def db_change_internal_version(self, internal_version):
+        self._db_internal_version = internal_version
+    def db_delete_internal_version(self, internal_version):
+        self._db_internal_version = None
+    
+    def __get_db_location(self):
+        return self._db_location
+    def __set_db_location(self, location):
+        self._db_location = location
+        self.is_dirty = True
+    db_location = property(__get_db_location, __set_db_location)
+    def db_add_location(self, location):
+        self._db_location = location
+    def db_change_location(self, location):
+        self._db_location = location
+    def db_delete_location(self, location):
+        if not self.is_new:
+            self.db_deleted_location.append(self._db_location)
+        self._db_location = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
+        self.is_dirty = True
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
+        self.is_dirty = True
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
+                found = True
+                break
+        if not found:
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
+        self.is_dirty = True
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
+                break
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
+        return None
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_controlParameters(self):
+        return self._db_controlParameters
+    def __set_db_controlParameters(self, controlParameters):
+        self._db_controlParameters = controlParameters
+        self.is_dirty = True
+    db_controlParameters = property(__get_db_controlParameters, __set_db_controlParameters)
+    def db_get_controlParameters(self):
+        return self._db_controlParameters
+    def db_add_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_change_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                self._db_controlParameters[i] = controlParameter
+                found = True
+                break
+        if not found:
+            self._db_controlParameters.append(controlParameter)
+        self.db_controlParameters_id_index[controlParameter.db_id] = controlParameter
+        self.db_controlParameters_name_index[controlParameter.db_name] = controlParameter
+    def db_delete_controlParameter(self, controlParameter):
+        self.is_dirty = True
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == controlParameter.db_id:
+                if not self._db_controlParameters[i].is_new:
+                    self.db_deleted_controlParameters.append(self._db_controlParameters[i])
+                del self._db_controlParameters[i]
+                break
+        del self.db_controlParameters_id_index[controlParameter.db_id]
+        del self.db_controlParameters_name_index[controlParameter.db_name]
+    def db_get_controlParameter(self, key):
+        for i in xrange(len(self._db_controlParameters)):
+            if self._db_controlParameters[i].db_id == key:
+                return self._db_controlParameters[i]
+        return None
+    def db_get_controlParameter_by_id(self, key):
+        return self.db_controlParameters_id_index[key]
+    def db_has_controlParameter_with_id(self, key):
+        return key in self.db_controlParameters_id_index
+    def db_get_controlParameter_by_name(self, key):
+        return self.db_controlParameters_name_index[key]
+    def db_has_controlParameter_with_name(self, key):
+        return key in self.db_controlParameters_name_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvAgent(object):
+
+    vtType = 'prov_agent'
+
+    def __init__(self, id=None, vt_id=None, prov_type=None, prov_label=None, vt_machine_os=None, vt_machine_architecture=None, vt_machine_processor=None, vt_machine_ram=None):
+        self._db_id = id
+        self._db_vt_id = vt_id
+        self._db_prov_type = prov_type
+        self._db_prov_label = prov_label
+        self._db_vt_machine_os = vt_machine_os
+        self._db_vt_machine_architecture = vt_machine_architecture
+        self._db_vt_machine_processor = vt_machine_processor
+        self._db_vt_machine_ram = vt_machine_ram
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvAgent.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvAgent(id=self._db_id,
+                         vt_id=self._db_vt_id,
+                         prov_type=self._db_prov_type,
+                         prov_label=self._db_prov_label,
+                         vt_machine_os=self._db_vt_machine_os,
+                         vt_machine_architecture=self._db_vt_machine_architecture,
+                         vt_machine_processor=self._db_vt_machine_processor,
+                         vt_machine_ram=self._db_vt_machine_ram)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvAgent()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'vt_id' in class_dict:
+            res = class_dict['vt_id'](old_obj, trans_dict)
+            new_obj.db_vt_id = res
+        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
+            new_obj.db_vt_id = old_obj.db_vt_id
+        if 'prov_type' in class_dict:
+            res = class_dict['prov_type'](old_obj, trans_dict)
+            new_obj.db_prov_type = res
+        elif hasattr(old_obj, 'db_prov_type') and old_obj.db_prov_type is not None:
+            new_obj.db_prov_type = old_obj.db_prov_type
+        if 'prov_label' in class_dict:
+            res = class_dict['prov_label'](old_obj, trans_dict)
+            new_obj.db_prov_label = res
+        elif hasattr(old_obj, 'db_prov_label') and old_obj.db_prov_label is not None:
+            new_obj.db_prov_label = old_obj.db_prov_label
+        if 'vt_machine_os' in class_dict:
+            res = class_dict['vt_machine_os'](old_obj, trans_dict)
+            new_obj.db_vt_machine_os = res
+        elif hasattr(old_obj, 'db_vt_machine_os') and old_obj.db_vt_machine_os is not None:
+            new_obj.db_vt_machine_os = old_obj.db_vt_machine_os
+        if 'vt_machine_architecture' in class_dict:
+            res = class_dict['vt_machine_architecture'](old_obj, trans_dict)
+            new_obj.db_vt_machine_architecture = res
+        elif hasattr(old_obj, 'db_vt_machine_architecture') and old_obj.db_vt_machine_architecture is not None:
+            new_obj.db_vt_machine_architecture = old_obj.db_vt_machine_architecture
+        if 'vt_machine_processor' in class_dict:
+            res = class_dict['vt_machine_processor'](old_obj, trans_dict)
+            new_obj.db_vt_machine_processor = res
+        elif hasattr(old_obj, 'db_vt_machine_processor') and old_obj.db_vt_machine_processor is not None:
+            new_obj.db_vt_machine_processor = old_obj.db_vt_machine_processor
+        if 'vt_machine_ram' in class_dict:
+            res = class_dict['vt_machine_ram'](old_obj, trans_dict)
+            new_obj.db_vt_machine_ram = res
+        elif hasattr(old_obj, 'db_vt_machine_ram') and old_obj.db_vt_machine_ram is not None:
+            new_obj.db_vt_machine_ram = old_obj.db_vt_machine_ram
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_vt_id(self):
+        return self._db_vt_id
+    def __set_db_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+        self.is_dirty = True
+    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
+    def db_add_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_change_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_delete_vt_id(self, vt_id):
+        self._db_vt_id = None
+    
+    def __get_db_prov_type(self):
+        return self._db_prov_type
+    def __set_db_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+        self.is_dirty = True
+    db_prov_type = property(__get_db_prov_type, __set_db_prov_type)
+    def db_add_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_change_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_delete_prov_type(self, prov_type):
+        self._db_prov_type = None
+    
+    def __get_db_prov_label(self):
+        return self._db_prov_label
+    def __set_db_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+        self.is_dirty = True
+    db_prov_label = property(__get_db_prov_label, __set_db_prov_label)
+    def db_add_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_change_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_delete_prov_label(self, prov_label):
+        self._db_prov_label = None
+    
+    def __get_db_vt_machine_os(self):
+        return self._db_vt_machine_os
+    def __set_db_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = vt_machine_os
+        self.is_dirty = True
+    db_vt_machine_os = property(__get_db_vt_machine_os, __set_db_vt_machine_os)
+    def db_add_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = vt_machine_os
+    def db_change_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = vt_machine_os
+    def db_delete_vt_machine_os(self, vt_machine_os):
+        self._db_vt_machine_os = None
+    
+    def __get_db_vt_machine_architecture(self):
+        return self._db_vt_machine_architecture
+    def __set_db_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = vt_machine_architecture
+        self.is_dirty = True
+    db_vt_machine_architecture = property(__get_db_vt_machine_architecture, __set_db_vt_machine_architecture)
+    def db_add_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = vt_machine_architecture
+    def db_change_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = vt_machine_architecture
+    def db_delete_vt_machine_architecture(self, vt_machine_architecture):
+        self._db_vt_machine_architecture = None
+    
+    def __get_db_vt_machine_processor(self):
+        return self._db_vt_machine_processor
+    def __set_db_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = vt_machine_processor
+        self.is_dirty = True
+    db_vt_machine_processor = property(__get_db_vt_machine_processor, __set_db_vt_machine_processor)
+    def db_add_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = vt_machine_processor
+    def db_change_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = vt_machine_processor
+    def db_delete_vt_machine_processor(self, vt_machine_processor):
+        self._db_vt_machine_processor = None
+    
+    def __get_db_vt_machine_ram(self):
+        return self._db_vt_machine_ram
+    def __set_db_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = vt_machine_ram
+        self.is_dirty = True
+    db_vt_machine_ram = property(__get_db_vt_machine_ram, __set_db_vt_machine_ram)
+    def db_add_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = vt_machine_ram
+    def db_change_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = vt_machine_ram
+    def db_delete_vt_machine_ram(self, vt_machine_ram):
+        self._db_vt_machine_ram = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBMashuptrail(object):
+
+    vtType = 'mashuptrail'
+
+    def __init__(self, id=None, name=None, version=None, vtVersion=None, last_modified=None, actions=None, annotations=None, actionAnnotations=None):
+        self._db_id = id
+        self._db_name = name
+        self._db_version = version
+        self._db_vtVersion = vtVersion
+        self._db_last_modified = last_modified
+        self.db_deleted_actions = []
+        self.db_actions_id_index = {}
+        if actions is None:
+            self._db_actions = []
+        else:
+            self._db_actions = actions
+            for v in self._db_actions:
+                self.db_actions_id_index[v.db_id] = v
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        self.db_annotations_key_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+                self.db_annotations_key_index[v.db_key] = v
+        self.db_deleted_actionAnnotations = []
+        self.db_actionAnnotations_id_index = {}
+        self.db_actionAnnotations_action_id_index = {}
+        self.db_actionAnnotations_key_index = {}
+        if actionAnnotations is None:
+            self._db_actionAnnotations = []
+        else:
+            self._db_actionAnnotations = actionAnnotations
+            for v in self._db_actionAnnotations:
+                self.db_actionAnnotations_id_index[v.db_id] = v
+                self.db_actionAnnotations_action_id_index[(v.db_action_id,v.db_key)] = v
+                self.db_actionAnnotations_key_index[(v.db_key,v.db_value)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashuptrail.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashuptrail(id=self._db_id,
+                           name=self._db_name,
+                           version=self._db_version,
+                           vtVersion=self._db_vtVersion,
+                           last_modified=self._db_last_modified)
+        if self._db_actions is None:
+            cp._db_actions = []
+        else:
+            cp._db_actions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actions]
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_actionAnnotations is None:
+            cp._db_actionAnnotations = []
+        else:
+            cp._db_actionAnnotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_actionAnnotations]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_actions_id_index = dict((v.db_id, v) for v in cp._db_actions)
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_annotations_key_index = dict((v.db_key, v) for v in cp._db_annotations)
+        cp.db_actionAnnotations_id_index = dict((v.db_id, v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_action_id_index = dict(((v.db_action_id,v.db_key), v) for v in cp._db_actionAnnotations)
+        cp.db_actionAnnotations_key_index = dict(((v.db_key,v.db_value), v) for v in cp._db_actionAnnotations)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMashuptrail()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'vtVersion' in class_dict:
+            res = class_dict['vtVersion'](old_obj, trans_dict)
+            new_obj.db_vtVersion = res
+        elif hasattr(old_obj, 'db_vtVersion') and old_obj.db_vtVersion is not None:
+            new_obj.db_vtVersion = old_obj.db_vtVersion
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'actions' in class_dict:
+            res = class_dict['actions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_action(obj)
+        elif hasattr(old_obj, 'db_actions') and old_obj.db_actions is not None:
+            for obj in old_obj.db_actions:
+                new_obj.db_add_action(DBMashupAction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actions') and hasattr(new_obj, 'db_deleted_actions'):
+            for obj in old_obj.db_deleted_actions:
+                n_obj = DBMashupAction.update_version(obj, trans_dict)
+                new_obj.db_deleted_actions.append(n_obj)
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'actionAnnotations' in class_dict:
+            res = class_dict['actionAnnotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_actionAnnotation(obj)
+        elif hasattr(old_obj, 'db_actionAnnotations') and old_obj.db_actionAnnotations is not None:
+            for obj in old_obj.db_actionAnnotations:
+                new_obj.db_add_actionAnnotation(DBMashupActionAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_actionAnnotations') and hasattr(new_obj, 'db_deleted_actionAnnotations'):
+            for obj in old_obj.db_deleted_actionAnnotations:
+                n_obj = DBMashupActionAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_actionAnnotations.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_actions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_action(child)
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_actionAnnotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_actionAnnotation(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_actions)
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_actionAnnotations)
+        if remove:
+            self.db_deleted_actions = []
+            self.db_deleted_annotations = []
+            self.db_deleted_actionAnnotations = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_actions:
+            if child.has_changes():
+                return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_actionAnnotations:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_vtVersion(self):
+        return self._db_vtVersion
+    def __set_db_vtVersion(self, vtVersion):
+        self._db_vtVersion = vtVersion
+        self.is_dirty = True
+    db_vtVersion = property(__get_db_vtVersion, __set_db_vtVersion)
+    def db_add_vtVersion(self, vtVersion):
+        self._db_vtVersion = vtVersion
+    def db_change_vtVersion(self, vtVersion):
+        self._db_vtVersion = vtVersion
+    def db_delete_vtVersion(self, vtVersion):
+        self._db_vtVersion = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_actions(self):
+        return self._db_actions
+    def __set_db_actions(self, actions):
+        self._db_actions = actions
+        self.is_dirty = True
+    db_actions = property(__get_db_actions, __set_db_actions)
+    def db_get_actions(self):
+        return self._db_actions
+    def db_add_action(self, action):
+        self.is_dirty = True
+        self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_change_action(self, action):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                self._db_actions[i] = action
+                found = True
+                break
+        if not found:
+            self._db_actions.append(action)
+        self.db_actions_id_index[action.db_id] = action
+    def db_delete_action(self, action):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == action.db_id:
+                if not self._db_actions[i].is_new:
+                    self.db_deleted_actions.append(self._db_actions[i])
+                del self._db_actions[i]
+                break
+        del self.db_actions_id_index[action.db_id]
+    def db_get_action(self, key):
+        for i in xrange(len(self._db_actions)):
+            if self._db_actions[i].db_id == key:
+                return self._db_actions[i]
+        return None
+    def db_get_action_by_id(self, key):
+        return self.db_actions_id_index[key]
+    def db_has_action_with_id(self, key):
+        return key in self.db_actions_id_index
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+        self.db_annotations_key_index[annotation.db_key] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+        del self.db_annotations_key_index[annotation.db_key]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    def db_get_annotation_by_key(self, key):
+        return self.db_annotations_key_index[key]
+    def db_has_annotation_with_key(self, key):
+        return key in self.db_annotations_key_index
+    
+    def __get_db_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def __set_db_actionAnnotations(self, actionAnnotations):
+        self._db_actionAnnotations = actionAnnotations
+        self.is_dirty = True
+    db_actionAnnotations = property(__get_db_actionAnnotations, __set_db_actionAnnotations)
+    def db_get_actionAnnotations(self):
+        return self._db_actionAnnotations
+    def db_add_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_change_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                self._db_actionAnnotations[i] = actionAnnotation
+                found = True
+                break
+        if not found:
+            self._db_actionAnnotations.append(actionAnnotation)
+        self.db_actionAnnotations_id_index[actionAnnotation.db_id] = actionAnnotation
+        self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)] = actionAnnotation
+        self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)] = actionAnnotation
+    def db_delete_actionAnnotation(self, actionAnnotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == actionAnnotation.db_id:
+                if not self._db_actionAnnotations[i].is_new:
+                    self.db_deleted_actionAnnotations.append(self._db_actionAnnotations[i])
+                del self._db_actionAnnotations[i]
+                break
+        del self.db_actionAnnotations_id_index[actionAnnotation.db_id]
+        del self.db_actionAnnotations_action_id_index[(actionAnnotation.db_action_id,actionAnnotation.db_key)]
+        try:
+            del self.db_actionAnnotations_key_index[(actionAnnotation.db_key,actionAnnotation.db_value)]
+        except KeyError:
+            pass
+    def db_get_actionAnnotation(self, key):
+        for i in xrange(len(self._db_actionAnnotations)):
+            if self._db_actionAnnotations[i].db_id == key:
+                return self._db_actionAnnotations[i]
+        return None
+    def db_get_actionAnnotation_by_id(self, key):
+        return self.db_actionAnnotations_id_index[key]
+    def db_has_actionAnnotation_with_id(self, key):
+        return key in self.db_actionAnnotations_id_index
+    def db_get_actionAnnotation_by_action_id(self, key):
+        return self.db_actionAnnotations_action_id_index[key]
+    def db_has_actionAnnotation_with_action_id(self, key):
+        return key in self.db_actionAnnotations_action_id_index
+    def db_get_actionAnnotation_by_key(self, key):
+        return self.db_actionAnnotations_key_index[key]
+    def db_has_actionAnnotation_with_key(self, key):
+        return key in self.db_actionAnnotations_key_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBRegistry(object):
+
+    vtType = 'registry'
+
+    def __init__(self, id=None, entity_type=None, version=None, root_descriptor_id=None, name=None, last_modified=None, packages=None):
+        self._db_id = id
+        self._db_entity_type = entity_type
+        self._db_version = version
+        self._db_root_descriptor_id = root_descriptor_id
+        self._db_name = name
+        self._db_last_modified = last_modified
+        self.db_deleted_packages = []
+        self.db_packages_id_index = {}
+        self.db_packages_identifier_index = {}
+        if packages is None:
+            self._db_packages = []
+        else:
+            self._db_packages = packages
+            for v in self._db_packages:
+                self.db_packages_id_index[v.db_id] = v
+                self.db_packages_identifier_index[(v.db_identifier,v.db_version)] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBRegistry.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBRegistry(id=self._db_id,
+                        entity_type=self._db_entity_type,
+                        version=self._db_version,
+                        root_descriptor_id=self._db_root_descriptor_id,
+                        name=self._db_name,
+                        last_modified=self._db_last_modified)
+        if self._db_packages is None:
+            cp._db_packages = []
+        else:
+            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_root_descriptor_id') and ('module_descriptor', self._db_root_descriptor_id) in id_remap:
+                cp._db_root_descriptor_id = id_remap[('module_descriptor', self._db_root_descriptor_id)]
+        
+        # recreate indices and set flags
+        cp.db_packages_id_index = dict((v.db_id, v) for v in cp._db_packages)
+        cp.db_packages_identifier_index = dict(((v.db_identifier,v.db_version), v) for v in cp._db_packages)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRegistry()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'entity_type' in class_dict:
+            res = class_dict['entity_type'](old_obj, trans_dict)
+            new_obj.db_entity_type = res
+        elif hasattr(old_obj, 'db_entity_type') and old_obj.db_entity_type is not None:
+            new_obj.db_entity_type = old_obj.db_entity_type
+        if 'version' in class_dict:
+            res = class_dict['version'](old_obj, trans_dict)
+            new_obj.db_version = res
+        elif hasattr(old_obj, 'db_version') and old_obj.db_version is not None:
+            new_obj.db_version = old_obj.db_version
+        if 'root_descriptor_id' in class_dict:
+            res = class_dict['root_descriptor_id'](old_obj, trans_dict)
+            new_obj.db_root_descriptor_id = res
+        elif hasattr(old_obj, 'db_root_descriptor_id') and old_obj.db_root_descriptor_id is not None:
+            new_obj.db_root_descriptor_id = old_obj.db_root_descriptor_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'last_modified' in class_dict:
+            res = class_dict['last_modified'](old_obj, trans_dict)
+            new_obj.db_last_modified = res
+        elif hasattr(old_obj, 'db_last_modified') and old_obj.db_last_modified is not None:
+            new_obj.db_last_modified = old_obj.db_last_modified
+        if 'packages' in class_dict:
+            res = class_dict['packages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_package(obj)
+        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
+            for obj in old_obj.db_packages:
+                new_obj.db_add_package(DBPackage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
+            for obj in old_obj.db_deleted_packages:
+                n_obj = DBPackage.update_version(obj, trans_dict)
+                new_obj.db_deleted_packages.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_packages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_package(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_packages)
+        if remove:
+            self.db_deleted_packages = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_packages:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_entity_type(self):
+        return self._db_entity_type
+    def __set_db_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+        self.is_dirty = True
+    db_entity_type = property(__get_db_entity_type, __set_db_entity_type)
+    def db_add_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_change_entity_type(self, entity_type):
+        self._db_entity_type = entity_type
+    def db_delete_entity_type(self, entity_type):
+        self._db_entity_type = None
+    
+    def __get_db_version(self):
+        return self._db_version
+    def __set_db_version(self, version):
+        self._db_version = version
+        self.is_dirty = True
+    db_version = property(__get_db_version, __set_db_version)
+    def db_add_version(self, version):
+        self._db_version = version
+    def db_change_version(self, version):
+        self._db_version = version
+    def db_delete_version(self, version):
+        self._db_version = None
+    
+    def __get_db_root_descriptor_id(self):
+        return self._db_root_descriptor_id
+    def __set_db_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = root_descriptor_id
+        self.is_dirty = True
+    db_root_descriptor_id = property(__get_db_root_descriptor_id, __set_db_root_descriptor_id)
+    def db_add_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = root_descriptor_id
+    def db_change_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = root_descriptor_id
+    def db_delete_root_descriptor_id(self, root_descriptor_id):
+        self._db_root_descriptor_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_last_modified(self):
+        return self._db_last_modified
+    def __set_db_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+        self.is_dirty = True
+    db_last_modified = property(__get_db_last_modified, __set_db_last_modified)
+    def db_add_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_change_last_modified(self, last_modified):
+        self._db_last_modified = last_modified
+    def db_delete_last_modified(self, last_modified):
+        self._db_last_modified = None
+    
+    def __get_db_packages(self):
+        return self._db_packages
+    def __set_db_packages(self, packages):
+        self._db_packages = packages
+        self.is_dirty = True
+    db_packages = property(__get_db_packages, __set_db_packages)
+    def db_get_packages(self):
+        return self._db_packages
+    def db_add_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_id_index[package.db_id] = package
+        self.db_packages_identifier_index[(package.db_identifier,package.db_version)] = package
+    def db_change_package(self, package):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_packages)):
+            if self._db_packages[i].db_id == package.db_id:
+                self._db_packages[i] = package
+                found = True
+                break
+        if not found:
+            self._db_packages.append(package)
+        self.db_packages_id_index[package.db_id] = package
+        self.db_packages_identifier_index[(package.db_identifier,package.db_version)] = package
+    def db_delete_package(self, package):
+        self.is_dirty = True
+        for i in xrange(len(self._db_packages)):
+            if self._db_packages[i].db_id == package.db_id:
+                if not self._db_packages[i].is_new:
+                    self.db_deleted_packages.append(self._db_packages[i])
+                del self._db_packages[i]
+                break
+        del self.db_packages_id_index[package.db_id]
+        del self.db_packages_identifier_index[(package.db_identifier,package.db_version)]
+    def db_get_package(self, key):
+        for i in xrange(len(self._db_packages)):
+            if self._db_packages[i].db_id == key:
+                return self._db_packages[i]
+        return None
+    def db_get_package_by_id(self, key):
+        return self.db_packages_id_index[key]
+    def db_has_package_with_id(self, key):
+        return key in self.db_packages_id_index
+    def db_get_package_by_identifier(self, key):
+        return self.db_packages_identifier_index[key]
+    def db_has_package_with_identifier(self, key):
+        return key in self.db_packages_identifier_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmAgent(object):
+
+    vtType = 'opm_agent'
+
+    def __init__(self, id=None, value=None, accounts=None):
+        self._db_id = id
+        self._db_value = value
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmAgent.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmAgent(id=self._db_id,
+                        value=self._db_value)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmAgent()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_accounts)
+        if remove:
+            self.db_deleted_accounts = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvEntity(object):
+
+    vtType = 'prov_entity'
+
+    def __init__(self, id=None, prov_type=None, prov_label=None, prov_value=None, vt_id=None, vt_type=None, vt_desc=None, vt_package=None, vt_version=None, vt_cache=None, vt_location_x=None, vt_location_y=None, is_part_of=None):
+        self._db_id = id
+        self._db_prov_type = prov_type
+        self._db_prov_label = prov_label
+        self._db_prov_value = prov_value
+        self._db_vt_id = vt_id
+        self._db_vt_type = vt_type
+        self._db_vt_desc = vt_desc
+        self._db_vt_package = vt_package
+        self._db_vt_version = vt_version
+        self._db_vt_cache = vt_cache
+        self._db_vt_location_x = vt_location_x
+        self._db_vt_location_y = vt_location_y
+        self.db_deleted_is_part_of = []
+        self._db_is_part_of = is_part_of
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvEntity.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvEntity(id=self._db_id,
+                          prov_type=self._db_prov_type,
+                          prov_label=self._db_prov_label,
+                          prov_value=self._db_prov_value,
+                          vt_id=self._db_vt_id,
+                          vt_type=self._db_vt_type,
+                          vt_desc=self._db_vt_desc,
+                          vt_package=self._db_vt_package,
+                          vt_version=self._db_vt_version,
+                          vt_cache=self._db_vt_cache,
+                          vt_location_x=self._db_vt_location_x,
+                          vt_location_y=self._db_vt_location_y)
+        if self._db_is_part_of is not None:
+            cp._db_is_part_of = self._db_is_part_of.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvEntity()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'prov_type' in class_dict:
+            res = class_dict['prov_type'](old_obj, trans_dict)
+            new_obj.db_prov_type = res
+        elif hasattr(old_obj, 'db_prov_type') and old_obj.db_prov_type is not None:
+            new_obj.db_prov_type = old_obj.db_prov_type
+        if 'prov_label' in class_dict:
+            res = class_dict['prov_label'](old_obj, trans_dict)
+            new_obj.db_prov_label = res
+        elif hasattr(old_obj, 'db_prov_label') and old_obj.db_prov_label is not None:
+            new_obj.db_prov_label = old_obj.db_prov_label
+        if 'prov_value' in class_dict:
+            res = class_dict['prov_value'](old_obj, trans_dict)
+            new_obj.db_prov_value = res
+        elif hasattr(old_obj, 'db_prov_value') and old_obj.db_prov_value is not None:
+            new_obj.db_prov_value = old_obj.db_prov_value
+        if 'vt_id' in class_dict:
+            res = class_dict['vt_id'](old_obj, trans_dict)
+            new_obj.db_vt_id = res
+        elif hasattr(old_obj, 'db_vt_id') and old_obj.db_vt_id is not None:
+            new_obj.db_vt_id = old_obj.db_vt_id
+        if 'vt_type' in class_dict:
+            res = class_dict['vt_type'](old_obj, trans_dict)
+            new_obj.db_vt_type = res
+        elif hasattr(old_obj, 'db_vt_type') and old_obj.db_vt_type is not None:
+            new_obj.db_vt_type = old_obj.db_vt_type
+        if 'vt_desc' in class_dict:
+            res = class_dict['vt_desc'](old_obj, trans_dict)
+            new_obj.db_vt_desc = res
+        elif hasattr(old_obj, 'db_vt_desc') and old_obj.db_vt_desc is not None:
+            new_obj.db_vt_desc = old_obj.db_vt_desc
+        if 'vt_package' in class_dict:
+            res = class_dict['vt_package'](old_obj, trans_dict)
+            new_obj.db_vt_package = res
+        elif hasattr(old_obj, 'db_vt_package') and old_obj.db_vt_package is not None:
+            new_obj.db_vt_package = old_obj.db_vt_package
+        if 'vt_version' in class_dict:
+            res = class_dict['vt_version'](old_obj, trans_dict)
+            new_obj.db_vt_version = res
+        elif hasattr(old_obj, 'db_vt_version') and old_obj.db_vt_version is not None:
+            new_obj.db_vt_version = old_obj.db_vt_version
+        if 'vt_cache' in class_dict:
+            res = class_dict['vt_cache'](old_obj, trans_dict)
+            new_obj.db_vt_cache = res
+        elif hasattr(old_obj, 'db_vt_cache') and old_obj.db_vt_cache is not None:
+            new_obj.db_vt_cache = old_obj.db_vt_cache
+        if 'vt_location_x' in class_dict:
+            res = class_dict['vt_location_x'](old_obj, trans_dict)
+            new_obj.db_vt_location_x = res
+        elif hasattr(old_obj, 'db_vt_location_x') and old_obj.db_vt_location_x is not None:
+            new_obj.db_vt_location_x = old_obj.db_vt_location_x
+        if 'vt_location_y' in class_dict:
+            res = class_dict['vt_location_y'](old_obj, trans_dict)
+            new_obj.db_vt_location_y = res
+        elif hasattr(old_obj, 'db_vt_location_y') and old_obj.db_vt_location_y is not None:
+            new_obj.db_vt_location_y = old_obj.db_vt_location_y
+        if 'is_part_of' in class_dict:
+            res = class_dict['is_part_of'](old_obj, trans_dict)
+            new_obj.db_is_part_of = res
+        elif hasattr(old_obj, 'db_is_part_of') and old_obj.db_is_part_of is not None:
+            obj = old_obj.db_is_part_of
+            new_obj.db_add_is_part_of(DBIsPartOf.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_is_part_of') and hasattr(new_obj, 'db_deleted_is_part_of'):
+            for obj in old_obj.db_deleted_is_part_of:
+                n_obj = DBIsPartOf.update_version(obj, trans_dict)
+                new_obj.db_deleted_is_part_of.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_is_part_of is not None:
+            children.extend(self._db_is_part_of.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_is_part_of = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_is_part_of)
+        if remove:
+            self.db_deleted_is_part_of = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_is_part_of is not None and self._db_is_part_of.has_changes():
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_prov_type(self):
+        return self._db_prov_type
+    def __set_db_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+        self.is_dirty = True
+    db_prov_type = property(__get_db_prov_type, __set_db_prov_type)
+    def db_add_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_change_prov_type(self, prov_type):
+        self._db_prov_type = prov_type
+    def db_delete_prov_type(self, prov_type):
+        self._db_prov_type = None
+    
+    def __get_db_prov_label(self):
+        return self._db_prov_label
+    def __set_db_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+        self.is_dirty = True
+    db_prov_label = property(__get_db_prov_label, __set_db_prov_label)
+    def db_add_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_change_prov_label(self, prov_label):
+        self._db_prov_label = prov_label
+    def db_delete_prov_label(self, prov_label):
+        self._db_prov_label = None
+    
+    def __get_db_prov_value(self):
+        return self._db_prov_value
+    def __set_db_prov_value(self, prov_value):
+        self._db_prov_value = prov_value
+        self.is_dirty = True
+    db_prov_value = property(__get_db_prov_value, __set_db_prov_value)
+    def db_add_prov_value(self, prov_value):
+        self._db_prov_value = prov_value
+    def db_change_prov_value(self, prov_value):
+        self._db_prov_value = prov_value
+    def db_delete_prov_value(self, prov_value):
+        self._db_prov_value = None
+    
+    def __get_db_vt_id(self):
+        return self._db_vt_id
+    def __set_db_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+        self.is_dirty = True
+    db_vt_id = property(__get_db_vt_id, __set_db_vt_id)
+    def db_add_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_change_vt_id(self, vt_id):
+        self._db_vt_id = vt_id
+    def db_delete_vt_id(self, vt_id):
+        self._db_vt_id = None
+    
+    def __get_db_vt_type(self):
+        return self._db_vt_type
+    def __set_db_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+        self.is_dirty = True
+    db_vt_type = property(__get_db_vt_type, __set_db_vt_type)
+    def db_add_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+    def db_change_vt_type(self, vt_type):
+        self._db_vt_type = vt_type
+    def db_delete_vt_type(self, vt_type):
+        self._db_vt_type = None
+    
+    def __get_db_vt_desc(self):
+        return self._db_vt_desc
+    def __set_db_vt_desc(self, vt_desc):
+        self._db_vt_desc = vt_desc
+        self.is_dirty = True
+    db_vt_desc = property(__get_db_vt_desc, __set_db_vt_desc)
+    def db_add_vt_desc(self, vt_desc):
+        self._db_vt_desc = vt_desc
+    def db_change_vt_desc(self, vt_desc):
+        self._db_vt_desc = vt_desc
+    def db_delete_vt_desc(self, vt_desc):
+        self._db_vt_desc = None
+    
+    def __get_db_vt_package(self):
+        return self._db_vt_package
+    def __set_db_vt_package(self, vt_package):
+        self._db_vt_package = vt_package
+        self.is_dirty = True
+    db_vt_package = property(__get_db_vt_package, __set_db_vt_package)
+    def db_add_vt_package(self, vt_package):
+        self._db_vt_package = vt_package
+    def db_change_vt_package(self, vt_package):
+        self._db_vt_package = vt_package
+    def db_delete_vt_package(self, vt_package):
+        self._db_vt_package = None
+    
+    def __get_db_vt_version(self):
+        return self._db_vt_version
+    def __set_db_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+        self.is_dirty = True
+    db_vt_version = property(__get_db_vt_version, __set_db_vt_version)
+    def db_add_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_change_vt_version(self, vt_version):
+        self._db_vt_version = vt_version
+    def db_delete_vt_version(self, vt_version):
+        self._db_vt_version = None
+    
+    def __get_db_vt_cache(self):
+        return self._db_vt_cache
+    def __set_db_vt_cache(self, vt_cache):
+        self._db_vt_cache = vt_cache
+        self.is_dirty = True
+    db_vt_cache = property(__get_db_vt_cache, __set_db_vt_cache)
+    def db_add_vt_cache(self, vt_cache):
+        self._db_vt_cache = vt_cache
+    def db_change_vt_cache(self, vt_cache):
+        self._db_vt_cache = vt_cache
+    def db_delete_vt_cache(self, vt_cache):
+        self._db_vt_cache = None
+    
+    def __get_db_vt_location_x(self):
+        return self._db_vt_location_x
+    def __set_db_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = vt_location_x
+        self.is_dirty = True
+    db_vt_location_x = property(__get_db_vt_location_x, __set_db_vt_location_x)
+    def db_add_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = vt_location_x
+    def db_change_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = vt_location_x
+    def db_delete_vt_location_x(self, vt_location_x):
+        self._db_vt_location_x = None
+    
+    def __get_db_vt_location_y(self):
+        return self._db_vt_location_y
+    def __set_db_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = vt_location_y
+        self.is_dirty = True
+    db_vt_location_y = property(__get_db_vt_location_y, __set_db_vt_location_y)
+    def db_add_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = vt_location_y
+    def db_change_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = vt_location_y
+    def db_delete_vt_location_y(self, vt_location_y):
+        self._db_vt_location_y = None
+    
+    def __get_db_is_part_of(self):
+        return self._db_is_part_of
+    def __set_db_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+        self.is_dirty = True
+    db_is_part_of = property(__get_db_is_part_of, __set_db_is_part_of)
+    def db_add_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_change_is_part_of(self, is_part_of):
+        self._db_is_part_of = is_part_of
+    def db_delete_is_part_of(self, is_part_of):
+        if not self.is_new:
+            self.db_deleted_is_part_of.append(self._db_is_part_of)
+        self._db_is_part_of = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBAnnotation(object):
+
+    vtType = 'annotation'
+
+    def __init__(self, id=None, key=None, value=None):
+        self._db_id = id
+        self._db_key = key
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBAnnotation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBAnnotation(id=self._db_id,
+                          key=self._db_key,
+                          value=self._db_value)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBAnnotation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
+        self.is_dirty = True
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmTime(object):
+
+    vtType = 'opm_time'
+
+    def __init__(self, no_later_than=None, no_earlier_than=None, clock_id=None):
+        self._db_no_later_than = no_later_than
+        self._db_no_earlier_than = no_earlier_than
+        self._db_clock_id = clock_id
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmTime.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmTime(no_later_than=self._db_no_later_than,
+                       no_earlier_than=self._db_no_earlier_than,
+                       clock_id=self._db_clock_id)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmTime()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'no_later_than' in class_dict:
+            res = class_dict['no_later_than'](old_obj, trans_dict)
+            new_obj.db_no_later_than = res
+        elif hasattr(old_obj, 'db_no_later_than') and old_obj.db_no_later_than is not None:
+            new_obj.db_no_later_than = old_obj.db_no_later_than
+        if 'no_earlier_than' in class_dict:
+            res = class_dict['no_earlier_than'](old_obj, trans_dict)
+            new_obj.db_no_earlier_than = res
+        elif hasattr(old_obj, 'db_no_earlier_than') and old_obj.db_no_earlier_than is not None:
+            new_obj.db_no_earlier_than = old_obj.db_no_earlier_than
+        if 'clock_id' in class_dict:
+            res = class_dict['clock_id'](old_obj, trans_dict)
+            new_obj.db_clock_id = res
+        elif hasattr(old_obj, 'db_clock_id') and old_obj.db_clock_id is not None:
+            new_obj.db_clock_id = old_obj.db_clock_id
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_no_later_than(self):
+        return self._db_no_later_than
+    def __set_db_no_later_than(self, no_later_than):
+        self._db_no_later_than = no_later_than
+        self.is_dirty = True
+    db_no_later_than = property(__get_db_no_later_than, __set_db_no_later_than)
+    def db_add_no_later_than(self, no_later_than):
+        self._db_no_later_than = no_later_than
+    def db_change_no_later_than(self, no_later_than):
+        self._db_no_later_than = no_later_than
+    def db_delete_no_later_than(self, no_later_than):
+        self._db_no_later_than = None
+    
+    def __get_db_no_earlier_than(self):
+        return self._db_no_earlier_than
+    def __set_db_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = no_earlier_than
+        self.is_dirty = True
+    db_no_earlier_than = property(__get_db_no_earlier_than, __set_db_no_earlier_than)
+    def db_add_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = no_earlier_than
+    def db_change_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = no_earlier_than
+    def db_delete_no_earlier_than(self, no_earlier_than):
+        self._db_no_earlier_than = None
+    
+    def __get_db_clock_id(self):
+        return self._db_clock_id
+    def __set_db_clock_id(self, clock_id):
+        self._db_clock_id = clock_id
+        self.is_dirty = True
+    db_clock_id = property(__get_db_clock_id, __set_db_clock_id)
+    def db_add_clock_id(self, clock_id):
+        self._db_clock_id = clock_id
+    def db_change_clock_id(self, clock_id):
+        self._db_clock_id = clock_id
+    def db_delete_clock_id(self, clock_id):
+        self._db_clock_id = None
+    
+
+
+class DBParameterExploration(object):
+
+    vtType = 'parameter_exploration'
+
+    def __init__(self, id=None, action_id=None, name=None, date=None, user=None, dims=None, layout=None, functions=None):
+        self._db_id = id
+        self._db_action_id = action_id
+        self._db_name = name
+        self._db_date = date
+        self._db_user = user
+        self._db_dims = dims
+        self._db_layout = layout
+        self.db_deleted_functions = []
+        self.db_functions_id_index = {}
+        if functions is None:
+            self._db_functions = []
+        else:
+            self._db_functions = functions
+            for v in self._db_functions:
+                self.db_functions_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBParameterExploration.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBParameterExploration(id=self._db_id,
+                                    action_id=self._db_action_id,
+                                    name=self._db_name,
+                                    date=self._db_date,
+                                    user=self._db_user,
+                                    dims=self._db_dims,
+                                    layout=self._db_layout)
+        if self._db_functions is None:
+            cp._db_functions = []
+        else:
+            cp._db_functions = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_functions]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_action_id') and ('action', self._db_action_id) in id_remap:
+                cp._db_action_id = id_remap[('action', self._db_action_id)]
+        
+        # recreate indices and set flags
+        cp.db_functions_id_index = dict((v.db_id, v) for v in cp._db_functions)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBParameterExploration()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'action_id' in class_dict:
+            res = class_dict['action_id'](old_obj, trans_dict)
+            new_obj.db_action_id = res
+        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
+            new_obj.db_action_id = old_obj.db_action_id
+        if 'name' in class_dict:
+            res = class_dict['name'](old_obj, trans_dict)
+            new_obj.db_name = res
+        elif hasattr(old_obj, 'db_name') and old_obj.db_name is not None:
+            new_obj.db_name = old_obj.db_name
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        if 'dims' in class_dict:
+            res = class_dict['dims'](old_obj, trans_dict)
+            new_obj.db_dims = res
+        elif hasattr(old_obj, 'db_dims') and old_obj.db_dims is not None:
+            new_obj.db_dims = old_obj.db_dims
+        if 'layout' in class_dict:
+            res = class_dict['layout'](old_obj, trans_dict)
+            new_obj.db_layout = res
+        elif hasattr(old_obj, 'db_layout') and old_obj.db_layout is not None:
+            new_obj.db_layout = old_obj.db_layout
+        if 'functions' in class_dict:
+            res = class_dict['functions'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_function(obj)
+        elif hasattr(old_obj, 'db_functions') and old_obj.db_functions is not None:
+            for obj in old_obj.db_functions:
+                new_obj.db_add_function(DBPEFunction.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_functions') and hasattr(new_obj, 'db_deleted_functions'):
+            for obj in old_obj.db_deleted_functions:
+                n_obj = DBPEFunction.update_version(obj, trans_dict)
+                new_obj.db_deleted_functions.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_functions:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_function(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_functions)
+        if remove:
+            self.db_deleted_functions = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_functions:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_action_id(self):
+        return self._db_action_id
+    def __set_db_action_id(self, action_id):
+        self._db_action_id = action_id
+        self.is_dirty = True
+    db_action_id = property(__get_db_action_id, __set_db_action_id)
+    def db_add_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_change_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_delete_action_id(self, action_id):
+        self._db_action_id = None
+    
+    def __get_db_name(self):
+        return self._db_name
+    def __set_db_name(self, name):
+        self._db_name = name
+        self.is_dirty = True
+    db_name = property(__get_db_name, __set_db_name)
+    def db_add_name(self, name):
+        self._db_name = name
+    def db_change_name(self, name):
+        self._db_name = name
+    def db_delete_name(self, name):
+        self._db_name = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
+        self.is_dirty = True
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def __get_db_dims(self):
+        return self._db_dims
+    def __set_db_dims(self, dims):
+        self._db_dims = dims
+        self.is_dirty = True
+    db_dims = property(__get_db_dims, __set_db_dims)
+    def db_add_dims(self, dims):
+        self._db_dims = dims
+    def db_change_dims(self, dims):
+        self._db_dims = dims
+    def db_delete_dims(self, dims):
+        self._db_dims = None
+    
+    def __get_db_layout(self):
+        return self._db_layout
+    def __set_db_layout(self, layout):
+        self._db_layout = layout
+        self.is_dirty = True
+    db_layout = property(__get_db_layout, __set_db_layout)
+    def db_add_layout(self, layout):
+        self._db_layout = layout
+    def db_change_layout(self, layout):
+        self._db_layout = layout
+    def db_delete_layout(self, layout):
+        self._db_layout = None
+    
+    def __get_db_functions(self):
+        return self._db_functions
+    def __set_db_functions(self, functions):
+        self._db_functions = functions
+        self.is_dirty = True
+    db_functions = property(__get_db_functions, __set_db_functions)
+    def db_get_functions(self):
+        return self._db_functions
+    def db_add_function(self, function):
+        self.is_dirty = True
+        self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_change_function(self, function):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                self._db_functions[i] = function
+                found = True
+                break
+        if not found:
+            self._db_functions.append(function)
+        self.db_functions_id_index[function.db_id] = function
+    def db_delete_function(self, function):
+        self.is_dirty = True
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == function.db_id:
+                if not self._db_functions[i].is_new:
+                    self.db_deleted_functions.append(self._db_functions[i])
+                del self._db_functions[i]
+                break
+        del self.db_functions_id_index[function.db_id]
+    def db_get_function(self, key):
+        for i in xrange(len(self._db_functions)):
+            if self._db_functions[i].db_id == key:
+                return self._db_functions[i]
+        return None
+    def db_get_function_by_id(self, key):
+        return self.db_functions_id_index[key]
+    def db_has_function_with_id(self, key):
+        return key in self.db_functions_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBMashupActionAnnotation(object):
+
+    vtType = 'mashup_actionAnnotation'
+
+    def __init__(self, id=None, key=None, value=None, action_id=None, date=None, user=None):
+        self._db_id = id
+        self._db_key = key
+        self._db_value = value
+        self._db_action_id = action_id
+        self._db_date = date
+        self._db_user = user
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBMashupActionAnnotation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBMashupActionAnnotation(id=self._db_id,
+                                      key=self._db_key,
+                                      value=self._db_value,
+                                      action_id=self._db_action_id,
+                                      date=self._db_date,
+                                      user=self._db_user)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_action_id') and ('mashup_action', self._db_action_id) in id_remap:
+                cp._db_action_id = id_remap[('mashup_action', self._db_action_id)]
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBMashupActionAnnotation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'key' in class_dict:
+            res = class_dict['key'](old_obj, trans_dict)
+            new_obj.db_key = res
+        elif hasattr(old_obj, 'db_key') and old_obj.db_key is not None:
+            new_obj.db_key = old_obj.db_key
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            new_obj.db_value = old_obj.db_value
+        if 'action_id' in class_dict:
+            res = class_dict['action_id'](old_obj, trans_dict)
+            new_obj.db_action_id = res
+        elif hasattr(old_obj, 'db_action_id') and old_obj.db_action_id is not None:
+            new_obj.db_action_id = old_obj.db_action_id
+        if 'date' in class_dict:
+            res = class_dict['date'](old_obj, trans_dict)
+            new_obj.db_date = res
+        elif hasattr(old_obj, 'db_date') and old_obj.db_date is not None:
+            new_obj.db_date = old_obj.db_date
+        if 'user' in class_dict:
+            res = class_dict['user'](old_obj, trans_dict)
+            new_obj.db_user = res
+        elif hasattr(old_obj, 'db_user') and old_obj.db_user is not None:
+            new_obj.db_user = old_obj.db_user
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        return [(self, parent[0], parent[1])]
+    def db_deleted_children(self, remove=False):
+        children = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_key(self):
+        return self._db_key
+    def __set_db_key(self, key):
+        self._db_key = key
+        self.is_dirty = True
+    db_key = property(__get_db_key, __set_db_key)
+    def db_add_key(self, key):
+        self._db_key = key
+    def db_change_key(self, key):
+        self._db_key = key
+    def db_delete_key(self, key):
+        self._db_key = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        self._db_value = None
+    
+    def __get_db_action_id(self):
+        return self._db_action_id
+    def __set_db_action_id(self, action_id):
+        self._db_action_id = action_id
+        self.is_dirty = True
+    db_action_id = property(__get_db_action_id, __set_db_action_id)
+    def db_add_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_change_action_id(self, action_id):
+        self._db_action_id = action_id
+    def db_delete_action_id(self, action_id):
+        self._db_action_id = None
+    
+    def __get_db_date(self):
+        return self._db_date
+    def __set_db_date(self, date):
+        self._db_date = date
+        self.is_dirty = True
+    db_date = property(__get_db_date, __set_db_date)
+    def db_add_date(self, date):
+        self._db_date = date
+    def db_change_date(self, date):
+        self._db_date = date
+    def db_delete_date(self, date):
+        self._db_date = None
+    
+    def __get_db_user(self):
+        return self._db_user
+    def __set_db_user(self, user):
+        self._db_user = user
+        self.is_dirty = True
+    db_user = property(__get_db_user, __set_db_user)
+    def db_add_user(self, user):
+        self._db_user = user
+    def db_change_user(self, user):
+        self._db_user = user
+    def db_delete_user(self, user):
+        self._db_user = None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBOpmProcess(object):
+
+    vtType = 'opm_process'
+
+    def __init__(self, id=None, value=None, accounts=None):
+        self._db_id = id
+        self.db_deleted_value = []
+        self._db_value = value
+        self.db_deleted_accounts = []
+        if accounts is None:
+            self._db_accounts = []
+        else:
+            self._db_accounts = accounts
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmProcess.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmProcess(id=self._db_id)
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        if self._db_accounts is None:
+            cp._db_accounts = []
+        else:
+            cp._db_accounts = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_accounts]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmProcess()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            new_obj.db_add_value(DBOpmProcessValue.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                n_obj = DBOpmProcessValue.update_version(obj, trans_dict)
+                new_obj.db_deleted_value.append(n_obj)
+        if 'accounts' in class_dict:
+            res = class_dict['accounts'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_account(obj)
+        elif hasattr(old_obj, 'db_accounts') and old_obj.db_accounts is not None:
+            for obj in old_obj.db_accounts:
+                new_obj.db_add_account(DBOpmAccountId.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_accounts') and hasattr(new_obj, 'db_deleted_accounts'):
+            for obj in old_obj.db_deleted_accounts:
+                n_obj = DBOpmAccountId.update_version(obj, trans_dict)
+                new_obj.db_deleted_accounts.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        to_del = []
+        for child in self.db_accounts:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_account(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_value)
+        children.extend(self.db_deleted_accounts)
+        if remove:
+            self.db_deleted_value = []
+            self.db_deleted_accounts = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        for child in self._db_accounts:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+    def __get_db_accounts(self):
+        return self._db_accounts
+    def __set_db_accounts(self, accounts):
+        self._db_accounts = accounts
+        self.is_dirty = True
+    db_accounts = property(__get_db_accounts, __set_db_accounts)
+    def db_get_accounts(self):
+        return self._db_accounts
+    def db_add_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_change_account(self, account):
+        self.is_dirty = True
+        self._db_accounts.append(account)
+    def db_delete_account(self, account):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_account(self, key):
+        return None
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBDisabledPackages(object):
+
+    vtType = 'disabled_packages'
+
+    def __init__(self, packages=None):
+        self.db_deleted_packages = []
+        self.db_packages_name_index = {}
+        if packages is None:
+            self._db_packages = []
+        else:
+            self._db_packages = packages
+            for v in self._db_packages:
+                self.db_packages_name_index[v.db_name] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBDisabledPackages.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBDisabledPackages()
+        if self._db_packages is None:
+            cp._db_packages = []
+        else:
+            cp._db_packages = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_packages]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        cp.db_packages_name_index = dict((v.db_name, v) for v in cp._db_packages)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBDisabledPackages()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'packages' in class_dict:
+            res = class_dict['packages'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_package(obj)
+        elif hasattr(old_obj, 'db_packages') and old_obj.db_packages is not None:
+            for obj in old_obj.db_packages:
+                new_obj.db_add_package(DBStartupPackage.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_packages') and hasattr(new_obj, 'db_deleted_packages'):
+            for obj in old_obj.db_deleted_packages:
+                n_obj = DBStartupPackage.update_version(obj, trans_dict)
+                new_obj.db_deleted_packages.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_packages:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_package(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_packages)
+        if remove:
+            self.db_deleted_packages = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_packages:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_packages(self):
+        return self._db_packages
+    def __set_db_packages(self, packages):
+        self._db_packages = packages
+        self.is_dirty = True
+    db_packages = property(__get_db_packages, __set_db_packages)
+    def db_get_packages(self):
+        return self._db_packages
+    def db_add_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_change_package(self, package):
+        self.is_dirty = True
+        self._db_packages.append(package)
+        self.db_packages_name_index[package.db_name] = package
+    def db_delete_package(self, package):
+        self.is_dirty = True
+        raise Exception('Cannot delete a non-keyed object')
+    def db_get_package(self, key):
+        return None
+    def db_get_package_by_name(self, key):
+        return self.db_packages_name_index[key]
+    def db_has_package_with_name(self, key):
+        return key in self.db_packages_name_index
+    
+
+
+class DBModuleExec(object):
+
+    vtType = 'module_exec'
+
+    def __init__(self, id=None, ts_start=None, ts_end=None, cached=None, module_id=None, module_name=None, completed=None, error=None, machine_id=None, annotations=None, loop_execs=None):
+        self._db_id = id
+        self._db_ts_start = ts_start
+        self._db_ts_end = ts_end
+        self._db_cached = cached
+        self._db_module_id = module_id
+        self._db_module_name = module_name
+        self._db_completed = completed
+        self._db_error = error
+        self._db_machine_id = machine_id
+        self.db_deleted_annotations = []
+        self.db_annotations_id_index = {}
+        if annotations is None:
+            self._db_annotations = []
+        else:
+            self._db_annotations = annotations
+            for v in self._db_annotations:
+                self.db_annotations_id_index[v.db_id] = v
+        self.db_deleted_loop_execs = []
+        self.db_loop_execs_id_index = {}
+        if loop_execs is None:
+            self._db_loop_execs = []
+        else:
+            self._db_loop_execs = loop_execs
+            for v in self._db_loop_execs:
+                self.db_loop_execs_id_index[v.db_id] = v
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBModuleExec.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBModuleExec(id=self._db_id,
+                          ts_start=self._db_ts_start,
+                          ts_end=self._db_ts_end,
+                          cached=self._db_cached,
+                          module_id=self._db_module_id,
+                          module_name=self._db_module_name,
+                          completed=self._db_completed,
+                          error=self._db_error,
+                          machine_id=self._db_machine_id)
+        if self._db_annotations is None:
+            cp._db_annotations = []
+        else:
+            cp._db_annotations = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_annotations]
+        if self._db_loop_execs is None:
+            cp._db_loop_execs = []
+        else:
+            cp._db_loop_execs = [v.do_copy(new_ids, id_scope, id_remap) for v in self._db_loop_execs]
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+            if hasattr(self, 'db_module_id') and ('module', self._db_module_id) in id_remap:
+                cp._db_module_id = id_remap[('module', self._db_module_id)]
+            if hasattr(self, 'db_machine_id') and ('machine', self._db_machine_id) in id_remap:
+                cp._db_machine_id = id_remap[('machine', self._db_machine_id)]
+        
+        # recreate indices and set flags
+        cp.db_annotations_id_index = dict((v.db_id, v) for v in cp._db_annotations)
+        cp.db_loop_execs_id_index = dict((v.db_id, v) for v in cp._db_loop_execs)
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBModuleExec()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'id' in class_dict:
+            res = class_dict['id'](old_obj, trans_dict)
+            new_obj.db_id = res
+        elif hasattr(old_obj, 'db_id') and old_obj.db_id is not None:
+            new_obj.db_id = old_obj.db_id
+        if 'ts_start' in class_dict:
+            res = class_dict['ts_start'](old_obj, trans_dict)
+            new_obj.db_ts_start = res
+        elif hasattr(old_obj, 'db_ts_start') and old_obj.db_ts_start is not None:
+            new_obj.db_ts_start = old_obj.db_ts_start
+        if 'ts_end' in class_dict:
+            res = class_dict['ts_end'](old_obj, trans_dict)
+            new_obj.db_ts_end = res
+        elif hasattr(old_obj, 'db_ts_end') and old_obj.db_ts_end is not None:
+            new_obj.db_ts_end = old_obj.db_ts_end
+        if 'cached' in class_dict:
+            res = class_dict['cached'](old_obj, trans_dict)
+            new_obj.db_cached = res
+        elif hasattr(old_obj, 'db_cached') and old_obj.db_cached is not None:
+            new_obj.db_cached = old_obj.db_cached
+        if 'module_id' in class_dict:
+            res = class_dict['module_id'](old_obj, trans_dict)
+            new_obj.db_module_id = res
+        elif hasattr(old_obj, 'db_module_id') and old_obj.db_module_id is not None:
+            new_obj.db_module_id = old_obj.db_module_id
+        if 'module_name' in class_dict:
+            res = class_dict['module_name'](old_obj, trans_dict)
+            new_obj.db_module_name = res
+        elif hasattr(old_obj, 'db_module_name') and old_obj.db_module_name is not None:
+            new_obj.db_module_name = old_obj.db_module_name
+        if 'completed' in class_dict:
+            res = class_dict['completed'](old_obj, trans_dict)
+            new_obj.db_completed = res
+        elif hasattr(old_obj, 'db_completed') and old_obj.db_completed is not None:
+            new_obj.db_completed = old_obj.db_completed
+        if 'error' in class_dict:
+            res = class_dict['error'](old_obj, trans_dict)
+            new_obj.db_error = res
+        elif hasattr(old_obj, 'db_error') and old_obj.db_error is not None:
+            new_obj.db_error = old_obj.db_error
+        if 'machine_id' in class_dict:
+            res = class_dict['machine_id'](old_obj, trans_dict)
+            new_obj.db_machine_id = res
+        elif hasattr(old_obj, 'db_machine_id') and old_obj.db_machine_id is not None:
+            new_obj.db_machine_id = old_obj.db_machine_id
+        if 'annotations' in class_dict:
+            res = class_dict['annotations'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_annotation(obj)
+        elif hasattr(old_obj, 'db_annotations') and old_obj.db_annotations is not None:
+            for obj in old_obj.db_annotations:
+                new_obj.db_add_annotation(DBAnnotation.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_annotations') and hasattr(new_obj, 'db_deleted_annotations'):
+            for obj in old_obj.db_deleted_annotations:
+                n_obj = DBAnnotation.update_version(obj, trans_dict)
+                new_obj.db_deleted_annotations.append(n_obj)
+        if 'loop_execs' in class_dict:
+            res = class_dict['loop_execs'](old_obj, trans_dict)
+            for obj in res:
+                new_obj.db_add_loop_exec(obj)
+        elif hasattr(old_obj, 'db_loop_execs') and old_obj.db_loop_execs is not None:
+            for obj in old_obj.db_loop_execs:
+                new_obj.db_add_loop_exec(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_loop_execs') and hasattr(new_obj, 'db_deleted_loop_execs'):
+            for obj in old_obj.db_deleted_loop_execs:
+                n_obj = DBLoopExec.update_version(obj, trans_dict)
+                new_obj.db_deleted_loop_execs.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        to_del = []
+        for child in self.db_annotations:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_annotation(child)
+        to_del = []
+        for child in self.db_loop_execs:
+            children.extend(child.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                to_del.append(child)
+        for child in to_del:
+            self.db_delete_loop_exec(child)
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_annotations)
+        children.extend(self.db_deleted_loop_execs)
+        if remove:
+            self.db_deleted_annotations = []
+            self.db_deleted_loop_execs = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        for child in self._db_annotations:
+            if child.has_changes():
+                return True
+        for child in self._db_loop_execs:
+            if child.has_changes():
+                return True
+        return False
+    def __get_db_id(self):
+        return self._db_id
+    def __set_db_id(self, id):
+        self._db_id = id
+        self.is_dirty = True
+    db_id = property(__get_db_id, __set_db_id)
+    def db_add_id(self, id):
+        self._db_id = id
+    def db_change_id(self, id):
+        self._db_id = id
+    def db_delete_id(self, id):
+        self._db_id = None
+    
+    def __get_db_ts_start(self):
+        return self._db_ts_start
+    def __set_db_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+        self.is_dirty = True
+    db_ts_start = property(__get_db_ts_start, __set_db_ts_start)
+    def db_add_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_change_ts_start(self, ts_start):
+        self._db_ts_start = ts_start
+    def db_delete_ts_start(self, ts_start):
+        self._db_ts_start = None
+    
+    def __get_db_ts_end(self):
+        return self._db_ts_end
+    def __set_db_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+        self.is_dirty = True
+    db_ts_end = property(__get_db_ts_end, __set_db_ts_end)
+    def db_add_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_change_ts_end(self, ts_end):
+        self._db_ts_end = ts_end
+    def db_delete_ts_end(self, ts_end):
+        self._db_ts_end = None
+    
+    def __get_db_cached(self):
+        return self._db_cached
+    def __set_db_cached(self, cached):
+        self._db_cached = cached
+        self.is_dirty = True
+    db_cached = property(__get_db_cached, __set_db_cached)
+    def db_add_cached(self, cached):
+        self._db_cached = cached
+    def db_change_cached(self, cached):
+        self._db_cached = cached
+    def db_delete_cached(self, cached):
+        self._db_cached = None
+    
+    def __get_db_module_id(self):
+        return self._db_module_id
+    def __set_db_module_id(self, module_id):
+        self._db_module_id = module_id
+        self.is_dirty = True
+    db_module_id = property(__get_db_module_id, __set_db_module_id)
+    def db_add_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_change_module_id(self, module_id):
+        self._db_module_id = module_id
+    def db_delete_module_id(self, module_id):
+        self._db_module_id = None
+    
+    def __get_db_module_name(self):
+        return self._db_module_name
+    def __set_db_module_name(self, module_name):
+        self._db_module_name = module_name
+        self.is_dirty = True
+    db_module_name = property(__get_db_module_name, __set_db_module_name)
+    def db_add_module_name(self, module_name):
+        self._db_module_name = module_name
+    def db_change_module_name(self, module_name):
+        self._db_module_name = module_name
+    def db_delete_module_name(self, module_name):
+        self._db_module_name = None
+    
+    def __get_db_completed(self):
+        return self._db_completed
+    def __set_db_completed(self, completed):
+        self._db_completed = completed
+        self.is_dirty = True
+    db_completed = property(__get_db_completed, __set_db_completed)
+    def db_add_completed(self, completed):
+        self._db_completed = completed
+    def db_change_completed(self, completed):
+        self._db_completed = completed
+    def db_delete_completed(self, completed):
+        self._db_completed = None
+    
+    def __get_db_error(self):
+        return self._db_error
+    def __set_db_error(self, error):
+        self._db_error = error
+        self.is_dirty = True
+    db_error = property(__get_db_error, __set_db_error)
+    def db_add_error(self, error):
+        self._db_error = error
+    def db_change_error(self, error):
+        self._db_error = error
+    def db_delete_error(self, error):
+        self._db_error = None
+    
+    def __get_db_machine_id(self):
+        return self._db_machine_id
+    def __set_db_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+        self.is_dirty = True
+    db_machine_id = property(__get_db_machine_id, __set_db_machine_id)
+    def db_add_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_change_machine_id(self, machine_id):
+        self._db_machine_id = machine_id
+    def db_delete_machine_id(self, machine_id):
+        self._db_machine_id = None
+    
+    def __get_db_annotations(self):
+        return self._db_annotations
+    def __set_db_annotations(self, annotations):
+        self._db_annotations = annotations
+        self.is_dirty = True
+    db_annotations = property(__get_db_annotations, __set_db_annotations)
+    def db_get_annotations(self):
+        return self._db_annotations
+    def db_add_annotation(self, annotation):
+        self.is_dirty = True
+        self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_change_annotation(self, annotation):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                self._db_annotations[i] = annotation
+                found = True
+                break
+        if not found:
+            self._db_annotations.append(annotation)
+        self.db_annotations_id_index[annotation.db_id] = annotation
+    def db_delete_annotation(self, annotation):
+        self.is_dirty = True
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == annotation.db_id:
+                if not self._db_annotations[i].is_new:
+                    self.db_deleted_annotations.append(self._db_annotations[i])
+                del self._db_annotations[i]
+                break
+        del self.db_annotations_id_index[annotation.db_id]
+    def db_get_annotation(self, key):
+        for i in xrange(len(self._db_annotations)):
+            if self._db_annotations[i].db_id == key:
+                return self._db_annotations[i]
+        return None
+    def db_get_annotation_by_id(self, key):
+        return self.db_annotations_id_index[key]
+    def db_has_annotation_with_id(self, key):
+        return key in self.db_annotations_id_index
+    
+    def __get_db_loop_execs(self):
+        return self._db_loop_execs
+    def __set_db_loop_execs(self, loop_execs):
+        self._db_loop_execs = loop_execs
+        self.is_dirty = True
+    db_loop_execs = property(__get_db_loop_execs, __set_db_loop_execs)
+    def db_get_loop_execs(self):
+        return self._db_loop_execs
+    def db_add_loop_exec(self, loop_exec):
+        self.is_dirty = True
+        self._db_loop_execs.append(loop_exec)
+        self.db_loop_execs_id_index[loop_exec.db_id] = loop_exec
+    def db_change_loop_exec(self, loop_exec):
+        self.is_dirty = True
+        found = False
+        for i in xrange(len(self._db_loop_execs)):
+            if self._db_loop_execs[i].db_id == loop_exec.db_id:
+                self._db_loop_execs[i] = loop_exec
+                found = True
+                break
+        if not found:
+            self._db_loop_execs.append(loop_exec)
+        self.db_loop_execs_id_index[loop_exec.db_id] = loop_exec
+    def db_delete_loop_exec(self, loop_exec):
+        self.is_dirty = True
+        for i in xrange(len(self._db_loop_execs)):
+            if self._db_loop_execs[i].db_id == loop_exec.db_id:
+                if not self._db_loop_execs[i].is_new:
+                    self.db_deleted_loop_execs.append(self._db_loop_execs[i])
+                del self._db_loop_execs[i]
+                break
+        del self.db_loop_execs_id_index[loop_exec.db_id]
+    def db_get_loop_exec(self, key):
+        for i in xrange(len(self._db_loop_execs)):
+            if self._db_loop_execs[i].db_id == key:
+                return self._db_loop_execs[i]
+        return None
+    def db_get_loop_exec_by_id(self, key):
+        return self.db_loop_execs_id_index[key]
+    def db_has_loop_exec_with_id(self, key):
+        return key in self.db_loop_execs_id_index
+    
+    def getPrimaryKey(self):
+        return self._db_id
+
+class DBProvAssociation(object):
+
+    vtType = 'prov_association'
+
+    def __init__(self, prov_activity=None, prov_agent=None, prov_plan=None, prov_role=None):
+        self.db_deleted_prov_activity = []
+        self._db_prov_activity = prov_activity
+        self.db_deleted_prov_agent = []
+        self._db_prov_agent = prov_agent
+        self.db_deleted_prov_plan = []
+        self._db_prov_plan = prov_plan
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBProvAssociation.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBProvAssociation(prov_role=self._db_prov_role)
+        if self._db_prov_activity is not None:
+            cp._db_prov_activity = self._db_prov_activity.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_agent is not None:
+            cp._db_prov_agent = self._db_prov_agent.do_copy(new_ids, id_scope, id_remap)
+        if self._db_prov_plan is not None:
+            cp._db_prov_plan = self._db_prov_plan.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBProvAssociation()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'prov_activity' in class_dict:
+            res = class_dict['prov_activity'](old_obj, trans_dict)
+            new_obj.db_prov_activity = res
+        elif hasattr(old_obj, 'db_prov_activity') and old_obj.db_prov_activity is not None:
+            obj = old_obj.db_prov_activity
+            new_obj.db_add_prov_activity(DBRefProvActivity.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_activity') and hasattr(new_obj, 'db_deleted_prov_activity'):
+            for obj in old_obj.db_deleted_prov_activity:
+                n_obj = DBRefProvActivity.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_activity.append(n_obj)
+        if 'prov_agent' in class_dict:
+            res = class_dict['prov_agent'](old_obj, trans_dict)
+            new_obj.db_prov_agent = res
+        elif hasattr(old_obj, 'db_prov_agent') and old_obj.db_prov_agent is not None:
+            obj = old_obj.db_prov_agent
+            new_obj.db_add_prov_agent(DBRefProvAgent.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_agent') and hasattr(new_obj, 'db_deleted_prov_agent'):
+            for obj in old_obj.db_deleted_prov_agent:
+                n_obj = DBRefProvAgent.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_agent.append(n_obj)
+        if 'prov_plan' in class_dict:
+            res = class_dict['prov_plan'](old_obj, trans_dict)
+            new_obj.db_prov_plan = res
+        elif hasattr(old_obj, 'db_prov_plan') and old_obj.db_prov_plan is not None:
+            obj = old_obj.db_prov_plan
+            new_obj.db_add_prov_plan(DBRefProvPlan.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_prov_plan') and hasattr(new_obj, 'db_deleted_prov_plan'):
+            for obj in old_obj.db_deleted_prov_plan:
+                n_obj = DBRefProvPlan.update_version(obj, trans_dict)
+                new_obj.db_deleted_prov_plan.append(n_obj)
+        if 'prov_role' in class_dict:
+            res = class_dict['prov_role'](old_obj, trans_dict)
+            new_obj.db_prov_role = res
+        elif hasattr(old_obj, 'db_prov_role') and old_obj.db_prov_role is not None:
+            new_obj.db_prov_role = old_obj.db_prov_role
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_prov_activity is not None:
+            children.extend(self._db_prov_activity.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_activity = None
+        if self._db_prov_agent is not None:
+            children.extend(self._db_prov_agent.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_agent = None
+        if self._db_prov_plan is not None:
+            children.extend(self._db_prov_plan.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_prov_plan = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_prov_activity)
+        children.extend(self.db_deleted_prov_agent)
+        children.extend(self.db_deleted_prov_plan)
+        if remove:
+            self.db_deleted_prov_activity = []
+            self.db_deleted_prov_agent = []
+            self.db_deleted_prov_plan = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_prov_activity is not None and self._db_prov_activity.has_changes():
+            return True
+        if self._db_prov_agent is not None and self._db_prov_agent.has_changes():
+            return True
+        if self._db_prov_plan is not None and self._db_prov_plan.has_changes():
+            return True
+        return False
+    def __get_db_prov_activity(self):
+        return self._db_prov_activity
+    def __set_db_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+        self.is_dirty = True
+    db_prov_activity = property(__get_db_prov_activity, __set_db_prov_activity)
+    def db_add_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_change_prov_activity(self, prov_activity):
+        self._db_prov_activity = prov_activity
+    def db_delete_prov_activity(self, prov_activity):
+        if not self.is_new:
+            self.db_deleted_prov_activity.append(self._db_prov_activity)
+        self._db_prov_activity = None
+    
+    def __get_db_prov_agent(self):
+        return self._db_prov_agent
+    def __set_db_prov_agent(self, prov_agent):
+        self._db_prov_agent = prov_agent
+        self.is_dirty = True
+    db_prov_agent = property(__get_db_prov_agent, __set_db_prov_agent)
+    def db_add_prov_agent(self, prov_agent):
+        self._db_prov_agent = prov_agent
+    def db_change_prov_agent(self, prov_agent):
+        self._db_prov_agent = prov_agent
+    def db_delete_prov_agent(self, prov_agent):
+        if not self.is_new:
+            self.db_deleted_prov_agent.append(self._db_prov_agent)
+        self._db_prov_agent = None
+    
+    def __get_db_prov_plan(self):
+        return self._db_prov_plan
+    def __set_db_prov_plan(self, prov_plan):
+        self._db_prov_plan = prov_plan
+        self.is_dirty = True
+    db_prov_plan = property(__get_db_prov_plan, __set_db_prov_plan)
+    def db_add_prov_plan(self, prov_plan):
+        self._db_prov_plan = prov_plan
+    def db_change_prov_plan(self, prov_plan):
+        self._db_prov_plan = prov_plan
+    def db_delete_prov_plan(self, prov_plan):
+        if not self.is_new:
+            self.db_deleted_prov_plan.append(self._db_prov_plan)
+        self._db_prov_plan = None
+    
+    def __get_db_prov_role(self):
+        return self._db_prov_role
+    def __set_db_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+        self.is_dirty = True
+    db_prov_role = property(__get_db_prov_role, __set_db_prov_role)
+    def db_add_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_change_prov_role(self, prov_role):
+        self._db_prov_role = prov_role
+    def db_delete_prov_role(self, prov_role):
+        self._db_prov_role = None
+    
+
+
+class DBOpmProcessValue(object):
+
+    vtType = 'opm_process_value'
+
+    def __init__(self, value=None):
+        self.db_deleted_value = []
+        self._db_value = value
+        self.is_dirty = True
+        self.is_new = True
+    
+    def __copy__(self):
+        return DBOpmProcessValue.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = DBOpmProcessValue()
+        if self._db_value is not None:
+            cp._db_value = self._db_value.do_copy(new_ids, id_scope, id_remap)
+        
+        # set new ids
+        if new_ids:
+            new_id = id_scope.getNewId(self.vtType)
+            if self.vtType in id_scope.remap:
+                id_remap[(id_scope.remap[self.vtType], self.db_id)] = new_id
+            else:
+                id_remap[(self.vtType, self.db_id)] = new_id
+            cp.db_id = new_id
+        
+        # recreate indices and set flags
+        if not new_ids:
+            cp.is_dirty = self.is_dirty
+            cp.is_new = self.is_new
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBOpmProcessValue()
+        class_dict = {}
+        if new_obj.__class__.__name__ in trans_dict:
+            class_dict = trans_dict[new_obj.__class__.__name__]
+        if 'value' in class_dict:
+            res = class_dict['value'](old_obj, trans_dict)
+            new_obj.db_value = res
+        elif hasattr(old_obj, 'db_value') and old_obj.db_value is not None:
+            obj = old_obj.db_value
+            if obj.vtType == 'module_exec':
+                new_obj.db_add_value(DBModuleExec.update_version(obj, trans_dict))
+            elif obj.vtType == 'group_exec':
+                new_obj.db_add_value(DBGroupExec.update_version(obj, trans_dict))
+            elif obj.vtType == 'loop_exec':
+                new_obj.db_add_value(DBLoopExec.update_version(obj, trans_dict))
+        if hasattr(old_obj, 'db_deleted_value') and hasattr(new_obj, 'db_deleted_value'):
+            for obj in old_obj.db_deleted_value:
+                if obj.vtType == 'module_exec':
+                    n_obj = DBModuleExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'group_exec':
+                    n_obj = DBGroupExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+                elif obj.vtType == 'loop_exec':
+                    n_obj = DBLoopExec.update_version(obj, trans_dict)
+                    new_obj.db_deleted_value.append(n_obj)
+        new_obj.is_new = old_obj.is_new
+        new_obj.is_dirty = old_obj.is_dirty
+        return new_obj
+
+    def db_children(self, parent=(None,None), orphan=False, for_action=False):
+        children = []
+        if self._db_value is not None:
+            children.extend(self._db_value.db_children((self.vtType, self.db_id), orphan, for_action))
+            if orphan:
+                self._db_value = None
+        children.append((self, parent[0], parent[1]))
+        return children
+    def db_deleted_children(self, remove=False):
+        children = []
+        children.extend(self.db_deleted_value)
+        if remove:
+            self.db_deleted_value = []
+        return children
+    def has_changes(self):
+        if self.is_dirty:
+            return True
+        if self._db_value is not None and self._db_value.has_changes():
+            return True
+        return False
+    def __get_db_value(self):
+        return self._db_value
+    def __set_db_value(self, value):
+        self._db_value = value
+        self.is_dirty = True
+    db_value = property(__get_db_value, __set_db_value)
+    def db_add_value(self, value):
+        self._db_value = value
+    def db_change_value(self, value):
+        self._db_value = value
+    def db_delete_value(self, value):
+        if not self.is_new:
+            self.db_deleted_value.append(self._db_value)
+        self._db_value = None
+    
+
+
diff --git a/vistrails/db/versions/v1_0_4/domain/id_scope.py b/vistrails/db/versions/v1_0_4/domain/id_scope.py
new file mode 100644
index 0000000..49f3707
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/id_scope.py
@@ -0,0 +1,88 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import copy
+
+class IdScope:
+    def __init__(self, beginId=0L, remap=None):
+        self.ids = {}
+        self.beginId = beginId
+        if remap is None:
+            self.remap = {}
+        else:
+            self.remap = remap
+
+    def __copy__(self):
+        cp = IdScope(beginId=self.beginId)
+        cp.ids = copy.copy(self.ids)
+        cp.remap = copy.copy(self.remap)
+        return cp
+
+    def __str__(self):
+        return str(self.ids)
+
+    def getNewId(self, objType):
+        try:
+            objType = self.remap[objType]
+        except KeyError:
+            pass
+        try:
+            id = self.ids[objType]
+            self.ids[objType] += 1
+            return id
+        except KeyError:
+            self.ids[objType] = self.beginId + 1
+            return self.beginId
+
+    def updateBeginId(self, objType, beginId):
+        try:
+            objType = self.remap[objType]
+        except KeyError:
+            pass
+        try:
+            if self.ids[objType] <= beginId:
+                self.ids[objType] = beginId
+        except KeyError:
+            self.ids[objType] = beginId
+        
+    def setBeginId(self, objType, beginId):
+        try:
+            objType = self.remap[objType]
+        except KeyError:
+            pass
+        self.ids[objType] = beginId
diff --git a/vistrails/db/versions/v1_0_4/domain/log.py b/vistrails/db/versions/v1_0_4/domain/log.py
new file mode 100644
index 0000000..49b1497
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/log.py
@@ -0,0 +1,75 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from auto_gen import DBLog as _DBLog
+from auto_gen import DBAbstraction, DBModule, DBGroup, DBLoopExec, \
+    DBGroupExec, DBModuleExec
+from id_scope import IdScope
+
+import copy
+
+class DBLog(_DBLog):
+
+    def __init__(self, *args, **kwargs):
+        _DBLog.__init__(self, *args, **kwargs)
+        self.id_scope = IdScope(1,
+                                {DBLoopExec.vtType: 'item_exec',
+                                 DBModuleExec.vtType: 'item_exec',
+                                 DBGroupExec.vtType: 'item_exec',
+                                 DBAbstraction.vtType: DBModule.vtType,
+                                 DBGroup.vtType: DBModule.vtType})
+
+    def __copy__(self):
+        return DBLog.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = _DBLog.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = DBLog
+        cp.id_scope = copy.copy(self.id_scope)
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBLog()
+        new_obj = _DBLog.update_version(old_obj, trans_dict, new_obj)
+        new_obj.update_id_scope()
+        return new_obj
+
+    def update_id_scope(self):
+        pass
diff --git a/vistrails/db/versions/v1_0_4/domain/registry.py b/vistrails/db/versions/v1_0_4/domain/registry.py
new file mode 100644
index 0000000..677b3d1
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/registry.py
@@ -0,0 +1,66 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from auto_gen import DBRegistry as _DBRegistry, DBPackage, DBModuleDescriptor, \
+    DBPortSpec
+from id_scope import IdScope
+
+class DBRegistry(_DBRegistry):
+    def __init__(self, *args, **kwargs):
+        _DBRegistry.__init__(self, *args, **kwargs)
+        self.idScope = IdScope()
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBRegistry()
+        new_obj = _DBRegistry.update_version(old_obj, trans_dict, new_obj)
+        new_obj.update_id_scope()
+        return new_obj
+    
+    def update_id_scope(self):
+        for package in self.db_packages:
+            self.idScope.updateBeginId(DBPackage.vtType, package.db_id+1)
+            for descriptor in package.db_module_descriptors:
+                self.idScope.updateBeginId(DBModuleDescriptor.vtType,
+                                           descriptor.db_id+1)
+                for port_spec in descriptor.db_portSpecs:
+                    self.idScope.updateBeginId(DBPortSpec.vtType, 
+                                               port_spec.db_id+1)
+
+
diff --git a/vistrails/db/versions/v1_0_4/domain/vistrail.py b/vistrails/db/versions/v1_0_4/domain/vistrail.py
new file mode 100644
index 0000000..7205ec7
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/vistrail.py
@@ -0,0 +1,223 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import copy
+import hashlib
+from auto_gen import DBVistrail as _DBVistrail
+from auto_gen import DBAdd, DBChange, DBDelete, DBAbstraction, DBGroup, \
+    DBModule, DBAnnotation, DBActionAnnotation, DBParameterExploration
+from id_scope import IdScope
+
+class DBVistrail(_DBVistrail):
+    def __init__(self, *args, **kwargs):
+        _DBVistrail.__init__(self, *args, **kwargs)
+        self.idScope = IdScope(remap={DBAdd.vtType: 'operation',
+                                      DBChange.vtType: 'operation',
+                                      DBDelete.vtType: 'operation',
+                                      DBAbstraction.vtType: DBModule.vtType,
+                                      DBGroup.vtType: DBModule.vtType,
+                                      DBActionAnnotation.vtType: \
+                                          DBAnnotation.vtType})
+
+        self.idScope.setBeginId('action', 1)
+        self.idScope.setBeginId(DBParameterExploration.vtType, 1)
+        self.db_objects = {}
+
+        # keep a reference to the current logging information here
+        self.db_log_filename = None
+        self.log = None
+
+    def __copy__(self):
+        return DBVistrail.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = _DBVistrail.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = DBVistrail
+        
+        cp.idScope = copy.copy(self.idScope)
+        cp.db_objects = copy.copy(self.db_objects)
+        cp.db_log_filename = self.db_log_filename
+        if self.log is not None:
+            cp.log = copy.copy(self.log)
+        else:
+            cp.log = None
+        
+        return cp
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBVistrail()
+        new_obj = _DBVistrail.update_version(old_obj, trans_dict, new_obj)
+        new_obj.update_id_scope()
+        if hasattr(old_obj, 'db_log_filename'):
+            new_obj.db_log_filename = old_obj.db_log_filename
+        if hasattr(old_obj, 'log'):
+            new_obj.log = old_obj.log
+        return new_obj
+
+    def update_id_scope(self):
+        def getOldObjId(operation):
+            if operation.vtType == 'change':
+                return operation.db_oldObjId
+            return operation.db_objectId
+
+        def getNewObjId(operation):
+            if operation.vtType == 'change':
+                return operation.db_newObjId
+            return operation.db_objectId
+
+        for action in self.db_actions:
+            self.idScope.updateBeginId('action', action.db_id+1)
+            if action.db_session is not None:
+                self.idScope.updateBeginId('session', action.db_session + 1)
+            for operation in action.db_operations:
+                self.idScope.updateBeginId('operation', operation.db_id+1)
+                if operation.vtType == 'add' or operation.vtType == 'change':
+                    # update ids of data
+                    self.idScope.updateBeginId(operation.db_what, 
+                                               getNewObjId(operation)+1)
+                    if operation.db_data is None:
+                        if operation.vtType == 'change':
+                            operation.db_objectId = operation.db_oldObjId
+                    self.db_add_object(operation.db_data)
+            for annotation in action.db_annotations:
+                self.idScope.updateBeginId('annotation', annotation.db_id+1)
+        
+        for annotation in self.db_annotations:
+            self.idScope.updateBeginId('annotation', annotation.db_id+1)
+        for annotation in self.db_actionAnnotations:
+            self.idScope.updateBeginId('annotation', annotation.db_id+1)
+        for paramexp in self.db_parameter_explorations:
+            self.idScope.updateBeginId('parameter_exploration',
+                                       paramexp.db_id+1)
+
+    def db_add_object(self, obj):
+        self.db_objects[(obj.vtType, obj.db_id)] = obj
+
+    def db_get_object(self, type, id):
+        return self.db_objects.get((type, id), None)
+
+    def db_update_object(self, obj, **kwargs):
+        # want to swap out old object with a new version
+        # need this for updating aliases...
+        # hack it using setattr...
+        real_obj = self.db_objects[(obj.vtType, obj.db_id)]
+        for (k, v) in kwargs.iteritems():
+            if hasattr(real_obj, k):
+                setattr(real_obj, k, v)
+
+    def update_checkout_version(self, app=''):
+        checkout_key = "__checkout_version_"
+        action_key = checkout_key + app
+        annotation_key = action_key + '_annotationhash'
+        action_annotation_key = action_key + '_actionannotationhash'
+
+        # delete previous checkout annotations
+        deletekeys = [action_key,annotation_key,action_annotation_key]
+        for key in deletekeys:
+            while self.db_has_annotation_with_key(key):
+                a = self.db_get_annotation_by_key(key)
+                self.db_delete_annotation(a)
+        
+        # annotation hash - requires annotations to be clean
+        value = self.hashAnnotations()
+        if self.db_has_annotation_with_key(annotation_key):
+            annotation = self.db_get_annotation_by_key(annotation_key)
+            annotation.db_value = value
+        else:
+            annotation=DBAnnotation(self.idScope.getNewId(DBAnnotation.vtType), 
+                                  annotation_key, value)
+            self.db_add_annotation(annotation)
+        # action annotation hash
+        value = self.hashActionAnnotations()
+        if self.db_has_annotation_with_key(action_annotation_key):
+            annotation = self.db_get_annotation_by_key(action_annotation_key)
+            annotation.db_value = value
+        else:
+            annotation=DBAnnotation(self.idScope.getNewId(DBAnnotation.vtType), 
+                                    action_annotation_key, value)
+            self.db_add_annotation(annotation)
+        # last action id hash
+        if len(self.db_actions) == 0:
+            value = 0
+        else:
+            value = max(v.db_id for v in self.db_actions)
+        if self.db_has_annotation_with_key(action_key):
+            annotation = self.db_get_annotation_by_key(action_key)
+            annotation.db_value = str(value)
+        else:
+            annotation=DBAnnotation(self.idScope.getNewId(DBAnnotation.vtType), 
+                                    action_key, str(value))
+            self.db_add_annotation(annotation)
+
+    def hashAnnotations(self):
+        annotations = {}
+        for annotation in self.db_annotations:
+            if annotation._db_key not in annotations:
+                annotations[annotation._db_key] = []
+            if annotation._db_value not in annotations[annotation._db_key]:
+                annotations[annotation._db_key].append(annotation._db_value)
+        keys = annotations.keys()
+        keys.sort()
+        m = hashlib.md5()
+        for k in keys:
+            m.update(str(k))
+            annotations[k].sort()
+            for v in annotations[k]:
+                m.update(str(v))
+        return m.hexdigest()
+
+    def hashActionAnnotations(self):
+        action_annotations = {}
+        for action_id, key, value in [[aa.db_action_id, aa.db_key, 
+                         aa.db_value] for aa in self.db_actionAnnotations]:
+            index = (str(action_id), key)
+            if index not in action_annotations:
+                action_annotations[index] = []
+            if value not in action_annotations[index]:
+                action_annotations[index].append(value)
+        keys = action_annotations.keys()
+        keys.sort()
+        m = hashlib.md5()
+        for k in keys:
+            m.update(k[0] + k[1])
+            action_annotations[k].sort()
+            for v in action_annotations[k]:
+                m.update(str(v))
+        return m.hexdigest()
diff --git a/vistrails/db/versions/v1_0_4/domain/workflow.py b/vistrails/db/versions/v1_0_4/domain/workflow.py
new file mode 100644
index 0000000..71aaef7
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/domain/workflow.py
@@ -0,0 +1,175 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from auto_gen import DBWorkflow as _DBWorkflow
+from auto_gen import DBAbstraction, DBModule, DBGroup
+from id_scope import IdScope
+
+import copy
+
+class DBWorkflow(_DBWorkflow):
+
+    def __init__(self, *args, **kwargs):
+        _DBWorkflow.__init__(self, *args, **kwargs)
+        self.objects = {}
+        self.tmp_id = IdScope(1,
+                              {DBAbstraction.vtType: DBModule.vtType,
+                               DBGroup.vtType: DBModule.vtType})
+
+    def __copy__(self):
+        return DBWorkflow.do_copy(self)
+
+    def do_copy(self, new_ids=False, id_scope=None, id_remap=None):
+        cp = _DBWorkflow.do_copy(self, new_ids, id_scope, id_remap)
+        cp.__class__ = DBWorkflow
+        # need to go through and reset the index to the copied objects
+        cp.build_index()
+        cp.tmp_id = copy.copy(self.tmp_id)
+        return cp        
+
+    @staticmethod
+    def update_version(old_obj, trans_dict, new_obj=None):
+        if new_obj is None:
+            new_obj = DBWorkflow()
+        new_obj = _DBWorkflow.update_version(old_obj, trans_dict, new_obj)
+        new_obj.update_id_scope()
+        new_obj.build_index()
+        return new_obj
+    
+    def update_id_scope(self):
+        pass
+
+    _vtTypeMap = {DBAbstraction.vtType: DBModule.vtType, 
+                  DBGroup.vtType: DBModule.vtType}
+
+    def build_index(self):
+        g = self._vtTypeMap.get
+        self.objects = dict(((g(o.vtType, o.vtType), o._db_id), o)
+                            for (o,_,_) in self.db_children())
+
+    def add_to_index(self, object):
+        obj_type = self._vtTypeMap.get(object.vtType, object.vtType)
+        self.objects[(obj_type, object.getPrimaryKey())] = object
+
+    def delete_from_index(self, object):
+        obj_type = self._vtTypeMap.get(object.vtType, object.vtType)
+        del self.objects[(obj_type, object.getPrimaryKey())]
+
+    def capitalizeOne(self, str):
+        return str[0].upper() + str[1:]
+
+    def db_print_objects(self):
+        for k,v in self.objects.iteritems():
+            print '%s: %s' % (k, v)
+
+    def db_has_object(self, type, id):
+        return (type, id) in self.objects
+
+    def db_get_object(self, type, id):
+        return self.objects[(type, id)]
+
+    def db_add_object(self, object, parent_obj_type=None,
+                      parent_obj_id=None, parent_obj=None):
+        if parent_obj is None:
+            if parent_obj_type is None or parent_obj_id is None:
+                parent_obj = self
+            else:
+                if parent_obj_type == DBAbstraction.vtType or \
+                        parent_obj_type == DBGroup.vtType:
+                    parent_obj_type = DBModule.vtType
+                try:
+                    parent_obj = self.objects[(parent_obj_type, parent_obj_id)]
+                except KeyError:
+                    msg = "Cannot find object of type '%s' with id '%s'" % \
+                        (parent_obj_type, parent_obj_id)
+                    raise Exception(msg)
+        if object.vtType == DBAbstraction.vtType or \
+                object.vtType == DBGroup.vtType:
+            obj_type = DBModule.vtType
+        else:
+            obj_type = object.vtType
+        funname = 'db_add_' + obj_type
+        obj_copy = copy.copy(object)
+        getattr(parent_obj, funname)(obj_copy)
+        self.add_to_index(obj_copy)
+
+    def db_change_object(self, old_id, object, parent_obj_type=None, 
+                         parent_obj_id=None, parent_obj=None):
+        if parent_obj is None:
+            if parent_obj_type is None or parent_obj_id is None:
+                parent_obj = self
+            else:
+                if parent_obj_type == DBAbstraction.vtType or \
+                        parent_obj_type == DBGroup.vtType:
+                    parent_obj_type = DBModule.vtType
+                try:
+                    parent_obj = self.objects[(parent_obj_type, parent_obj_id)]
+                except KeyError:
+                    msg = "Cannot find object of type '%s' with id '%s'" % \
+                        (parent_obj_type, parent_obj_id)
+                    raise Exception(msg)
+
+        self.db_delete_object(old_id, object.vtType, None, None, parent_obj)
+        self.db_add_object(object, None, None, parent_obj)
+
+    def db_delete_object(self, obj_id, obj_type, parent_obj_type=None, 
+                         parent_obj_id=None, parent_obj=None):
+        if parent_obj is None:
+            if parent_obj_type is None or parent_obj_id is None:
+                parent_obj = self
+            else:
+                if parent_obj_type == DBAbstraction.vtType or \
+                        parent_obj_type == DBGroup.vtType:
+                    parent_obj_type = DBModule.vtType
+                try:
+                    parent_obj = self.objects[(parent_obj_type, parent_obj_id)]
+                except KeyError:
+                    msg = "Cannot find object of type '%s' with id '%s'" % \
+                        (parent_obj_type, parent_obj_id)
+                    raise Exception(msg)
+        if obj_type == DBAbstraction.vtType or obj_type == DBGroup.vtType:
+            obj_type = DBModule.vtType
+        funname = 'db_get_' + obj_type
+        if hasattr(parent_obj, funname):
+            object = getattr(parent_obj, funname)(obj_id)
+        else:
+            attr_name = 'db_' + obj_type
+            object = getattr(parent_obj, attr_name)
+        funname = 'db_delete_' + obj_type
+        getattr(parent_obj, funname)(object)
+        self.delete_from_index(object)
diff --git a/vistrails/db/versions/v1_0_4/persistence/__init__.py b/vistrails/db/versions/v1_0_4/persistence/__init__.py
new file mode 100644
index 0000000..3b574b6
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/__init__.py
@@ -0,0 +1,475 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from xml.auto_gen import XMLDAOListBase
+from sql.auto_gen import SQLDAOListBase
+from vistrails.core.system import get_elementtree_library
+
+from vistrails.db import VistrailsDBException
+from vistrails.db.versions.v1_0_4 import version as my_version
+from vistrails.db.versions.v1_0_4.domain import DBGroup, DBWorkflow, DBVistrail, DBLog, \
+    DBRegistry, DBMashuptrail
+
+root_set = set([DBVistrail.vtType, DBWorkflow.vtType, 
+                DBLog.vtType, DBRegistry.vtType, DBMashuptrail.vtType])
+
+ElementTree = get_elementtree_library()
+
+
+class DAOList(dict):
+    def __init__(self):
+        self['xml'] = XMLDAOListBase()
+        self['sql'] = SQLDAOListBase()
+
+    def parse_xml_file(self, filename):
+        return ElementTree.parse(filename)
+
+    def write_xml_file(self, filename, tree):
+        def indent(elem, level=0):
+            i = "\n" + level*"  "
+            if len(elem):
+                if not elem.text or not elem.text.strip():
+                    elem.text = i + "  "
+                if not elem.tail or not elem.tail.strip():
+                    elem.tail = i
+                for elem in elem:
+                    indent(elem, level+1)
+                if not elem.tail or not elem.tail.strip():
+                    elem.tail = i
+            else:
+                if level and (not elem.tail or not elem.tail.strip()):
+                    elem.tail = i
+        indent(tree.getroot())
+        tree.write(filename)
+
+    def read_xml_object(self, vtType, node):
+        return self['xml'][vtType].fromXML(node)
+
+    def write_xml_object(self, obj, node=None):
+        res_node = self['xml'][obj.vtType].toXML(obj, node)
+        return res_node
+        
+    def open_from_xml(self, filename, vtType, tree=None):
+        """open_from_xml(filename) -> DBVistrail"""
+        if tree is None:
+            tree = self.parse_xml_file(filename)
+        vistrail = self.read_xml_object(vtType, tree.getroot())
+        return vistrail
+
+    def save_to_xml(self, obj, filename, tags, version=None):
+        """save_to_xml(obj : object, filename: str, tags: dict,
+                       version: str) -> None
+    
+        """
+        root = self.write_xml_object(obj)
+        if version is None:
+            version = my_version
+        root.set('version', version)
+        for k, v in tags.iteritems():
+            root.set(k, v)
+        tree = ElementTree.ElementTree(root)
+        self.write_xml_file(filename, tree)
+
+    def open_from_db(self, db_connection, vtType, id=None, lock=False, 
+                     global_props=None):
+        all_objects = {}
+        if global_props is None:
+            global_props = {}
+        if id is not None:
+            global_props['id'] = id
+        #  global_props
+        res_objects = self['sql'][vtType].get_sql_columns(db_connection, 
+                                                          global_props,
+                                                          lock)
+        if len(res_objects) > 1:
+            raise VistrailsDBException("More than object of type '%s' and "
+                                       "id '%s' exist in the database" % \
+                                           (vtType, id))
+        elif len(res_objects) <= 0:
+            raise VistrailsDBException("No objects of type '%s' and "
+                                       "id '%s' exist in the database" % \
+                                           (vtType, id))
+        
+        all_objects.update(res_objects)
+        res = res_objects.values()[0]
+        global_props = {'entity_id': res.db_id,
+                        'entity_type': res.vtType}
+
+        # collect all commands so that they can be executed together
+        # daoList should contain (dao_type, dao, dbCommand) values
+        daoList = []
+        # dbCommandList should contain dbCommand values
+        dbCommandList = []
+        
+        # generate SELECT statements
+        for dao_type, dao in self['sql'].iteritems():
+            if dao_type in root_set:
+                continue
+
+            daoList.append([dao_type, dao, None])
+            dbCommand = dao.get_sql_select(db_connection, global_props, lock)
+            dbCommandList.append(dbCommand)
+            
+        # Exacute all select statements
+        results = self['sql'][vtType].executeSQLGroup(db_connection,
+                                                      dbCommandList, True)
+
+        # add result to correct dao
+        for i in xrange(len(daoList)):
+            daoList[i][2] = results[i]
+        
+        # process results
+        for dao_type, dao, data in daoList:
+            current_objs = dao.process_sql_columns(data, global_props)
+            all_objects.update(current_objs)
+
+            if dao_type == DBGroup.vtType:
+                for key, obj in current_objs.iteritems():
+                    new_props = {'parent_id': key[1],
+                                 'entity_id': global_props['entity_id'],
+                                 'entity_type': global_props['entity_type']}
+                    res_obj = self.open_from_db(db_connection, 
+                                                DBWorkflow.vtType, 
+                                                None, lock, new_props)
+                    res_dict = {}
+                    res_dict[(res_obj.vtType, res_obj.db_id)] = res_obj
+                    all_objects.update(res_dict)
+
+        for key, obj in all_objects.iteritems():
+            if key[0] == vtType and key[1] == id:
+                continue
+            self['sql'][obj.vtType].from_sql_fast(obj, all_objects)
+        for obj in all_objects.itervalues():
+            obj.is_dirty = False
+            obj.is_new = False
+
+        return res
+
+    def open_many_from_db(self, db_connection, vtType, ids, lock=False):
+        """ Loads multiple objects. They need to be loaded as one single
+            multiple select statement command for performance reasons.
+        """
+
+        log_dao = self['sql'][vtType]
+        # loop through ids and build SELECT statements
+        selects = [log_dao.get_sql_select(db_connection, {'id': id}, lock)
+                   for id in ids]
+        # Execute all SELECT statements for main objects
+        results = log_dao.executeSQLGroup(db_connection, selects, True)
+
+        # list of final objects
+        objects = []
+        # list of selects
+        selects = []
+        # list of children id:all_objects_dict
+        all_objects_dict = {}
+        # process each result and extract child SELECTS
+        # daoList should contain (id, dao_type, dao, result) values
+        daoList = []
+        # selects should contain dbCommand values
+        selects = []
+        global_props = {}
+        for id, data in zip(ids, results):
+            res_objects = log_dao.process_sql_columns(data, global_props)
+            if len(res_objects) > 1:
+                raise VistrailsDBException("More than object of type '%s' and "
+                                           "id '%s' exist in the database" % \
+                                               (vtType, id))
+            elif len(res_objects) <= 0:
+                raise VistrailsDBException("No objects of type '%s' and "
+                                           "id '%s' exist in the database" % \
+                                               (vtType, id))
+            all_objects = {}
+            all_objects_dict[id] = all_objects
+            all_objects.update(res_objects)
+            objects.append(res_objects.values()[0])
+            # collect all commands so that they can be executed together
+        
+            # generate SELECT statements for children
+            for dao_type, dao in self['sql'].iteritems():
+                if dao_type in root_set:
+                    continue
+    
+                daoList.append([id, dao_type, dao, None])
+                dbCommand = dao.get_sql_select(db_connection, global_props, lock)
+                selects.append(dbCommand)
+
+        # Execute all child select statements
+        results = self['sql'][vtType].executeSQLGroup(db_connection,
+                                                      selects, True)
+        for i in xrange(len(daoList)):
+            daoList[i][3] = results[i]
+
+        # process results
+        for id, dao_type, dao, data in daoList:
+            all_objects = all_objects_dict[id]
+            current_objs = dao.process_sql_columns(data, global_props)
+            all_objects.update(current_objs)
+
+            if dao_type == DBGroup.vtType:
+                for key, obj in current_objs.iteritems():
+                    new_props = {'parent_id': key[1],
+                                 'entity_id': global_props['entity_id'],
+                                 'entity_type': global_props['entity_type']}
+                    res_obj = self.open_from_db(db_connection, 
+                                                DBWorkflow.vtType, 
+                                                None, lock, new_props)
+                    res_dict = {}
+                    res_dict[(res_obj.vtType, res_obj.db_id)] = res_obj
+                    all_objects.update(res_dict)
+
+        
+        for id, all_objects in all_objects_dict.iteritems():
+            for key, obj in all_objects.iteritems():
+                if key[0] == vtType and key[1] == id:
+                    continue
+                self['sql'][obj.vtType].from_sql_fast(obj, all_objects)
+        for id, dao_type, dao, data in daoList:
+            all_objects = all_objects_dict[id]
+            for obj in all_objects.itervalues():
+                obj.is_dirty = False
+                obj.is_new = False
+    
+        return objects
+
+    def save_to_db(self, db_connection, obj, do_copy=False, global_props=None):
+        if do_copy == 'with_ids':
+            do_copy = True
+        elif do_copy and obj.db_id is not None:
+            obj.db_id = None
+
+        children = obj.db_children()
+        children.reverse()
+        if global_props is None:
+            global_props = {'entity_type': obj.vtType}
+        # print 'global_props:', global_props
+
+        # assumes not deleting entire thing
+        child = children[0][0]
+        self['sql'][child.vtType].set_sql_columns(db_connection, child, 
+                                                  global_props, do_copy)
+        self['sql'][child.vtType].to_sql_fast(child, do_copy)
+
+        global_props = {'entity_id': child.db_id,
+                        'entity_type': child.vtType}
+
+        # do deletes
+        if not do_copy:
+            for (child, _, _) in children:
+                for c in child.db_deleted_children(True):
+                    self['sql'][c.vtType].delete_sql_column(db_connection,
+                                                            c,
+                                                            global_props)
+        child = children.pop(0)[0]
+        child.is_dirty = False
+        child.is_new = False
+        
+        if not len(children):
+            return
+
+        # list of all children
+        dbCommandList = []
+        writtenChildren = []
+        # process remaining children
+        for (child, _, _) in children:
+            dbCommand = self['sql'][child.vtType].set_sql_command(
+                            db_connection, child, global_props, do_copy)
+            if dbCommand is not None:
+                dbCommandList.append(dbCommand)
+                writtenChildren.append(child)
+            self['sql'][child.vtType].to_sql_fast(child, do_copy)
+
+        # Debug version of Execute all insert/update statements
+        #results = [self['sql'][children[0][0].vtType].executeSQL(
+        #                      db_connection, c, False) for c in dbCommandList]
+
+        # Execute all insert/update statements
+        results = self['sql'][children[0][0].vtType].executeSQLGroup(
+                                                    db_connection,
+                                                    dbCommandList, False)
+        resultDict = dict(zip(writtenChildren, results))
+        # process remaining children
+        for (child, _, _) in children:
+            if child in resultDict:
+                lastId = resultDict[child]
+                self['sql'][child.vtType].set_sql_process(child, 
+                                                          global_props,
+                                                          lastId)
+            self['sql'][child.vtType].to_sql_fast(child, do_copy)
+            if child.vtType == DBGroup.vtType:
+                if child.db_workflow:
+                    # print '*** entity_type:', global_props['entity_type']
+                    new_props = {'entity_id': global_props['entity_id'],
+                                 'entity_type': global_props['entity_type']}
+                    is_dirty = child.db_workflow.is_dirty
+                    child.db_workflow.db_entity_type = DBWorkflow.vtType
+                    child.db_workflow.is_dirty = is_dirty
+                    self.save_to_db(db_connection, child.db_workflow, do_copy,
+                                    new_props)
+
+    def save_many_to_db(self, db_connection, objList, do_copy=False):
+        if do_copy == 'with_ids':
+            do_copy = True
+        if not len(objList):
+            return
+        childrenDict = {}
+        global_propsDict = {}
+        dbCommandList = []
+        writtenChildren = []
+        for obj in objList:
+            if do_copy and obj.db_id is not None:
+                obj.db_id = None
+
+            children = obj.db_children()
+            children.reverse()
+            global_props = {'entity_type': obj.vtType}
+
+            child = children[0][0]
+            dbCommand = self['sql'][child.vtType].set_sql_command(
+                db_connection, child, global_props, do_copy)
+            if dbCommand is not None:
+                dbCommandList.append(dbCommand)
+                writtenChildren.append(child)
+            
+            childrenDict[child] = children
+            global_propsDict[child] = global_props
+
+        # Execute all insert/update statements for the main objects
+        results = self['sql'][children[0][0].vtType].executeSQLGroup(
+                                                    db_connection,
+                                                    dbCommandList, False)
+        resultDict = dict(zip(writtenChildren, results))
+        dbCommandList = []
+        writtenChildren = []
+        for child, children in childrenDict.iteritems():
+            # process objects
+            if child in resultDict:
+                lastId = resultDict[child]
+                self['sql'][child.vtType].set_sql_process(
+                    child, global_propsDict[child], lastId)
+            self['sql'][child.vtType].to_sql_fast(child, do_copy)
+
+            # process children
+            global_props = {'entity_id': child.db_id,
+                                       'entity_type': child.vtType}
+            global_propsDict[child] = global_props
+            # do deletes
+            if not do_copy:
+                for (child, _, _) in childrenDict[child]:
+                    for c in child.db_deleted_children(True):
+                        self['sql'][c.vtType].delete_sql_column(db_connection,
+                                                                c,
+                                                                global_props)
+            child = children.pop(0)[0]
+            child.is_dirty = False
+            child.is_new = False
+            
+            # list of all children
+            # process remaining children
+            for (child, _, _) in children:
+                dbCommand = self['sql'][child.vtType].set_sql_command(
+                                db_connection, child, global_props, do_copy)
+                if dbCommand is not None:
+                    dbCommandList.append(dbCommand)
+                    writtenChildren.append(child)
+                self['sql'][child.vtType].to_sql_fast(child, do_copy)
+    
+        # Execute all child insert/update statements
+        results = self['sql'][children[0][0].vtType].executeSQLGroup(
+                                                        db_connection,
+                                                        dbCommandList, False)
+        resultDict = dict(zip(writtenChildren, results))
+
+        for child, children in childrenDict.iteritems():
+            global_props = global_propsDict[child]
+            # process remaining children
+            for (child, _, _) in children:
+                if child in resultDict:
+                    lastId = resultDict[child]
+                    self['sql'][child.vtType].set_sql_process(child, 
+                                                              global_props,
+                                                              lastId)
+                self['sql'][child.vtType].to_sql_fast(child, do_copy)
+                if child.vtType == DBGroup.vtType:
+                    if child.db_workflow:
+                        # print '*** entity_type:', global_props['entity_type']
+                        new_props = {'entity_id': global_props['entity_id'],
+                                     'entity_type': global_props['entity_type']}
+                        is_dirty = child.db_workflow.is_dirty
+                        child.db_workflow.db_entity_type = DBWorkflow.vtType
+                        child.db_workflow.is_dirty = is_dirty
+                        self.save_to_db(db_connection, child.db_workflow, do_copy,
+                                        new_props)
+
+    def delete_from_db(self, db_connection, type, obj_id):
+        if type not in root_set:
+            raise VistrailsDBException("Cannot delete entity of type '%s'" \
+                                           % type)
+
+        id_str = str(obj_id)
+        for (dao_type, dao) in self['sql'].iteritems():
+            if dao_type not in root_set:
+                db_cmd = \
+                    self['sql'][type].createSQLDelete(dao.table,
+                                                      {'entity_type': type,
+                                                       'entity_id': id_str})
+                self['sql'][type].executeSQL(db_connection, db_cmd, False)
+        db_cmd = self['sql'][type].createSQLDelete(self['sql'][type].table,
+                                                   {'id': id_str})
+        self['sql'][type].executeSQL(db_connection, db_cmd, False)
+
+    def serialize(self, object):
+        root = self.write_xml_object(object)
+        return ElementTree.tostring(root)
+
+    def unserialize(self, str, obj_type):
+        def set_dirty(obj):
+            for child, _, _ in obj.db_children():
+                if child.vtType == DBGroup.vtType:
+                    if child.db_workflow:
+                        set_dirty(child.db_workflow)
+                child.is_dirty = True
+                child.is_new = True
+        try:
+            root = ElementTree.fromstring(str)
+            obj = self.read_xml_object(obj_type, root)
+            set_dirty(obj)
+            return obj
+        except SyntaxError, e:
+            msg = "Invalid VisTrails serialized object %s" % str
+            raise VistrailsDBException(msg)
+            return None
diff --git a/vistrails/db/versions/v1_0_4/persistence/sql/__init__.py b/vistrails/db/versions/v1_0_4/persistence/sql/__init__.py
new file mode 100644
index 0000000..5474457
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/sql/__init__.py
@@ -0,0 +1,39 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_4/persistence/sql/auto_gen.py b/vistrails/db/versions/v1_0_4/persistence/sql/auto_gen.py
new file mode 100644
index 0000000..e362d7e
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/sql/auto_gen.py
@@ -0,0 +1,8352 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""generated automatically by auto_dao.py"""
+
+from __future__ import division
+
+from sql_dao import SQLDAO
+from vistrails.db.versions.v1_0_4.domain import *
+
+class DBMashupAliasSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'mashup_alias'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            parent = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            
+            mashup_alias = DBMashupAlias(name=name,
+                                         id=id)
+            mashup_alias.db_parent = parent
+            mashup_alias.db_entity_id = entity_id
+            mashup_alias.db_entity_type = entity_type
+            mashup_alias.is_dirty = False
+            res[('mashup_alias', id)] = mashup_alias
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            parent = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            
+            mashup_alias = DBMashupAlias(name=name,
+                                         id=id)
+            mashup_alias.db_parent = parent
+            mashup_alias.db_entity_id = entity_id
+            mashup_alias.db_entity_type = entity_type
+            mashup_alias.is_dirty = False
+            res[('mashup_alias', id)] = mashup_alias
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('mashup', obj.db_parent) in all_objects:
+            p = all_objects[('mashup', obj.db_parent)]
+            p.db_add_alias(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_alias'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_component is not None:
+            child = obj.db_component
+            child.db_mashup_alias = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'mashup_alias'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBGroupSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'group_tbl'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            group = DBGroup(cache=cache,
+                            name=name,
+                            namespace=namespace,
+                            package=package,
+                            version=version,
+                            id=id)
+            group.db_parentType = parentType
+            group.db_entity_id = entity_id
+            group.db_entity_type = entity_type
+            group.db_parent = parent
+            group.is_dirty = False
+            res[('group', id)] = group
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            group = DBGroup(cache=cache,
+                            name=name,
+                            namespace=namespace,
+                            package=package,
+                            version=version,
+                            id=id)
+            group.db_parentType = parentType
+            group.db_entity_id = entity_id
+            group.db_entity_type = entity_type
+            group.db_parent = parent
+            group.is_dirty = False
+            res[('group', id)] = group
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_module(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_workflow is not None:
+            child = obj.db_workflow
+            child.db_group = obj.db_id
+        if obj.db_location is not None:
+            child = obj.db_location
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_functions:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_controlParameters:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'group_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBAddSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'add_tbl'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            add = DBAdd(what=what,
+                        objectId=objectId,
+                        parentObjId=parentObjId,
+                        parentObjType=parentObjType,
+                        id=id)
+            add.db_action = action
+            add.db_entity_id = entity_id
+            add.db_entity_type = entity_type
+            add.is_dirty = False
+            res[('add', id)] = add
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            add = DBAdd(what=what,
+                        objectId=objectId,
+                        parentObjId=parentObjId,
+                        parentObjType=parentObjType,
+                        id=id)
+            add.db_action = action
+            add.db_entity_id = entity_id
+            add.db_entity_type = entity_type
+            add.is_dirty = False
+            res[('add', id)] = add
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('action', obj.db_action) in all_objects:
+            p = all_objects[('action', obj.db_action)]
+            p.db_add_operation(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'add_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_data is not None:
+            child = obj.db_data
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'add_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBGroupExecSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'group_exec'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            cached = self.convertFromDB(row[3], 'int', 'int')
+            module_id = self.convertFromDB(row[4], 'long', 'int')
+            group_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            group_type = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            completed = self.convertFromDB(row[7], 'int', 'int')
+            error = self.convertFromDB(row[8], 'str', 'varchar(1023)')
+            machine_id = self.convertFromDB(row[9], 'long', 'int')
+            parentType = self.convertFromDB(row[10], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[11], 'long', 'int')
+            entity_type = self.convertFromDB(row[12], 'str', 'char(16)')
+            parent = self.convertFromDB(row[13], 'long', 'long')
+            
+            group_exec = DBGroupExec(ts_start=ts_start,
+                                     ts_end=ts_end,
+                                     cached=cached,
+                                     module_id=module_id,
+                                     group_name=group_name,
+                                     group_type=group_type,
+                                     completed=completed,
+                                     error=error,
+                                     machine_id=machine_id,
+                                     id=id)
+            group_exec.db_parentType = parentType
+            group_exec.db_entity_id = entity_id
+            group_exec.db_entity_type = entity_type
+            group_exec.db_parent = parent
+            group_exec.is_dirty = False
+            res[('group_exec', id)] = group_exec
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            cached = self.convertFromDB(row[3], 'int', 'int')
+            module_id = self.convertFromDB(row[4], 'long', 'int')
+            group_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            group_type = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            completed = self.convertFromDB(row[7], 'int', 'int')
+            error = self.convertFromDB(row[8], 'str', 'varchar(1023)')
+            machine_id = self.convertFromDB(row[9], 'long', 'int')
+            parentType = self.convertFromDB(row[10], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[11], 'long', 'int')
+            entity_type = self.convertFromDB(row[12], 'str', 'char(16)')
+            parent = self.convertFromDB(row[13], 'long', 'long')
+            
+            group_exec = DBGroupExec(ts_start=ts_start,
+                                     ts_end=ts_end,
+                                     cached=cached,
+                                     module_id=module_id,
+                                     group_name=group_name,
+                                     group_type=group_type,
+                                     completed=completed,
+                                     error=error,
+                                     machine_id=machine_id,
+                                     id=id)
+            group_exec.db_parentType = parentType
+            group_exec.db_entity_id = entity_id
+            group_exec.db_entity_type = entity_type
+            group_exec.db_parent = parent
+            group_exec.is_dirty = False
+            res[('group_exec', id)] = group_exec
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'loop_iteration':
+            p = all_objects[('loop_iteration', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
+            columnMap['cached'] = \
+                self.convertToDB(obj.db_cached, 'int', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_group_name') and obj.db_group_name is not None:
+            columnMap['group_name'] = \
+                self.convertToDB(obj.db_group_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_group_type') and obj.db_group_type is not None:
+            columnMap['group_type'] = \
+                self.convertToDB(obj.db_group_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
+            columnMap['machine_id'] = \
+                self.convertToDB(obj.db_machine_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'group_name', 'group_type', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'group_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
+            columnMap['cached'] = \
+                self.convertToDB(obj.db_cached, 'int', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_group_name') and obj.db_group_name is not None:
+            columnMap['group_name'] = \
+                self.convertToDB(obj.db_group_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_group_type') and obj.db_group_type is not None:
+            columnMap['group_type'] = \
+                self.convertToDB(obj.db_group_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
+            columnMap['machine_id'] = \
+                self.convertToDB(obj.db_machine_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_item_execs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'group_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBParameterSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'parameter'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[4], 'str', 'mediumtext')
+            alias = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            parameter = DBParameter(pos=pos,
+                                    name=name,
+                                    type=type,
+                                    val=val,
+                                    alias=alias,
+                                    id=id)
+            parameter.db_parentType = parentType
+            parameter.db_entity_id = entity_id
+            parameter.db_entity_type = entity_type
+            parameter.db_parent = parent
+            parameter.is_dirty = False
+            res[('parameter', id)] = parameter
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[4], 'str', 'mediumtext')
+            alias = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            parameter = DBParameter(pos=pos,
+                                    name=name,
+                                    type=type,
+                                    val=val,
+                                    alias=alias,
+                                    id=id)
+            parameter.db_parentType = parentType
+            parameter.db_entity_id = entity_id
+            parameter.db_entity_type = entity_type
+            parameter.db_parent = parent
+            parameter.is_dirty = False
+            res[('parameter', id)] = parameter
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'function':
+            p = all_objects[('function', obj.db_parent)]
+            p.db_add_parameter(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_alias') and obj.db_alias is not None:
+            columnMap['alias'] = \
+                self.convertToDB(obj.db_alias, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'pos', 'name', 'type', 'val', 'alias', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_alias') and obj.db_alias is not None:
+            columnMap['alias'] = \
+                self.convertToDB(obj.db_alias, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBVistrailSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'vistrail'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            
+            vistrail = DBVistrail(entity_type=entity_type,
+                                  version=version,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            vistrail.is_dirty = False
+            res[('vistrail', id)] = vistrail
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            
+            vistrail = DBVistrail(entity_type=entity_type,
+                                  version=version,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            vistrail.is_dirty = False
+            res[('vistrail', id)] = vistrail
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        pass
+    
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified']
+        table = 'vistrail'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_actions:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_tags:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_controlParameters:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_vistrailVariables:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_parameter_explorations:
+            child.db_vistrail = obj.db_id
+        for child in obj.db_actionAnnotations:
+            child.db_vistrail = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'vistrail'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBModuleSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'module'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            module = DBModule(cache=cache,
+                              name=name,
+                              namespace=namespace,
+                              package=package,
+                              version=version,
+                              id=id)
+            module.db_parentType = parentType
+            module.db_entity_id = entity_id
+            module.db_entity_type = entity_type
+            module.db_parent = parent
+            module.is_dirty = False
+            res[('module', id)] = module
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            module = DBModule(cache=cache,
+                              name=name,
+                              namespace=namespace,
+                              package=package,
+                              version=version,
+                              id=id)
+            module.db_parentType = parentType
+            module.db_entity_id = entity_id
+            module.db_entity_type = entity_type
+            module.db_parent = parent
+            module.is_dirty = False
+            res[('module', id)] = module
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_module(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_location is not None:
+            child = obj.db_location
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_functions:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_controlParameters:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_portSpecs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'module'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPortSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'port'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            type = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            moduleId = self.convertFromDB(row[2], 'long', 'int')
+            moduleName = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            signature = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            port = DBPort(type=type,
+                          moduleId=moduleId,
+                          moduleName=moduleName,
+                          name=name,
+                          signature=signature,
+                          id=id)
+            port.db_parentType = parentType
+            port.db_entity_id = entity_id
+            port.db_entity_type = entity_type
+            port.db_parent = parent
+            port.is_dirty = False
+            res[('port', id)] = port
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            type = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            moduleId = self.convertFromDB(row[2], 'long', 'int')
+            moduleName = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            signature = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            parentType = self.convertFromDB(row[6], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            parent = self.convertFromDB(row[9], 'long', 'long')
+            
+            port = DBPort(type=type,
+                          moduleId=moduleId,
+                          moduleName=moduleName,
+                          name=name,
+                          signature=signature,
+                          id=id)
+            port.db_parentType = parentType
+            port.db_entity_id = entity_id
+            port.db_entity_type = entity_type
+            port.db_parent = parent
+            port.is_dirty = False
+            res[('port', id)] = port
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'connection':
+            p = all_objects[('connection', obj.db_parent)]
+            p.db_add_port(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_moduleId') and obj.db_moduleId is not None:
+            columnMap['moduleId'] = \
+                self.convertToDB(obj.db_moduleId, 'long', 'int')
+        if hasattr(obj, 'db_moduleName') and obj.db_moduleName is not None:
+            columnMap['moduleName'] = \
+                self.convertToDB(obj.db_moduleName, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_signature') and obj.db_signature is not None:
+            columnMap['signature'] = \
+                self.convertToDB(obj.db_signature, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'type', 'moduleId', 'moduleName', 'name', 'signature', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_moduleId') and obj.db_moduleId is not None:
+            columnMap['moduleId'] = \
+                self.convertToDB(obj.db_moduleId, 'long', 'int')
+        if hasattr(obj, 'db_moduleName') and obj.db_moduleName is not None:
+            columnMap['moduleName'] = \
+                self.convertToDB(obj.db_moduleName, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_signature') and obj.db_signature is not None:
+            columnMap['signature'] = \
+                self.convertToDB(obj.db_signature, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'port'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPEFunctionSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'pe_function'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            module_id = self.convertFromDB(row[1], 'long', 'int')
+            port_name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            is_alias = self.convertFromDB(row[3], 'long', 'int')
+            parentType = self.convertFromDB(row[4], 'str', 'char(32)')
+            parameter_exploration = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            pe_function = DBPEFunction(module_id=module_id,
+                                       port_name=port_name,
+                                       id=id)
+            pe_function.db_parentType = parentType
+            pe_function.db_parameter_exploration = parameter_exploration
+            pe_function.db_entity_id = entity_id
+            pe_function.db_entity_type = entity_type
+            pe_function.is_dirty = False
+            res[('pe_function', id)] = pe_function
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            module_id = self.convertFromDB(row[1], 'long', 'int')
+            port_name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            is_alias = self.convertFromDB(row[3], 'long', 'int')
+            parentType = self.convertFromDB(row[4], 'str', 'char(32)')
+            parameter_exploration = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            pe_function = DBPEFunction(module_id=module_id,
+                                       port_name=port_name,
+                                       id=id)
+            pe_function.db_parentType = parentType
+            pe_function.db_parameter_exploration = parameter_exploration
+            pe_function.db_entity_id = entity_id
+            pe_function.db_entity_type = entity_type
+            pe_function.is_dirty = False
+            res[('pe_function', id)] = pe_function
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('parameter_exploration', obj.db_parameter_exploration) in all_objects:
+            p = all_objects[('parameter_exploration', obj.db_parameter_exploration)]
+            p.db_add_function(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_port_name') and obj.db_port_name is not None:
+            columnMap['port_name'] = \
+                self.convertToDB(obj.db_port_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_is_alias') and obj.db_is_alias is not None:
+            columnMap['is_alias'] = \
+                self.convertToDB(obj.db_is_alias, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_parameter_exploration') and obj.db_parameter_exploration is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parameter_exploration, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'module_id', 'port_name', 'is_alias', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_function'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_port_name') and obj.db_port_name is not None:
+            columnMap['port_name'] = \
+                self.convertToDB(obj.db_port_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_is_alias') and obj.db_is_alias is not None:
+            columnMap['is_alias'] = \
+                self.convertToDB(obj.db_is_alias, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_parameter_exploration') and obj.db_parameter_exploration is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parameter_exploration, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_parameters:
+            child.db_pe_function = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'pe_function'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBWorkflowSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'workflow'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_id = self.convertFromDB(row[1], 'long', 'int')
+            entity_type = self.convertFromDB(row[2], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[4], 'str', 'char(16)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[6], 'long', 'int')
+            group = self.convertFromDB(row[7], 'long', 'int')
+            
+            workflow = DBWorkflow(entity_type=entity_type,
+                                  name=name,
+                                  version=version,
+                                  last_modified=last_modified,
+                                  vistrail_id=vistrail_id,
+                                  id=id)
+            workflow.db_entity_id = entity_id
+            workflow.db_group = group
+            workflow.is_dirty = False
+            res[('workflow', id)] = workflow
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_id = self.convertFromDB(row[1], 'long', 'int')
+            entity_type = self.convertFromDB(row[2], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[4], 'str', 'char(16)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[6], 'long', 'int')
+            group = self.convertFromDB(row[7], 'long', 'int')
+            
+            workflow = DBWorkflow(entity_type=entity_type,
+                                  name=name,
+                                  version=version,
+                                  last_modified=last_modified,
+                                  vistrail_id=vistrail_id,
+                                  id=id)
+            workflow.db_entity_id = entity_id
+            workflow.db_group = group
+            workflow.is_dirty = False
+            res[('workflow', id)] = workflow
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('group', obj.db_group) in all_objects:
+            p = all_objects[('group', obj.db_group)]
+            p.db_add_workflow(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        if hasattr(obj, 'db_group') and obj.db_group is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_group, 'long', 'int')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'entity_id', 'entity_type', 'name', 'version', 'last_modified', 'vistrail_id', 'parent_id']
+        table = 'workflow'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        if hasattr(obj, 'db_group') and obj.db_group is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_group, 'long', 'int')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_connections:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_plugin_datas:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_others:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_modules:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'workflow'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBMashupActionSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'mashup_action'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            user = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[4], 'long', 'int')
+            entity_id = self.convertFromDB(row[5], 'long', 'int')
+            entity_type = self.convertFromDB(row[6], 'str', 'char(16)')
+            
+            mashup_action = DBMashupAction(prevId=prevId,
+                                           date=date,
+                                           user=user,
+                                           id=id)
+            mashup_action.db_mashuptrail = mashuptrail
+            mashup_action.db_entity_id = entity_id
+            mashup_action.db_entity_type = entity_type
+            mashup_action.is_dirty = False
+            res[('mashup_action', id)] = mashup_action
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            user = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[4], 'long', 'int')
+            entity_id = self.convertFromDB(row[5], 'long', 'int')
+            entity_type = self.convertFromDB(row[6], 'str', 'char(16)')
+            
+            mashup_action = DBMashupAction(prevId=prevId,
+                                           date=date,
+                                           user=user,
+                                           id=id)
+            mashup_action.db_mashuptrail = mashuptrail
+            mashup_action.db_entity_id = entity_id
+            mashup_action.db_entity_type = entity_type
+            mashup_action.is_dirty = False
+            res[('mashup_action', id)] = mashup_action
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('mashuptrail', obj.db_mashuptrail) in all_objects:
+            p = all_objects[('mashuptrail', obj.db_mashuptrail)]
+            p.db_add_action(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'prev_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_mashup is not None:
+            child = obj.db_mashup
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'mashup_action'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBChangeSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'change_tbl'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            oldObjId = self.convertFromDB(row[2], 'long', 'int')
+            newObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjId = self.convertFromDB(row[4], 'long', 'int')
+            parentObjType = self.convertFromDB(row[5], 'str', 'char(16)')
+            action = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            change = DBChange(what=what,
+                              oldObjId=oldObjId,
+                              newObjId=newObjId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            change.db_action = action
+            change.db_entity_id = entity_id
+            change.db_entity_type = entity_type
+            change.is_dirty = False
+            res[('change', id)] = change
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            oldObjId = self.convertFromDB(row[2], 'long', 'int')
+            newObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjId = self.convertFromDB(row[4], 'long', 'int')
+            parentObjType = self.convertFromDB(row[5], 'str', 'char(16)')
+            action = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            change = DBChange(what=what,
+                              oldObjId=oldObjId,
+                              newObjId=newObjId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            change.db_action = action
+            change.db_entity_id = entity_id
+            change.db_entity_type = entity_type
+            change.is_dirty = False
+            res[('change', id)] = change
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('action', obj.db_action) in all_objects:
+            p = all_objects[('action', obj.db_action)]
+            p.db_add_operation(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_oldObjId') and obj.db_oldObjId is not None:
+            columnMap['old_obj_id'] = \
+                self.convertToDB(obj.db_oldObjId, 'long', 'int')
+        if hasattr(obj, 'db_newObjId') and obj.db_newObjId is not None:
+            columnMap['new_obj_id'] = \
+                self.convertToDB(obj.db_newObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'what', 'old_obj_id', 'new_obj_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'change_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_oldObjId') and obj.db_oldObjId is not None:
+            columnMap['old_obj_id'] = \
+                self.convertToDB(obj.db_oldObjId, 'long', 'int')
+        if hasattr(obj, 'db_newObjId') and obj.db_newObjId is not None:
+            columnMap['new_obj_id'] = \
+                self.convertToDB(obj.db_newObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_data is not None:
+            child = obj.db_data
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'change_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPackageSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'package'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            identifier = self.convertFromDB(row[2], 'str', 'varchar(1023)')
+            codepath = self.convertFromDB(row[3], 'str', 'varchar(1023)')
+            load_configuration = self.convertFromDB(row[4], 'int', 'int')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            description = self.convertFromDB(row[6], 'str', 'varchar(1023)')
+            registry = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            package = DBPackage(name=name,
+                                identifier=identifier,
+                                codepath=codepath,
+                                load_configuration=load_configuration,
+                                version=version,
+                                description=description,
+                                id=id)
+            package.db_registry = registry
+            package.db_entity_id = entity_id
+            package.db_entity_type = entity_type
+            package.is_dirty = False
+            res[('package', id)] = package
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            identifier = self.convertFromDB(row[2], 'str', 'varchar(1023)')
+            codepath = self.convertFromDB(row[3], 'str', 'varchar(1023)')
+            load_configuration = self.convertFromDB(row[4], 'int', 'int')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            description = self.convertFromDB(row[6], 'str', 'varchar(1023)')
+            registry = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            package = DBPackage(name=name,
+                                identifier=identifier,
+                                codepath=codepath,
+                                load_configuration=load_configuration,
+                                version=version,
+                                description=description,
+                                id=id)
+            package.db_registry = registry
+            package.db_entity_id = entity_id
+            package.db_entity_type = entity_type
+            package.is_dirty = False
+            res[('package', id)] = package
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('registry', obj.db_registry) in all_objects:
+            p = all_objects[('registry', obj.db_registry)]
+            p.db_add_package(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_identifier') and obj.db_identifier is not None:
+            columnMap['identifier'] = \
+                self.convertToDB(obj.db_identifier, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_codepath') and obj.db_codepath is not None:
+            columnMap['codepath'] = \
+                self.convertToDB(obj.db_codepath, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_load_configuration') and obj.db_load_configuration is not None:
+            columnMap['load_configuration'] = \
+                self.convertToDB(obj.db_load_configuration, 'int', 'int')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_description') and obj.db_description is not None:
+            columnMap['description'] = \
+                self.convertToDB(obj.db_description, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_registry') and obj.db_registry is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_registry, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'identifier', 'codepath', 'load_configuration', 'version', 'description', 'parent_id', 'entity_id', 'entity_type']
+        table = 'package'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_identifier') and obj.db_identifier is not None:
+            columnMap['identifier'] = \
+                self.convertToDB(obj.db_identifier, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_codepath') and obj.db_codepath is not None:
+            columnMap['codepath'] = \
+                self.convertToDB(obj.db_codepath, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_load_configuration') and obj.db_load_configuration is not None:
+            columnMap['load_configuration'] = \
+                self.convertToDB(obj.db_load_configuration, 'int', 'int')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_description') and obj.db_description is not None:
+            columnMap['description'] = \
+                self.convertToDB(obj.db_description, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_registry') and obj.db_registry is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_registry, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_module_descriptors:
+            child.db_package = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'package'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBLoopExecSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'loop_exec'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            loop_exec = DBLoopExec(ts_start=ts_start,
+                                   ts_end=ts_end,
+                                   id=id)
+            loop_exec.db_parentType = parentType
+            loop_exec.db_entity_id = entity_id
+            loop_exec.db_entity_type = entity_type
+            loop_exec.db_parent = parent
+            loop_exec.is_dirty = False
+            res[('loop_exec', id)] = loop_exec
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            loop_exec = DBLoopExec(ts_start=ts_start,
+                                   ts_end=ts_end,
+                                   id=id)
+            loop_exec.db_parentType = parentType
+            loop_exec.db_entity_id = entity_id
+            loop_exec.db_entity_type = entity_type
+            loop_exec.db_parent = parent
+            loop_exec.is_dirty = False
+            res[('loop_exec', id)] = loop_exec
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'module_exec':
+            p = all_objects[('module_exec', obj.db_parent)]
+            p.db_add_loop_exec(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'ts_start', 'ts_end', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'ts_start', 'ts_end', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'loop_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_loop_iterations:
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'loop_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBConnectionSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'connection_tbl'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            parentType = self.convertFromDB(row[1], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[2], 'long', 'int')
+            entity_type = self.convertFromDB(row[3], 'str', 'char(16)')
+            parent = self.convertFromDB(row[4], 'long', 'long')
+            
+            connection = DBConnection(id=id)
+            connection.db_parentType = parentType
+            connection.db_entity_id = entity_id
+            connection.db_entity_type = entity_type
+            connection.db_parent = parent
+            connection.is_dirty = False
+            res[('connection', id)] = connection
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            parentType = self.convertFromDB(row[1], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[2], 'long', 'int')
+            entity_type = self.convertFromDB(row[3], 'str', 'char(16)')
+            parent = self.convertFromDB(row[4], 'long', 'long')
+            
+            connection = DBConnection(id=id)
+            connection.db_parentType = parentType
+            connection.db_entity_id = entity_id
+            connection.db_entity_type = entity_type
+            connection.db_parent = parent
+            connection.is_dirty = False
+            res[('connection', id)] = connection
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_connection(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'connection_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_ports:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'connection_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBActionSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'action'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            action = DBAction(prevId=prevId,
+                              date=date,
+                              session=session,
+                              user=user,
+                              id=id)
+            action.db_vistrail = vistrail
+            action.db_entity_id = entity_id
+            action.db_entity_type = entity_type
+            action.is_dirty = False
+            res[('action', id)] = action
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            prevId = self.convertFromDB(row[1], 'long', 'int')
+            date = self.convertFromDB(row[2], 'datetime', 'datetime')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            action = DBAction(prevId=prevId,
+                              date=date,
+                              session=session,
+                              user=user,
+                              id=id)
+            action.db_vistrail = vistrail
+            action.db_entity_id = entity_id
+            action.db_entity_type = entity_type
+            action.is_dirty = False
+            res[('action', id)] = action
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_action(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'prev_id', 'date', 'session', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_prevId') and obj.db_prevId is not None:
+            columnMap['prev_id'] = \
+                self.convertToDB(obj.db_prevId, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_operations:
+            child.db_action = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'action'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPortSpecSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'port_spec'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'type', 'optional', 'depth', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            optional = self.convertFromDB(row[3], 'int', 'int')
+            depth = self.convertFromDB(row[4], 'int', 'int')
+            sort_key = self.convertFromDB(row[5], 'int', 'int')
+            min_conns = self.convertFromDB(row[6], 'int', 'int')
+            max_conns = self.convertFromDB(row[7], 'int', 'int')
+            parentType = self.convertFromDB(row[8], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[9], 'long', 'int')
+            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
+            parent = self.convertFromDB(row[11], 'long', 'long')
+            
+            portSpec = DBPortSpec(name=name,
+                                  type=type,
+                                  optional=optional,
+                                  depth=depth,
+                                  sort_key=sort_key,
+                                  min_conns=min_conns,
+                                  max_conns=max_conns,
+                                  id=id)
+            portSpec.db_parentType = parentType
+            portSpec.db_entity_id = entity_id
+            portSpec.db_entity_type = entity_type
+            portSpec.db_parent = parent
+            portSpec.is_dirty = False
+            res[('portSpec', id)] = portSpec
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'type', 'optional', 'depth', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            type = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            optional = self.convertFromDB(row[3], 'int', 'int')
+            depth = self.convertFromDB(row[4], 'int', 'int')
+            sort_key = self.convertFromDB(row[5], 'int', 'int')
+            min_conns = self.convertFromDB(row[6], 'int', 'int')
+            max_conns = self.convertFromDB(row[7], 'int', 'int')
+            parentType = self.convertFromDB(row[8], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[9], 'long', 'int')
+            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
+            parent = self.convertFromDB(row[11], 'long', 'long')
+            
+            portSpec = DBPortSpec(name=name,
+                                  type=type,
+                                  optional=optional,
+                                  depth=depth,
+                                  sort_key=sort_key,
+                                  min_conns=min_conns,
+                                  max_conns=max_conns,
+                                  id=id)
+            portSpec.db_parentType = parentType
+            portSpec.db_entity_id = entity_id
+            portSpec.db_entity_type = entity_type
+            portSpec.db_parent = parent
+            portSpec.is_dirty = False
+            res[('portSpec', id)] = portSpec
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_portSpec(obj)
+        elif obj.db_parentType == 'module_descriptor':
+            p = all_objects[('module_descriptor', obj.db_parent)]
+            p.db_add_portSpec(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'type', 'optional', 'depth', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_optional') and obj.db_optional is not None:
+            columnMap['optional'] = \
+                self.convertToDB(obj.db_optional, 'int', 'int')
+        if hasattr(obj, 'db_depth') and obj.db_depth is not None:
+            columnMap['depth'] = \
+                self.convertToDB(obj.db_depth, 'int', 'int')
+        if hasattr(obj, 'db_sort_key') and obj.db_sort_key is not None:
+            columnMap['sort_key'] = \
+                self.convertToDB(obj.db_sort_key, 'int', 'int')
+        if hasattr(obj, 'db_min_conns') and obj.db_min_conns is not None:
+            columnMap['min_conns'] = \
+                self.convertToDB(obj.db_min_conns, 'int', 'int')
+        if hasattr(obj, 'db_max_conns') and obj.db_max_conns is not None:
+            columnMap['max_conns'] = \
+                self.convertToDB(obj.db_max_conns, 'int', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'type', 'optional', 'depth', 'sort_key', 'min_conns', 'max_conns', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'port_spec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_optional') and obj.db_optional is not None:
+            columnMap['optional'] = \
+                self.convertToDB(obj.db_optional, 'int', 'int')
+        if hasattr(obj, 'db_depth') and obj.db_depth is not None:
+            columnMap['depth'] = \
+                self.convertToDB(obj.db_depth, 'int', 'int')
+        if hasattr(obj, 'db_sort_key') and obj.db_sort_key is not None:
+            columnMap['sort_key'] = \
+                self.convertToDB(obj.db_sort_key, 'int', 'int')
+        if hasattr(obj, 'db_min_conns') and obj.db_min_conns is not None:
+            columnMap['min_conns'] = \
+                self.convertToDB(obj.db_min_conns, 'int', 'int')
+        if hasattr(obj, 'db_max_conns') and obj.db_max_conns is not None:
+            columnMap['max_conns'] = \
+                self.convertToDB(obj.db_max_conns, 'int', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_portSpecItems:
+            child.db_portSpec = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'port_spec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBLogSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'log_tbl'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[5], 'long', 'int')
+            
+            log = DBLog(entity_type=entity_type,
+                        version=version,
+                        name=name,
+                        last_modified=last_modified,
+                        vistrail_id=vistrail_id,
+                        id=id)
+            log.is_dirty = False
+            res[('log', id)] = log
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            name = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            vistrail_id = self.convertFromDB(row[5], 'long', 'int')
+            
+            log = DBLog(entity_type=entity_type,
+                        version=version,
+                        name=name,
+                        last_modified=last_modified,
+                        vistrail_id=vistrail_id,
+                        id=id)
+            log.is_dirty = False
+            res[('log', id)] = log
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        pass
+    
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'entity_type', 'version', 'name', 'last_modified', 'vistrail_id']
+        table = 'log_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_vistrail_id') and obj.db_vistrail_id is not None:
+            columnMap['vistrail_id'] = \
+                self.convertToDB(obj.db_vistrail_id, 'long', 'int')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_workflow_execs:
+            child.db_log = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'log_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBLoopIterationSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'loop_iteration'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_id', 'entity_id', 'entity_type']
+        table = 'loop_iteration'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            iteration = self.convertFromDB(row[3], 'int', 'int')
+            completed = self.convertFromDB(row[4], 'int', 'int')
+            error = self.convertFromDB(row[5], 'str', 'varchar(1023)')
+            parent = self.convertFromDB(row[6], 'str', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            loop_iteration = DBLoopIteration(ts_start=ts_start,
+                                             ts_end=ts_end,
+                                             iteration=iteration,
+                                             completed=completed,
+                                             error=error,
+                                             id=id)
+            loop_iteration.db_parent = parent
+            loop_iteration.db_entity_id = entity_id
+            loop_iteration.db_entity_type = entity_type
+            loop_iteration.is_dirty = False
+            res[('loop_iteration', id)] = loop_iteration
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_id', 'entity_id', 'entity_type']
+        table = 'loop_iteration'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            iteration = self.convertFromDB(row[3], 'int', 'int')
+            completed = self.convertFromDB(row[4], 'int', 'int')
+            error = self.convertFromDB(row[5], 'str', 'varchar(1023)')
+            parent = self.convertFromDB(row[6], 'str', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            loop_iteration = DBLoopIteration(ts_start=ts_start,
+                                             ts_end=ts_end,
+                                             iteration=iteration,
+                                             completed=completed,
+                                             error=error,
+                                             id=id)
+            loop_iteration.db_parent = parent
+            loop_iteration.db_entity_id = entity_id
+            loop_iteration.db_entity_type = entity_type
+            loop_iteration.is_dirty = False
+            res[('loop_iteration', id)] = loop_iteration
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('loop_exec', obj.db_parent) in all_objects:
+            p = all_objects[('loop_exec', obj.db_parent)]
+            p.db_add_loop_iteration(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_id', 'entity_id', 'entity_type']
+        table = 'loop_iteration'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_iteration') and obj.db_iteration is not None:
+            columnMap['iteration'] = \
+                self.convertToDB(obj.db_iteration, 'int', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'str', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'ts_start', 'ts_end', 'iteration', 'completed', 'error', 'parent_id', 'entity_id', 'entity_type']
+        table = 'loop_iteration'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_iteration') and obj.db_iteration is not None:
+            columnMap['iteration'] = \
+                self.convertToDB(obj.db_iteration, 'int', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'str', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_item_execs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'loop_iteration'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPEParameterSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'pe_parameter'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            interpolator = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[3], 'str', 'mediumtext')
+            dimension = self.convertFromDB(row[4], 'long', 'int')
+            parentType = self.convertFromDB(row[5], 'str', 'char(32)')
+            pe_function = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            pe_parameter = DBPEParameter(pos=pos,
+                                         interpolator=interpolator,
+                                         value=value,
+                                         dimension=dimension,
+                                         id=id)
+            pe_parameter.db_parentType = parentType
+            pe_parameter.db_pe_function = pe_function
+            pe_parameter.db_entity_id = entity_id
+            pe_parameter.db_entity_type = entity_type
+            pe_parameter.is_dirty = False
+            res[('pe_parameter', id)] = pe_parameter
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            interpolator = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[3], 'str', 'mediumtext')
+            dimension = self.convertFromDB(row[4], 'long', 'int')
+            parentType = self.convertFromDB(row[5], 'str', 'char(32)')
+            pe_function = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            pe_parameter = DBPEParameter(pos=pos,
+                                         interpolator=interpolator,
+                                         value=value,
+                                         dimension=dimension,
+                                         id=id)
+            pe_parameter.db_parentType = parentType
+            pe_parameter.db_pe_function = pe_function
+            pe_parameter.db_entity_id = entity_id
+            pe_parameter.db_entity_type = entity_type
+            pe_parameter.is_dirty = False
+            res[('pe_parameter', id)] = pe_parameter
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('pe_function', obj.db_pe_function) in all_objects:
+            p = all_objects[('pe_function', obj.db_pe_function)]
+            p.db_add_parameter(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_interpolator') and obj.db_interpolator is not None:
+            columnMap['interpolator'] = \
+                self.convertToDB(obj.db_interpolator, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_dimension') and obj.db_dimension is not None:
+            columnMap['dimension'] = \
+                self.convertToDB(obj.db_dimension, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_pe_function') and obj.db_pe_function is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_pe_function, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'pos', 'interpolator', 'value', 'dimension', 'parent_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'pe_parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_interpolator') and obj.db_interpolator is not None:
+            columnMap['interpolator'] = \
+                self.convertToDB(obj.db_interpolator, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_dimension') and obj.db_dimension is not None:
+            columnMap['dimension'] = \
+                self.convertToDB(obj.db_dimension, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_pe_function') and obj.db_pe_function is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_pe_function, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'pe_parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBWorkflowExecSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'workflow_exec'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            user = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            ip = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            vt_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ts_start = self.convertFromDB(row[5], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[6], 'datetime', 'datetime')
+            parent_id = self.convertFromDB(row[7], 'long', 'int')
+            parent_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            parent_version = self.convertFromDB(row[9], 'long', 'int')
+            completed = self.convertFromDB(row[10], 'int', 'int')
+            name = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            log = self.convertFromDB(row[12], 'long', 'int')
+            entity_id = self.convertFromDB(row[13], 'long', 'int')
+            entity_type = self.convertFromDB(row[14], 'str', 'char(16)')
+            
+            workflow_exec = DBWorkflowExec(user=user,
+                                           ip=ip,
+                                           session=session,
+                                           vt_version=vt_version,
+                                           ts_start=ts_start,
+                                           ts_end=ts_end,
+                                           parent_id=parent_id,
+                                           parent_type=parent_type,
+                                           parent_version=parent_version,
+                                           completed=completed,
+                                           name=name,
+                                           id=id)
+            workflow_exec.db_log = log
+            workflow_exec.db_entity_id = entity_id
+            workflow_exec.db_entity_type = entity_type
+            workflow_exec.is_dirty = False
+            res[('workflow_exec', id)] = workflow_exec
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            user = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            ip = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            session = self.convertFromDB(row[3], 'long', 'int')
+            vt_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ts_start = self.convertFromDB(row[5], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[6], 'datetime', 'datetime')
+            parent_id = self.convertFromDB(row[7], 'long', 'int')
+            parent_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            parent_version = self.convertFromDB(row[9], 'long', 'int')
+            completed = self.convertFromDB(row[10], 'int', 'int')
+            name = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            log = self.convertFromDB(row[12], 'long', 'int')
+            entity_id = self.convertFromDB(row[13], 'long', 'int')
+            entity_type = self.convertFromDB(row[14], 'str', 'char(16)')
+            
+            workflow_exec = DBWorkflowExec(user=user,
+                                           ip=ip,
+                                           session=session,
+                                           vt_version=vt_version,
+                                           ts_start=ts_start,
+                                           ts_end=ts_end,
+                                           parent_id=parent_id,
+                                           parent_type=parent_type,
+                                           parent_version=parent_version,
+                                           completed=completed,
+                                           name=name,
+                                           id=id)
+            workflow_exec.db_log = log
+            workflow_exec.db_entity_id = entity_id
+            workflow_exec.db_entity_type = entity_type
+            workflow_exec.is_dirty = False
+            res[('workflow_exec', id)] = workflow_exec
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('log', obj.db_log) in all_objects:
+            p = all_objects[('log', obj.db_log)]
+            p.db_add_workflow_exec(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ip') and obj.db_ip is not None:
+            columnMap['ip'] = \
+                self.convertToDB(obj.db_ip, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_vt_version') and obj.db_vt_version is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vt_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_parent_id') and obj.db_parent_id is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent_id, 'long', 'int')
+        if hasattr(obj, 'db_parent_type') and obj.db_parent_type is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parent_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parent_version') and obj.db_parent_version is not None:
+            columnMap['parent_version'] = \
+                self.convertToDB(obj.db_parent_version, 'long', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_log') and obj.db_log is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_log, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'user', 'ip', 'session', 'vt_version', 'ts_start', 'ts_end', 'parent_id', 'parent_type', 'parent_version', 'completed', 'name', 'log_id', 'entity_id', 'entity_type']
+        table = 'workflow_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ip') and obj.db_ip is not None:
+            columnMap['ip'] = \
+                self.convertToDB(obj.db_ip, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_session') and obj.db_session is not None:
+            columnMap['session'] = \
+                self.convertToDB(obj.db_session, 'long', 'int')
+        if hasattr(obj, 'db_vt_version') and obj.db_vt_version is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vt_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_parent_id') and obj.db_parent_id is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent_id, 'long', 'int')
+        if hasattr(obj, 'db_parent_type') and obj.db_parent_type is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parent_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parent_version') and obj.db_parent_version is not None:
+            columnMap['parent_version'] = \
+                self.convertToDB(obj.db_parent_version, 'long', 'int')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_log') and obj.db_log is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_log, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_machines:
+            child.db_workflow_exec = obj.db_id
+        for child in obj.db_item_execs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'workflow_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBLocationSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'location'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            x = self.convertFromDB(row[1], 'float', 'DECIMAL(18,12)')
+            y = self.convertFromDB(row[2], 'float', 'DECIMAL(18,12)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            location = DBLocation(x=x,
+                                  y=y,
+                                  id=id)
+            location.db_parentType = parentType
+            location.db_entity_id = entity_id
+            location.db_entity_type = entity_type
+            location.db_parent = parent
+            location.is_dirty = False
+            res[('location', id)] = location
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            x = self.convertFromDB(row[1], 'float', 'DECIMAL(18,12)')
+            y = self.convertFromDB(row[2], 'float', 'DECIMAL(18,12)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            location = DBLocation(x=x,
+                                  y=y,
+                                  id=id)
+            location.db_parentType = parentType
+            location.db_entity_id = entity_id
+            location.db_entity_type = entity_type
+            location.db_parent = parent
+            location.is_dirty = False
+            res[('location', id)] = location
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_location(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_location(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_location(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_x') and obj.db_x is not None:
+            columnMap['x'] = \
+                self.convertToDB(obj.db_x, 'float', 'DECIMAL(18,12)')
+        if hasattr(obj, 'db_y') and obj.db_y is not None:
+            columnMap['y'] = \
+                self.convertToDB(obj.db_y, 'float', 'DECIMAL(18,12)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'x', 'y', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'location'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_x') and obj.db_x is not None:
+            columnMap['x'] = \
+                self.convertToDB(obj.db_x, 'float', 'DECIMAL(18,12)')
+        if hasattr(obj, 'db_y') and obj.db_y is not None:
+            columnMap['y'] = \
+                self.convertToDB(obj.db_y, 'float', 'DECIMAL(18,12)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'location'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBFunctionSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'function'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            function = DBFunction(pos=pos,
+                                  name=name,
+                                  id=id)
+            function.db_parentType = parentType
+            function.db_entity_id = entity_id
+            function.db_entity_type = entity_type
+            function.db_parent = parent
+            function.is_dirty = False
+            res[('function', id)] = function
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            function = DBFunction(pos=pos,
+                                  name=name,
+                                  id=id)
+            function.db_parentType = parentType
+            function.db_entity_id = entity_id
+            function.db_entity_type = entity_type
+            function.db_parent = parent
+            function.is_dirty = False
+            res[('function', id)] = function
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_function(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_function(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_function(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'pos', 'name', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'function'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_parameters:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'function'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBActionAnnotationSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'action_annotation'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            actionAnnotation = DBActionAnnotation(key=key,
+                                                  value=value,
+                                                  action_id=action_id,
+                                                  date=date,
+                                                  user=user,
+                                                  id=id)
+            actionAnnotation.db_vistrail = vistrail
+            actionAnnotation.db_entity_id = entity_id
+            actionAnnotation.db_entity_type = entity_type
+            actionAnnotation.is_dirty = False
+            res[('actionAnnotation', id)] = actionAnnotation
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            actionAnnotation = DBActionAnnotation(key=key,
+                                                  value=value,
+                                                  action_id=action_id,
+                                                  date=date,
+                                                  user=user,
+                                                  id=id)
+            actionAnnotation.db_vistrail = vistrail
+            actionAnnotation.db_entity_id = entity_id
+            actionAnnotation.db_entity_type = entity_type
+            actionAnnotation.is_dirty = False
+            res[('actionAnnotation', id)] = actionAnnotation
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_actionAnnotation(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'action_annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'action_annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBControlParameterSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'control_parameter'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'control_parameter'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'mediumtext')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            controlParameter = DBControlParameter(name=name,
+                                                  value=value,
+                                                  id=id)
+            controlParameter.db_parentType = parentType
+            controlParameter.db_entity_id = entity_id
+            controlParameter.db_entity_type = entity_type
+            controlParameter.db_parent = parent
+            controlParameter.is_dirty = False
+            res[('controlParameter', id)] = controlParameter
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'control_parameter'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'mediumtext')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            controlParameter = DBControlParameter(name=name,
+                                                  value=value,
+                                                  id=id)
+            controlParameter.db_parentType = parentType
+            controlParameter.db_entity_id = entity_id
+            controlParameter.db_entity_type = entity_type
+            controlParameter.db_parent = parent
+            controlParameter.is_dirty = False
+            res[('controlParameter', id)] = controlParameter
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'vistrail':
+            p = all_objects[('vistrail', obj.db_parent)]
+            p.db_add_controlParameter(obj)
+        elif obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_controlParameter(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_controlParameter(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_controlParameter(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'control_parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'control_parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'control_parameter'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPluginDataSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'plugin_data'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            data = self.convertFromDB(row[1], 'str', 'varchar(8191)')
+            parentType = self.convertFromDB(row[2], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            parent = self.convertFromDB(row[5], 'long', 'long')
+            
+            plugin_data = DBPluginData(data=data,
+                                       id=id)
+            plugin_data.db_parentType = parentType
+            plugin_data.db_entity_id = entity_id
+            plugin_data.db_entity_type = entity_type
+            plugin_data.db_parent = parent
+            plugin_data.is_dirty = False
+            res[('plugin_data', id)] = plugin_data
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            data = self.convertFromDB(row[1], 'str', 'varchar(8191)')
+            parentType = self.convertFromDB(row[2], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            parent = self.convertFromDB(row[5], 'long', 'long')
+            
+            plugin_data = DBPluginData(data=data,
+                                       id=id)
+            plugin_data.db_parentType = parentType
+            plugin_data.db_entity_id = entity_id
+            plugin_data.db_entity_type = entity_type
+            plugin_data.db_parent = parent
+            plugin_data.is_dirty = False
+            res[('plugin_data', id)] = plugin_data
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_plugin_data(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_data') and obj.db_data is not None:
+            columnMap['data'] = \
+                self.convertToDB(obj.db_data, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'data', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'plugin_data'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_data') and obj.db_data is not None:
+            columnMap['data'] = \
+                self.convertToDB(obj.db_data, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'plugin_data'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBDeleteSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'delete_tbl'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            delete = DBDelete(what=what,
+                              objectId=objectId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            delete.db_action = action
+            delete.db_entity_id = entity_id
+            delete.db_entity_type = entity_type
+            delete.is_dirty = False
+            res[('delete', id)] = delete
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            what = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            objectId = self.convertFromDB(row[2], 'long', 'int')
+            parentObjId = self.convertFromDB(row[3], 'long', 'int')
+            parentObjType = self.convertFromDB(row[4], 'str', 'char(16)')
+            action = self.convertFromDB(row[5], 'long', 'int')
+            entity_id = self.convertFromDB(row[6], 'long', 'int')
+            entity_type = self.convertFromDB(row[7], 'str', 'char(16)')
+            
+            delete = DBDelete(what=what,
+                              objectId=objectId,
+                              parentObjId=parentObjId,
+                              parentObjType=parentObjType,
+                              id=id)
+            delete.db_action = action
+            delete.db_entity_id = entity_id
+            delete.db_entity_type = entity_type
+            delete.is_dirty = False
+            res[('delete', id)] = delete
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('action', obj.db_action) in all_objects:
+            p = all_objects[('action', obj.db_action)]
+            p.db_add_operation(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'what', 'object_id', 'par_obj_id', 'par_obj_type', 'action_id', 'entity_id', 'entity_type']
+        table = 'delete_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_what') and obj.db_what is not None:
+            columnMap['what'] = \
+                self.convertToDB(obj.db_what, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_objectId') and obj.db_objectId is not None:
+            columnMap['object_id'] = \
+                self.convertToDB(obj.db_objectId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjId') and obj.db_parentObjId is not None:
+            columnMap['par_obj_id'] = \
+                self.convertToDB(obj.db_parentObjId, 'long', 'int')
+        if hasattr(obj, 'db_parentObjType') and obj.db_parentObjType is not None:
+            columnMap['par_obj_type'] = \
+                self.convertToDB(obj.db_parentObjType, 'str', 'char(16)')
+        if hasattr(obj, 'db_action') and obj.db_action is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'delete_tbl'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBVistrailVariableSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'vistrail_variable'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
+        whereMap = global_props
+        orderBy = 'name'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            name = self.convertFromDB(row[0], 'str', 'varchar(255)')
+            uuid = self.convertFromDB(row[1], 'str', 'char(36)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            module = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[5], 'str', 'varchar(8191)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            vistrailVariable = DBVistrailVariable(uuid=uuid,
+                                                  package=package,
+                                                  module=module,
+                                                  namespace=namespace,
+                                                  value=value,
+                                                  name=name)
+            vistrailVariable.db_vistrail = vistrail
+            vistrailVariable.db_entity_id = entity_id
+            vistrailVariable.db_entity_type = entity_type
+            vistrailVariable.is_dirty = False
+            res[('vistrailVariable', name)] = vistrailVariable
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
+        whereMap = global_props
+        orderBy = 'name'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            name = self.convertFromDB(row[0], 'str', 'varchar(255)')
+            uuid = self.convertFromDB(row[1], 'str', 'char(36)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            module = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[5], 'str', 'varchar(8191)')
+            vistrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            vistrailVariable = DBVistrailVariable(uuid=uuid,
+                                                  package=package,
+                                                  module=module,
+                                                  namespace=namespace,
+                                                  value=value,
+                                                  name=name)
+            vistrailVariable.db_vistrail = vistrail
+            vistrailVariable.db_entity_id = entity_id
+            vistrailVariable.db_entity_type = entity_type
+            vistrailVariable.is_dirty = False
+            res[('vistrailVariable', name)] = vistrailVariable
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_vistrailVariable(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_name is not None:
+            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+            whereMap['name'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_uuid') and obj.db_uuid is not None:
+            columnMap['uuid'] = \
+                self.convertToDB(obj.db_uuid, 'str', 'char(36)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['name', 'uuid', 'package', 'module', 'namespace', 'value', 'parent_id', 'entity_id', 'entity_type']
+        table = 'vistrail_variable'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_name is not None:
+            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+            whereMap['name'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_uuid') and obj.db_uuid is not None:
+            columnMap['uuid'] = \
+                self.convertToDB(obj.db_uuid, 'str', 'char(36)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'vistrail_variable'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_name is not None:
+            keyStr = self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+            whereMap['name'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBModuleDescriptorSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'module_descriptor'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            base_descriptor_id = self.convertFromDB(row[6], 'long', 'int')
+            package = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            module_descriptor = DBModuleDescriptor(name=name,
+                                                   package=package,
+                                                   namespace=namespace,
+                                                   package_version=package_version,
+                                                   version=version,
+                                                   base_descriptor_id=base_descriptor_id,
+                                                   id=id)
+            module_descriptor.db_package = package
+            module_descriptor.db_entity_id = entity_id
+            module_descriptor.db_entity_type = entity_type
+            module_descriptor.is_dirty = False
+            res[('module_descriptor', id)] = module_descriptor
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package_version = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            base_descriptor_id = self.convertFromDB(row[6], 'long', 'int')
+            package = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            module_descriptor = DBModuleDescriptor(name=name,
+                                                   package=package,
+                                                   namespace=namespace,
+                                                   package_version=package_version,
+                                                   version=version,
+                                                   base_descriptor_id=base_descriptor_id,
+                                                   id=id)
+            module_descriptor.db_package = package
+            module_descriptor.db_entity_id = entity_id
+            module_descriptor.db_entity_type = entity_type
+            module_descriptor.is_dirty = False
+            res[('module_descriptor', id)] = module_descriptor
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('package', obj.db_package) in all_objects:
+            p = all_objects[('package', obj.db_package)]
+            p.db_add_module_descriptor(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package_version') and obj.db_package_version is not None:
+            columnMap['package_version'] = \
+                self.convertToDB(obj.db_package_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_base_descriptor_id') and obj.db_base_descriptor_id is not None:
+            columnMap['base_descriptor_id'] = \
+                self.convertToDB(obj.db_base_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_package, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'package', 'namespace', 'package_version', 'version', 'base_descriptor_id', 'parent_id', 'entity_id', 'entity_type']
+        table = 'module_descriptor'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package_version') and obj.db_package_version is not None:
+            columnMap['package_version'] = \
+                self.convertToDB(obj.db_package_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_base_descriptor_id') and obj.db_base_descriptor_id is not None:
+            columnMap['base_descriptor_id'] = \
+                self.convertToDB(obj.db_base_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_package, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_portSpecs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'module_descriptor'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBTagSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'tag'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            
+            tag = DBTag(name=name,
+                        id=id)
+            tag.db_vistrail = vistrail
+            tag.db_entity_id = entity_id
+            tag.db_entity_type = entity_type
+            tag.is_dirty = False
+            res[('tag', id)] = tag
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[2], 'long', 'int')
+            entity_id = self.convertFromDB(row[3], 'long', 'int')
+            entity_type = self.convertFromDB(row[4], 'str', 'char(16)')
+            
+            tag = DBTag(name=name,
+                        id=id)
+            tag.db_vistrail = vistrail
+            tag.db_entity_id = entity_id
+            tag.db_entity_type = entity_type
+            tag.is_dirty = False
+            res[('tag', id)] = tag
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_tag(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'parent_id', 'entity_id', 'entity_type']
+        table = 'tag'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'tag'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBPortSpecItemSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'port_spec_item'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            module = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            label = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            default = self.convertFromDB(row[6], 'str', 'varchar(4095)')
+            values = self.convertFromDB(row[7], 'str', 'mediumtext')
+            entry_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            portSpec = self.convertFromDB(row[9], 'long', 'int')
+            entity_id = self.convertFromDB(row[10], 'long', 'int')
+            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
+            
+            portSpecItem = DBPortSpecItem(pos=pos,
+                                          module=module,
+                                          package=package,
+                                          namespace=namespace,
+                                          label=label,
+                                          default=default,
+                                          values=values,
+                                          entry_type=entry_type,
+                                          id=id)
+            portSpecItem.db_portSpec = portSpec
+            portSpecItem.db_entity_id = entity_id
+            portSpecItem.db_entity_type = entity_type
+            portSpecItem.is_dirty = False
+            res[('portSpecItem', id)] = portSpecItem
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            pos = self.convertFromDB(row[1], 'long', 'int')
+            module = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            label = self.convertFromDB(row[5], 'str', 'varchar(4095)')
+            default = self.convertFromDB(row[6], 'str', 'varchar(4095)')
+            values = self.convertFromDB(row[7], 'str', 'mediumtext')
+            entry_type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            portSpec = self.convertFromDB(row[9], 'long', 'int')
+            entity_id = self.convertFromDB(row[10], 'long', 'int')
+            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
+            
+            portSpecItem = DBPortSpecItem(pos=pos,
+                                          module=module,
+                                          package=package,
+                                          namespace=namespace,
+                                          label=label,
+                                          default=default,
+                                          values=values,
+                                          entry_type=entry_type,
+                                          id=id)
+            portSpecItem.db_portSpec = portSpec
+            portSpecItem.db_entity_id = entity_id
+            portSpecItem.db_entity_type = entity_type
+            portSpecItem.is_dirty = False
+            res[('portSpecItem', id)] = portSpecItem
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('portSpec', obj.db_portSpec) in all_objects:
+            p = all_objects[('portSpec', obj.db_portSpec)]
+            p.db_add_portSpecItem(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_label') and obj.db_label is not None:
+            columnMap['label'] = \
+                self.convertToDB(obj.db_label, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_default') and obj.db_default is not None:
+            columnMap['_default'] = \
+                self.convertToDB(obj.db_default, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_values') and obj.db_values is not None:
+            columnMap['_values'] = \
+                self.convertToDB(obj.db_values, 'str', 'mediumtext')
+        if hasattr(obj, 'db_entry_type') and obj.db_entry_type is not None:
+            columnMap['entry_type'] = \
+                self.convertToDB(obj.db_entry_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_portSpec') and obj.db_portSpec is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_portSpec, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'pos', 'module', 'package', 'namespace', 'label', '_default', '_values', 'entry_type', 'parent_id', 'entity_id', 'entity_type']
+        table = 'port_spec_item'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_module') and obj.db_module is not None:
+            columnMap['module'] = \
+                self.convertToDB(obj.db_module, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_label') and obj.db_label is not None:
+            columnMap['label'] = \
+                self.convertToDB(obj.db_label, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_default') and obj.db_default is not None:
+            columnMap['_default'] = \
+                self.convertToDB(obj.db_default, 'str', 'varchar(4095)')
+        if hasattr(obj, 'db_values') and obj.db_values is not None:
+            columnMap['_values'] = \
+                self.convertToDB(obj.db_values, 'str', 'mediumtext')
+        if hasattr(obj, 'db_entry_type') and obj.db_entry_type is not None:
+            columnMap['entry_type'] = \
+                self.convertToDB(obj.db_entry_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_portSpec') and obj.db_portSpec is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_portSpec, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'port_spec_item'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBMashupComponentSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'mashup_component'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            vtid = self.convertFromDB(row[1], 'long', 'int')
+            vttype = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            vtparent_type = self.convertFromDB(row[3], 'str', 'char(32)')
+            vtparent_id = self.convertFromDB(row[4], 'long', 'int')
+            vtpos = self.convertFromDB(row[5], 'long', 'int')
+            vtmid = self.convertFromDB(row[6], 'long', 'int')
+            pos = self.convertFromDB(row[7], 'long', 'int')
+            type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[9], 'str', 'mediumtext')
+            minVal = self.convertFromDB(row[10], 'str', 'varchar(255)')
+            maxVal = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            stepSize = self.convertFromDB(row[12], 'str', 'varchar(255)')
+            strvaluelist = self.convertFromDB(row[13], 'str', 'mediumtext')
+            widget = self.convertFromDB(row[14], 'str', 'varchar(255)')
+            seq = self.convertFromDB(row[15], 'int', 'int')
+            parent = self.convertFromDB(row[16], 'str', 'varchar(255)')
+            mashup_alias = self.convertFromDB(row[17], 'long', 'int')
+            entity_id = self.convertFromDB(row[18], 'long', 'int')
+            entity_type = self.convertFromDB(row[19], 'str', 'char(16)')
+            
+            mashup_component = DBMashupComponent(vtid=vtid,
+                                                 vttype=vttype,
+                                                 vtparent_type=vtparent_type,
+                                                 vtparent_id=vtparent_id,
+                                                 vtpos=vtpos,
+                                                 vtmid=vtmid,
+                                                 pos=pos,
+                                                 type=type,
+                                                 val=val,
+                                                 minVal=minVal,
+                                                 maxVal=maxVal,
+                                                 stepSize=stepSize,
+                                                 strvaluelist=strvaluelist,
+                                                 widget=widget,
+                                                 seq=seq,
+                                                 parent=parent,
+                                                 id=id)
+            mashup_component.db_mashup_alias = mashup_alias
+            mashup_component.db_entity_id = entity_id
+            mashup_component.db_entity_type = entity_type
+            mashup_component.is_dirty = False
+            res[('mashup_component', id)] = mashup_component
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            vtid = self.convertFromDB(row[1], 'long', 'int')
+            vttype = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            vtparent_type = self.convertFromDB(row[3], 'str', 'char(32)')
+            vtparent_id = self.convertFromDB(row[4], 'long', 'int')
+            vtpos = self.convertFromDB(row[5], 'long', 'int')
+            vtmid = self.convertFromDB(row[6], 'long', 'int')
+            pos = self.convertFromDB(row[7], 'long', 'int')
+            type = self.convertFromDB(row[8], 'str', 'varchar(255)')
+            val = self.convertFromDB(row[9], 'str', 'mediumtext')
+            minVal = self.convertFromDB(row[10], 'str', 'varchar(255)')
+            maxVal = self.convertFromDB(row[11], 'str', 'varchar(255)')
+            stepSize = self.convertFromDB(row[12], 'str', 'varchar(255)')
+            strvaluelist = self.convertFromDB(row[13], 'str', 'mediumtext')
+            widget = self.convertFromDB(row[14], 'str', 'varchar(255)')
+            seq = self.convertFromDB(row[15], 'int', 'int')
+            parent = self.convertFromDB(row[16], 'str', 'varchar(255)')
+            mashup_alias = self.convertFromDB(row[17], 'long', 'int')
+            entity_id = self.convertFromDB(row[18], 'long', 'int')
+            entity_type = self.convertFromDB(row[19], 'str', 'char(16)')
+            
+            mashup_component = DBMashupComponent(vtid=vtid,
+                                                 vttype=vttype,
+                                                 vtparent_type=vtparent_type,
+                                                 vtparent_id=vtparent_id,
+                                                 vtpos=vtpos,
+                                                 vtmid=vtmid,
+                                                 pos=pos,
+                                                 type=type,
+                                                 val=val,
+                                                 minVal=minVal,
+                                                 maxVal=maxVal,
+                                                 stepSize=stepSize,
+                                                 strvaluelist=strvaluelist,
+                                                 widget=widget,
+                                                 seq=seq,
+                                                 parent=parent,
+                                                 id=id)
+            mashup_component.db_mashup_alias = mashup_alias
+            mashup_component.db_entity_id = entity_id
+            mashup_component.db_entity_type = entity_type
+            mashup_component.is_dirty = False
+            res[('mashup_component', id)] = mashup_component
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('mashup_alias', obj.db_mashup_alias) in all_objects:
+            p = all_objects[('mashup_alias', obj.db_mashup_alias)]
+            p.db_add_component(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_vttype') and obj.db_vttype is not None:
+            columnMap['vttype'] = \
+                self.convertToDB(obj.db_vttype, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtparent_type') and obj.db_vtparent_type is not None:
+            columnMap['vtparent_type'] = \
+                self.convertToDB(obj.db_vtparent_type, 'str', 'char(32)')
+        if hasattr(obj, 'db_vtparent_id') and obj.db_vtparent_id is not None:
+            columnMap['vtparent_id'] = \
+                self.convertToDB(obj.db_vtparent_id, 'long', 'int')
+        if hasattr(obj, 'db_vtpos') and obj.db_vtpos is not None:
+            columnMap['vtpos'] = \
+                self.convertToDB(obj.db_vtpos, 'long', 'int')
+        if hasattr(obj, 'db_vtmid') and obj.db_vtmid is not None:
+            columnMap['vtmid'] = \
+                self.convertToDB(obj.db_vtmid, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_minVal') and obj.db_minVal is not None:
+            columnMap['minVal'] = \
+                self.convertToDB(obj.db_minVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_maxVal') and obj.db_maxVal is not None:
+            columnMap['maxVal'] = \
+                self.convertToDB(obj.db_maxVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_stepSize') and obj.db_stepSize is not None:
+            columnMap['stepSize'] = \
+                self.convertToDB(obj.db_stepSize, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_strvaluelist') and obj.db_strvaluelist is not None:
+            columnMap['strvaluelist'] = \
+                self.convertToDB(obj.db_strvaluelist, 'str', 'mediumtext')
+        if hasattr(obj, 'db_widget') and obj.db_widget is not None:
+            columnMap['widget'] = \
+                self.convertToDB(obj.db_widget, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_seq') and obj.db_seq is not None:
+            columnMap['seq'] = \
+                self.convertToDB(obj.db_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent'] = \
+                self.convertToDB(obj.db_parent, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashup_alias') and obj.db_mashup_alias is not None:
+            columnMap['alias_id'] = \
+                self.convertToDB(obj.db_mashup_alias, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'vtid', 'vttype', 'vtparent_type', 'vtparent_id', 'vtpos', 'vtmid', 'pos', 'type', 'val', 'minVal', 'maxVal', 'stepSize', 'strvaluelist', 'widget', 'seq', 'parent', 'alias_id', 'entity_id', 'entity_type']
+        table = 'mashup_component'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_vttype') and obj.db_vttype is not None:
+            columnMap['vttype'] = \
+                self.convertToDB(obj.db_vttype, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtparent_type') and obj.db_vtparent_type is not None:
+            columnMap['vtparent_type'] = \
+                self.convertToDB(obj.db_vtparent_type, 'str', 'char(32)')
+        if hasattr(obj, 'db_vtparent_id') and obj.db_vtparent_id is not None:
+            columnMap['vtparent_id'] = \
+                self.convertToDB(obj.db_vtparent_id, 'long', 'int')
+        if hasattr(obj, 'db_vtpos') and obj.db_vtpos is not None:
+            columnMap['vtpos'] = \
+                self.convertToDB(obj.db_vtpos, 'long', 'int')
+        if hasattr(obj, 'db_vtmid') and obj.db_vtmid is not None:
+            columnMap['vtmid'] = \
+                self.convertToDB(obj.db_vtmid, 'long', 'int')
+        if hasattr(obj, 'db_pos') and obj.db_pos is not None:
+            columnMap['pos'] = \
+                self.convertToDB(obj.db_pos, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_val') and obj.db_val is not None:
+            columnMap['val'] = \
+                self.convertToDB(obj.db_val, 'str', 'mediumtext')
+        if hasattr(obj, 'db_minVal') and obj.db_minVal is not None:
+            columnMap['minVal'] = \
+                self.convertToDB(obj.db_minVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_maxVal') and obj.db_maxVal is not None:
+            columnMap['maxVal'] = \
+                self.convertToDB(obj.db_maxVal, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_stepSize') and obj.db_stepSize is not None:
+            columnMap['stepSize'] = \
+                self.convertToDB(obj.db_stepSize, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_strvaluelist') and obj.db_strvaluelist is not None:
+            columnMap['strvaluelist'] = \
+                self.convertToDB(obj.db_strvaluelist, 'str', 'mediumtext')
+        if hasattr(obj, 'db_widget') and obj.db_widget is not None:
+            columnMap['widget'] = \
+                self.convertToDB(obj.db_widget, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_seq') and obj.db_seq is not None:
+            columnMap['seq'] = \
+                self.convertToDB(obj.db_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent'] = \
+                self.convertToDB(obj.db_parent, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashup_alias') and obj.db_mashup_alias is not None:
+            columnMap['alias_id'] = \
+                self.convertToDB(obj.db_mashup_alias, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'mashup_component'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBMashupSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'mashup'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[2], 'long', 'int')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            vtid = self.convertFromDB(row[4], 'long', 'int')
+            layout = self.convertFromDB(row[5], 'str', 'mediumtext')
+            geometry = self.convertFromDB(row[6], 'str', 'mediumtext')
+            has_seq = self.convertFromDB(row[7], 'int', 'int')
+            parent = self.convertFromDB(row[8], 'long', 'int')
+            entity_id = self.convertFromDB(row[9], 'long', 'int')
+            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
+            
+            mashup = DBMashup(name=name,
+                              version=version,
+                              type=type,
+                              vtid=vtid,
+                              layout=layout,
+                              geometry=geometry,
+                              has_seq=has_seq,
+                              id=id)
+            mashup.db_parent = parent
+            mashup.db_entity_id = entity_id
+            mashup.db_entity_type = entity_type
+            mashup.is_dirty = False
+            res[('mashup', id)] = mashup
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            version = self.convertFromDB(row[2], 'long', 'int')
+            type = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            vtid = self.convertFromDB(row[4], 'long', 'int')
+            layout = self.convertFromDB(row[5], 'str', 'mediumtext')
+            geometry = self.convertFromDB(row[6], 'str', 'mediumtext')
+            has_seq = self.convertFromDB(row[7], 'int', 'int')
+            parent = self.convertFromDB(row[8], 'long', 'int')
+            entity_id = self.convertFromDB(row[9], 'long', 'int')
+            entity_type = self.convertFromDB(row[10], 'str', 'char(16)')
+            
+            mashup = DBMashup(name=name,
+                              version=version,
+                              type=type,
+                              vtid=vtid,
+                              layout=layout,
+                              geometry=geometry,
+                              has_seq=has_seq,
+                              id=id)
+            mashup.db_parent = parent
+            mashup.db_entity_id = entity_id
+            mashup.db_entity_type = entity_type
+            mashup.is_dirty = False
+            res[('mashup', id)] = mashup
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('mashup_action', obj.db_parent) in all_objects:
+            p = all_objects[('mashup_action', obj.db_parent)]
+            p.db_add_mashup(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'mediumtext')
+        if hasattr(obj, 'db_geometry') and obj.db_geometry is not None:
+            columnMap['geometry'] = \
+                self.convertToDB(obj.db_geometry, 'str', 'mediumtext')
+        if hasattr(obj, 'db_has_seq') and obj.db_has_seq is not None:
+            columnMap['has_seq'] = \
+                self.convertToDB(obj.db_has_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'version', 'type', 'vtid', 'layout', 'geometry', 'has_seq', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'long', 'int')
+        if hasattr(obj, 'db_type') and obj.db_type is not None:
+            columnMap['type'] = \
+                self.convertToDB(obj.db_type, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vtid') and obj.db_vtid is not None:
+            columnMap['vtid'] = \
+                self.convertToDB(obj.db_vtid, 'long', 'int')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'mediumtext')
+        if hasattr(obj, 'db_geometry') and obj.db_geometry is not None:
+            columnMap['geometry'] = \
+                self.convertToDB(obj.db_geometry, 'str', 'mediumtext')
+        if hasattr(obj, 'db_has_seq') and obj.db_has_seq is not None:
+            columnMap['has_seq'] = \
+                self.convertToDB(obj.db_has_seq, 'int', 'int')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_aliases:
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'mashup'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBMachineSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'machine'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            os = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            architecture = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            processor = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ram = self.convertFromDB(row[5], 'int', 'bigint')
+            vistrailId = self.convertFromDB(row[6], 'long', 'int')
+            workflow_exec = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            machine = DBMachine(name=name,
+                                os=os,
+                                architecture=architecture,
+                                processor=processor,
+                                ram=ram,
+                                id=id)
+            machine.db_vistrailId = vistrailId
+            machine.db_workflow_exec = workflow_exec
+            machine.db_entity_id = entity_id
+            machine.db_entity_type = entity_type
+            machine.is_dirty = False
+            res[('machine', id)] = machine
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            os = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            architecture = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            processor = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            ram = self.convertFromDB(row[5], 'int', 'bigint')
+            vistrailId = self.convertFromDB(row[6], 'long', 'int')
+            workflow_exec = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            machine = DBMachine(name=name,
+                                os=os,
+                                architecture=architecture,
+                                processor=processor,
+                                ram=ram,
+                                id=id)
+            machine.db_vistrailId = vistrailId
+            machine.db_workflow_exec = workflow_exec
+            machine.db_entity_id = entity_id
+            machine.db_entity_type = entity_type
+            machine.is_dirty = False
+            res[('machine', id)] = machine
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('workflow_exec', obj.db_workflow_exec) in all_objects:
+            p = all_objects[('workflow_exec', obj.db_workflow_exec)]
+            p.db_add_machine(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_os') and obj.db_os is not None:
+            columnMap['os'] = \
+                self.convertToDB(obj.db_os, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_architecture') and obj.db_architecture is not None:
+            columnMap['architecture'] = \
+                self.convertToDB(obj.db_architecture, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_processor') and obj.db_processor is not None:
+            columnMap['processor'] = \
+                self.convertToDB(obj.db_processor, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ram') and obj.db_ram is not None:
+            columnMap['ram'] = \
+                self.convertToDB(obj.db_ram, 'int', 'bigint')
+        if hasattr(obj, 'db_vistrailId') and obj.db_vistrailId is not None:
+            columnMap['vt_id'] = \
+                self.convertToDB(obj.db_vistrailId, 'long', 'int')
+        if hasattr(obj, 'db_workflow_exec') and obj.db_workflow_exec is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_workflow_exec, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'os', 'architecture', 'processor', 'ram', 'vt_id', 'log_id', 'entity_id', 'entity_type']
+        table = 'machine'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_os') and obj.db_os is not None:
+            columnMap['os'] = \
+                self.convertToDB(obj.db_os, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_architecture') and obj.db_architecture is not None:
+            columnMap['architecture'] = \
+                self.convertToDB(obj.db_architecture, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_processor') and obj.db_processor is not None:
+            columnMap['processor'] = \
+                self.convertToDB(obj.db_processor, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_ram') and obj.db_ram is not None:
+            columnMap['ram'] = \
+                self.convertToDB(obj.db_ram, 'int', 'bigint')
+        if hasattr(obj, 'db_vistrailId') and obj.db_vistrailId is not None:
+            columnMap['vt_id'] = \
+                self.convertToDB(obj.db_vistrailId, 'long', 'int')
+        if hasattr(obj, 'db_workflow_exec') and obj.db_workflow_exec is not None:
+            columnMap['log_id'] = \
+                self.convertToDB(obj.db_workflow_exec, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'machine'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBOtherSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'other'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            other = DBOther(key=key,
+                            value=value,
+                            id=id)
+            other.db_parentType = parentType
+            other.db_entity_id = entity_id
+            other.db_entity_type = entity_type
+            other.db_parent = parent
+            other.is_dirty = False
+            res[('other', id)] = other
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            other = DBOther(key=key,
+                            value=value,
+                            id=id)
+            other.db_parentType = parentType
+            other.db_entity_id = entity_id
+            other.db_entity_type = entity_type
+            other.db_parent = parent
+            other.is_dirty = False
+            res[('other', id)] = other
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_other(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['okey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'okey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'other'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['okey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'other'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBAbstractionSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'abstraction'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            internal_version = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            parent = self.convertFromDB(row[10], 'long', 'long')
+            
+            abstraction = DBAbstraction(cache=cache,
+                                        name=name,
+                                        namespace=namespace,
+                                        package=package,
+                                        version=version,
+                                        internal_version=internal_version,
+                                        id=id)
+            abstraction.db_parentType = parentType
+            abstraction.db_entity_id = entity_id
+            abstraction.db_entity_type = entity_type
+            abstraction.db_parent = parent
+            abstraction.is_dirty = False
+            res[('abstraction', id)] = abstraction
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            cache = self.convertFromDB(row[1], 'int', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            namespace = self.convertFromDB(row[3], 'str', 'varchar(255)')
+            package = self.convertFromDB(row[4], 'str', 'varchar(511)')
+            version = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            internal_version = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            parentType = self.convertFromDB(row[7], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            parent = self.convertFromDB(row[10], 'long', 'long')
+            
+            abstraction = DBAbstraction(cache=cache,
+                                        name=name,
+                                        namespace=namespace,
+                                        package=package,
+                                        version=version,
+                                        internal_version=internal_version,
+                                        id=id)
+            abstraction.db_parentType = parentType
+            abstraction.db_entity_id = entity_id
+            abstraction.db_entity_type = entity_type
+            abstraction.db_parent = parent
+            abstraction.is_dirty = False
+            res[('abstraction', id)] = abstraction
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_module(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_internal_version') and obj.db_internal_version is not None:
+            columnMap['internal_version'] = \
+                self.convertToDB(obj.db_internal_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'cache', 'name', 'namespace', 'package', 'version', 'internal_version', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'abstraction'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_cache') and obj.db_cache is not None:
+            columnMap['cache'] = \
+                self.convertToDB(obj.db_cache, 'int', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_namespace') and obj.db_namespace is not None:
+            columnMap['namespace'] = \
+                self.convertToDB(obj.db_namespace, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_package') and obj.db_package is not None:
+            columnMap['package'] = \
+                self.convertToDB(obj.db_package, 'str', 'varchar(511)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_internal_version') and obj.db_internal_version is not None:
+            columnMap['internal_version'] = \
+                self.convertToDB(obj.db_internal_version, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        if obj.db_location is not None:
+            child = obj.db_location
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_functions:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_controlParameters:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'abstraction'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBMashuptrailSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'mashuptrail'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'char(36)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            vtVersion = self.convertFromDB(row[3], 'long', 'int')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            
+            mashuptrail = DBMashuptrail(name=name,
+                                        version=version,
+                                        vtVersion=vtVersion,
+                                        last_modified=last_modified,
+                                        id=id)
+            mashuptrail.db_entity_type = entity_type
+            mashuptrail.is_dirty = False
+            res[('mashuptrail', id)] = mashuptrail
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            name = self.convertFromDB(row[1], 'str', 'char(36)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            vtVersion = self.convertFromDB(row[3], 'long', 'int')
+            last_modified = self.convertFromDB(row[4], 'datetime', 'datetime')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            
+            mashuptrail = DBMashuptrail(name=name,
+                                        version=version,
+                                        vtVersion=vtVersion,
+                                        last_modified=last_modified,
+                                        id=id)
+            mashuptrail.db_entity_type = entity_type
+            mashuptrail.is_dirty = False
+            res[('mashuptrail', id)] = mashuptrail
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        pass
+    
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'char(36)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_vtVersion') and obj.db_vtVersion is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vtVersion, 'long', 'int')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'name', 'version', 'vt_version', 'last_modified', 'entity_type']
+        table = 'mashuptrail'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'char(36)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_vtVersion') and obj.db_vtVersion is not None:
+            columnMap['vt_version'] = \
+                self.convertToDB(obj.db_vtVersion, 'long', 'int')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_actions:
+            child.db_mashuptrail = obj.db_id
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_actionAnnotations:
+            child.db_mashuptrail = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'mashuptrail'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBRegistrySQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'registry'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            root_descriptor_id = self.convertFromDB(row[3], 'long', 'int')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            
+            registry = DBRegistry(entity_type=entity_type,
+                                  version=version,
+                                  root_descriptor_id=root_descriptor_id,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            registry.is_dirty = False
+            res[('registry', id)] = registry
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            global_props['entity_id'] = self.convertToDB(id, 'long', 'int')
+            entity_type = self.convertFromDB(row[1], 'str', 'char(16)')
+            global_props['entity_type'] = self.convertToDB(entity_type, 'str', 'char(16)')
+            version = self.convertFromDB(row[2], 'str', 'char(16)')
+            root_descriptor_id = self.convertFromDB(row[3], 'long', 'int')
+            name = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            last_modified = self.convertFromDB(row[5], 'datetime', 'datetime')
+            
+            registry = DBRegistry(entity_type=entity_type,
+                                  version=version,
+                                  root_descriptor_id=root_descriptor_id,
+                                  name=name,
+                                  last_modified=last_modified,
+                                  id=id)
+            registry.is_dirty = False
+            res[('registry', id)] = registry
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        pass
+    
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_root_descriptor_id') and obj.db_root_descriptor_id is not None:
+            columnMap['root_descriptor_id'] = \
+                self.convertToDB(obj.db_root_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'entity_type', 'version', 'root_descriptor_id', 'name', 'last_modified']
+        table = 'registry'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_version') and obj.db_version is not None:
+            columnMap['version'] = \
+                self.convertToDB(obj.db_version, 'str', 'char(16)')
+        if hasattr(obj, 'db_root_descriptor_id') and obj.db_root_descriptor_id is not None:
+            columnMap['root_descriptor_id'] = \
+                self.convertToDB(obj.db_root_descriptor_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_last_modified') and obj.db_last_modified is not None:
+            columnMap['last_modified'] = \
+                self.convertToDB(obj.db_last_modified, 'datetime', 'datetime')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        if obj.db_id is None:
+            obj.db_id = lastId
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            global_props['entity_type'] = self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            global_props['entity_id'] = self.convertToDB(obj.db_id, 'long', 'int')
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_packages:
+            child.db_registry = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'registry'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBAnnotationSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'annotation'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'mediumtext')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            annotation = DBAnnotation(key=key,
+                                      value=value,
+                                      id=id)
+            annotation.db_parentType = parentType
+            annotation.db_entity_id = entity_id
+            annotation.db_entity_type = entity_type
+            annotation.db_parent = parent
+            annotation.is_dirty = False
+            res[('annotation', id)] = annotation
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'mediumtext')
+            parentType = self.convertFromDB(row[3], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[4], 'long', 'int')
+            entity_type = self.convertFromDB(row[5], 'str', 'char(16)')
+            parent = self.convertFromDB(row[6], 'long', 'long')
+            
+            annotation = DBAnnotation(key=key,
+                                      value=value,
+                                      id=id)
+            annotation.db_parentType = parentType
+            annotation.db_entity_id = entity_id
+            annotation.db_entity_type = entity_type
+            annotation.db_parent = parent
+            annotation.is_dirty = False
+            res[('annotation', id)] = annotation
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'vistrail':
+            p = all_objects[('vistrail', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'workflow':
+            p = all_objects[('workflow', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'module':
+            p = all_objects[('module', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'module_exec':
+            p = all_objects[('module_exec', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'add':
+            p = all_objects[('add', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'change':
+            p = all_objects[('change', obj.db_parent)]
+            p.db_add_data(obj)
+        elif obj.db_parentType == 'action':
+            p = all_objects[('action', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'abstraction':
+            p = all_objects[('abstraction', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'mashuptrail':
+            p = all_objects[('mashuptrail', obj.db_parent)]
+            p.db_add_annotation(obj)
+        elif obj.db_parentType == 'group':
+            p = all_objects[('group', obj.db_parent)]
+            p.db_add_annotation(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'akey', 'value', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'mediumtext')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBParameterExplorationSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'parameter_exploration'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            action_id = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            date = self.convertFromDB(row[3], 'datetime', 'datetime')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            dims = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            layout = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            parameter_exploration = DBParameterExploration(action_id=action_id,
+                                                           name=name,
+                                                           date=date,
+                                                           user=user,
+                                                           dims=dims,
+                                                           layout=layout,
+                                                           id=id)
+            parameter_exploration.db_vistrail = vistrail
+            parameter_exploration.db_entity_id = entity_id
+            parameter_exploration.db_entity_type = entity_type
+            parameter_exploration.is_dirty = False
+            res[('parameter_exploration', id)] = parameter_exploration
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            action_id = self.convertFromDB(row[1], 'long', 'int')
+            name = self.convertFromDB(row[2], 'str', 'varchar(255)')
+            date = self.convertFromDB(row[3], 'datetime', 'datetime')
+            user = self.convertFromDB(row[4], 'str', 'varchar(255)')
+            dims = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            layout = self.convertFromDB(row[6], 'str', 'varchar(255)')
+            vistrail = self.convertFromDB(row[7], 'long', 'int')
+            entity_id = self.convertFromDB(row[8], 'long', 'int')
+            entity_type = self.convertFromDB(row[9], 'str', 'char(16)')
+            
+            parameter_exploration = DBParameterExploration(action_id=action_id,
+                                                           name=name,
+                                                           date=date,
+                                                           user=user,
+                                                           dims=dims,
+                                                           layout=layout,
+                                                           id=id)
+            parameter_exploration.db_vistrail = vistrail
+            parameter_exploration.db_entity_id = entity_id
+            parameter_exploration.db_entity_type = entity_type
+            parameter_exploration.is_dirty = False
+            res[('parameter_exploration', id)] = parameter_exploration
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('vistrail', obj.db_vistrail) in all_objects:
+            p = all_objects[('vistrail', obj.db_vistrail)]
+            p.db_add_parameter_exploration(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_dims') and obj.db_dims is not None:
+            columnMap['dims'] = \
+                self.convertToDB(obj.db_dims, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'action_id', 'name', 'date', 'user', 'dims', 'layout', 'parent_id', 'entity_id', 'entity_type']
+        table = 'parameter_exploration'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_name') and obj.db_name is not None:
+            columnMap['name'] = \
+                self.convertToDB(obj.db_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_dims') and obj.db_dims is not None:
+            columnMap['dims'] = \
+                self.convertToDB(obj.db_dims, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_layout') and obj.db_layout is not None:
+            columnMap['layout'] = \
+                self.convertToDB(obj.db_layout, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_vistrail') and obj.db_vistrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_vistrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_functions:
+            child.db_parameter_exploration = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'parameter_exploration'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBMashupActionAnnotationSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'mashup_action_annotation'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            mashup_actionAnnotation = DBMashupActionAnnotation(key=key,
+                                                               value=value,
+                                                               action_id=action_id,
+                                                               date=date,
+                                                               user=user,
+                                                               id=id)
+            mashup_actionAnnotation.db_mashuptrail = mashuptrail
+            mashup_actionAnnotation.db_entity_id = entity_id
+            mashup_actionAnnotation.db_entity_type = entity_type
+            mashup_actionAnnotation.is_dirty = False
+            res[('mashup_actionAnnotation', id)] = mashup_actionAnnotation
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            key = self.convertFromDB(row[1], 'str', 'varchar(255)')
+            value = self.convertFromDB(row[2], 'str', 'varchar(8191)')
+            action_id = self.convertFromDB(row[3], 'long', 'int')
+            date = self.convertFromDB(row[4], 'datetime', 'datetime')
+            user = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            mashuptrail = self.convertFromDB(row[6], 'long', 'int')
+            entity_id = self.convertFromDB(row[7], 'long', 'int')
+            entity_type = self.convertFromDB(row[8], 'str', 'char(16)')
+            
+            mashup_actionAnnotation = DBMashupActionAnnotation(key=key,
+                                                               value=value,
+                                                               action_id=action_id,
+                                                               date=date,
+                                                               user=user,
+                                                               id=id)
+            mashup_actionAnnotation.db_mashuptrail = mashuptrail
+            mashup_actionAnnotation.db_entity_id = entity_id
+            mashup_actionAnnotation.db_entity_type = entity_type
+            mashup_actionAnnotation.is_dirty = False
+            res[('mashup_actionAnnotation', id)] = mashup_actionAnnotation
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if ('mashuptrail', obj.db_mashuptrail) in all_objects:
+            p = all_objects[('mashuptrail', obj.db_mashuptrail)]
+            p.db_add_actionAnnotation(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'akey', 'value', 'action_id', 'date', 'user', 'parent_id', 'entity_id', 'entity_type']
+        table = 'mashup_action_annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_key') and obj.db_key is not None:
+            columnMap['akey'] = \
+                self.convertToDB(obj.db_key, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_value') and obj.db_value is not None:
+            columnMap['value'] = \
+                self.convertToDB(obj.db_value, 'str', 'varchar(8191)')
+        if hasattr(obj, 'db_action_id') and obj.db_action_id is not None:
+            columnMap['action_id'] = \
+                self.convertToDB(obj.db_action_id, 'long', 'int')
+        if hasattr(obj, 'db_date') and obj.db_date is not None:
+            columnMap['date'] = \
+                self.convertToDB(obj.db_date, 'datetime', 'datetime')
+        if hasattr(obj, 'db_user') and obj.db_user is not None:
+            columnMap['user'] = \
+                self.convertToDB(obj.db_user, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_mashuptrail') and obj.db_mashuptrail is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_mashuptrail, 'long', 'int')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        pass
+    
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'mashup_action_annotation'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+class DBModuleExecSQLDAOBase(SQLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+        self.table = 'module_exec'
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def get_sql_columns(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'module_name', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module_exec'
+        whereMap = global_props
+        orderBy = 'id'
+
+        dbCommand = self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+        data = self.executeSQL(db, dbCommand, True)
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            cached = self.convertFromDB(row[3], 'int', 'int')
+            module_id = self.convertFromDB(row[4], 'long', 'int')
+            module_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            completed = self.convertFromDB(row[6], 'int', 'int')
+            error = self.convertFromDB(row[7], 'str', 'varchar(1023)')
+            machine_id = self.convertFromDB(row[8], 'long', 'int')
+            parentType = self.convertFromDB(row[9], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[10], 'long', 'int')
+            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
+            parent = self.convertFromDB(row[12], 'long', 'long')
+            
+            module_exec = DBModuleExec(ts_start=ts_start,
+                                       ts_end=ts_end,
+                                       cached=cached,
+                                       module_id=module_id,
+                                       module_name=module_name,
+                                       completed=completed,
+                                       error=error,
+                                       machine_id=machine_id,
+                                       id=id)
+            module_exec.db_parentType = parentType
+            module_exec.db_entity_id = entity_id
+            module_exec.db_entity_type = entity_type
+            module_exec.db_parent = parent
+            module_exec.is_dirty = False
+            res[('module_exec', id)] = module_exec
+        return res
+
+    def get_sql_select(self, db, global_props,lock=False):
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'module_name', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module_exec'
+        whereMap = global_props
+        orderBy = 'id'
+        return self.createSQLSelect(table, columns, whereMap, orderBy, lock)
+
+    def process_sql_columns(self, data, global_props):
+        res = {}
+        for row in data:
+            id = self.convertFromDB(row[0], 'long', 'int')
+            ts_start = self.convertFromDB(row[1], 'datetime', 'datetime')
+            ts_end = self.convertFromDB(row[2], 'datetime', 'datetime')
+            cached = self.convertFromDB(row[3], 'int', 'int')
+            module_id = self.convertFromDB(row[4], 'long', 'int')
+            module_name = self.convertFromDB(row[5], 'str', 'varchar(255)')
+            completed = self.convertFromDB(row[6], 'int', 'int')
+            error = self.convertFromDB(row[7], 'str', 'varchar(1023)')
+            machine_id = self.convertFromDB(row[8], 'long', 'int')
+            parentType = self.convertFromDB(row[9], 'str', 'char(32)')
+            entity_id = self.convertFromDB(row[10], 'long', 'int')
+            entity_type = self.convertFromDB(row[11], 'str', 'char(16)')
+            parent = self.convertFromDB(row[12], 'long', 'long')
+            
+            module_exec = DBModuleExec(ts_start=ts_start,
+                                       ts_end=ts_end,
+                                       cached=cached,
+                                       module_id=module_id,
+                                       module_name=module_name,
+                                       completed=completed,
+                                       error=error,
+                                       machine_id=machine_id,
+                                       id=id)
+            module_exec.db_parentType = parentType
+            module_exec.db_entity_id = entity_id
+            module_exec.db_entity_type = entity_type
+            module_exec.db_parent = parent
+            module_exec.is_dirty = False
+            res[('module_exec', id)] = module_exec
+        return res
+
+    def from_sql_fast(self, obj, all_objects):
+        if obj.db_parentType == 'workflow_exec':
+            p = all_objects[('workflow_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'group_exec':
+            p = all_objects[('group_exec', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        elif obj.db_parentType == 'loop_iteration':
+            p = all_objects[('loop_iteration', obj.db_parent)]
+            p.db_add_item_exec(obj)
+        
+    def set_sql_columns(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'module_name', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
+            columnMap['cached'] = \
+                self.convertToDB(obj.db_cached, 'int', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_module_name') and obj.db_module_name is not None:
+            columnMap['module_name'] = \
+                self.convertToDB(obj.db_module_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
+            columnMap['machine_id'] = \
+                self.convertToDB(obj.db_machine_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        lastId = self.executeSQL(db, dbCommand, False)
+        
+    def set_sql_command(self, db, obj, global_props, do_copy=True):
+        if not do_copy and not obj.is_dirty:
+            return None
+        columns = ['id', 'ts_start', 'ts_end', 'cached', 'module_id', 'module_name', 'completed', 'error', 'machine_id', 'parent_type', 'entity_id', 'entity_type', 'parent_id']
+        table = 'module_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        columnMap = {}
+        if hasattr(obj, 'db_id') and obj.db_id is not None:
+            columnMap['id'] = \
+                self.convertToDB(obj.db_id, 'long', 'int')
+        if hasattr(obj, 'db_ts_start') and obj.db_ts_start is not None:
+            columnMap['ts_start'] = \
+                self.convertToDB(obj.db_ts_start, 'datetime', 'datetime')
+        if hasattr(obj, 'db_ts_end') and obj.db_ts_end is not None:
+            columnMap['ts_end'] = \
+                self.convertToDB(obj.db_ts_end, 'datetime', 'datetime')
+        if hasattr(obj, 'db_cached') and obj.db_cached is not None:
+            columnMap['cached'] = \
+                self.convertToDB(obj.db_cached, 'int', 'int')
+        if hasattr(obj, 'db_module_id') and obj.db_module_id is not None:
+            columnMap['module_id'] = \
+                self.convertToDB(obj.db_module_id, 'long', 'int')
+        if hasattr(obj, 'db_module_name') and obj.db_module_name is not None:
+            columnMap['module_name'] = \
+                self.convertToDB(obj.db_module_name, 'str', 'varchar(255)')
+        if hasattr(obj, 'db_completed') and obj.db_completed is not None:
+            columnMap['completed'] = \
+                self.convertToDB(obj.db_completed, 'int', 'int')
+        if hasattr(obj, 'db_error') and obj.db_error is not None:
+            columnMap['error'] = \
+                self.convertToDB(obj.db_error, 'str', 'varchar(1023)')
+        if hasattr(obj, 'db_machine_id') and obj.db_machine_id is not None:
+            columnMap['machine_id'] = \
+                self.convertToDB(obj.db_machine_id, 'long', 'int')
+        if hasattr(obj, 'db_parentType') and obj.db_parentType is not None:
+            columnMap['parent_type'] = \
+                self.convertToDB(obj.db_parentType, 'str', 'char(32)')
+        if hasattr(obj, 'db_entity_id') and obj.db_entity_id is not None:
+            columnMap['entity_id'] = \
+                self.convertToDB(obj.db_entity_id, 'long', 'int')
+        if hasattr(obj, 'db_entity_type') and obj.db_entity_type is not None:
+            columnMap['entity_type'] = \
+                self.convertToDB(obj.db_entity_type, 'str', 'char(16)')
+        if hasattr(obj, 'db_parent') and obj.db_parent is not None:
+            columnMap['parent_id'] = \
+                self.convertToDB(obj.db_parent, 'long', 'long')
+        columnMap.update(global_props)
+
+        if obj.is_new or do_copy:
+            dbCommand = self.createSQLInsert(table, columnMap)
+        else:
+            dbCommand = self.createSQLUpdate(table, columnMap, whereMap)
+        return dbCommand
+
+    def set_sql_process(self, obj, global_props, lastId):
+        pass
+
+    def to_sql_fast(self, obj, do_copy=True):
+        for child in obj.db_annotations:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        for child in obj.db_loop_execs:
+            child.db_parentType = obj.vtType
+            child.db_parent = obj.db_id
+        
+    def delete_sql_column(self, db, obj, global_props):
+        table = 'module_exec'
+        whereMap = {}
+        whereMap.update(global_props)
+        if obj.db_id is not None:
+            keyStr = self.convertToDB(obj.db_id, 'long', 'int')
+            whereMap['id'] = keyStr
+        dbCommand = self.createSQLDelete(table, whereMap)
+        self.executeSQL(db, dbCommand, False)
+
+"""generated automatically by auto_dao.py"""
+
+class SQLDAOListBase(dict):
+
+    def __init__(self, daos=None):
+        if daos is not None:
+            dict.update(self, daos)
+
+        if 'mashup_alias' not in self:
+            self['mashup_alias'] = DBMashupAliasSQLDAOBase(self)
+        if 'group' not in self:
+            self['group'] = DBGroupSQLDAOBase(self)
+        if 'add' not in self:
+            self['add'] = DBAddSQLDAOBase(self)
+        if 'group_exec' not in self:
+            self['group_exec'] = DBGroupExecSQLDAOBase(self)
+        if 'parameter' not in self:
+            self['parameter'] = DBParameterSQLDAOBase(self)
+        if 'vistrail' not in self:
+            self['vistrail'] = DBVistrailSQLDAOBase(self)
+        if 'module' not in self:
+            self['module'] = DBModuleSQLDAOBase(self)
+        if 'port' not in self:
+            self['port'] = DBPortSQLDAOBase(self)
+        if 'pe_function' not in self:
+            self['pe_function'] = DBPEFunctionSQLDAOBase(self)
+        if 'workflow' not in self:
+            self['workflow'] = DBWorkflowSQLDAOBase(self)
+        if 'mashup_action' not in self:
+            self['mashup_action'] = DBMashupActionSQLDAOBase(self)
+        if 'change' not in self:
+            self['change'] = DBChangeSQLDAOBase(self)
+        if 'package' not in self:
+            self['package'] = DBPackageSQLDAOBase(self)
+        if 'loop_exec' not in self:
+            self['loop_exec'] = DBLoopExecSQLDAOBase(self)
+        if 'connection' not in self:
+            self['connection'] = DBConnectionSQLDAOBase(self)
+        if 'action' not in self:
+            self['action'] = DBActionSQLDAOBase(self)
+        if 'portSpec' not in self:
+            self['portSpec'] = DBPortSpecSQLDAOBase(self)
+        if 'log' not in self:
+            self['log'] = DBLogSQLDAOBase(self)
+        if 'loop_iteration' not in self:
+            self['loop_iteration'] = DBLoopIterationSQLDAOBase(self)
+        if 'pe_parameter' not in self:
+            self['pe_parameter'] = DBPEParameterSQLDAOBase(self)
+        if 'workflow_exec' not in self:
+            self['workflow_exec'] = DBWorkflowExecSQLDAOBase(self)
+        if 'location' not in self:
+            self['location'] = DBLocationSQLDAOBase(self)
+        if 'function' not in self:
+            self['function'] = DBFunctionSQLDAOBase(self)
+        if 'actionAnnotation' not in self:
+            self['actionAnnotation'] = DBActionAnnotationSQLDAOBase(self)
+        if 'controlParameter' not in self:
+            self['controlParameter'] = DBControlParameterSQLDAOBase(self)
+        if 'plugin_data' not in self:
+            self['plugin_data'] = DBPluginDataSQLDAOBase(self)
+        if 'delete' not in self:
+            self['delete'] = DBDeleteSQLDAOBase(self)
+        if 'vistrailVariable' not in self:
+            self['vistrailVariable'] = DBVistrailVariableSQLDAOBase(self)
+        if 'module_descriptor' not in self:
+            self['module_descriptor'] = DBModuleDescriptorSQLDAOBase(self)
+        if 'tag' not in self:
+            self['tag'] = DBTagSQLDAOBase(self)
+        if 'portSpecItem' not in self:
+            self['portSpecItem'] = DBPortSpecItemSQLDAOBase(self)
+        if 'mashup_component' not in self:
+            self['mashup_component'] = DBMashupComponentSQLDAOBase(self)
+        if 'mashup' not in self:
+            self['mashup'] = DBMashupSQLDAOBase(self)
+        if 'machine' not in self:
+            self['machine'] = DBMachineSQLDAOBase(self)
+        if 'other' not in self:
+            self['other'] = DBOtherSQLDAOBase(self)
+        if 'abstraction' not in self:
+            self['abstraction'] = DBAbstractionSQLDAOBase(self)
+        if 'mashuptrail' not in self:
+            self['mashuptrail'] = DBMashuptrailSQLDAOBase(self)
+        if 'registry' not in self:
+            self['registry'] = DBRegistrySQLDAOBase(self)
+        if 'annotation' not in self:
+            self['annotation'] = DBAnnotationSQLDAOBase(self)
+        if 'parameter_exploration' not in self:
+            self['parameter_exploration'] = DBParameterExplorationSQLDAOBase(self)
+        if 'mashup_actionAnnotation' not in self:
+            self['mashup_actionAnnotation'] = DBMashupActionAnnotationSQLDAOBase(self)
+        if 'module_exec' not in self:
+            self['module_exec'] = DBModuleExecSQLDAOBase(self)
diff --git a/vistrails/db/versions/v1_0_4/persistence/sql/sql_dao.py b/vistrails/db/versions/v1_0_4/persistence/sql/sql_dao.py
new file mode 100644
index 0000000..9eb069d
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/sql/sql_dao.py
@@ -0,0 +1,262 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from datetime import date, datetime
+
+from vistrails.core import debug
+from vistrails.core.system import strftime, time_strptime
+from vistrails.db import VistrailsDBException
+from vistrails.db.services.io import get_db_lib
+
+class SQLDAO:
+    def __init__(self):
+        pass
+
+    def convertFromDB(self, value, type, db_type):
+        if value is not None:
+            if type == 'str':
+                return str(value)
+            elif type == 'long':
+                return long(value)
+            elif type == 'float':
+                return float(value)
+            elif type == 'int':
+                return int(value)
+            elif type == 'date':
+                if db_type == 'date':
+                    return value
+                else:
+                    return date(*time_strptime(str(value), '%Y-%m-%d')[0:3])
+            elif type == 'datetime':
+                if db_type == 'datetime':
+                    return value
+                else:
+                    return datetime(*time_strptime(str(value),
+                                                   '%Y-%m-%d %H:%M:%S')[0:6])
+        return None
+
+    def convertWarning(self, before, after, _from, to):
+        text = ["Value truncated when saving to database",
+                "%s truncated to %s\nwhile converting '%s' to '%s'"]
+        debug.warning(text[0], text[1] % (before, after, _from, to))
+
+    def convertToDB(self, value, type, db_type):
+        if value is not None:
+            if type == 'str':
+                value = str(value)
+                if db_type.startswith('varchar'):
+                    try:
+                        length = int(db_type[8:-1])
+                        if len(value) > length:
+                            self.convertWarning(value, value[:length],
+                                                type, db_type)
+                            value = value[:length]
+                    except Exception, e:
+                        pass
+                if db_type.startswith('char'):
+                    try:
+                        length = int(db_type[5:-1])
+                        if len(value) > length:
+                            self.convertWarning(value, value[:length],
+                                                type, db_type)
+                            value = value[:length]
+                    except Exception, e:
+                        pass
+                # return "'" + str(value).replace("'", "''") + "'"
+                return value
+            elif type == 'long':
+                return str(value)
+            elif type == 'float':
+                # necessary to avoid conversion warnings in MySQL
+                if db_type.startswith('DECIMAL'):
+                    try:
+                        value="%%.%sf"%str(db_type[8:-1].split(',')[1])%value
+                    except Exception, e:
+                        pass
+                return str(value)
+            elif type == 'int':
+                # note: on 64-bit machines int:s are 64-bit
+                MIN_INT = -2147483648
+                MAX_INT =  2147483647
+                if db_type == 'int':
+                    if int(value) < MIN_INT:
+                        self.convertWarning(value, MIN_INT, type, db_type)
+                        value = MIN_INT
+                    if int(value) > MAX_INT:
+                        self.convertWarning(value, MAX_INT, type, db_type)
+                        value = MAX_INT
+                return str(value)
+            elif type == 'date':
+                return value.isoformat()
+            elif type == 'datetime':
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
+            else:
+                return str(value)
+
+        return None
+
+    def createSQLSelect(self, table, columns, whereMap, orderBy=None, 
+                        forUpdate=False):
+        columnStr = ', '.join(columns)
+        whereStr = ''
+        whereClause = ''
+        values = []
+        for column, value in whereMap.iteritems():
+            whereStr += '%s%s = %%s' % \
+                        (whereClause, column)
+            values.append(value)
+            whereClause = ' AND '
+        dbCommand = """SELECT %s FROM %s WHERE %s""" % \
+                    (columnStr, table, whereStr)
+        if orderBy is not None:
+            dbCommand += " ORDER BY " + orderBy
+        if forUpdate:
+            dbCommand += " FOR UPDATE"
+        dbCommand += ";"
+        return (dbCommand, tuple(values))
+
+    def createSQLInsert(self, table, columnMap):
+        columns = []
+        values = []
+        for column, value in columnMap.iteritems():
+            if value is None:
+                value = 'NULL'
+            columns.append(column)
+            values.append(value)
+        columnStr = ', '.join(columns)
+        # valueStr = '%s, '.join(values)
+        valueStr = ''
+        if len(values) > 1:
+            valueStr = '%s,' * (len(values) - 1) + '%s'
+        dbCommand = """INSERT INTO %s(%s) VALUES (%s);""" % \
+                    (table, columnStr, valueStr)
+        return (dbCommand, tuple(values))
+
+    def createSQLUpdate(self, table, columnMap, whereMap):
+        setStr = ''
+        comma = ''
+        values = []
+        for column, value in columnMap.iteritems():
+#            if value is None:
+#                value = 'NULL'
+            setStr += '%s%s = %%s' % (comma, column)
+            comma = ', '
+            values.append(value)
+        whereStr = ''
+        whereClause = ''
+        for column, value in whereMap.iteritems():
+            whereStr += '%s%s = %%s' % (whereClause, column)
+            values.append(value)
+            whereClause = ' AND '
+        dbCommand = """UPDATE %s SET %s WHERE %s;""" % \
+                    (table, setStr, whereStr)
+        return (dbCommand, tuple(values))
+
+    def createSQLDelete(self, table, whereMap):
+        whereStr = ''
+        whereClause = ''
+        values = []
+        for column, value in whereMap.iteritems():
+            whereStr += '%s %s = %%s' % (whereClause, column)
+            values.append(value)
+            whereClause = ' AND '
+        dbCommand = """DELETE FROM %s WHERE %s;""" % \
+            (table, whereStr)
+        return (dbCommand, tuple(values))
+
+    def executeSQL(self, db, cmd_tuple, isFetch):
+        dbCommand, values = cmd_tuple
+        # print 'db: %s' % dbCommand
+        # print 'values:', values
+        data = None
+        cursor = db.cursor()
+        try:
+            cursor.execute(dbCommand, values)
+            if isFetch:
+                data = cursor.fetchall()
+            else:
+                data = cursor.lastrowid
+        except Exception, e:
+            raise VistrailsDBException('Command "%s" with values "%s" '
+                                       'failed: %s' % (dbCommand, values, e))
+        finally:
+            cursor.close()
+        return data
+
+    def executeSQLGroup(self, db, dbCommandList, isFetch):
+        """ Executes a command consisting of multiple SELECT statements
+            It returns a list of results from the SELECT statements
+        """
+        data = []
+        # break up into bundles
+        BUNDLE_SIZE = 10000
+        num_commands = len(dbCommandList)
+        n = 0
+        while n<num_commands:
+            dbCommands = dbCommandList[n:(n+BUNDLE_SIZE)]
+            commandString = ''
+            for prepared, values in dbCommands:
+                command = prepared % \
+                              db.escape(values, get_db_lib().converters.conversions)
+                commandString += command
+            cur = db.cursor()
+            try:
+                result = cur.execute(commandString)
+                while True:
+                    r = cur.fetchall() if isFetch else cur.lastrowid
+                    data.append(r)
+                    next = cur.nextset()
+                    if not next:
+                        break
+            except Exception, e:
+                raise VistrailsDBException('Command failed: %s -- """ %s """' % 
+                                           (e, commandString))
+            finally:
+                cur.close()
+            
+            n += BUNDLE_SIZE
+        return data
+
+    def start_transaction(self, db):
+        db.begin()
+
+    def commit_transaction(self, db):
+        db.commit()
+
+    def rollback_transaction(self, db):
+        db.rollback()
diff --git a/vistrails/db/versions/v1_0_4/persistence/xml/__init__.py b/vistrails/db/versions/v1_0_4/persistence/xml/__init__.py
new file mode 100644
index 0000000..5474457
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/xml/__init__.py
@@ -0,0 +1,39 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+pass
\ No newline at end of file
diff --git a/vistrails/db/versions/v1_0_4/persistence/xml/auto_gen.py b/vistrails/db/versions/v1_0_4/persistence/xml/auto_gen.py
new file mode 100644
index 0000000..8afefa0
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/xml/auto_gen.py
@@ -0,0 +1,6509 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""generated automatically by auto_dao.py"""
+
+from __future__ import division
+
+from vistrails.core.system import get_elementtree_library
+ElementTree = get_elementtree_library()
+
+from xml_dao import XMLDAO
+from vistrails.db.versions.v1_0_4.domain import *
+
+class DBOpmWasGeneratedByXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'wasGeneratedBy':
+            return None
+        
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        opm_times = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'effect':
+                _data = self.getDao('opm_artifact_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'cause':
+                _data = self.getDao('opm_process_id_cause').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                opm_times.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmWasGeneratedBy(effect=effect,
+                                  role=role,
+                                  cause=cause,
+                                  accounts=accounts,
+                                  opm_times=opm_times)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_was_generated_by, node=None):
+        if node is None:
+            node = ElementTree.Element('wasGeneratedBy')
+        
+        # set elements
+        effect = opm_was_generated_by.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_artifact_id_effect').toXML(effect, childNode)
+        role = opm_was_generated_by.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_was_generated_by.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'cause')
+                self.getDao('opm_process_id_cause').toXML(cause, childNode)
+        accounts = opm_was_generated_by.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        opm_times = opm_was_generated_by.db_opm_times
+        for opm_time in opm_times:
+            if (opm_times is not None) and (opm_times != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(opm_time, childNode)
+        
+        return node
+
+class DBConfigKeyXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'key':
+            return None
+        
+        # read attributes
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'str':
+                _data = self.getDao('config_str').fromXML(child)
+                value = _data
+            elif child_tag == 'int':
+                _data = self.getDao('config_int').fromXML(child)
+                value = _data
+            elif child_tag == 'float':
+                _data = self.getDao('config_float').fromXML(child)
+                value = _data
+            elif child_tag == 'bool':
+                _data = self.getDao('config_bool').fromXML(child)
+                value = _data
+            elif child_tag == 'configuration':
+                _data = self.getDao('configuration').fromXML(child)
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBConfigKey(value=value,
+                          name=name)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, config_key, node=None):
+        if node is None:
+            node = ElementTree.Element('key')
+        
+        # set attributes
+        node.set('name',self.convertToStr(config_key.db_name, 'str'))
+        
+        # set elements
+        value = config_key.db_value
+        if value is not None:
+            if value.vtType == 'config_str':
+                childNode = ElementTree.SubElement(node, 'str')
+                self.getDao('config_str').toXML(value, childNode)
+            elif value.vtType == 'config_int':
+                childNode = ElementTree.SubElement(node, 'int')
+                self.getDao('config_int').toXML(value, childNode)
+            elif value.vtType == 'config_float':
+                childNode = ElementTree.SubElement(node, 'float')
+                self.getDao('config_float').toXML(value, childNode)
+            elif value.vtType == 'config_bool':
+                childNode = ElementTree.SubElement(node, 'bool')
+                self.getDao('config_bool').toXML(value, childNode)
+            elif value.vtType == 'configuration':
+                childNode = ElementTree.SubElement(node, 'configuration')
+                self.getDao('configuration').toXML(value, childNode)
+        
+        return node
+
+class DBMashupAliasXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'alias':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        component = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'component':
+                _data = self.getDao('mashup_component').fromXML(child)
+                component = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBMashupAlias(id=id,
+                            name=name,
+                            component=component)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashup_alias, node=None):
+        if node is None:
+            node = ElementTree.Element('alias')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup_alias.db_id, 'long'))
+        node.set('name',self.convertToStr(mashup_alias.db_name, 'str'))
+        
+        # set elements
+        component = mashup_alias.db_component
+        if component is not None:
+            if (component is not None) and (component != ""):
+                childNode = ElementTree.SubElement(node, 'component')
+                self.getDao('mashup_component').toXML(component, childNode)
+        
+        return node
+
+class DBGroupXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'group':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('cache', None)
+        cache = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        
+        workflow = None
+        location = None
+        functions = []
+        annotations = []
+        controlParameters = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'workflow':
+                _data = self.getDao('workflow').fromXML(child)
+                workflow = _data
+            elif child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                location = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                functions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'controlParameter':
+                _data = self.getDao('controlParameter').fromXML(child)
+                controlParameters.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBGroup(id=id,
+                      workflow=workflow,
+                      cache=cache,
+                      name=name,
+                      namespace=namespace,
+                      package=package,
+                      version=version,
+                      location=location,
+                      functions=functions,
+                      annotations=annotations,
+                      controlParameters=controlParameters)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, group, node=None):
+        if node is None:
+            node = ElementTree.Element('group')
+        
+        # set attributes
+        node.set('id',self.convertToStr(group.db_id, 'long'))
+        node.set('cache',self.convertToStr(group.db_cache, 'int'))
+        node.set('name',self.convertToStr(group.db_name, 'str'))
+        node.set('namespace',self.convertToStr(group.db_namespace, 'str'))
+        node.set('package',self.convertToStr(group.db_package, 'str'))
+        node.set('version',self.convertToStr(group.db_version, 'str'))
+        
+        # set elements
+        workflow = group.db_workflow
+        if workflow is not None:
+            if (workflow is not None) and (workflow != ""):
+                childNode = ElementTree.SubElement(node, 'workflow')
+                self.getDao('workflow').toXML(workflow, childNode)
+        location = group.db_location
+        if location is not None:
+            if (location is not None) and (location != ""):
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(location, childNode)
+        functions = group.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(function, childNode)
+        annotations = group.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        controlParameters = group.db_controlParameters
+        for controlParameter in controlParameters:
+            if (controlParameters is not None) and (controlParameters != ""):
+                childNode = ElementTree.SubElement(node, 'controlParameter')
+                self.getDao('controlParameter').toXML(controlParameter, childNode)
+        
+        return node
+
+class DBOpmWasControlledByXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'wasControlledBy':
+            return None
+        
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        starts = []
+        ends = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'effect':
+                _data = self.getDao('opm_process_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'agent':
+                _data = self.getDao('opm_agent_id').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                starts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                ends.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmWasControlledBy(effect=effect,
+                                   role=role,
+                                   cause=cause,
+                                   accounts=accounts,
+                                   starts=starts,
+                                   ends=ends)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_was_controlled_by, node=None):
+        if node is None:
+            node = ElementTree.Element('wasControlledBy')
+        
+        # set elements
+        effect = opm_was_controlled_by.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_process_id_effect').toXML(effect, childNode)
+        role = opm_was_controlled_by.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_was_controlled_by.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'agent')
+                self.getDao('opm_agent_id').toXML(cause, childNode)
+        accounts = opm_was_controlled_by.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        starts = opm_was_controlled_by.db_starts
+        for start in starts:
+            if (starts is not None) and (starts != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(start, childNode)
+        ends = opm_was_controlled_by.db_ends
+        for end in ends:
+            if (ends is not None) and (ends != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(end, childNode)
+        
+        return node
+
+class DBAddXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'add':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('what', None)
+        what = self.convertFromStr(data, 'str')
+        data = node.get('objectId', None)
+        objectId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjId', None)
+        parentObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjType', None)
+        parentObjType = self.convertFromStr(data, 'str')
+        
+        data = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'module':
+                _data = self.getDao('module').fromXML(child)
+                data = _data
+            elif child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                data = _data
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                data = _data
+            elif child_tag == 'controlParameter':
+                _data = self.getDao('controlParameter').fromXML(child)
+                data = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                data = _data
+            elif child_tag == 'connection':
+                _data = self.getDao('connection').fromXML(child)
+                data = _data
+            elif child_tag == 'port':
+                _data = self.getDao('port').fromXML(child)
+                data = _data
+            elif child_tag == 'parameter':
+                _data = self.getDao('parameter').fromXML(child)
+                data = _data
+            elif child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                data = _data
+            elif child_tag == 'abstraction':
+                _data = self.getDao('abstraction').fromXML(child)
+                data = _data
+            elif child_tag == 'group':
+                _data = self.getDao('group').fromXML(child)
+                data = _data
+            elif child_tag == 'other':
+                _data = self.getDao('other').fromXML(child)
+                data = _data
+            elif child_tag == 'plugin_data':
+                _data = self.getDao('plugin_data').fromXML(child)
+                data = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBAdd(data=data,
+                    id=id,
+                    what=what,
+                    objectId=objectId,
+                    parentObjId=parentObjId,
+                    parentObjType=parentObjType)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, add, node=None):
+        if node is None:
+            node = ElementTree.Element('add')
+        
+        # set attributes
+        node.set('id',self.convertToStr(add.db_id, 'long'))
+        node.set('what',self.convertToStr(add.db_what, 'str'))
+        node.set('objectId',self.convertToStr(add.db_objectId, 'long'))
+        node.set('parentObjId',self.convertToStr(add.db_parentObjId, 'long'))
+        node.set('parentObjType',self.convertToStr(add.db_parentObjType, 'str'))
+        
+        # set elements
+        data = add.db_data
+        if data is not None:
+            if data.vtType == 'module':
+                childNode = ElementTree.SubElement(node, 'module')
+                self.getDao('module').toXML(data, childNode)
+            elif data.vtType == 'location':
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(data, childNode)
+            elif data.vtType == 'annotation':
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(data, childNode)
+            elif data.vtType == 'controlParameter':
+                childNode = ElementTree.SubElement(node, 'controlParameter')
+                self.getDao('controlParameter').toXML(data, childNode)
+            elif data.vtType == 'function':
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(data, childNode)
+            elif data.vtType == 'connection':
+                childNode = ElementTree.SubElement(node, 'connection')
+                self.getDao('connection').toXML(data, childNode)
+            elif data.vtType == 'port':
+                childNode = ElementTree.SubElement(node, 'port')
+                self.getDao('port').toXML(data, childNode)
+            elif data.vtType == 'parameter':
+                childNode = ElementTree.SubElement(node, 'parameter')
+                self.getDao('parameter').toXML(data, childNode)
+            elif data.vtType == 'portSpec':
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(data, childNode)
+            elif data.vtType == 'abstraction':
+                childNode = ElementTree.SubElement(node, 'abstraction')
+                self.getDao('abstraction').toXML(data, childNode)
+            elif data.vtType == 'group':
+                childNode = ElementTree.SubElement(node, 'group')
+                self.getDao('group').toXML(data, childNode)
+            elif data.vtType == 'other':
+                childNode = ElementTree.SubElement(node, 'other')
+                self.getDao('other').toXML(data, childNode)
+            elif data.vtType == 'plugin_data':
+                childNode = ElementTree.SubElement(node, 'plugin_data')
+                self.getDao('plugin_data').toXML(data, childNode)
+        
+        return node
+
+class DBProvGenerationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:wasGeneratedBy':
+            return None
+        
+        prov_entity = None
+        prov_activity = None
+        prov_role = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:entity':
+                _data = self.getDao('ref_prov_entity').fromXML(child)
+                prov_entity = _data
+            elif child_tag == 'prov:activity':
+                _data = self.getDao('ref_prov_activity').fromXML(child)
+                prov_activity = _data
+            elif child_tag == 'prov:role':
+                _data = self.convertFromStr(child.text,'str')
+                prov_role = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvGeneration(prov_entity=prov_entity,
+                               prov_activity=prov_activity,
+                               prov_role=prov_role)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_generation, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:wasGeneratedBy')
+        
+        # set elements
+        prov_entity = prov_generation.db_prov_entity
+        if prov_entity is not None:
+            if (prov_entity is not None) and (prov_entity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:entity')
+                self.getDao('ref_prov_entity').toXML(prov_entity, childNode)
+        prov_activity = prov_generation.db_prov_activity
+        if prov_activity is not None:
+            if (prov_activity is not None) and (prov_activity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
+        prov_role = prov_generation.db_prov_role
+        if (prov_role is not None) and (prov_role != ""):
+            childNode = ElementTree.SubElement(node, 'prov:role')
+            childNode.text = self.convertToStr(prov_role, 'str')
+        
+        return node
+
+class DBOpmUsedXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'used':
+            return None
+        
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        opm_times = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'effect':
+                _data = self.getDao('opm_process_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'cause':
+                _data = self.getDao('opm_artifact_id_cause').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                opm_times.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmUsed(effect=effect,
+                        role=role,
+                        cause=cause,
+                        accounts=accounts,
+                        opm_times=opm_times)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_used, node=None):
+        if node is None:
+            node = ElementTree.Element('used')
+        
+        # set elements
+        effect = opm_used.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_process_id_effect').toXML(effect, childNode)
+        role = opm_used.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_used.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'cause')
+                self.getDao('opm_artifact_id_cause').toXML(cause, childNode)
+        accounts = opm_used.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        opm_times = opm_used.db_opm_times
+        for opm_time in opm_times:
+            if (opm_times is not None) and (opm_times != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(opm_time, childNode)
+        
+        return node
+
+class DBOpmArtifactIdCauseXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'cause':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmArtifactIdCause(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_artifact_id_cause, node=None):
+        if node is None:
+            node = ElementTree.Element('cause')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_artifact_id_cause.db_id, 'str'))
+        
+        return node
+
+class DBRefProvEntityXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:entity':
+            return None
+        
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
+        
+        obj = DBRefProvEntity(prov_ref=prov_ref)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, ref_prov_entity, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:entity')
+        
+        # set attributes
+        node.set('prov:ref',self.convertToStr(ref_prov_entity.db_prov_ref, 'str'))
+        
+        return node
+
+class DBVtConnectionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'vt:connection':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        vt_source = None
+        vt_dest = None
+        vt_source_port = None
+        vt_dest_port = None
+        vt_source_signature = None
+        vt_dest_signature = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'vt:source':
+                _data = self.convertFromStr(child.text,'str')
+                vt_source = _data
+            elif child_tag == 'vt:dest':
+                _data = self.convertFromStr(child.text,'str')
+                vt_dest = _data
+            elif child_tag == 'vt:source_port':
+                _data = self.convertFromStr(child.text,'str')
+                vt_source_port = _data
+            elif child_tag == 'vt:dest_port':
+                _data = self.convertFromStr(child.text,'str')
+                vt_dest_port = _data
+            elif child_tag == 'vt:source_signature':
+                _data = self.convertFromStr(child.text,'str')
+                vt_source_signature = _data
+            elif child_tag == 'vt:dest_signature':
+                _data = self.convertFromStr(child.text,'str')
+                vt_dest_signature = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBVtConnection(id=id,
+                             vt_source=vt_source,
+                             vt_dest=vt_dest,
+                             vt_source_port=vt_source_port,
+                             vt_dest_port=vt_dest_port,
+                             vt_source_signature=vt_source_signature,
+                             vt_dest_signature=vt_dest_signature)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, vt_connection, node=None):
+        if node is None:
+            node = ElementTree.Element('vt:connection')
+        
+        # set attributes
+        node.set('id',self.convertToStr(vt_connection.db_id, 'str'))
+        
+        # set elements
+        vt_source = vt_connection.db_vt_source
+        if (vt_source is not None) and (vt_source != ""):
+            childNode = ElementTree.SubElement(node, 'vt:source')
+            childNode.text = self.convertToStr(vt_source, 'str')
+        vt_dest = vt_connection.db_vt_dest
+        if (vt_dest is not None) and (vt_dest != ""):
+            childNode = ElementTree.SubElement(node, 'vt:dest')
+            childNode.text = self.convertToStr(vt_dest, 'str')
+        vt_source_port = vt_connection.db_vt_source_port
+        if (vt_source_port is not None) and (vt_source_port != ""):
+            childNode = ElementTree.SubElement(node, 'vt:source_port')
+            childNode.text = self.convertToStr(vt_source_port, 'str')
+        vt_dest_port = vt_connection.db_vt_dest_port
+        if (vt_dest_port is not None) and (vt_dest_port != ""):
+            childNode = ElementTree.SubElement(node, 'vt:dest_port')
+            childNode.text = self.convertToStr(vt_dest_port, 'str')
+        vt_source_signature = vt_connection.db_vt_source_signature
+        if (vt_source_signature is not None) and (vt_source_signature != ""):
+            childNode = ElementTree.SubElement(node, 'vt:source_signature')
+            childNode.text = self.convertToStr(vt_source_signature, 'str')
+        vt_dest_signature = vt_connection.db_vt_dest_signature
+        if (vt_dest_signature is not None) and (vt_dest_signature != ""):
+            childNode = ElementTree.SubElement(node, 'vt:dest_signature')
+            childNode.text = self.convertToStr(vt_dest_signature, 'str')
+        
+        return node
+
+class DBOpmAccountXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'account':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.convertFromStr(child.text,'str')
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAccount(id=id,
+                           value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_account, node=None):
+        if node is None:
+            node = ElementTree.Element('account')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_account.db_id, 'str'))
+        
+        # set elements
+        value = opm_account.db_value
+        if (value is not None) and (value != ""):
+            childNode = ElementTree.SubElement(node, 'value')
+            childNode.text = self.convertToStr(value, 'str')
+        
+        return node
+
+class DBGroupExecXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'groupExec':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('cached', None)
+        cached = self.convertFromStr(data, 'int')
+        data = node.get('moduleId', None)
+        module_id = self.convertFromStr(data, 'long')
+        data = node.get('groupName', None)
+        group_name = self.convertFromStr(data, 'str')
+        data = node.get('groupType', None)
+        group_type = self.convertFromStr(data, 'str')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('error', None)
+        error = self.convertFromStr(data, 'str')
+        data = node.get('machine_id', None)
+        machine_id = self.convertFromStr(data, 'long')
+        
+        annotations = []
+        item_execs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBGroupExec(item_execs=item_execs,
+                          id=id,
+                          ts_start=ts_start,
+                          ts_end=ts_end,
+                          cached=cached,
+                          module_id=module_id,
+                          group_name=group_name,
+                          group_type=group_type,
+                          completed=completed,
+                          error=error,
+                          machine_id=machine_id,
+                          annotations=annotations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, group_exec, node=None):
+        if node is None:
+            node = ElementTree.Element('groupExec')
+        
+        # set attributes
+        node.set('id',self.convertToStr(group_exec.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(group_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(group_exec.db_ts_end, 'datetime'))
+        node.set('cached',self.convertToStr(group_exec.db_cached, 'int'))
+        node.set('moduleId',self.convertToStr(group_exec.db_module_id, 'long'))
+        node.set('groupName',self.convertToStr(group_exec.db_group_name, 'str'))
+        node.set('groupType',self.convertToStr(group_exec.db_group_type, 'str'))
+        node.set('completed',self.convertToStr(group_exec.db_completed, 'int'))
+        node.set('error',self.convertToStr(group_exec.db_error, 'str'))
+        node.set('machine_id',self.convertToStr(group_exec.db_machine_id, 'long'))
+        
+        # set elements
+        annotations = group_exec.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        item_execs = group_exec.db_item_execs
+        for item_exec in item_execs:
+            if item_exec.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(item_exec, childNode)
+        
+        return node
+
+class DBOpmAgentIdXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'agent':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmAgentId(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_agent_id, node=None):
+        if node is None:
+            node = ElementTree.Element('agent')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_agent_id.db_id, 'str'))
+        
+        return node
+
+class DBParameterXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'parameter':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('val', None)
+        val = self.convertFromStr(data, 'str')
+        data = node.get('alias', None)
+        alias = self.convertFromStr(data, 'str')
+        
+        obj = DBParameter(id=id,
+                          pos=pos,
+                          name=name,
+                          type=type,
+                          val=val,
+                          alias=alias)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, parameter, node=None):
+        if node is None:
+            node = ElementTree.Element('parameter')
+        
+        # set attributes
+        node.set('id',self.convertToStr(parameter.db_id, 'long'))
+        node.set('pos',self.convertToStr(parameter.db_pos, 'long'))
+        node.set('name',self.convertToStr(parameter.db_name, 'str'))
+        node.set('type',self.convertToStr(parameter.db_type, 'str'))
+        node.set('val',self.convertToStr(parameter.db_val, 'str'))
+        node.set('alias',self.convertToStr(parameter.db_alias, 'str'))
+        
+        return node
+
+class DBVistrailXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'vistrail':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        actions = []
+        tags = []
+        annotations = []
+        controlParameters = []
+        vistrailVariables = []
+        parameter_explorations = []
+        actionAnnotations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'action':
+                _data = self.getDao('action').fromXML(child)
+                actions.append(_data)
+            elif child_tag == 'tag':
+                _data = self.getDao('tag').fromXML(child)
+                tags.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'controlParameter':
+                _data = self.getDao('controlParameter').fromXML(child)
+                controlParameters.append(_data)
+            elif child_tag == 'vistrailVariable':
+                _data = self.getDao('vistrailVariable').fromXML(child)
+                vistrailVariables.append(_data)
+            elif child_tag == 'parameterExploration':
+                _data = self.getDao('parameter_exploration').fromXML(child)
+                parameter_explorations.append(_data)
+            elif child_tag == 'actionAnnotation':
+                _data = self.getDao('actionAnnotation').fromXML(child)
+                actionAnnotations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBVistrail(id=id,
+                         version=version,
+                         name=name,
+                         actions=actions,
+                         tags=tags,
+                         annotations=annotations,
+                         controlParameters=controlParameters,
+                         vistrailVariables=vistrailVariables,
+                         parameter_explorations=parameter_explorations,
+                         actionAnnotations=actionAnnotations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, vistrail, node=None):
+        if node is None:
+            node = ElementTree.Element('vistrail')
+        
+        # set attributes
+        node.set('id',self.convertToStr(vistrail.db_id, 'long'))
+        node.set('version',self.convertToStr(vistrail.db_version, 'str'))
+        node.set('name',self.convertToStr(vistrail.db_name, 'str'))
+        
+        # set elements
+        actions = vistrail.db_actions
+        for action in actions:
+            if (actions is not None) and (actions != ""):
+                childNode = ElementTree.SubElement(node, 'action')
+                self.getDao('action').toXML(action, childNode)
+        tags = vistrail.db_tags
+        for tag in tags:
+            if (tags is not None) and (tags != ""):
+                childNode = ElementTree.SubElement(node, 'tag')
+                self.getDao('tag').toXML(tag, childNode)
+        annotations = vistrail.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        controlParameters = vistrail.db_controlParameters
+        for controlParameter in controlParameters:
+            if (controlParameters is not None) and (controlParameters != ""):
+                childNode = ElementTree.SubElement(node, 'controlParameter')
+                self.getDao('controlParameter').toXML(controlParameter, childNode)
+        vistrailVariables = vistrail.db_vistrailVariables
+        for vistrailVariable in vistrailVariables:
+            if (vistrailVariables is not None) and (vistrailVariables != ""):
+                childNode = ElementTree.SubElement(node, 'vistrailVariable')
+                self.getDao('vistrailVariable').toXML(vistrailVariable, childNode)
+        parameter_explorations = vistrail.db_parameter_explorations
+        for parameter_exploration in parameter_explorations:
+            if (parameter_explorations is not None) and (parameter_explorations != ""):
+                childNode = ElementTree.SubElement(node, 'parameterExploration')
+                self.getDao('parameter_exploration').toXML(parameter_exploration, childNode)
+        actionAnnotations = vistrail.db_actionAnnotations
+        for actionAnnotation in actionAnnotations:
+            if (actionAnnotations is not None) and (actionAnnotations != ""):
+                childNode = ElementTree.SubElement(node, 'actionAnnotation')
+                self.getDao('actionAnnotation').toXML(actionAnnotation, childNode)
+        
+        return node
+
+class DBOpmArtifactValueXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'value':
+            return None
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                value = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmArtifactValue(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_artifact_value, node=None):
+        if node is None:
+            node = ElementTree.Element('value')
+        
+        # set elements
+        value = opm_artifact_value.db_value
+        if value is not None:
+            if value.vtType == 'portSpec':
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(value, childNode)
+            elif value.vtType == 'function':
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(value, childNode)
+        
+        return node
+
+class DBConfigStrXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'str':
+            return None
+        
+        # read attributes
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBConfigStr(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, config_str, node=None):
+        if node is None:
+            node = ElementTree.Element('str')
+        
+        # set attributes
+        node.set('value',self.convertToStr(config_str.db_value, 'str'))
+        
+        return node
+
+class DBStartupXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'startup':
+            return None
+        
+        # read attributes
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        
+        configuration = None
+        enabled_packages = None
+        disabled_packages = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'configuration':
+                _data = self.getDao('configuration').fromXML(child)
+                configuration = _data
+            elif child_tag == 'packages':
+                _data = self.getDao('enabled_packages').fromXML(child)
+                enabled_packages = _data
+            elif child_tag == 'disabledpackages':
+                _data = self.getDao('disabled_packages').fromXML(child)
+                disabled_packages = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBStartup(version=version,
+                        configuration=configuration,
+                        enabled_packages=enabled_packages,
+                        disabled_packages=disabled_packages)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, startup, node=None):
+        if node is None:
+            node = ElementTree.Element('startup')
+        
+        # set attributes
+        node.set('version',self.convertToStr(startup.db_version, 'str'))
+        
+        # set elements
+        configuration = startup.db_configuration
+        if configuration is not None:
+            if (configuration is not None) and (configuration != ""):
+                childNode = ElementTree.SubElement(node, 'configuration')
+                self.getDao('configuration').toXML(configuration, childNode)
+        enabled_packages = startup.db_enabled_packages
+        if enabled_packages is not None:
+            if (enabled_packages is not None) and (enabled_packages != ""):
+                childNode = ElementTree.SubElement(node, 'packages')
+                self.getDao('enabled_packages').toXML(enabled_packages, childNode)
+        disabled_packages = startup.db_disabled_packages
+        if disabled_packages is not None:
+            if (disabled_packages is not None) and (disabled_packages != ""):
+                childNode = ElementTree.SubElement(node, 'disabledpackages')
+                self.getDao('disabled_packages').toXML(disabled_packages, childNode)
+        
+        return node
+
+class DBModuleXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'module':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('cache', None)
+        cache = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        
+        location = None
+        functions = []
+        annotations = []
+        controlParameters = []
+        portSpecs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                location = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                functions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'controlParameter':
+                _data = self.getDao('controlParameter').fromXML(child)
+                controlParameters.append(_data)
+            elif child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                portSpecs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBModule(id=id,
+                       cache=cache,
+                       name=name,
+                       namespace=namespace,
+                       package=package,
+                       version=version,
+                       location=location,
+                       functions=functions,
+                       annotations=annotations,
+                       controlParameters=controlParameters,
+                       portSpecs=portSpecs)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, module, node=None):
+        if node is None:
+            node = ElementTree.Element('module')
+        
+        # set attributes
+        node.set('id',self.convertToStr(module.db_id, 'long'))
+        node.set('cache',self.convertToStr(module.db_cache, 'int'))
+        node.set('name',self.convertToStr(module.db_name, 'str'))
+        node.set('namespace',self.convertToStr(module.db_namespace, 'str'))
+        node.set('package',self.convertToStr(module.db_package, 'str'))
+        node.set('version',self.convertToStr(module.db_version, 'str'))
+        
+        # set elements
+        location = module.db_location
+        if location is not None:
+            if (location is not None) and (location != ""):
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(location, childNode)
+        functions = module.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(function, childNode)
+        annotations = module.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        controlParameters = module.db_controlParameters
+        for controlParameter in controlParameters:
+            if (controlParameters is not None) and (controlParameters != ""):
+                childNode = ElementTree.SubElement(node, 'controlParameter')
+                self.getDao('controlParameter').toXML(controlParameter, childNode)
+        portSpecs = module.db_portSpecs
+        for portSpec in portSpecs:
+            if (portSpecs is not None) and (portSpecs != ""):
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(portSpec, childNode)
+        
+        return node
+
+class DBPortXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'port':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('moduleId', None)
+        moduleId = self.convertFromStr(data, 'long')
+        data = node.get('moduleName', None)
+        moduleName = self.convertFromStr(data, 'str')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('signature', None)
+        signature = self.convertFromStr(data, 'str')
+        
+        obj = DBPort(id=id,
+                     type=type,
+                     moduleId=moduleId,
+                     moduleName=moduleName,
+                     name=name,
+                     signature=signature)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, port, node=None):
+        if node is None:
+            node = ElementTree.Element('port')
+        
+        # set attributes
+        node.set('id',self.convertToStr(port.db_id, 'long'))
+        node.set('type',self.convertToStr(port.db_type, 'str'))
+        node.set('moduleId',self.convertToStr(port.db_moduleId, 'long'))
+        node.set('moduleName',self.convertToStr(port.db_moduleName, 'str'))
+        node.set('name',self.convertToStr(port.db_name, 'str'))
+        node.set('signature',self.convertToStr(port.db_signature, 'str'))
+        
+        return node
+
+class DBOpmAgentsXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'agents':
+            return None
+        
+        agents = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'agent':
+                _data = self.getDao('opm_agent').fromXML(child)
+                agents.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAgents(agents=agents)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_agents, node=None):
+        if node is None:
+            node = ElementTree.Element('agents')
+        
+        # set elements
+        agents = opm_agents.db_agents
+        for agent in agents:
+            if (agents is not None) and (agents != ""):
+                childNode = ElementTree.SubElement(node, 'agent')
+                self.getDao('opm_agent').toXML(agent, childNode)
+        
+        return node
+
+class DBOpmDependenciesXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'causalDependencies':
+            return None
+        
+        dependencys = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'used':
+                _data = self.getDao('opm_used').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasGeneratedBy':
+                _data = self.getDao('opm_was_generated_by').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasTriggeredBy':
+                _data = self.getDao('opm_was_triggered_by').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasDerivedFrom':
+                _data = self.getDao('opm_was_derived_from').fromXML(child)
+                dependencys.append(_data)
+            elif child_tag == 'wasControlledBy':
+                _data = self.getDao('opm_was_controlled_by').fromXML(child)
+                dependencys.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmDependencies(dependencys=dependencys)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_dependencies, node=None):
+        if node is None:
+            node = ElementTree.Element('causalDependencies')
+        
+        # set elements
+        dependencys = opm_dependencies.db_dependencys
+        for dependency in dependencys:
+            if dependency.vtType == 'opm_used':
+                childNode = ElementTree.SubElement(node, 'used')
+                self.getDao('opm_used').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_generated_by':
+                childNode = ElementTree.SubElement(node, 'wasGeneratedBy')
+                self.getDao('opm_was_generated_by').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_triggered_by':
+                childNode = ElementTree.SubElement(node, 'wasTriggeredBy')
+                self.getDao('opm_was_triggered_by').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_derived_from':
+                childNode = ElementTree.SubElement(node, 'wasDerivedFrom')
+                self.getDao('opm_was_derived_from').toXML(dependency, childNode)
+            elif dependency.vtType == 'opm_was_controlled_by':
+                childNode = ElementTree.SubElement(node, 'wasControlledBy')
+                self.getDao('opm_was_controlled_by').toXML(dependency, childNode)
+        
+        return node
+
+class DBPEFunctionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'peFunction':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('moduleId', None)
+        module_id = self.convertFromStr(data, 'long')
+        data = node.get('port_name', None)
+        port_name = self.convertFromStr(data, 'str')
+        data = node.get('is_alias', None)
+        is_alias = self.convertFromStr(data, 'long')
+        
+        parameters = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'peParameter':
+                _data = self.getDao('pe_parameter').fromXML(child)
+                parameters.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBPEFunction(id=id,
+                           module_id=module_id,
+                           port_name=port_name,
+                           is_alias=is_alias,
+                           parameters=parameters)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, pe_function, node=None):
+        if node is None:
+            node = ElementTree.Element('peFunction')
+        
+        # set attributes
+        node.set('id',self.convertToStr(pe_function.db_id, 'long'))
+        node.set('moduleId',self.convertToStr(pe_function.db_module_id, 'long'))
+        node.set('port_name',self.convertToStr(pe_function.db_port_name, 'str'))
+        node.set('is_alias',self.convertToStr(pe_function.db_is_alias, 'long'))
+        
+        # set elements
+        parameters = pe_function.db_parameters
+        for parameter in parameters:
+            if (parameters is not None) and (parameters != ""):
+                childNode = ElementTree.SubElement(node, 'peParameter')
+                self.getDao('pe_parameter').toXML(parameter, childNode)
+        
+        return node
+
+class DBWorkflowXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'workflow':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('vistrail_id', None)
+        vistrail_id = self.convertFromStr(data, 'long')
+        
+        connections = []
+        annotations = []
+        plugin_datas = []
+        others = []
+        modules = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'connection':
+                _data = self.getDao('connection').fromXML(child)
+                connections.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'plugin_data':
+                _data = self.getDao('plugin_data').fromXML(child)
+                plugin_datas.append(_data)
+            elif child_tag == 'other':
+                _data = self.getDao('other').fromXML(child)
+                others.append(_data)
+            elif child_tag == 'module':
+                _data = self.getDao('module').fromXML(child)
+                modules.append(_data)
+            elif child_tag == 'abstraction':
+                _data = self.getDao('abstraction').fromXML(child)
+                modules.append(_data)
+            elif child_tag == 'group':
+                _data = self.getDao('group').fromXML(child)
+                modules.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBWorkflow(modules=modules,
+                         id=id,
+                         name=name,
+                         version=version,
+                         connections=connections,
+                         annotations=annotations,
+                         plugin_datas=plugin_datas,
+                         others=others,
+                         vistrail_id=vistrail_id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, workflow, node=None):
+        if node is None:
+            node = ElementTree.Element('workflow')
+        
+        # set attributes
+        node.set('id',self.convertToStr(workflow.db_id, 'long'))
+        node.set('name',self.convertToStr(workflow.db_name, 'str'))
+        node.set('version',self.convertToStr(workflow.db_version, 'str'))
+        node.set('vistrail_id',self.convertToStr(workflow.db_vistrail_id, 'long'))
+        
+        # set elements
+        connections = workflow.db_connections
+        for connection in connections:
+            if (connections is not None) and (connections != ""):
+                childNode = ElementTree.SubElement(node, 'connection')
+                self.getDao('connection').toXML(connection, childNode)
+        annotations = workflow.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        plugin_datas = workflow.db_plugin_datas
+        for plugin_data in plugin_datas:
+            if (plugin_datas is not None) and (plugin_datas != ""):
+                childNode = ElementTree.SubElement(node, 'plugin_data')
+                self.getDao('plugin_data').toXML(plugin_data, childNode)
+        others = workflow.db_others
+        for other in others:
+            if (others is not None) and (others != ""):
+                childNode = ElementTree.SubElement(node, 'other')
+                self.getDao('other').toXML(other, childNode)
+        modules = workflow.db_modules
+        for module in modules:
+            if module.vtType == 'module':
+                childNode = ElementTree.SubElement(node, 'module')
+                self.getDao('module').toXML(module, childNode)
+            elif module.vtType == 'abstraction':
+                childNode = ElementTree.SubElement(node, 'abstraction')
+                self.getDao('abstraction').toXML(module, childNode)
+            elif module.vtType == 'group':
+                childNode = ElementTree.SubElement(node, 'group')
+                self.getDao('group').toXML(module, childNode)
+        
+        return node
+
+class DBMashupActionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'action':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('prevId', None)
+        prevId = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        
+        mashup = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'mashup':
+                _data = self.getDao('mashup').fromXML(child)
+                mashup = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBMashupAction(id=id,
+                             prevId=prevId,
+                             date=date,
+                             user=user,
+                             mashup=mashup)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashup_action, node=None):
+        if node is None:
+            node = ElementTree.Element('action')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup_action.db_id, 'long'))
+        node.set('prevId',self.convertToStr(mashup_action.db_prevId, 'long'))
+        node.set('date',self.convertToStr(mashup_action.db_date, 'datetime'))
+        node.set('user',self.convertToStr(mashup_action.db_user, 'str'))
+        
+        # set elements
+        mashup = mashup_action.db_mashup
+        if mashup is not None:
+            if (mashup is not None) and (mashup != ""):
+                childNode = ElementTree.SubElement(node, 'mashup')
+                self.getDao('mashup').toXML(mashup, childNode)
+        
+        return node
+
+class DBConfigurationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'configuration':
+            return None
+        
+        config_keys = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'key':
+                _data = self.getDao('config_key').fromXML(child)
+                config_keys.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBConfiguration(config_keys=config_keys)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, configuration, node=None):
+        if node is None:
+            node = ElementTree.Element('configuration')
+        
+        # set elements
+        config_keys = configuration.db_config_keys
+        for config_key in config_keys:
+            if (config_keys is not None) and (config_keys != ""):
+                childNode = ElementTree.SubElement(node, 'key')
+                self.getDao('config_key').toXML(config_key, childNode)
+        
+        return node
+
+class DBChangeXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'change':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('what', None)
+        what = self.convertFromStr(data, 'str')
+        data = node.get('oldObjId', None)
+        oldObjId = self.convertFromStr(data, 'long')
+        data = node.get('newObjId', None)
+        newObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjId', None)
+        parentObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjType', None)
+        parentObjType = self.convertFromStr(data, 'str')
+        
+        data = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'module':
+                _data = self.getDao('module').fromXML(child)
+                data = _data
+            elif child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                data = _data
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                data = _data
+            elif child_tag == 'controlParameter':
+                _data = self.getDao('controlParameter').fromXML(child)
+                data = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                data = _data
+            elif child_tag == 'connection':
+                _data = self.getDao('connection').fromXML(child)
+                data = _data
+            elif child_tag == 'port':
+                _data = self.getDao('port').fromXML(child)
+                data = _data
+            elif child_tag == 'parameter':
+                _data = self.getDao('parameter').fromXML(child)
+                data = _data
+            elif child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                data = _data
+            elif child_tag == 'abstraction':
+                _data = self.getDao('abstraction').fromXML(child)
+                data = _data
+            elif child_tag == 'group':
+                _data = self.getDao('group').fromXML(child)
+                data = _data
+            elif child_tag == 'other':
+                _data = self.getDao('other').fromXML(child)
+                data = _data
+            elif child_tag == 'plugin_data':
+                _data = self.getDao('plugin_data').fromXML(child)
+                data = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBChange(data=data,
+                       id=id,
+                       what=what,
+                       oldObjId=oldObjId,
+                       newObjId=newObjId,
+                       parentObjId=parentObjId,
+                       parentObjType=parentObjType)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, change, node=None):
+        if node is None:
+            node = ElementTree.Element('change')
+        
+        # set attributes
+        node.set('id',self.convertToStr(change.db_id, 'long'))
+        node.set('what',self.convertToStr(change.db_what, 'str'))
+        node.set('oldObjId',self.convertToStr(change.db_oldObjId, 'long'))
+        node.set('newObjId',self.convertToStr(change.db_newObjId, 'long'))
+        node.set('parentObjId',self.convertToStr(change.db_parentObjId, 'long'))
+        node.set('parentObjType',self.convertToStr(change.db_parentObjType, 'str'))
+        
+        # set elements
+        data = change.db_data
+        if data is not None:
+            if data.vtType == 'module':
+                childNode = ElementTree.SubElement(node, 'module')
+                self.getDao('module').toXML(data, childNode)
+            elif data.vtType == 'location':
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(data, childNode)
+            elif data.vtType == 'annotation':
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(data, childNode)
+            elif data.vtType == 'controlParameter':
+                childNode = ElementTree.SubElement(node, 'controlParameter')
+                self.getDao('controlParameter').toXML(data, childNode)
+            elif data.vtType == 'function':
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(data, childNode)
+            elif data.vtType == 'connection':
+                childNode = ElementTree.SubElement(node, 'connection')
+                self.getDao('connection').toXML(data, childNode)
+            elif data.vtType == 'port':
+                childNode = ElementTree.SubElement(node, 'port')
+                self.getDao('port').toXML(data, childNode)
+            elif data.vtType == 'parameter':
+                childNode = ElementTree.SubElement(node, 'parameter')
+                self.getDao('parameter').toXML(data, childNode)
+            elif data.vtType == 'portSpec':
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(data, childNode)
+            elif data.vtType == 'abstraction':
+                childNode = ElementTree.SubElement(node, 'abstraction')
+                self.getDao('abstraction').toXML(data, childNode)
+            elif data.vtType == 'group':
+                childNode = ElementTree.SubElement(node, 'group')
+                self.getDao('group').toXML(data, childNode)
+            elif data.vtType == 'other':
+                childNode = ElementTree.SubElement(node, 'other')
+                self.getDao('other').toXML(data, childNode)
+            elif data.vtType == 'plugin_data':
+                childNode = ElementTree.SubElement(node, 'plugin_data')
+                self.getDao('plugin_data').toXML(data, childNode)
+        
+        return node
+
+class DBPackageXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'package':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('identifier', None)
+        identifier = self.convertFromStr(data, 'str')
+        data = node.get('codepath', None)
+        codepath = self.convertFromStr(data, 'str')
+        data = node.get('loadConfiguration', None)
+        load_configuration = self.convertFromStr(data, 'int')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('description', None)
+        description = self.convertFromStr(data, 'str')
+        
+        module_descriptors = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'moduleDescriptor':
+                _data = self.getDao('module_descriptor').fromXML(child)
+                module_descriptors.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBPackage(id=id,
+                        name=name,
+                        identifier=identifier,
+                        codepath=codepath,
+                        load_configuration=load_configuration,
+                        version=version,
+                        description=description,
+                        module_descriptors=module_descriptors)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, package, node=None):
+        if node is None:
+            node = ElementTree.Element('package')
+        
+        # set attributes
+        node.set('id',self.convertToStr(package.db_id, 'long'))
+        node.set('name',self.convertToStr(package.db_name, 'str'))
+        node.set('identifier',self.convertToStr(package.db_identifier, 'str'))
+        node.set('codepath',self.convertToStr(package.db_codepath, 'str'))
+        node.set('loadConfiguration',self.convertToStr(package.db_load_configuration, 'int'))
+        node.set('version',self.convertToStr(package.db_version, 'str'))
+        node.set('description',self.convertToStr(package.db_description, 'str'))
+        
+        # set elements
+        module_descriptors = package.db_module_descriptors
+        for module_descriptor in module_descriptors:
+            if (module_descriptors is not None) and (module_descriptors != ""):
+                childNode = ElementTree.SubElement(node, 'moduleDescriptor')
+                self.getDao('module_descriptor').toXML(module_descriptor, childNode)
+        
+        return node
+
+class DBLoopExecXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'loopExec':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        
+        loop_iterations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'loopIteration':
+                _data = self.getDao('loop_iteration').fromXML(child)
+                loop_iterations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBLoopExec(id=id,
+                         ts_start=ts_start,
+                         ts_end=ts_end,
+                         loop_iterations=loop_iterations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, loop_exec, node=None):
+        if node is None:
+            node = ElementTree.Element('loopExec')
+        
+        # set attributes
+        node.set('id',self.convertToStr(loop_exec.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(loop_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(loop_exec.db_ts_end, 'datetime'))
+        
+        # set elements
+        loop_iterations = loop_exec.db_loop_iterations
+        for loop_iteration in loop_iterations:
+            if (loop_iterations is not None) and (loop_iterations != ""):
+                childNode = ElementTree.SubElement(node, 'loopIteration')
+                self.getDao('loop_iteration').toXML(loop_iteration, childNode)
+        
+        return node
+
+class DBConnectionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'connection':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        
+        ports = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'port':
+                _data = self.getDao('port').fromXML(child)
+                ports.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBConnection(id=id,
+                           ports=ports)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, connection, node=None):
+        if node is None:
+            node = ElementTree.Element('connection')
+        
+        # set attributes
+        node.set('id',self.convertToStr(connection.db_id, 'long'))
+        
+        # set elements
+        ports = connection.db_ports
+        for port in ports:
+            if (ports is not None) and (ports != ""):
+                childNode = ElementTree.SubElement(node, 'port')
+                self.getDao('port').toXML(port, childNode)
+        
+        return node
+
+class DBConfigBoolXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'bool':
+            return None
+        
+        # read attributes
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBConfigBool(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, config_bool, node=None):
+        if node is None:
+            node = ElementTree.Element('bool')
+        
+        # set attributes
+        node.set('value',self.convertToStr(config_bool.db_value, 'str'))
+        
+        return node
+
+class DBActionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'action':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('prevId', None)
+        prevId = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('session', None)
+        session = self.convertFromStr(data, 'long')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        
+        annotations = []
+        operations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'add':
+                _data = self.getDao('add').fromXML(child)
+                operations.append(_data)
+            elif child_tag == 'delete':
+                _data = self.getDao('delete').fromXML(child)
+                operations.append(_data)
+            elif child_tag == 'change':
+                _data = self.getDao('change').fromXML(child)
+                operations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBAction(operations=operations,
+                       id=id,
+                       prevId=prevId,
+                       date=date,
+                       session=session,
+                       user=user,
+                       annotations=annotations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, action, node=None):
+        if node is None:
+            node = ElementTree.Element('action')
+        
+        # set attributes
+        node.set('id',self.convertToStr(action.db_id, 'long'))
+        node.set('prevId',self.convertToStr(action.db_prevId, 'long'))
+        node.set('date',self.convertToStr(action.db_date, 'datetime'))
+        node.set('session',self.convertToStr(action.db_session, 'long'))
+        node.set('user',self.convertToStr(action.db_user, 'str'))
+        
+        # set elements
+        annotations = action.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        operations = action.db_operations
+        for operation in operations:
+            if operation.vtType == 'add':
+                childNode = ElementTree.SubElement(node, 'add')
+                self.getDao('add').toXML(operation, childNode)
+            elif operation.vtType == 'delete':
+                childNode = ElementTree.SubElement(node, 'delete')
+                self.getDao('delete').toXML(operation, childNode)
+            elif operation.vtType == 'change':
+                childNode = ElementTree.SubElement(node, 'change')
+                self.getDao('change').toXML(operation, childNode)
+        
+        return node
+
+class DBStartupPackageXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'package':
+            return None
+        
+        # read attributes
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        configuration = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'configuration':
+                _data = self.getDao('configuration').fromXML(child)
+                configuration = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBStartupPackage(name=name,
+                               configuration=configuration)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, startup_package, node=None):
+        if node is None:
+            node = ElementTree.Element('package')
+        
+        # set attributes
+        node.set('name',self.convertToStr(startup_package.db_name, 'str'))
+        
+        # set elements
+        configuration = startup_package.db_configuration
+        if configuration is not None:
+            if (configuration is not None) and (configuration != ""):
+                childNode = ElementTree.SubElement(node, 'configuration')
+                self.getDao('configuration').toXML(configuration, childNode)
+        
+        return node
+
+class DBConfigIntXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'int':
+            return None
+        
+        # read attributes
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'int')
+        
+        obj = DBConfigInt(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, config_int, node=None):
+        if node is None:
+            node = ElementTree.Element('int')
+        
+        # set attributes
+        node.set('value',self.convertToStr(config_int.db_value, 'int'))
+        
+        return node
+
+class DBOpmProcessIdEffectXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'effect':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmProcessIdEffect(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process_id_effect, node=None):
+        if node is None:
+            node = ElementTree.Element('effect')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_process_id_effect.db_id, 'str'))
+        
+        return node
+
+class DBRefProvPlanXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:plan':
+            return None
+        
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
+        
+        obj = DBRefProvPlan(prov_ref=prov_ref)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, ref_prov_plan, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:plan')
+        
+        # set attributes
+        node.set('prov:ref',self.convertToStr(ref_prov_plan.db_prov_ref, 'str'))
+        
+        return node
+
+class DBOpmAccountsXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'accounts':
+            return None
+        
+        accounts = []
+        opm_overlapss = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'account':
+                _data = self.getDao('opm_account').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'overlaps':
+                _data = self.getDao('opm_overlaps').fromXML(child)
+                opm_overlapss.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAccounts(accounts=accounts,
+                            opm_overlapss=opm_overlapss)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_accounts, node=None):
+        if node is None:
+            node = ElementTree.Element('accounts')
+        
+        # set elements
+        accounts = opm_accounts.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account').toXML(account, childNode)
+        opm_overlapss = opm_accounts.db_opm_overlapss
+        for opm_overlaps in opm_overlapss:
+            if (opm_overlapss is not None) and (opm_overlapss != ""):
+                childNode = ElementTree.SubElement(node, 'overlaps')
+                self.getDao('opm_overlaps').toXML(opm_overlaps, childNode)
+        
+        return node
+
+class DBRefProvAgentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:agent':
+            return None
+        
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
+        
+        obj = DBRefProvAgent(prov_ref=prov_ref)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, ref_prov_agent, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:agent')
+        
+        # set attributes
+        node.set('prov:ref',self.convertToStr(ref_prov_agent.db_prov_ref, 'str'))
+        
+        return node
+
+class DBPortSpecXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'portSpec':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('optional', None)
+        optional = self.convertFromStr(data, 'int')
+        data = node.get('depth', None)
+        depth = self.convertFromStr(data, 'int')
+        data = node.get('sortKey', None)
+        sort_key = self.convertFromStr(data, 'int')
+        data = node.get('minConns', None)
+        min_conns = self.convertFromStr(data, 'int')
+        data = node.get('maxConns', None)
+        max_conns = self.convertFromStr(data, 'int')
+        
+        portSpecItems = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'portSpecItem':
+                _data = self.getDao('portSpecItem').fromXML(child)
+                portSpecItems.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBPortSpec(id=id,
+                         name=name,
+                         type=type,
+                         optional=optional,
+                         depth=depth,
+                         sort_key=sort_key,
+                         portSpecItems=portSpecItems,
+                         min_conns=min_conns,
+                         max_conns=max_conns)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, portSpec, node=None):
+        if node is None:
+            node = ElementTree.Element('portSpec')
+        
+        # set attributes
+        node.set('id',self.convertToStr(portSpec.db_id, 'long'))
+        node.set('name',self.convertToStr(portSpec.db_name, 'str'))
+        node.set('type',self.convertToStr(portSpec.db_type, 'str'))
+        node.set('optional',self.convertToStr(portSpec.db_optional, 'int'))
+        node.set('depth',self.convertToStr(portSpec.db_depth, 'int'))
+        node.set('sortKey',self.convertToStr(portSpec.db_sort_key, 'int'))
+        node.set('minConns',self.convertToStr(portSpec.db_min_conns, 'int'))
+        node.set('maxConns',self.convertToStr(portSpec.db_max_conns, 'int'))
+        
+        # set elements
+        portSpecItems = portSpec.db_portSpecItems
+        for portSpecItem in portSpecItems:
+            if (portSpecItems is not None) and (portSpecItems != ""):
+                childNode = ElementTree.SubElement(node, 'portSpecItem')
+                self.getDao('portSpecItem').toXML(portSpecItem, childNode)
+        
+        return node
+
+class DBEnabledPackagesXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'packages':
+            return None
+        
+        packages = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'package':
+                _data = self.getDao('startup_package').fromXML(child)
+                packages.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBEnabledPackages(packages=packages)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, enabled_packages, node=None):
+        if node is None:
+            node = ElementTree.Element('packages')
+        
+        # set elements
+        packages = enabled_packages.db_packages
+        for package in packages:
+            if (packages is not None) and (packages != ""):
+                childNode = ElementTree.SubElement(node, 'package')
+                self.getDao('startup_package').toXML(package, childNode)
+        
+        return node
+
+class DBOpmArtifactXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'artifact':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        value = None
+        accounts = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.getDao('opm_artifact_value').fromXML(child)
+                value = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmArtifact(id=id,
+                            value=value,
+                            accounts=accounts)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_artifact, node=None):
+        if node is None:
+            node = ElementTree.Element('artifact')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_artifact.db_id, 'str'))
+        
+        # set elements
+        value = opm_artifact.db_value
+        if value is not None:
+            if (value is not None) and (value != ""):
+                childNode = ElementTree.SubElement(node, 'value')
+                self.getDao('opm_artifact_value').toXML(value, childNode)
+        accounts = opm_artifact.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        
+        return node
+
+class DBLogXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'log':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('vistrail_id', None)
+        vistrail_id = self.convertFromStr(data, 'long')
+        
+        workflow_execs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'workflowExec':
+                _data = self.getDao('workflow_exec').fromXML(child)
+                workflow_execs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBLog(id=id,
+                    version=version,
+                    name=name,
+                    workflow_execs=workflow_execs,
+                    vistrail_id=vistrail_id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, log, node=None):
+        if node is None:
+            node = ElementTree.Element('log')
+        
+        # set attributes
+        node.set('id',self.convertToStr(log.db_id, 'long'))
+        node.set('version',self.convertToStr(log.db_version, 'str'))
+        node.set('name',self.convertToStr(log.db_name, 'str'))
+        node.set('vistrail_id',self.convertToStr(log.db_vistrail_id, 'long'))
+        
+        # set elements
+        workflow_execs = log.db_workflow_execs
+        for workflow_exec in workflow_execs:
+            if (workflow_execs is not None) and (workflow_execs != ""):
+                childNode = ElementTree.SubElement(node, 'workflowExec')
+                self.getDao('workflow_exec').toXML(workflow_exec, childNode)
+        
+        return node
+
+class DBLoopIterationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'loopIteration':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('iteration', None)
+        iteration = self.convertFromStr(data, 'int')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('error', None)
+        error = self.convertFromStr(data, 'str')
+        
+        item_execs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBLoopIteration(item_execs=item_execs,
+                              id=id,
+                              ts_start=ts_start,
+                              ts_end=ts_end,
+                              iteration=iteration,
+                              completed=completed,
+                              error=error)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, loop_iteration, node=None):
+        if node is None:
+            node = ElementTree.Element('loopIteration')
+        
+        # set attributes
+        node.set('id',self.convertToStr(loop_iteration.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(loop_iteration.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(loop_iteration.db_ts_end, 'datetime'))
+        node.set('iteration',self.convertToStr(loop_iteration.db_iteration, 'int'))
+        node.set('completed',self.convertToStr(loop_iteration.db_completed, 'int'))
+        node.set('error',self.convertToStr(loop_iteration.db_error, 'str'))
+        
+        # set elements
+        item_execs = loop_iteration.db_item_execs
+        for item_exec in item_execs:
+            if item_exec.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(item_exec, childNode)
+        
+        return node
+
+class DBOpmProcessIdCauseXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'cause':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmProcessIdCause(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process_id_cause, node=None):
+        if node is None:
+            node = ElementTree.Element('cause')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_process_id_cause.db_id, 'str'))
+        
+        return node
+
+class DBOpmArtifactsXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'artifacts':
+            return None
+        
+        artifacts = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'artifact':
+                _data = self.getDao('opm_artifact').fromXML(child)
+                artifacts.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmArtifacts(artifacts=artifacts)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_artifacts, node=None):
+        if node is None:
+            node = ElementTree.Element('artifacts')
+        
+        # set elements
+        artifacts = opm_artifacts.db_artifacts
+        for artifact in artifacts:
+            if (artifacts is not None) and (artifacts != ""):
+                childNode = ElementTree.SubElement(node, 'artifact')
+                self.getDao('opm_artifact').toXML(artifact, childNode)
+        
+        return node
+
+class DBPEParameterXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'peParameter':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('interpolator', None)
+        interpolator = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        data = node.get('dimension', None)
+        dimension = self.convertFromStr(data, 'long')
+        
+        obj = DBPEParameter(id=id,
+                            pos=pos,
+                            interpolator=interpolator,
+                            value=value,
+                            dimension=dimension)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, pe_parameter, node=None):
+        if node is None:
+            node = ElementTree.Element('peParameter')
+        
+        # set attributes
+        node.set('id',self.convertToStr(pe_parameter.db_id, 'long'))
+        node.set('pos',self.convertToStr(pe_parameter.db_pos, 'long'))
+        node.set('interpolator',self.convertToStr(pe_parameter.db_interpolator, 'str'))
+        node.set('value',self.convertToStr(pe_parameter.db_value, 'str'))
+        node.set('dimension',self.convertToStr(pe_parameter.db_dimension, 'long'))
+        
+        return node
+
+class DBWorkflowExecXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'workflowExec':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        data = node.get('ip', None)
+        ip = self.convertFromStr(data, 'str')
+        data = node.get('session', None)
+        session = self.convertFromStr(data, 'long')
+        data = node.get('vtVersion', None)
+        vt_version = self.convertFromStr(data, 'str')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('parentId', None)
+        parent_id = self.convertFromStr(data, 'long')
+        data = node.get('parentType', None)
+        parent_type = self.convertFromStr(data, 'str')
+        data = node.get('parentVersion', None)
+        parent_version = self.convertFromStr(data, 'long')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        annotations = []
+        machines = []
+        item_execs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'machine':
+                _data = self.getDao('machine').fromXML(child)
+                machines.append(_data)
+            elif child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                item_execs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBWorkflowExec(item_execs=item_execs,
+                             id=id,
+                             user=user,
+                             ip=ip,
+                             session=session,
+                             vt_version=vt_version,
+                             ts_start=ts_start,
+                             ts_end=ts_end,
+                             parent_id=parent_id,
+                             parent_type=parent_type,
+                             parent_version=parent_version,
+                             completed=completed,
+                             name=name,
+                             annotations=annotations,
+                             machines=machines)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, workflow_exec, node=None):
+        if node is None:
+            node = ElementTree.Element('workflowExec')
+        
+        # set attributes
+        node.set('id',self.convertToStr(workflow_exec.db_id, 'long'))
+        node.set('user',self.convertToStr(workflow_exec.db_user, 'str'))
+        node.set('ip',self.convertToStr(workflow_exec.db_ip, 'str'))
+        node.set('session',self.convertToStr(workflow_exec.db_session, 'long'))
+        node.set('vtVersion',self.convertToStr(workflow_exec.db_vt_version, 'str'))
+        node.set('tsStart',self.convertToStr(workflow_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(workflow_exec.db_ts_end, 'datetime'))
+        node.set('parentId',self.convertToStr(workflow_exec.db_parent_id, 'long'))
+        node.set('parentType',self.convertToStr(workflow_exec.db_parent_type, 'str'))
+        node.set('parentVersion',self.convertToStr(workflow_exec.db_parent_version, 'long'))
+        node.set('completed',self.convertToStr(workflow_exec.db_completed, 'int'))
+        node.set('name',self.convertToStr(workflow_exec.db_name, 'str'))
+        
+        # set elements
+        annotations = workflow_exec.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        machines = workflow_exec.db_machines
+        for machine in machines:
+            if (machines is not None) and (machines != ""):
+                childNode = ElementTree.SubElement(node, 'machine')
+                self.getDao('machine').toXML(machine, childNode)
+        item_execs = workflow_exec.db_item_execs
+        for item_exec in item_execs:
+            if item_exec.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(item_exec, childNode)
+            elif item_exec.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(item_exec, childNode)
+        
+        return node
+
+class DBLocationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'location':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('x', None)
+        x = self.convertFromStr(data, 'float')
+        data = node.get('y', None)
+        y = self.convertFromStr(data, 'float')
+        
+        obj = DBLocation(id=id,
+                         x=x,
+                         y=y)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, location, node=None):
+        if node is None:
+            node = ElementTree.Element('location')
+        
+        # set attributes
+        node.set('id',self.convertToStr(location.db_id, 'long'))
+        node.set('x',self.convertToStr(location.db_x, 'float'))
+        node.set('y',self.convertToStr(location.db_y, 'float'))
+        
+        return node
+
+class DBFunctionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'function':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        parameters = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'parameter':
+                _data = self.getDao('parameter').fromXML(child)
+                parameters.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBFunction(id=id,
+                         pos=pos,
+                         name=name,
+                         parameters=parameters)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, function, node=None):
+        if node is None:
+            node = ElementTree.Element('function')
+        
+        # set attributes
+        node.set('id',self.convertToStr(function.db_id, 'long'))
+        node.set('pos',self.convertToStr(function.db_pos, 'long'))
+        node.set('name',self.convertToStr(function.db_name, 'str'))
+        
+        # set elements
+        parameters = function.db_parameters
+        for parameter in parameters:
+            if (parameters is not None) and (parameters != ""):
+                childNode = ElementTree.SubElement(node, 'parameter')
+                self.getDao('parameter').toXML(parameter, childNode)
+        
+        return node
+
+class DBActionAnnotationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'actionAnnotation':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        data = node.get('actionId', None)
+        action_id = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        
+        obj = DBActionAnnotation(id=id,
+                                 key=key,
+                                 value=value,
+                                 action_id=action_id,
+                                 date=date,
+                                 user=user)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, actionAnnotation, node=None):
+        if node is None:
+            node = ElementTree.Element('actionAnnotation')
+        
+        # set attributes
+        node.set('id',self.convertToStr(actionAnnotation.db_id, 'long'))
+        node.set('key',self.convertToStr(actionAnnotation.db_key, 'str'))
+        node.set('value',self.convertToStr(actionAnnotation.db_value, 'str'))
+        node.set('actionId',self.convertToStr(actionAnnotation.db_action_id, 'long'))
+        node.set('date',self.convertToStr(actionAnnotation.db_date, 'datetime'))
+        node.set('user',self.convertToStr(actionAnnotation.db_user, 'str'))
+        
+        return node
+
+class DBProvActivityXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:activity':
+            return None
+        
+        # read attributes
+        data = node.get('prov:id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        startTime = None
+        endTime = None
+        vt_id = None
+        vt_type = None
+        vt_cached = None
+        vt_completed = None
+        vt_machine_id = None
+        vt_error = None
+        is_part_of = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:startTime':
+                _data = self.convertFromStr(child.text,'str')
+                startTime = _data
+            elif child_tag == 'prov:endTime':
+                _data = self.convertFromStr(child.text,'str')
+                endTime = _data
+            elif child_tag == 'vt:id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_id = _data
+            elif child_tag == 'vt:type':
+                _data = self.convertFromStr(child.text,'str')
+                vt_type = _data
+            elif child_tag == 'vt:cached':
+                _data = self.convertFromStr(child.text,'str')
+                vt_cached = _data
+            elif child_tag == 'vt:completed':
+                _data = self.convertFromStr(child.text,'str')
+                vt_completed = _data
+            elif child_tag == 'vt:machine_id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_id = _data
+            elif child_tag == 'vt:error':
+                _data = self.convertFromStr(child.text,'str')
+                vt_error = _data
+            elif child_tag == 'dcterms:isPartOf':
+                _data = self.getDao('is_part_of').fromXML(child)
+                is_part_of = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvActivity(id=id,
+                             startTime=startTime,
+                             endTime=endTime,
+                             vt_id=vt_id,
+                             vt_type=vt_type,
+                             vt_cached=vt_cached,
+                             vt_completed=vt_completed,
+                             vt_machine_id=vt_machine_id,
+                             vt_error=vt_error,
+                             is_part_of=is_part_of)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_activity, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:activity')
+        
+        # set attributes
+        node.set('prov:id',self.convertToStr(prov_activity.db_id, 'str'))
+        
+        # set elements
+        startTime = prov_activity.db_startTime
+        if (startTime is not None) and (startTime != ""):
+            childNode = ElementTree.SubElement(node, 'prov:startTime')
+            childNode.text = self.convertToStr(startTime, 'str')
+        endTime = prov_activity.db_endTime
+        if (endTime is not None) and (endTime != ""):
+            childNode = ElementTree.SubElement(node, 'prov:endTime')
+            childNode.text = self.convertToStr(endTime, 'str')
+        vt_id = prov_activity.db_vt_id
+        if (vt_id is not None) and (vt_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:id')
+            childNode.text = self.convertToStr(vt_id, 'str')
+        vt_type = prov_activity.db_vt_type
+        if (vt_type is not None) and (vt_type != ""):
+            childNode = ElementTree.SubElement(node, 'vt:type')
+            childNode.text = self.convertToStr(vt_type, 'str')
+        vt_cached = prov_activity.db_vt_cached
+        if (vt_cached is not None) and (vt_cached != ""):
+            childNode = ElementTree.SubElement(node, 'vt:cached')
+            childNode.text = self.convertToStr(vt_cached, 'str')
+        vt_completed = prov_activity.db_vt_completed
+        if (vt_completed is not None) and (vt_completed != ""):
+            childNode = ElementTree.SubElement(node, 'vt:completed')
+            childNode.text = self.convertToStr(vt_completed, 'str')
+        vt_machine_id = prov_activity.db_vt_machine_id
+        if (vt_machine_id is not None) and (vt_machine_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_id')
+            childNode.text = self.convertToStr(vt_machine_id, 'str')
+        vt_error = prov_activity.db_vt_error
+        if (vt_error is not None) and (vt_error != ""):
+            childNode = ElementTree.SubElement(node, 'vt:error')
+            childNode.text = self.convertToStr(vt_error, 'str')
+        is_part_of = prov_activity.db_is_part_of
+        if is_part_of is not None:
+            if (is_part_of is not None) and (is_part_of != ""):
+                childNode = ElementTree.SubElement(node, 'dcterms:isPartOf')
+                self.getDao('is_part_of').toXML(is_part_of, childNode)
+        
+        return node
+
+class DBProvUsageXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:used':
+            return None
+        
+        prov_activity = None
+        prov_entity = None
+        prov_role = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:activity':
+                _data = self.getDao('ref_prov_activity').fromXML(child)
+                prov_activity = _data
+            elif child_tag == 'prov:entity':
+                _data = self.getDao('ref_prov_entity').fromXML(child)
+                prov_entity = _data
+            elif child_tag == 'prov:role':
+                _data = self.convertFromStr(child.text,'str')
+                prov_role = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvUsage(prov_activity=prov_activity,
+                          prov_entity=prov_entity,
+                          prov_role=prov_role)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_usage, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:used')
+        
+        # set elements
+        prov_activity = prov_usage.db_prov_activity
+        if prov_activity is not None:
+            if (prov_activity is not None) and (prov_activity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
+        prov_entity = prov_usage.db_prov_entity
+        if prov_entity is not None:
+            if (prov_entity is not None) and (prov_entity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:entity')
+                self.getDao('ref_prov_entity').toXML(prov_entity, childNode)
+        prov_role = prov_usage.db_prov_role
+        if (prov_role is not None) and (prov_role != ""):
+            childNode = ElementTree.SubElement(node, 'prov:role')
+            childNode.text = self.convertToStr(prov_role, 'str')
+        
+        return node
+
+class DBOpmArtifactIdEffectXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'effect':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmArtifactIdEffect(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_artifact_id_effect, node=None):
+        if node is None:
+            node = ElementTree.Element('effect')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_artifact_id_effect.db_id, 'str'))
+        
+        return node
+
+class DBOpmGraphXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'opmGraph':
+            return None
+        
+        accounts = None
+        processes = None
+        artifacts = None
+        agents = None
+        dependencies = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'accounts':
+                _data = self.getDao('opm_accounts').fromXML(child)
+                accounts = _data
+            elif child_tag == 'processes':
+                _data = self.getDao('opm_processes').fromXML(child)
+                processes = _data
+            elif child_tag == 'artifacts':
+                _data = self.getDao('opm_artifacts').fromXML(child)
+                artifacts = _data
+            elif child_tag == 'agents':
+                _data = self.getDao('opm_agents').fromXML(child)
+                agents = _data
+            elif child_tag == 'causalDependencies':
+                _data = self.getDao('opm_dependencies').fromXML(child)
+                dependencies = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmGraph(accounts=accounts,
+                         processes=processes,
+                         artifacts=artifacts,
+                         agents=agents,
+                         dependencies=dependencies)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_graph, node=None):
+        if node is None:
+            node = ElementTree.Element('opmGraph')
+        
+        # set elements
+        accounts = opm_graph.db_accounts
+        if accounts is not None:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'accounts')
+                self.getDao('opm_accounts').toXML(accounts, childNode)
+        processes = opm_graph.db_processes
+        if processes is not None:
+            if (processes is not None) and (processes != ""):
+                childNode = ElementTree.SubElement(node, 'processes')
+                self.getDao('opm_processes').toXML(processes, childNode)
+        artifacts = opm_graph.db_artifacts
+        if artifacts is not None:
+            if (artifacts is not None) and (artifacts != ""):
+                childNode = ElementTree.SubElement(node, 'artifacts')
+                self.getDao('opm_artifacts').toXML(artifacts, childNode)
+        agents = opm_graph.db_agents
+        if agents is not None:
+            if (agents is not None) and (agents != ""):
+                childNode = ElementTree.SubElement(node, 'agents')
+                self.getDao('opm_agents').toXML(agents, childNode)
+        dependencies = opm_graph.db_dependencies
+        if dependencies is not None:
+            if (dependencies is not None) and (dependencies != ""):
+                childNode = ElementTree.SubElement(node, 'causalDependencies')
+                self.getDao('opm_dependencies').toXML(dependencies, childNode)
+        
+        return node
+
+class DBIsPartOfXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'dcterms:isPartOf':
+            return None
+        
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
+        
+        obj = DBIsPartOf(prov_ref=prov_ref)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, is_part_of, node=None):
+        if node is None:
+            node = ElementTree.Element('dcterms:isPartOf')
+        
+        # set attributes
+        node.set('prov:ref',self.convertToStr(is_part_of.db_prov_ref, 'str'))
+        
+        return node
+
+class DBOpmWasDerivedFromXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'wasDerivedFrom':
+            return None
+        
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        opm_times = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'effect':
+                _data = self.getDao('opm_artifact_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'cause':
+                _data = self.getDao('opm_artifact_id_cause').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                opm_times.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmWasDerivedFrom(effect=effect,
+                                  role=role,
+                                  cause=cause,
+                                  accounts=accounts,
+                                  opm_times=opm_times)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_was_derived_from, node=None):
+        if node is None:
+            node = ElementTree.Element('wasDerivedFrom')
+        
+        # set elements
+        effect = opm_was_derived_from.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_artifact_id_effect').toXML(effect, childNode)
+        role = opm_was_derived_from.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_was_derived_from.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'cause')
+                self.getDao('opm_artifact_id_cause').toXML(cause, childNode)
+        accounts = opm_was_derived_from.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        opm_times = opm_was_derived_from.db_opm_times
+        for opm_time in opm_times:
+            if (opm_times is not None) and (opm_times != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(opm_time, childNode)
+        
+        return node
+
+class DBControlParameterXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'controlParameter':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBControlParameter(id=id,
+                                 name=name,
+                                 value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, controlParameter, node=None):
+        if node is None:
+            node = ElementTree.Element('controlParameter')
+        
+        # set attributes
+        node.set('id',self.convertToStr(controlParameter.db_id, 'long'))
+        node.set('name',self.convertToStr(controlParameter.db_name, 'str'))
+        node.set('value',self.convertToStr(controlParameter.db_value, 'str'))
+        
+        return node
+
+class DBPluginDataXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'plugin_data':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('data', None)
+        data = self.convertFromStr(data, 'str')
+        
+        obj = DBPluginData(id=id,
+                           data=data)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, plugin_data, node=None):
+        if node is None:
+            node = ElementTree.Element('plugin_data')
+        
+        # set attributes
+        node.set('id',self.convertToStr(plugin_data.db_id, 'long'))
+        node.set('data',self.convertToStr(plugin_data.db_data, 'str'))
+        
+        return node
+
+class DBDeleteXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'delete':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('what', None)
+        what = self.convertFromStr(data, 'str')
+        data = node.get('objectId', None)
+        objectId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjId', None)
+        parentObjId = self.convertFromStr(data, 'long')
+        data = node.get('parentObjType', None)
+        parentObjType = self.convertFromStr(data, 'str')
+        
+        obj = DBDelete(id=id,
+                       what=what,
+                       objectId=objectId,
+                       parentObjId=parentObjId,
+                       parentObjType=parentObjType)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, delete, node=None):
+        if node is None:
+            node = ElementTree.Element('delete')
+        
+        # set attributes
+        node.set('id',self.convertToStr(delete.db_id, 'long'))
+        node.set('what',self.convertToStr(delete.db_what, 'str'))
+        node.set('objectId',self.convertToStr(delete.db_objectId, 'long'))
+        node.set('parentObjId',self.convertToStr(delete.db_parentObjId, 'long'))
+        node.set('parentObjType',self.convertToStr(delete.db_parentObjType, 'str'))
+        
+        return node
+
+class DBVistrailVariableXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'vistrailVariable':
+            return None
+        
+        # read attributes
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('uuid', None)
+        uuid = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('module', None)
+        module = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBVistrailVariable(name=name,
+                                 uuid=uuid,
+                                 package=package,
+                                 module=module,
+                                 namespace=namespace,
+                                 value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, vistrailVariable, node=None):
+        if node is None:
+            node = ElementTree.Element('vistrailVariable')
+        
+        # set attributes
+        node.set('name',self.convertToStr(vistrailVariable.db_name, 'str'))
+        node.set('uuid',self.convertToStr(vistrailVariable.db_uuid, 'str'))
+        node.set('package',self.convertToStr(vistrailVariable.db_package, 'str'))
+        node.set('module',self.convertToStr(vistrailVariable.db_module, 'str'))
+        node.set('namespace',self.convertToStr(vistrailVariable.db_namespace, 'str'))
+        node.set('value',self.convertToStr(vistrailVariable.db_value, 'str'))
+        
+        return node
+
+class DBOpmOverlapsXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'overlaps':
+            return None
+        
+        opm_account_ids = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                opm_account_ids.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmOverlaps(opm_account_ids=opm_account_ids)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_overlaps, node=None):
+        if node is None:
+            node = ElementTree.Element('overlaps')
+        
+        # set elements
+        opm_account_ids = opm_overlaps.db_opm_account_ids
+        for opm_account_id in opm_account_ids:
+            if (opm_account_ids is not None) and (opm_account_ids != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(opm_account_id, childNode)
+        
+        return node
+
+class DBOpmWasTriggeredByXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'wasTriggeredBy':
+            return None
+        
+        effect = None
+        role = None
+        cause = None
+        accounts = []
+        opm_times = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'effect':
+                _data = self.getDao('opm_process_id_effect').fromXML(child)
+                effect = _data
+            elif child_tag == 'role':
+                _data = self.getDao('opm_role').fromXML(child)
+                role = _data
+            elif child_tag == 'cause':
+                _data = self.getDao('opm_process_id_cause').fromXML(child)
+                cause = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child_tag == 'time':
+                _data = self.getDao('opm_time').fromXML(child)
+                opm_times.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmWasTriggeredBy(effect=effect,
+                                  role=role,
+                                  cause=cause,
+                                  accounts=accounts,
+                                  opm_times=opm_times)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_was_triggered_by, node=None):
+        if node is None:
+            node = ElementTree.Element('wasTriggeredBy')
+        
+        # set elements
+        effect = opm_was_triggered_by.db_effect
+        if effect is not None:
+            if (effect is not None) and (effect != ""):
+                childNode = ElementTree.SubElement(node, 'effect')
+                self.getDao('opm_process_id_effect').toXML(effect, childNode)
+        role = opm_was_triggered_by.db_role
+        if role is not None:
+            if (role is not None) and (role != ""):
+                childNode = ElementTree.SubElement(node, 'role')
+                self.getDao('opm_role').toXML(role, childNode)
+        cause = opm_was_triggered_by.db_cause
+        if cause is not None:
+            if (cause is not None) and (cause != ""):
+                childNode = ElementTree.SubElement(node, 'cause')
+                self.getDao('opm_process_id_cause').toXML(cause, childNode)
+        accounts = opm_was_triggered_by.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        opm_times = opm_was_triggered_by.db_opm_times
+        for opm_time in opm_times:
+            if (opm_times is not None) and (opm_times != ""):
+                childNode = ElementTree.SubElement(node, 'time')
+                self.getDao('opm_time').toXML(opm_time, childNode)
+        
+        return node
+
+class DBModuleDescriptorXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'moduleDescriptor':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('packageVersion', None)
+        package_version = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('baseDescriptorId', None)
+        base_descriptor_id = self.convertFromStr(data, 'long')
+        
+        portSpecs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'portSpec':
+                _data = self.getDao('portSpec').fromXML(child)
+                portSpecs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBModuleDescriptor(id=id,
+                                 name=name,
+                                 package=package,
+                                 namespace=namespace,
+                                 package_version=package_version,
+                                 version=version,
+                                 base_descriptor_id=base_descriptor_id,
+                                 portSpecs=portSpecs)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, module_descriptor, node=None):
+        if node is None:
+            node = ElementTree.Element('moduleDescriptor')
+        
+        # set attributes
+        node.set('id',self.convertToStr(module_descriptor.db_id, 'long'))
+        node.set('name',self.convertToStr(module_descriptor.db_name, 'str'))
+        node.set('package',self.convertToStr(module_descriptor.db_package, 'str'))
+        node.set('namespace',self.convertToStr(module_descriptor.db_namespace, 'str'))
+        node.set('packageVersion',self.convertToStr(module_descriptor.db_package_version, 'str'))
+        node.set('version',self.convertToStr(module_descriptor.db_version, 'str'))
+        node.set('baseDescriptorId',self.convertToStr(module_descriptor.db_base_descriptor_id, 'long'))
+        
+        # set elements
+        portSpecs = module_descriptor.db_portSpecs
+        for portSpec in portSpecs:
+            if (portSpecs is not None) and (portSpecs != ""):
+                childNode = ElementTree.SubElement(node, 'portSpec')
+                self.getDao('portSpec').toXML(portSpec, childNode)
+        
+        return node
+
+class DBTagXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'tag':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        
+        obj = DBTag(id=id,
+                    name=name)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, tag, node=None):
+        if node is None:
+            node = ElementTree.Element('tag')
+        
+        # set attributes
+        node.set('id',self.convertToStr(tag.db_id, 'long'))
+        node.set('name',self.convertToStr(tag.db_name, 'str'))
+        
+        return node
+
+class DBOpmRoleXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'role':
+            return None
+        
+        # read attributes
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmRole(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_role, node=None):
+        if node is None:
+            node = ElementTree.Element('role')
+        
+        # set attributes
+        node.set('value',self.convertToStr(opm_role.db_value, 'str'))
+        
+        return node
+
+class DBProvDocumentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:document':
+            return None
+        
+        prov_entitys = []
+        prov_activitys = []
+        prov_agents = []
+        vt_connections = []
+        prov_usages = []
+        prov_generations = []
+        prov_associations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:entity':
+                _data = self.getDao('prov_entity').fromXML(child)
+                prov_entitys.append(_data)
+            elif child_tag == 'prov:activity':
+                _data = self.getDao('prov_activity').fromXML(child)
+                prov_activitys.append(_data)
+            elif child_tag == 'prov:agent':
+                _data = self.getDao('prov_agent').fromXML(child)
+                prov_agents.append(_data)
+            elif child_tag == 'vt:connection':
+                _data = self.getDao('vt_connection').fromXML(child)
+                vt_connections.append(_data)
+            elif child_tag == 'prov:used':
+                _data = self.getDao('prov_usage').fromXML(child)
+                prov_usages.append(_data)
+            elif child_tag == 'prov:wasGeneratedBy':
+                _data = self.getDao('prov_generation').fromXML(child)
+                prov_generations.append(_data)
+            elif child_tag == 'prov:wasAssociatedWith':
+                _data = self.getDao('prov_association').fromXML(child)
+                prov_associations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvDocument(prov_entitys=prov_entitys,
+                             prov_activitys=prov_activitys,
+                             prov_agents=prov_agents,
+                             vt_connections=vt_connections,
+                             prov_usages=prov_usages,
+                             prov_generations=prov_generations,
+                             prov_associations=prov_associations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_document, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:document')
+        
+        # set elements
+        prov_entitys = prov_document.db_prov_entitys
+        for prov_entity in prov_entitys:
+            if (prov_entitys is not None) and (prov_entitys != ""):
+                childNode = ElementTree.SubElement(node, 'prov:entity')
+                self.getDao('prov_entity').toXML(prov_entity, childNode)
+        prov_activitys = prov_document.db_prov_activitys
+        for prov_activity in prov_activitys:
+            if (prov_activitys is not None) and (prov_activitys != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('prov_activity').toXML(prov_activity, childNode)
+        prov_agents = prov_document.db_prov_agents
+        for prov_agent in prov_agents:
+            if (prov_agents is not None) and (prov_agents != ""):
+                childNode = ElementTree.SubElement(node, 'prov:agent')
+                self.getDao('prov_agent').toXML(prov_agent, childNode)
+        vt_connections = prov_document.db_vt_connections
+        for vt_connection in vt_connections:
+            if (vt_connections is not None) and (vt_connections != ""):
+                childNode = ElementTree.SubElement(node, 'vt:connection')
+                self.getDao('vt_connection').toXML(vt_connection, childNode)
+        prov_usages = prov_document.db_prov_usages
+        for prov_usage in prov_usages:
+            if (prov_usages is not None) and (prov_usages != ""):
+                childNode = ElementTree.SubElement(node, 'prov:used')
+                self.getDao('prov_usage').toXML(prov_usage, childNode)
+        prov_generations = prov_document.db_prov_generations
+        for prov_generation in prov_generations:
+            if (prov_generations is not None) and (prov_generations != ""):
+                childNode = ElementTree.SubElement(node, 'prov:wasGeneratedBy')
+                self.getDao('prov_generation').toXML(prov_generation, childNode)
+        prov_associations = prov_document.db_prov_associations
+        for prov_association in prov_associations:
+            if (prov_associations is not None) and (prov_associations != ""):
+                childNode = ElementTree.SubElement(node, 'prov:wasAssociatedWith')
+                self.getDao('prov_association').toXML(prov_association, childNode)
+        
+        return node
+
+class DBOpmProcessesXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'processes':
+            return None
+        
+        processs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'process':
+                _data = self.getDao('opm_process').fromXML(child)
+                processs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmProcesses(processs=processs)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_processes, node=None):
+        if node is None:
+            node = ElementTree.Element('processes')
+        
+        # set elements
+        processs = opm_processes.db_processs
+        for process in processs:
+            if (processs is not None) and (processs != ""):
+                childNode = ElementTree.SubElement(node, 'process')
+                self.getDao('opm_process').toXML(process, childNode)
+        
+        return node
+
+class DBOpmAccountIdXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'account':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmAccountId(id=id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_account_id, node=None):
+        if node is None:
+            node = ElementTree.Element('account')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_account_id.db_id, 'str'))
+        
+        return node
+
+class DBPortSpecItemXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'portSpecItem':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('module', None)
+        module = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('label', None)
+        label = self.convertFromStr(data, 'str')
+        data = node.get('default', None)
+        default = self.convertFromStr(data, 'str')
+        data = node.get('values', None)
+        values = self.convertFromStr(data, 'str')
+        data = node.get('entryType', None)
+        entry_type = self.convertFromStr(data, 'str')
+        
+        obj = DBPortSpecItem(id=id,
+                             pos=pos,
+                             module=module,
+                             package=package,
+                             namespace=namespace,
+                             label=label,
+                             default=default,
+                             values=values,
+                             entry_type=entry_type)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, portSpecItem, node=None):
+        if node is None:
+            node = ElementTree.Element('portSpecItem')
+        
+        # set attributes
+        node.set('id',self.convertToStr(portSpecItem.db_id, 'long'))
+        node.set('pos',self.convertToStr(portSpecItem.db_pos, 'long'))
+        node.set('module',self.convertToStr(portSpecItem.db_module, 'str'))
+        node.set('package',self.convertToStr(portSpecItem.db_package, 'str'))
+        node.set('namespace',self.convertToStr(portSpecItem.db_namespace, 'str'))
+        node.set('label',self.convertToStr(portSpecItem.db_label, 'str'))
+        node.set('default',self.convertToStr(portSpecItem.db_default, 'str'))
+        node.set('values',self.convertToStr(portSpecItem.db_values, 'str'))
+        node.set('entryType',self.convertToStr(portSpecItem.db_entry_type, 'str'))
+        
+        return node
+
+class DBMashupComponentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'component':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('vtid', None)
+        vtid = self.convertFromStr(data, 'long')
+        data = node.get('vttype', None)
+        vttype = self.convertFromStr(data, 'str')
+        data = node.get('vtparent_type', None)
+        vtparent_type = self.convertFromStr(data, 'str')
+        data = node.get('vtparent_id', None)
+        vtparent_id = self.convertFromStr(data, 'long')
+        data = node.get('vtpos', None)
+        vtpos = self.convertFromStr(data, 'long')
+        data = node.get('vtmid', None)
+        vtmid = self.convertFromStr(data, 'long')
+        data = node.get('pos', None)
+        pos = self.convertFromStr(data, 'long')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('val', None)
+        val = self.convertFromStr(data, 'str')
+        data = node.get('minVal', None)
+        minVal = self.convertFromStr(data, 'str')
+        data = node.get('maxVal', None)
+        maxVal = self.convertFromStr(data, 'str')
+        data = node.get('stepSize', None)
+        stepSize = self.convertFromStr(data, 'str')
+        data = node.get('valueList', None)
+        strvaluelist = self.convertFromStr(data, 'str')
+        data = node.get('widget', None)
+        widget = self.convertFromStr(data, 'str')
+        data = node.get('seq', None)
+        seq = self.convertFromStr(data, 'int')
+        data = node.get('parent', None)
+        parent = self.convertFromStr(data, 'str')
+        
+        obj = DBMashupComponent(id=id,
+                                vtid=vtid,
+                                vttype=vttype,
+                                vtparent_type=vtparent_type,
+                                vtparent_id=vtparent_id,
+                                vtpos=vtpos,
+                                vtmid=vtmid,
+                                pos=pos,
+                                type=type,
+                                val=val,
+                                minVal=minVal,
+                                maxVal=maxVal,
+                                stepSize=stepSize,
+                                strvaluelist=strvaluelist,
+                                widget=widget,
+                                seq=seq,
+                                parent=parent)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashup_component, node=None):
+        if node is None:
+            node = ElementTree.Element('component')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup_component.db_id, 'long'))
+        node.set('vtid',self.convertToStr(mashup_component.db_vtid, 'long'))
+        node.set('vttype',self.convertToStr(mashup_component.db_vttype, 'str'))
+        node.set('vtparent_type',self.convertToStr(mashup_component.db_vtparent_type, 'str'))
+        node.set('vtparent_id',self.convertToStr(mashup_component.db_vtparent_id, 'long'))
+        node.set('vtpos',self.convertToStr(mashup_component.db_vtpos, 'long'))
+        node.set('vtmid',self.convertToStr(mashup_component.db_vtmid, 'long'))
+        node.set('pos',self.convertToStr(mashup_component.db_pos, 'long'))
+        node.set('type',self.convertToStr(mashup_component.db_type, 'str'))
+        node.set('val',self.convertToStr(mashup_component.db_val, 'str'))
+        node.set('minVal',self.convertToStr(mashup_component.db_minVal, 'str'))
+        node.set('maxVal',self.convertToStr(mashup_component.db_maxVal, 'str'))
+        node.set('stepSize',self.convertToStr(mashup_component.db_stepSize, 'str'))
+        node.set('valueList',self.convertToStr(mashup_component.db_strvaluelist, 'str'))
+        node.set('widget',self.convertToStr(mashup_component.db_widget, 'str'))
+        node.set('seq',self.convertToStr(mashup_component.db_seq, 'int'))
+        node.set('parent',self.convertToStr(mashup_component.db_parent, 'str'))
+        
+        return node
+
+class DBMashupXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'mashup':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'long')
+        data = node.get('type', None)
+        type = self.convertFromStr(data, 'str')
+        data = node.get('vtid', None)
+        vtid = self.convertFromStr(data, 'long')
+        data = node.get('has_seq', None)
+        has_seq = self.convertFromStr(data, 'int')
+        
+        aliases = []
+        layout = None
+        geometry = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'alias':
+                _data = self.getDao('mashup_alias').fromXML(child)
+                aliases.append(_data)
+            elif child_tag == 'layout':
+                _data = self.convertFromStr(child.text,'str')
+                layout = _data
+            elif child_tag == 'geometry':
+                _data = self.convertFromStr(child.text,'str')
+                geometry = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBMashup(id=id,
+                       name=name,
+                       version=version,
+                       aliases=aliases,
+                       type=type,
+                       vtid=vtid,
+                       layout=layout,
+                       geometry=geometry,
+                       has_seq=has_seq)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashup, node=None):
+        if node is None:
+            node = ElementTree.Element('mashup')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup.db_id, 'long'))
+        node.set('name',self.convertToStr(mashup.db_name, 'str'))
+        node.set('version',self.convertToStr(mashup.db_version, 'long'))
+        node.set('type',self.convertToStr(mashup.db_type, 'str'))
+        node.set('vtid',self.convertToStr(mashup.db_vtid, 'long'))
+        node.set('has_seq',self.convertToStr(mashup.db_has_seq, 'int'))
+        
+        # set elements
+        aliases = mashup.db_aliases
+        for alias in aliases:
+            if (aliases is not None) and (aliases != ""):
+                childNode = ElementTree.SubElement(node, 'alias')
+                self.getDao('mashup_alias').toXML(alias, childNode)
+        layout = mashup.db_layout
+        if (layout is not None) and (layout != ""):
+            childNode = ElementTree.SubElement(node, 'layout')
+            childNode.text = self.convertToStr(layout, 'str')
+        geometry = mashup.db_geometry
+        if (geometry is not None) and (geometry != ""):
+            childNode = ElementTree.SubElement(node, 'geometry')
+            childNode.text = self.convertToStr(geometry, 'str')
+        
+        return node
+
+class DBMachineXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'machine':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('os', None)
+        os = self.convertFromStr(data, 'str')
+        data = node.get('architecture', None)
+        architecture = self.convertFromStr(data, 'str')
+        data = node.get('processor', None)
+        processor = self.convertFromStr(data, 'str')
+        data = node.get('ram', None)
+        ram = self.convertFromStr(data, 'int')
+        
+        obj = DBMachine(id=id,
+                        name=name,
+                        os=os,
+                        architecture=architecture,
+                        processor=processor,
+                        ram=ram)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, machine, node=None):
+        if node is None:
+            node = ElementTree.Element('machine')
+        
+        # set attributes
+        node.set('id',self.convertToStr(machine.db_id, 'long'))
+        node.set('name',self.convertToStr(machine.db_name, 'str'))
+        node.set('os',self.convertToStr(machine.db_os, 'str'))
+        node.set('architecture',self.convertToStr(machine.db_architecture, 'str'))
+        node.set('processor',self.convertToStr(machine.db_processor, 'str'))
+        node.set('ram',self.convertToStr(machine.db_ram, 'int'))
+        
+        return node
+
+class DBConfigFloatXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'float':
+            return None
+        
+        # read attributes
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'float')
+        
+        obj = DBConfigFloat(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, config_float, node=None):
+        if node is None:
+            node = ElementTree.Element('float')
+        
+        # set attributes
+        node.set('value',self.convertToStr(config_float.db_value, 'float'))
+        
+        return node
+
+class DBOtherXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'other':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.convertFromStr(child.text,'str')
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOther(id=id,
+                      key=key,
+                      value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, other, node=None):
+        if node is None:
+            node = ElementTree.Element('other')
+        
+        # set attributes
+        node.set('id',self.convertToStr(other.db_id, 'long'))
+        node.set('key',self.convertToStr(other.db_key, 'str'))
+        
+        # set elements
+        value = other.db_value
+        if (value is not None) and (value != ""):
+            childNode = ElementTree.SubElement(node, 'value')
+            childNode.text = self.convertToStr(value, 'str')
+        
+        return node
+
+class DBRefProvActivityXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:activity':
+            return None
+        
+        # read attributes
+        data = node.get('prov:ref', None)
+        prov_ref = self.convertFromStr(data, 'str')
+        
+        obj = DBRefProvActivity(prov_ref=prov_ref)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, ref_prov_activity, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:activity')
+        
+        # set attributes
+        node.set('prov:ref',self.convertToStr(ref_prov_activity.db_prov_ref, 'str'))
+        
+        return node
+
+class DBAbstractionXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'abstraction':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('cache', None)
+        cache = self.convertFromStr(data, 'int')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('namespace', None)
+        namespace = self.convertFromStr(data, 'str')
+        data = node.get('package', None)
+        package = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('internalVersion', None)
+        internal_version = self.convertFromStr(data, 'str')
+        
+        location = None
+        functions = []
+        annotations = []
+        controlParameters = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'location':
+                _data = self.getDao('location').fromXML(child)
+                location = _data
+            elif child_tag == 'function':
+                _data = self.getDao('function').fromXML(child)
+                functions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'controlParameter':
+                _data = self.getDao('controlParameter').fromXML(child)
+                controlParameters.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBAbstraction(id=id,
+                            cache=cache,
+                            name=name,
+                            namespace=namespace,
+                            package=package,
+                            version=version,
+                            internal_version=internal_version,
+                            location=location,
+                            functions=functions,
+                            annotations=annotations,
+                            controlParameters=controlParameters)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, abstraction, node=None):
+        if node is None:
+            node = ElementTree.Element('abstraction')
+        
+        # set attributes
+        node.set('id',self.convertToStr(abstraction.db_id, 'long'))
+        node.set('cache',self.convertToStr(abstraction.db_cache, 'int'))
+        node.set('name',self.convertToStr(abstraction.db_name, 'str'))
+        node.set('namespace',self.convertToStr(abstraction.db_namespace, 'str'))
+        node.set('package',self.convertToStr(abstraction.db_package, 'str'))
+        node.set('version',self.convertToStr(abstraction.db_version, 'str'))
+        node.set('internalVersion',self.convertToStr(abstraction.db_internal_version, 'str'))
+        
+        # set elements
+        location = abstraction.db_location
+        if location is not None:
+            if (location is not None) and (location != ""):
+                childNode = ElementTree.SubElement(node, 'location')
+                self.getDao('location').toXML(location, childNode)
+        functions = abstraction.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'function')
+                self.getDao('function').toXML(function, childNode)
+        annotations = abstraction.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        controlParameters = abstraction.db_controlParameters
+        for controlParameter in controlParameters:
+            if (controlParameters is not None) and (controlParameters != ""):
+                childNode = ElementTree.SubElement(node, 'controlParameter')
+                self.getDao('controlParameter').toXML(controlParameter, childNode)
+        
+        return node
+
+class DBProvAgentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:agent':
+            return None
+        
+        # read attributes
+        data = node.get('prov:id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        vt_id = None
+        prov_type = None
+        prov_label = None
+        vt_machine_os = None
+        vt_machine_architecture = None
+        vt_machine_processor = None
+        vt_machine_ram = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'vt:id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_id = _data
+            elif child_tag == 'prov:type':
+                _data = self.convertFromStr(child.text,'str')
+                prov_type = _data
+            elif child_tag == 'prov:label':
+                _data = self.convertFromStr(child.text,'str')
+                prov_label = _data
+            elif child_tag == 'vt:machine_os':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_os = _data
+            elif child_tag == 'vt:machine_architecture':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_architecture = _data
+            elif child_tag == 'vt:machine_processor':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_processor = _data
+            elif child_tag == 'vt:machine_ram':
+                _data = self.convertFromStr(child.text,'str')
+                vt_machine_ram = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvAgent(id=id,
+                          vt_id=vt_id,
+                          prov_type=prov_type,
+                          prov_label=prov_label,
+                          vt_machine_os=vt_machine_os,
+                          vt_machine_architecture=vt_machine_architecture,
+                          vt_machine_processor=vt_machine_processor,
+                          vt_machine_ram=vt_machine_ram)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_agent, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:agent')
+        
+        # set attributes
+        node.set('prov:id',self.convertToStr(prov_agent.db_id, 'str'))
+        
+        # set elements
+        vt_id = prov_agent.db_vt_id
+        if (vt_id is not None) and (vt_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:id')
+            childNode.text = self.convertToStr(vt_id, 'str')
+        prov_type = prov_agent.db_prov_type
+        if (prov_type is not None) and (prov_type != ""):
+            childNode = ElementTree.SubElement(node, 'prov:type')
+            childNode.text = self.convertToStr(prov_type, 'str')
+        prov_label = prov_agent.db_prov_label
+        if (prov_label is not None) and (prov_label != ""):
+            childNode = ElementTree.SubElement(node, 'prov:label')
+            childNode.text = self.convertToStr(prov_label, 'str')
+        vt_machine_os = prov_agent.db_vt_machine_os
+        if (vt_machine_os is not None) and (vt_machine_os != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_os')
+            childNode.text = self.convertToStr(vt_machine_os, 'str')
+        vt_machine_architecture = prov_agent.db_vt_machine_architecture
+        if (vt_machine_architecture is not None) and (vt_machine_architecture != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_architecture')
+            childNode.text = self.convertToStr(vt_machine_architecture, 'str')
+        vt_machine_processor = prov_agent.db_vt_machine_processor
+        if (vt_machine_processor is not None) and (vt_machine_processor != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_processor')
+            childNode.text = self.convertToStr(vt_machine_processor, 'str')
+        vt_machine_ram = prov_agent.db_vt_machine_ram
+        if (vt_machine_ram is not None) and (vt_machine_ram != ""):
+            childNode = ElementTree.SubElement(node, 'vt:machine_ram')
+            childNode.text = self.convertToStr(vt_machine_ram, 'str')
+        
+        return node
+
+class DBMashuptrailXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'mashuptrail':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('vtVersion', None)
+        vtVersion = self.convertFromStr(data, 'long')
+        
+        actions = []
+        annotations = []
+        actionAnnotations = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'action':
+                _data = self.getDao('mashup_action').fromXML(child)
+                actions.append(_data)
+            elif child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'actionAnnotation':
+                _data = self.getDao('mashup_actionAnnotation').fromXML(child)
+                actionAnnotations.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBMashuptrail(name=name,
+                            version=version,
+                            vtVersion=vtVersion,
+                            actions=actions,
+                            annotations=annotations,
+                            actionAnnotations=actionAnnotations)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashuptrail, node=None):
+        if node is None:
+            node = ElementTree.Element('mashuptrail')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashuptrail.db_name, 'str'))
+        node.set('version',self.convertToStr(mashuptrail.db_version, 'str'))
+        node.set('vtVersion',self.convertToStr(mashuptrail.db_vtVersion, 'long'))
+        
+        # set elements
+        actions = mashuptrail.db_actions
+        for action in actions:
+            if (actions is not None) and (actions != ""):
+                childNode = ElementTree.SubElement(node, 'action')
+                self.getDao('mashup_action').toXML(action, childNode)
+        annotations = mashuptrail.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        actionAnnotations = mashuptrail.db_actionAnnotations
+        for actionAnnotation in actionAnnotations:
+            if (actionAnnotations is not None) and (actionAnnotations != ""):
+                childNode = ElementTree.SubElement(node, 'actionAnnotation')
+                self.getDao('mashup_actionAnnotation').toXML(actionAnnotation, childNode)
+        
+        return node
+
+class DBRegistryXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'registry':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('version', None)
+        version = self.convertFromStr(data, 'str')
+        data = node.get('rootDescriptorId', None)
+        root_descriptor_id = self.convertFromStr(data, 'long')
+        
+        packages = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'package':
+                _data = self.getDao('package').fromXML(child)
+                packages.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBRegistry(id=id,
+                         version=version,
+                         root_descriptor_id=root_descriptor_id,
+                         packages=packages)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, registry, node=None):
+        if node is None:
+            node = ElementTree.Element('registry')
+        
+        # set attributes
+        node.set('id',self.convertToStr(registry.db_id, 'long'))
+        node.set('version',self.convertToStr(registry.db_version, 'str'))
+        node.set('rootDescriptorId',self.convertToStr(registry.db_root_descriptor_id, 'long'))
+        
+        # set elements
+        packages = registry.db_packages
+        for package in packages:
+            if (packages is not None) and (packages != ""):
+                childNode = ElementTree.SubElement(node, 'package')
+                self.getDao('package').toXML(package, childNode)
+        
+        return node
+
+class DBOpmAgentXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'agent':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        value = None
+        accounts = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.convertFromStr(child.text,'str')
+                value = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmAgent(id=id,
+                         value=value,
+                         accounts=accounts)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_agent, node=None):
+        if node is None:
+            node = ElementTree.Element('agent')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_agent.db_id, 'str'))
+        
+        # set elements
+        value = opm_agent.db_value
+        if (value is not None) and (value != ""):
+            childNode = ElementTree.SubElement(node, 'value')
+            childNode.text = self.convertToStr(value, 'str')
+        accounts = opm_agent.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        
+        return node
+
+class DBProvEntityXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:entity':
+            return None
+        
+        # read attributes
+        data = node.get('prov:id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        prov_type = None
+        prov_label = None
+        prov_value = None
+        vt_id = None
+        vt_type = None
+        vt_desc = None
+        vt_package = None
+        vt_version = None
+        vt_cache = None
+        vt_location_x = None
+        vt_location_y = None
+        is_part_of = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:type':
+                _data = self.convertFromStr(child.text,'str')
+                prov_type = _data
+            elif child_tag == 'prov:label':
+                _data = self.convertFromStr(child.text,'str')
+                prov_label = _data
+            elif child_tag == 'prov:value':
+                _data = self.convertFromStr(child.text,'str')
+                prov_value = _data
+            elif child_tag == 'vt:id':
+                _data = self.convertFromStr(child.text,'str')
+                vt_id = _data
+            elif child_tag == 'vt:type':
+                _data = self.convertFromStr(child.text,'str')
+                vt_type = _data
+            elif child_tag == 'vt:desc':
+                _data = self.convertFromStr(child.text,'str')
+                vt_desc = _data
+            elif child_tag == 'vt:package':
+                _data = self.convertFromStr(child.text,'str')
+                vt_package = _data
+            elif child_tag == 'vt:version':
+                _data = self.convertFromStr(child.text,'str')
+                vt_version = _data
+            elif child_tag == 'vt:cache':
+                _data = self.convertFromStr(child.text,'str')
+                vt_cache = _data
+            elif child_tag == 'vt:location_x':
+                _data = self.convertFromStr(child.text,'str')
+                vt_location_x = _data
+            elif child_tag == 'vt:location_y':
+                _data = self.convertFromStr(child.text,'str')
+                vt_location_y = _data
+            elif child_tag == 'dcterms:isPartOf':
+                _data = self.getDao('is_part_of').fromXML(child)
+                is_part_of = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvEntity(id=id,
+                           prov_type=prov_type,
+                           prov_label=prov_label,
+                           prov_value=prov_value,
+                           vt_id=vt_id,
+                           vt_type=vt_type,
+                           vt_desc=vt_desc,
+                           vt_package=vt_package,
+                           vt_version=vt_version,
+                           vt_cache=vt_cache,
+                           vt_location_x=vt_location_x,
+                           vt_location_y=vt_location_y,
+                           is_part_of=is_part_of)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_entity, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:entity')
+        
+        # set attributes
+        node.set('prov:id',self.convertToStr(prov_entity.db_id, 'str'))
+        
+        # set elements
+        prov_type = prov_entity.db_prov_type
+        if (prov_type is not None) and (prov_type != ""):
+            childNode = ElementTree.SubElement(node, 'prov:type')
+            childNode.text = self.convertToStr(prov_type, 'str')
+        prov_label = prov_entity.db_prov_label
+        if (prov_label is not None) and (prov_label != ""):
+            childNode = ElementTree.SubElement(node, 'prov:label')
+            childNode.text = self.convertToStr(prov_label, 'str')
+        prov_value = prov_entity.db_prov_value
+        if (prov_value is not None) and (prov_value != ""):
+            childNode = ElementTree.SubElement(node, 'prov:value')
+            childNode.text = self.convertToStr(prov_value, 'str')
+        vt_id = prov_entity.db_vt_id
+        if (vt_id is not None) and (vt_id != ""):
+            childNode = ElementTree.SubElement(node, 'vt:id')
+            childNode.text = self.convertToStr(vt_id, 'str')
+        vt_type = prov_entity.db_vt_type
+        if (vt_type is not None) and (vt_type != ""):
+            childNode = ElementTree.SubElement(node, 'vt:type')
+            childNode.text = self.convertToStr(vt_type, 'str')
+        vt_desc = prov_entity.db_vt_desc
+        if (vt_desc is not None) and (vt_desc != ""):
+            childNode = ElementTree.SubElement(node, 'vt:desc')
+            childNode.text = self.convertToStr(vt_desc, 'str')
+        vt_package = prov_entity.db_vt_package
+        if (vt_package is not None) and (vt_package != ""):
+            childNode = ElementTree.SubElement(node, 'vt:package')
+            childNode.text = self.convertToStr(vt_package, 'str')
+        vt_version = prov_entity.db_vt_version
+        if (vt_version is not None) and (vt_version != ""):
+            childNode = ElementTree.SubElement(node, 'vt:version')
+            childNode.text = self.convertToStr(vt_version, 'str')
+        vt_cache = prov_entity.db_vt_cache
+        if (vt_cache is not None) and (vt_cache != ""):
+            childNode = ElementTree.SubElement(node, 'vt:cache')
+            childNode.text = self.convertToStr(vt_cache, 'str')
+        vt_location_x = prov_entity.db_vt_location_x
+        if (vt_location_x is not None) and (vt_location_x != ""):
+            childNode = ElementTree.SubElement(node, 'vt:location_x')
+            childNode.text = self.convertToStr(vt_location_x, 'str')
+        vt_location_y = prov_entity.db_vt_location_y
+        if (vt_location_y is not None) and (vt_location_y != ""):
+            childNode = ElementTree.SubElement(node, 'vt:location_y')
+            childNode.text = self.convertToStr(vt_location_y, 'str')
+        is_part_of = prov_entity.db_is_part_of
+        if is_part_of is not None:
+            if (is_part_of is not None) and (is_part_of != ""):
+                childNode = ElementTree.SubElement(node, 'dcterms:isPartOf')
+                self.getDao('is_part_of').toXML(is_part_of, childNode)
+        
+        return node
+
+class DBAnnotationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'annotation':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        
+        obj = DBAnnotation(id=id,
+                           key=key,
+                           value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, annotation, node=None):
+        if node is None:
+            node = ElementTree.Element('annotation')
+        
+        # set attributes
+        node.set('id',self.convertToStr(annotation.db_id, 'long'))
+        node.set('key',self.convertToStr(annotation.db_key, 'str'))
+        node.set('value',self.convertToStr(annotation.db_value, 'str'))
+        
+        return node
+
+class DBOpmTimeXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'time':
+            return None
+        
+        # read attributes
+        data = node.get('noLaterThan', None)
+        no_later_than = self.convertFromStr(data, 'datetime')
+        data = node.get('noEarlierThan', None)
+        no_earlier_than = self.convertFromStr(data, 'datetime')
+        data = node.get('clockId', None)
+        clock_id = self.convertFromStr(data, 'str')
+        
+        obj = DBOpmTime(no_later_than=no_later_than,
+                        no_earlier_than=no_earlier_than,
+                        clock_id=clock_id)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_time, node=None):
+        if node is None:
+            node = ElementTree.Element('time')
+        
+        # set attributes
+        node.set('noLaterThan',self.convertToStr(opm_time.db_no_later_than, 'datetime'))
+        node.set('noEarlierThan',self.convertToStr(opm_time.db_no_earlier_than, 'datetime'))
+        node.set('clockId',self.convertToStr(opm_time.db_clock_id, 'str'))
+        
+        return node
+
+class DBParameterExplorationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'parameterExploration':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('actionId', None)
+        action_id = self.convertFromStr(data, 'long')
+        data = node.get('name', None)
+        name = self.convertFromStr(data, 'str')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        data = node.get('dims', None)
+        dims = self.convertFromStr(data, 'str')
+        data = node.get('layout', None)
+        layout = self.convertFromStr(data, 'str')
+        
+        functions = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'peFunction':
+                _data = self.getDao('pe_function').fromXML(child)
+                functions.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBParameterExploration(id=id,
+                                     action_id=action_id,
+                                     name=name,
+                                     date=date,
+                                     user=user,
+                                     dims=dims,
+                                     layout=layout,
+                                     functions=functions)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, parameter_exploration, node=None):
+        if node is None:
+            node = ElementTree.Element('parameterExploration')
+        
+        # set attributes
+        node.set('id',self.convertToStr(parameter_exploration.db_id, 'long'))
+        node.set('actionId',self.convertToStr(parameter_exploration.db_action_id, 'long'))
+        node.set('name',self.convertToStr(parameter_exploration.db_name, 'str'))
+        node.set('date',self.convertToStr(parameter_exploration.db_date, 'datetime'))
+        node.set('user',self.convertToStr(parameter_exploration.db_user, 'str'))
+        node.set('dims',self.convertToStr(parameter_exploration.db_dims, 'str'))
+        node.set('layout',self.convertToStr(parameter_exploration.db_layout, 'str'))
+        
+        # set elements
+        functions = parameter_exploration.db_functions
+        for function in functions:
+            if (functions is not None) and (functions != ""):
+                childNode = ElementTree.SubElement(node, 'peFunction')
+                self.getDao('pe_function').toXML(function, childNode)
+        
+        return node
+
+class DBMashupActionAnnotationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'actionAnnotation':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('key', None)
+        key = self.convertFromStr(data, 'str')
+        data = node.get('value', None)
+        value = self.convertFromStr(data, 'str')
+        data = node.get('action_id', None)
+        action_id = self.convertFromStr(data, 'long')
+        data = node.get('date', None)
+        date = self.convertFromStr(data, 'datetime')
+        data = node.get('user', None)
+        user = self.convertFromStr(data, 'str')
+        
+        obj = DBMashupActionAnnotation(id=id,
+                                       key=key,
+                                       value=value,
+                                       action_id=action_id,
+                                       date=date,
+                                       user=user)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, mashup_actionAnnotation, node=None):
+        if node is None:
+            node = ElementTree.Element('actionAnnotation')
+        
+        # set attributes
+        node.set('id',self.convertToStr(mashup_actionAnnotation.db_id, 'long'))
+        node.set('key',self.convertToStr(mashup_actionAnnotation.db_key, 'str'))
+        node.set('value',self.convertToStr(mashup_actionAnnotation.db_value, 'str'))
+        node.set('action_id',self.convertToStr(mashup_actionAnnotation.db_action_id, 'long'))
+        node.set('date',self.convertToStr(mashup_actionAnnotation.db_date, 'datetime'))
+        node.set('user',self.convertToStr(mashup_actionAnnotation.db_user, 'str'))
+        
+        return node
+
+class DBOpmProcessXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'process':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'str')
+        
+        value = None
+        accounts = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'value':
+                _data = self.getDao('opm_process_value').fromXML(child)
+                value = _data
+            elif child_tag == 'account':
+                _data = self.getDao('opm_account_id').fromXML(child)
+                accounts.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmProcess(id=id,
+                           value=value,
+                           accounts=accounts)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process, node=None):
+        if node is None:
+            node = ElementTree.Element('process')
+        
+        # set attributes
+        node.set('id',self.convertToStr(opm_process.db_id, 'str'))
+        
+        # set elements
+        value = opm_process.db_value
+        if value is not None:
+            if (value is not None) and (value != ""):
+                childNode = ElementTree.SubElement(node, 'value')
+                self.getDao('opm_process_value').toXML(value, childNode)
+        accounts = opm_process.db_accounts
+        for account in accounts:
+            if (accounts is not None) and (accounts != ""):
+                childNode = ElementTree.SubElement(node, 'account')
+                self.getDao('opm_account_id').toXML(account, childNode)
+        
+        return node
+
+class DBDisabledPackagesXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'disabledpackages':
+            return None
+        
+        packages = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'package':
+                _data = self.getDao('startup_package').fromXML(child)
+                packages.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBDisabledPackages(packages=packages)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, disabled_packages, node=None):
+        if node is None:
+            node = ElementTree.Element('disabledpackages')
+        
+        # set elements
+        packages = disabled_packages.db_packages
+        for package in packages:
+            if (packages is not None) and (packages != ""):
+                childNode = ElementTree.SubElement(node, 'package')
+                self.getDao('startup_package').toXML(package, childNode)
+        
+        return node
+
+class DBModuleExecXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'moduleExec':
+            return None
+        
+        # read attributes
+        data = node.get('id', None)
+        id = self.convertFromStr(data, 'long')
+        data = node.get('tsStart', None)
+        ts_start = self.convertFromStr(data, 'datetime')
+        data = node.get('tsEnd', None)
+        ts_end = self.convertFromStr(data, 'datetime')
+        data = node.get('cached', None)
+        cached = self.convertFromStr(data, 'int')
+        data = node.get('moduleId', None)
+        module_id = self.convertFromStr(data, 'long')
+        data = node.get('moduleName', None)
+        module_name = self.convertFromStr(data, 'str')
+        data = node.get('completed', None)
+        completed = self.convertFromStr(data, 'int')
+        data = node.get('error', None)
+        error = self.convertFromStr(data, 'str')
+        data = node.get('machine_id', None)
+        machine_id = self.convertFromStr(data, 'long')
+        
+        annotations = []
+        loop_execs = []
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'annotation':
+                _data = self.getDao('annotation').fromXML(child)
+                annotations.append(_data)
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                loop_execs.append(_data)
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBModuleExec(id=id,
+                           ts_start=ts_start,
+                           ts_end=ts_end,
+                           cached=cached,
+                           module_id=module_id,
+                           module_name=module_name,
+                           completed=completed,
+                           error=error,
+                           machine_id=machine_id,
+                           annotations=annotations,
+                           loop_execs=loop_execs)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, module_exec, node=None):
+        if node is None:
+            node = ElementTree.Element('moduleExec')
+        
+        # set attributes
+        node.set('id',self.convertToStr(module_exec.db_id, 'long'))
+        node.set('tsStart',self.convertToStr(module_exec.db_ts_start, 'datetime'))
+        node.set('tsEnd',self.convertToStr(module_exec.db_ts_end, 'datetime'))
+        node.set('cached',self.convertToStr(module_exec.db_cached, 'int'))
+        node.set('moduleId',self.convertToStr(module_exec.db_module_id, 'long'))
+        node.set('moduleName',self.convertToStr(module_exec.db_module_name, 'str'))
+        node.set('completed',self.convertToStr(module_exec.db_completed, 'int'))
+        node.set('error',self.convertToStr(module_exec.db_error, 'str'))
+        node.set('machine_id',self.convertToStr(module_exec.db_machine_id, 'long'))
+        
+        # set elements
+        annotations = module_exec.db_annotations
+        for annotation in annotations:
+            if (annotations is not None) and (annotations != ""):
+                childNode = ElementTree.SubElement(node, 'annotation')
+                self.getDao('annotation').toXML(annotation, childNode)
+        loop_execs = module_exec.db_loop_execs
+        for loop_exec in loop_execs:
+            if (loop_execs is not None) and (loop_execs != ""):
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(loop_exec, childNode)
+        
+        return node
+
+class DBProvAssociationXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'prov:wasAssociatedWith':
+            return None
+        
+        prov_activity = None
+        prov_agent = None
+        prov_plan = None
+        prov_role = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'prov:activity':
+                _data = self.getDao('ref_prov_activity').fromXML(child)
+                prov_activity = _data
+            elif child_tag == 'prov:agent':
+                _data = self.getDao('ref_prov_agent').fromXML(child)
+                prov_agent = _data
+            elif child_tag == 'prov:plan':
+                _data = self.getDao('ref_prov_plan').fromXML(child)
+                prov_plan = _data
+            elif child_tag == 'prov:role':
+                _data = self.convertFromStr(child.text,'str')
+                prov_role = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBProvAssociation(prov_activity=prov_activity,
+                                prov_agent=prov_agent,
+                                prov_plan=prov_plan,
+                                prov_role=prov_role)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, prov_association, node=None):
+        if node is None:
+            node = ElementTree.Element('prov:wasAssociatedWith')
+        
+        # set elements
+        prov_activity = prov_association.db_prov_activity
+        if prov_activity is not None:
+            if (prov_activity is not None) and (prov_activity != ""):
+                childNode = ElementTree.SubElement(node, 'prov:activity')
+                self.getDao('ref_prov_activity').toXML(prov_activity, childNode)
+        prov_agent = prov_association.db_prov_agent
+        if prov_agent is not None:
+            if (prov_agent is not None) and (prov_agent != ""):
+                childNode = ElementTree.SubElement(node, 'prov:agent')
+                self.getDao('ref_prov_agent').toXML(prov_agent, childNode)
+        prov_plan = prov_association.db_prov_plan
+        if prov_plan is not None:
+            if (prov_plan is not None) and (prov_plan != ""):
+                childNode = ElementTree.SubElement(node, 'prov:plan')
+                self.getDao('ref_prov_plan').toXML(prov_plan, childNode)
+        prov_role = prov_association.db_prov_role
+        if (prov_role is not None) and (prov_role != ""):
+            childNode = ElementTree.SubElement(node, 'prov:role')
+            childNode.text = self.convertToStr(prov_role, 'str')
+        
+        return node
+
+class DBOpmProcessValueXMLDAOBase(XMLDAO):
+
+    def __init__(self, daoList):
+        self.daoList = daoList
+
+    def getDao(self, dao):
+        return self.daoList[dao]
+
+    def fromXML(self, node):
+        if node.tag[0] == "{":
+            node_tag = node.tag.split("}")[1]
+        else:
+            node_tag = node.tag
+        if node_tag != 'value':
+            return None
+        
+        value = None
+        
+        # read children
+        for child in node.getchildren():
+            if child.tag[0] == "{":
+                child_tag = child.tag.split("}")[1]
+            else:
+                child_tag = child.tag
+            if child_tag == 'moduleExec':
+                _data = self.getDao('module_exec').fromXML(child)
+                value = _data
+            elif child_tag == 'groupExec':
+                _data = self.getDao('group_exec').fromXML(child)
+                value = _data
+            elif child_tag == 'loopExec':
+                _data = self.getDao('loop_exec').fromXML(child)
+                value = _data
+            elif child.text is None or child.text.strip() == '':
+                pass
+            else:
+                print '*** ERROR *** tag = %s' % child.tag
+        
+        obj = DBOpmProcessValue(value=value)
+        obj.is_dirty = False
+        return obj
+    
+    def toXML(self, opm_process_value, node=None):
+        if node is None:
+            node = ElementTree.Element('value')
+        
+        # set elements
+        value = opm_process_value.db_value
+        if value is not None:
+            if value.vtType == 'module_exec':
+                childNode = ElementTree.SubElement(node, 'moduleExec')
+                self.getDao('module_exec').toXML(value, childNode)
+            elif value.vtType == 'group_exec':
+                childNode = ElementTree.SubElement(node, 'groupExec')
+                self.getDao('group_exec').toXML(value, childNode)
+            elif value.vtType == 'loop_exec':
+                childNode = ElementTree.SubElement(node, 'loopExec')
+                self.getDao('loop_exec').toXML(value, childNode)
+        
+        return node
+
+"""generated automatically by auto_dao.py"""
+
+class XMLDAOListBase(dict):
+
+    def __init__(self, daos=None):
+        if daos is not None:
+            dict.update(self, daos)
+
+        if 'opm_was_generated_by' not in self:
+            self['opm_was_generated_by'] = DBOpmWasGeneratedByXMLDAOBase(self)
+        if 'config_key' not in self:
+            self['config_key'] = DBConfigKeyXMLDAOBase(self)
+        if 'mashup_alias' not in self:
+            self['mashup_alias'] = DBMashupAliasXMLDAOBase(self)
+        if 'group' not in self:
+            self['group'] = DBGroupXMLDAOBase(self)
+        if 'opm_was_controlled_by' not in self:
+            self['opm_was_controlled_by'] = DBOpmWasControlledByXMLDAOBase(self)
+        if 'add' not in self:
+            self['add'] = DBAddXMLDAOBase(self)
+        if 'prov_generation' not in self:
+            self['prov_generation'] = DBProvGenerationXMLDAOBase(self)
+        if 'opm_used' not in self:
+            self['opm_used'] = DBOpmUsedXMLDAOBase(self)
+        if 'opm_artifact_id_cause' not in self:
+            self['opm_artifact_id_cause'] = DBOpmArtifactIdCauseXMLDAOBase(self)
+        if 'ref_prov_entity' not in self:
+            self['ref_prov_entity'] = DBRefProvEntityXMLDAOBase(self)
+        if 'vt_connection' not in self:
+            self['vt_connection'] = DBVtConnectionXMLDAOBase(self)
+        if 'opm_account' not in self:
+            self['opm_account'] = DBOpmAccountXMLDAOBase(self)
+        if 'group_exec' not in self:
+            self['group_exec'] = DBGroupExecXMLDAOBase(self)
+        if 'opm_agent_id' not in self:
+            self['opm_agent_id'] = DBOpmAgentIdXMLDAOBase(self)
+        if 'parameter' not in self:
+            self['parameter'] = DBParameterXMLDAOBase(self)
+        if 'vistrail' not in self:
+            self['vistrail'] = DBVistrailXMLDAOBase(self)
+        if 'opm_artifact_value' not in self:
+            self['opm_artifact_value'] = DBOpmArtifactValueXMLDAOBase(self)
+        if 'config_str' not in self:
+            self['config_str'] = DBConfigStrXMLDAOBase(self)
+        if 'startup' not in self:
+            self['startup'] = DBStartupXMLDAOBase(self)
+        if 'module' not in self:
+            self['module'] = DBModuleXMLDAOBase(self)
+        if 'port' not in self:
+            self['port'] = DBPortXMLDAOBase(self)
+        if 'opm_agents' not in self:
+            self['opm_agents'] = DBOpmAgentsXMLDAOBase(self)
+        if 'opm_dependencies' not in self:
+            self['opm_dependencies'] = DBOpmDependenciesXMLDAOBase(self)
+        if 'pe_function' not in self:
+            self['pe_function'] = DBPEFunctionXMLDAOBase(self)
+        if 'workflow' not in self:
+            self['workflow'] = DBWorkflowXMLDAOBase(self)
+        if 'mashup_action' not in self:
+            self['mashup_action'] = DBMashupActionXMLDAOBase(self)
+        if 'configuration' not in self:
+            self['configuration'] = DBConfigurationXMLDAOBase(self)
+        if 'change' not in self:
+            self['change'] = DBChangeXMLDAOBase(self)
+        if 'package' not in self:
+            self['package'] = DBPackageXMLDAOBase(self)
+        if 'loop_exec' not in self:
+            self['loop_exec'] = DBLoopExecXMLDAOBase(self)
+        if 'connection' not in self:
+            self['connection'] = DBConnectionXMLDAOBase(self)
+        if 'config_bool' not in self:
+            self['config_bool'] = DBConfigBoolXMLDAOBase(self)
+        if 'action' not in self:
+            self['action'] = DBActionXMLDAOBase(self)
+        if 'startup_package' not in self:
+            self['startup_package'] = DBStartupPackageXMLDAOBase(self)
+        if 'config_int' not in self:
+            self['config_int'] = DBConfigIntXMLDAOBase(self)
+        if 'opm_process_id_effect' not in self:
+            self['opm_process_id_effect'] = DBOpmProcessIdEffectXMLDAOBase(self)
+        if 'ref_prov_plan' not in self:
+            self['ref_prov_plan'] = DBRefProvPlanXMLDAOBase(self)
+        if 'opm_accounts' not in self:
+            self['opm_accounts'] = DBOpmAccountsXMLDAOBase(self)
+        if 'ref_prov_agent' not in self:
+            self['ref_prov_agent'] = DBRefProvAgentXMLDAOBase(self)
+        if 'portSpec' not in self:
+            self['portSpec'] = DBPortSpecXMLDAOBase(self)
+        if 'enabled_packages' not in self:
+            self['enabled_packages'] = DBEnabledPackagesXMLDAOBase(self)
+        if 'opm_artifact' not in self:
+            self['opm_artifact'] = DBOpmArtifactXMLDAOBase(self)
+        if 'log' not in self:
+            self['log'] = DBLogXMLDAOBase(self)
+        if 'loop_iteration' not in self:
+            self['loop_iteration'] = DBLoopIterationXMLDAOBase(self)
+        if 'opm_process_id_cause' not in self:
+            self['opm_process_id_cause'] = DBOpmProcessIdCauseXMLDAOBase(self)
+        if 'opm_artifacts' not in self:
+            self['opm_artifacts'] = DBOpmArtifactsXMLDAOBase(self)
+        if 'pe_parameter' not in self:
+            self['pe_parameter'] = DBPEParameterXMLDAOBase(self)
+        if 'workflow_exec' not in self:
+            self['workflow_exec'] = DBWorkflowExecXMLDAOBase(self)
+        if 'location' not in self:
+            self['location'] = DBLocationXMLDAOBase(self)
+        if 'function' not in self:
+            self['function'] = DBFunctionXMLDAOBase(self)
+        if 'actionAnnotation' not in self:
+            self['actionAnnotation'] = DBActionAnnotationXMLDAOBase(self)
+        if 'prov_activity' not in self:
+            self['prov_activity'] = DBProvActivityXMLDAOBase(self)
+        if 'prov_usage' not in self:
+            self['prov_usage'] = DBProvUsageXMLDAOBase(self)
+        if 'opm_artifact_id_effect' not in self:
+            self['opm_artifact_id_effect'] = DBOpmArtifactIdEffectXMLDAOBase(self)
+        if 'opm_graph' not in self:
+            self['opm_graph'] = DBOpmGraphXMLDAOBase(self)
+        if 'is_part_of' not in self:
+            self['is_part_of'] = DBIsPartOfXMLDAOBase(self)
+        if 'opm_was_derived_from' not in self:
+            self['opm_was_derived_from'] = DBOpmWasDerivedFromXMLDAOBase(self)
+        if 'controlParameter' not in self:
+            self['controlParameter'] = DBControlParameterXMLDAOBase(self)
+        if 'plugin_data' not in self:
+            self['plugin_data'] = DBPluginDataXMLDAOBase(self)
+        if 'delete' not in self:
+            self['delete'] = DBDeleteXMLDAOBase(self)
+        if 'vistrailVariable' not in self:
+            self['vistrailVariable'] = DBVistrailVariableXMLDAOBase(self)
+        if 'opm_overlaps' not in self:
+            self['opm_overlaps'] = DBOpmOverlapsXMLDAOBase(self)
+        if 'opm_was_triggered_by' not in self:
+            self['opm_was_triggered_by'] = DBOpmWasTriggeredByXMLDAOBase(self)
+        if 'module_descriptor' not in self:
+            self['module_descriptor'] = DBModuleDescriptorXMLDAOBase(self)
+        if 'tag' not in self:
+            self['tag'] = DBTagXMLDAOBase(self)
+        if 'opm_role' not in self:
+            self['opm_role'] = DBOpmRoleXMLDAOBase(self)
+        if 'prov_document' not in self:
+            self['prov_document'] = DBProvDocumentXMLDAOBase(self)
+        if 'opm_processes' not in self:
+            self['opm_processes'] = DBOpmProcessesXMLDAOBase(self)
+        if 'opm_account_id' not in self:
+            self['opm_account_id'] = DBOpmAccountIdXMLDAOBase(self)
+        if 'portSpecItem' not in self:
+            self['portSpecItem'] = DBPortSpecItemXMLDAOBase(self)
+        if 'mashup_component' not in self:
+            self['mashup_component'] = DBMashupComponentXMLDAOBase(self)
+        if 'mashup' not in self:
+            self['mashup'] = DBMashupXMLDAOBase(self)
+        if 'machine' not in self:
+            self['machine'] = DBMachineXMLDAOBase(self)
+        if 'config_float' not in self:
+            self['config_float'] = DBConfigFloatXMLDAOBase(self)
+        if 'other' not in self:
+            self['other'] = DBOtherXMLDAOBase(self)
+        if 'ref_prov_activity' not in self:
+            self['ref_prov_activity'] = DBRefProvActivityXMLDAOBase(self)
+        if 'abstraction' not in self:
+            self['abstraction'] = DBAbstractionXMLDAOBase(self)
+        if 'prov_agent' not in self:
+            self['prov_agent'] = DBProvAgentXMLDAOBase(self)
+        if 'mashuptrail' not in self:
+            self['mashuptrail'] = DBMashuptrailXMLDAOBase(self)
+        if 'registry' not in self:
+            self['registry'] = DBRegistryXMLDAOBase(self)
+        if 'opm_agent' not in self:
+            self['opm_agent'] = DBOpmAgentXMLDAOBase(self)
+        if 'prov_entity' not in self:
+            self['prov_entity'] = DBProvEntityXMLDAOBase(self)
+        if 'annotation' not in self:
+            self['annotation'] = DBAnnotationXMLDAOBase(self)
+        if 'opm_time' not in self:
+            self['opm_time'] = DBOpmTimeXMLDAOBase(self)
+        if 'parameter_exploration' not in self:
+            self['parameter_exploration'] = DBParameterExplorationXMLDAOBase(self)
+        if 'mashup_actionAnnotation' not in self:
+            self['mashup_actionAnnotation'] = DBMashupActionAnnotationXMLDAOBase(self)
+        if 'opm_process' not in self:
+            self['opm_process'] = DBOpmProcessXMLDAOBase(self)
+        if 'disabled_packages' not in self:
+            self['disabled_packages'] = DBDisabledPackagesXMLDAOBase(self)
+        if 'module_exec' not in self:
+            self['module_exec'] = DBModuleExecXMLDAOBase(self)
+        if 'prov_association' not in self:
+            self['prov_association'] = DBProvAssociationXMLDAOBase(self)
+        if 'opm_process_value' not in self:
+            self['opm_process_value'] = DBOpmProcessValueXMLDAOBase(self)
diff --git a/vistrails/db/versions/v1_0_4/persistence/xml/xml_dao.py b/vistrails/db/versions/v1_0_4/persistence/xml/xml_dao.py
new file mode 100644
index 0000000..dc29f8f
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/persistence/xml/xml_dao.py
@@ -0,0 +1,93 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from datetime import date, datetime
+
+from vistrails.core.system import strftime, time_strptime
+
+class XMLDAO:
+    def __init__(self):
+        pass
+
+    def hasAttribute(self, node, attr):
+        return node.hasAttribute(attr)
+
+    def getAttribute(self, node, attr):
+        try:
+            attribute = node.attributes.get(attr)
+            if attribute is not None:
+                return attribute.value
+        except KeyError:
+            pass
+        return None
+
+    def convertFromStr(self, value, type):
+        if value is not None:
+            if type == 'str':
+                return str(value)
+            elif value.strip() != '':
+                if type == 'long':
+                    try:
+                        return long(value)
+                    except ValueError:
+                        return -1
+                elif type == 'float':
+                    return float(value)
+                elif type == 'int':
+                    try:
+                        return int(value)
+                    except ValueError:
+                        if 'False' == value:
+                            return -1
+                        else:
+                            return 0
+                elif type == 'date':
+                    return date(*time_strptime(value, '%Y-%m-%d')[0:3])
+                elif type == 'datetime':
+                    return datetime(*time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+        return None
+
+    def convertToStr(self, value, type):
+        if value is not None:
+            if type == 'date':
+                return value.isoformat()
+            elif type == 'datetime':
+                return strftime(value, '%Y-%m-%d %H:%M:%S')
+            else:
+                return str(value)
+        return ''
diff --git a/vistrails/db/versions/v1_0_4/schemas/sql/vistrails.sql b/vistrails/db/versions/v1_0_4/schemas/sql/vistrails.sql
new file mode 100644
index 0000000..3582c18
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/schemas/sql/vistrails.sql
@@ -0,0 +1,549 @@
+--#############################################################################
+--
+-- Copyright (C) 2014-2015, New York University.
+-- Copyright (C) 2011-2014, NYU-Poly.
+-- Copyright (C) 2006-2011, University of Utah.
+-- All rights reserved.
+-- Contact: contact at vistrails.org
+--
+-- This file is part of VisTrails.
+--
+-- "Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+--  - Redistributions of source code must retain the above copyright notice,
+--    this list of conditions and the following disclaimer.
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
+--    documentation and/or other materials provided with the distribution.
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
+--    this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+--
+--#############################################################################
+
+CREATE TABLE `vistrails_version`(`version` char(16)) engine=InnoDB;
+INSERT INTO `vistrails_version`(`version`) VALUES ('1.0.4');
+
+CREATE TABLE thumbnail(
+    id int not null auto_increment primary key,
+    file_name varchar(255),
+    image_bytes mediumblob,
+    last_modified datetime
+) engine=InnoDB;
+
+-- generated automatically by auto_dao.py
+
+CREATE TABLE mashup_alias(
+    id int,
+    name varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE group_tbl(
+    id int,
+    cache int,
+    name varchar(255),
+    namespace varchar(255),
+    package varchar(511),
+    version varchar(255),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE add_tbl(
+    id int,
+    what varchar(255),
+    object_id int,
+    par_obj_id int,
+    par_obj_type char(16),
+    action_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE group_exec(
+    id int,
+    ts_start datetime,
+    ts_end datetime,
+    cached int,
+    module_id int,
+    group_name varchar(255),
+    group_type varchar(255),
+    completed int,
+    error varchar(1023),
+    machine_id int,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE parameter(
+    id int,
+    pos int,
+    name varchar(255),
+    type varchar(255),
+    val mediumtext,
+    alias varchar(255),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE vistrail(
+    id int not null auto_increment primary key,
+    entity_type char(16),
+    version char(16),
+    name varchar(255),
+    last_modified datetime
+) engine=InnoDB;
+
+CREATE TABLE module(
+    id int,
+    cache int,
+    name varchar(255),
+    namespace varchar(255),
+    package varchar(511),
+    version varchar(255),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE port(
+    id int,
+    type varchar(255),
+    moduleId int,
+    moduleName varchar(255),
+    name varchar(255),
+    signature varchar(4095),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE pe_function(
+    id int,
+    module_id int,
+    port_name varchar(255),
+    is_alias int,
+    parent_type char(32),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE workflow(
+    id int not null auto_increment primary key,
+    entity_id int,
+    entity_type char(16),
+    name varchar(255),
+    version char(16),
+    last_modified datetime,
+    vistrail_id int,
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE mashup_action(
+    id int,
+    prev_id int,
+    date datetime,
+    user varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE change_tbl(
+    id int,
+    what varchar(255),
+    old_obj_id int,
+    new_obj_id int,
+    par_obj_id int,
+    par_obj_type char(16),
+    action_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE package(
+    id int not null auto_increment primary key,
+    name varchar(255),
+    identifier varchar(1023),
+    codepath varchar(1023),
+    load_configuration int,
+    version varchar(255),
+    description varchar(1023),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE loop_exec(
+    id int,
+    ts_start datetime,
+    ts_end datetime,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE connection_tbl(
+    id int,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE action(
+    id int,
+    prev_id int,
+    date datetime,
+    session int,
+    user varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE port_spec(
+    id int,
+    name varchar(255),
+    type varchar(255),
+    optional int,
+    depth int,
+    sort_key int,
+    min_conns int,
+    max_conns int,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE log_tbl(
+    id int not null auto_increment primary key,
+    entity_type char(16),
+    version char(16),
+    name varchar(255),
+    last_modified datetime,
+    vistrail_id int
+) engine=InnoDB;
+
+CREATE TABLE loop_iteration(
+    id int,
+    ts_start datetime,
+    ts_end datetime,
+    iteration int,
+    completed int,
+    error varchar(1023),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE pe_parameter(
+    id int,
+    pos int,
+    interpolator varchar(255),
+    value mediumtext,
+    dimension int,
+    parent_type char(32),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE workflow_exec(
+    id int,
+    user varchar(255),
+    ip varchar(255),
+    session int,
+    vt_version varchar(255),
+    ts_start datetime,
+    ts_end datetime,
+    parent_id int,
+    parent_type varchar(255),
+    parent_version int,
+    completed int,
+    name varchar(255),
+    log_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE location(
+    id int,
+    x DECIMAL(18,12),
+    y DECIMAL(18,12),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE function(
+    id int,
+    pos int,
+    name varchar(255),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE action_annotation(
+    id int,
+    akey varchar(255),
+    value varchar(8191),
+    action_id int,
+    date datetime,
+    user varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE control_parameter(
+    id int,
+    name varchar(255),
+    value mediumtext,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE plugin_data(
+    id int,
+    data varchar(8191),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE delete_tbl(
+    id int,
+    what varchar(255),
+    object_id int,
+    par_obj_id int,
+    par_obj_type char(16),
+    action_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE vistrail_variable(
+    name varchar(255),
+    uuid char(36),
+    package varchar(255),
+    module varchar(255),
+    namespace varchar(255),
+    value varchar(8191),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE module_descriptor(
+    id int,
+    name varchar(255),
+    package varchar(255),
+    namespace varchar(255),
+    package_version varchar(255),
+    version varchar(255),
+    base_descriptor_id int,
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE tag(
+    id int,
+    name varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE port_spec_item(
+    id int,
+    pos int,
+    module varchar(255),
+    package varchar(255),
+    namespace varchar(255),
+    label varchar(4095),
+    _default varchar(4095),
+    _values mediumtext,
+    entry_type varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE mashup_component(
+    id int,
+    vtid int,
+    vttype varchar(255),
+    vtparent_type char(32),
+    vtparent_id int,
+    vtpos int,
+    vtmid int,
+    pos int,
+    type varchar(255),
+    val mediumtext,
+    minVal varchar(255),
+    maxVal varchar(255),
+    stepSize varchar(255),
+    strvaluelist mediumtext,
+    widget varchar(255),
+    seq int,
+    parent varchar(255),
+    alias_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE mashup(
+    id int,
+    name varchar(255),
+    version int,
+    type varchar(255),
+    vtid int,
+    layout mediumtext,
+    geometry mediumtext,
+    has_seq int,
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE machine(
+    id int,
+    name varchar(255),
+    os varchar(255),
+    architecture varchar(255),
+    processor varchar(255),
+    ram bigint,
+    vt_id int,
+    log_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE other(
+    id int,
+    okey varchar(255),
+    value varchar(255),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE abstraction(
+    id int,
+    cache int,
+    name varchar(255),
+    namespace varchar(255),
+    package varchar(511),
+    version varchar(255),
+    internal_version varchar(255),
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE mashuptrail(
+    id int not null auto_increment primary key,
+    name char(36),
+    version char(16),
+    vt_version int,
+    last_modified datetime,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE registry(
+    id int not null auto_increment primary key,
+    entity_type char(16),
+    version char(16),
+    root_descriptor_id int,
+    name varchar(255),
+    last_modified datetime
+) engine=InnoDB;
+
+CREATE TABLE annotation(
+    id int,
+    akey varchar(255),
+    value mediumtext,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
+CREATE TABLE parameter_exploration(
+    id int,
+    action_id int,
+    name varchar(255),
+    date datetime,
+    user varchar(255),
+    dims varchar(255),
+    layout varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE mashup_action_annotation(
+    id int,
+    akey varchar(255),
+    value varchar(8191),
+    action_id int,
+    date datetime,
+    user varchar(255),
+    parent_id int,
+    entity_id int,
+    entity_type char(16)
+) engine=InnoDB;
+
+CREATE TABLE module_exec(
+    id int,
+    ts_start datetime,
+    ts_end datetime,
+    cached int,
+    module_id int,
+    module_name varchar(255),
+    completed int,
+    error varchar(1023),
+    machine_id int,
+    parent_type char(32),
+    entity_id int,
+    entity_type char(16),
+    parent_id int
+) engine=InnoDB;
+
diff --git a/vistrails/db/versions/v1_0_4/schemas/sql/vistrails_drop.sql b/vistrails/db/versions/v1_0_4/schemas/sql/vistrails_drop.sql
new file mode 100644
index 0000000..c77d787
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/schemas/sql/vistrails_drop.sql
@@ -0,0 +1,43 @@
+--#############################################################################
+--
+-- Copyright (C) 2014-2015, New York University.
+-- Copyright (C) 2011-2014, NYU-Poly.
+-- Copyright (C) 2006-2011, University of Utah.
+-- All rights reserved.
+-- Contact: contact at vistrails.org
+--
+-- This file is part of VisTrails.
+--
+-- "Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+--  - Redistributions of source code must retain the above copyright notice,
+--    this list of conditions and the following disclaimer.
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
+--    documentation and/or other materials provided with the distribution.
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
+--    this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+--
+--#############################################################################
+
+DROP TABLE IF EXISTS `vistrails_version`;
+
+DROP TABLE IF EXISTS thumbnail;
+
+-- genereated automatically by generate.py
+
+DROP TABLE IF EXISTS mashup_alias, group_tbl, add_tbl, group_exec, parameter, vistrail, module, port, pe_function, workflow, mashup_action, change_tbl, package, loop_exec, connection_tbl, action, port_spec, log_tbl, loop_iteration, pe_parameter, workflow_exec, location, function, action_annotation, control_parameter, plugin_data, delete_tbl, vistrail_variable, module_descriptor, tag, port_spec_item, mashup_component, mashup, machine, other, abstraction, mashuptrail, registry, annotation, [...]
diff --git a/vistrails/db/versions/v1_0_4/schemas/xml/log.xsd b/vistrails/db/versions/v1_0_4/schemas/xml/log.xsd
new file mode 100644
index 0000000..e0e518e
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/schemas/xml/log.xsd
@@ -0,0 +1,157 @@
+<!--###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+-->
+
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:element name="log">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="workflow_exec" ref="workflowExec" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="version" type="xs:string"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="vistrail_id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="workflowExec">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="machine" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:choice>
+          <xs:element name="module_exec" ref="moduleExec" minOccurs="0" maxOccurs="1"/>
+          <xs:element name="group_exec" ref="groupExec" minOccurs="0" maxOccurs="1"/>
+          <xs:element name="loop_exec" ref="loopExec" minOccurs="0" maxOccurs="1"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="user" type="xs:string"/>
+      <xs:attribute name="ip" type="xs:string"/>
+      <xs:attribute name="session" type="xs:int"/>
+      <xs:attribute name="vtVersion" type="xs:string"/>
+      <xs:attribute name="tsStart" type="xs:dateTime"/>
+      <xs:attribute name="tsEnd" type="xs:dateTime"/>
+      <xs:attribute name="parentId" type="xs:int"/>
+      <xs:attribute name="parentType" type="xs:string"/>
+      <xs:attribute name="parentVersion" type="xs:int"/>
+      <xs:attribute name="completed" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="annotation">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="key" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="machine">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="os" type="xs:string"/>
+      <xs:attribute name="architecture" type="xs:string"/>
+      <xs:attribute name="processor" type="xs:string"/>
+      <xs:attribute name="ram" type="xs:long"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="moduleExec">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="loop_exec" ref="loopExec" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="tsStart" type="xs:dateTime"/>
+      <xs:attribute name="tsEnd" type="xs:dateTime"/>
+      <xs:attribute name="cached" type="xs:int"/>
+      <xs:attribute name="moduleId" type="xs:int"/>
+      <xs:attribute name="moduleName" type="xs:string"/>
+      <xs:attribute name="completed" type="xs:int"/>
+      <xs:attribute name="error" type="xs:string"/>
+      <xs:attribute name="machine_id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="groupExec">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:choice>
+          <xs:element name="module_exec" ref="moduleExec" minOccurs="0" maxOccurs="1"/>
+          <xs:element name="group_exec" ref="groupExec" minOccurs="0" maxOccurs="1"/>
+          <xs:element name="loop_exec" ref="loopExec" minOccurs="0" maxOccurs="1"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="tsStart" type="xs:dateTime"/>
+      <xs:attribute name="tsEnd" type="xs:dateTime"/>
+      <xs:attribute name="cached" type="xs:int"/>
+      <xs:attribute name="moduleId" type="xs:int"/>
+      <xs:attribute name="groupName" type="xs:string"/>
+      <xs:attribute name="groupType" type="xs:string"/>
+      <xs:attribute name="completed" type="xs:int"/>
+      <xs:attribute name="error" type="xs:string"/>
+      <xs:attribute name="machine_id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="loopExec">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="loop_iteration" ref="loopIteration" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="tsStart" type="xs:dateTime"/>
+      <xs:attribute name="tsEnd" type="xs:dateTime"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="loopIteration">
+    <xs:complexType>
+      <xs:choice>
+        <xs:element name="module_exec" ref="moduleExec" minOccurs="0" maxOccurs="1"/>
+        <xs:element name="group_exec" ref="groupExec" minOccurs="0" maxOccurs="1"/>
+        <xs:element name="loop_exec" ref="loopExec" minOccurs="0" maxOccurs="1"/>
+      </xs:choice>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="tsStart" type="xs:dateTime"/>
+      <xs:attribute name="tsEnd" type="xs:dateTime"/>
+      <xs:attribute name="iteration" type="xs:int"/>
+      <xs:attribute name="completed" type="xs:int"/>
+      <xs:attribute name="error" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/vistrails/db/versions/v1_0_4/schemas/xml/vistrail.xsd b/vistrails/db/versions/v1_0_4/schemas/xml/vistrail.xsd
new file mode 100644
index 0000000..7ab802f
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/schemas/xml/vistrail.xsd
@@ -0,0 +1,363 @@
+<!--###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+-->
+
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:element name="vistrail">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="action" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="vistrailVariable" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element name="parameter_exploration" ref="parameterExploration" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="actionAnnotation" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="version" type="xs:string"/>
+      <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="action">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:choice>
+          <xs:element ref="add" minOccurs="0" maxOccurs="1"/>
+          <xs:element ref="delete" minOccurs="0" maxOccurs="1"/>
+          <xs:element ref="change" minOccurs="0" maxOccurs="1"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="prevId" type="xs:int"/>
+      <xs:attribute name="date" type="xs:dateTime"/>
+      <xs:attribute name="session" type="xs:int"/>
+      <xs:attribute name="user" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="tag">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="annotation">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="key" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="controlParameter">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="vistrailVariable">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="uuid" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="module" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="parameterExploration">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="function" ref="peFunction" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="actionId" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="date" type="xs:dateTime"/>
+      <xs:attribute name="user" type="xs:string"/>
+      <xs:attribute name="dims" type="xs:string"/>
+      <xs:attribute name="layout" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="actionAnnotation">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="key" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+      <xs:attribute name="actionId" type="xs:int"/>
+      <xs:attribute name="date" type="xs:dateTime"/>
+      <xs:attribute name="user" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="add">
+    <xs:complexType>
+      <xs:choice>
+        <xs:element ref="module" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="connection" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="port" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="parameter" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="portSpec" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="abstraction" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="group" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="other" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="plugin_data" minOccurs="0" maxOccurs="1"/>
+      </xs:choice>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="what" type="xs:string"/>
+      <xs:attribute name="objectId" type="xs:int"/>
+      <xs:attribute name="parentObjId" type="xs:int"/>
+      <xs:attribute name="parentObjType" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="delete">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="what" type="xs:string"/>
+      <xs:attribute name="objectId" type="xs:int"/>
+      <xs:attribute name="parentObjId" type="xs:int"/>
+      <xs:attribute name="parentObjType" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="change">
+    <xs:complexType>
+      <xs:choice>
+        <xs:element ref="module" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="connection" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="port" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="parameter" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="portSpec" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="abstraction" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="group" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="other" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="plugin_data" minOccurs="0" maxOccurs="1"/>
+      </xs:choice>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="what" type="xs:string"/>
+      <xs:attribute name="oldObjId" type="xs:int"/>
+      <xs:attribute name="newObjId" type="xs:int"/>
+      <xs:attribute name="parentObjId" type="xs:int"/>
+      <xs:attribute name="parentObjType" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="peFunction">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="parameter" ref="peParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="moduleId" type="xs:int"/>
+      <xs:attribute name="port_name" type="xs:string"/>
+      <xs:attribute name="is_alias" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="module">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="portSpec" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="cache" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="location">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="x" type="xs:float"/>
+      <xs:attribute name="y" type="xs:float"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="function">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="connection">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="port" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="port">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="moduleId" type="xs:int"/>
+      <xs:attribute name="moduleName" type="xs:string"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="signature" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="parameter">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="val" type="xs:string"/>
+      <xs:attribute name="alias" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="portSpec">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="portSpecItem" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="optional" type="xs:int"/>
+      <xs:attribute name="depth" type="xs:int"/>
+      <xs:attribute name="sortKey" type="xs:int"/>
+      <xs:attribute name="minConns" type="xs:int"/>
+      <xs:attribute name="maxConns" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="abstraction">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="cache" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+      <xs:attribute name="internalVersion" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="group">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="workflow" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="cache" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="other">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="value" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="key" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="plugin_data">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="data" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="peParameter">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="interpolator" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+      <xs:attribute name="dimension" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="portSpecItem">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="module" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="label" type="xs:string"/>
+      <xs:attribute name="default" type="xs:string"/>
+      <xs:attribute name="values" type="xs:string"/>
+      <xs:attribute name="entryType" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="workflow">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="plugin_data" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="other" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:choice>
+          <xs:element ref="module" minOccurs="0" maxOccurs="1"/>
+          <xs:element ref="abstraction" minOccurs="0" maxOccurs="1"/>
+          <xs:element ref="group" minOccurs="0" maxOccurs="1"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+      <xs:attribute name="vistrail_id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/vistrails/db/versions/v1_0_4/schemas/xml/vtlink.xsd b/vistrails/db/versions/v1_0_4/schemas/xml/vtlink.xsd
new file mode 100644
index 0000000..3453317
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/schemas/xml/vtlink.xsd
@@ -0,0 +1,70 @@
+<!--###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+-->
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xs:element name="vtlink">
+<xs:complexType>
+<!-- if the vistrail is in a DB use host, database, port and vtid -->
+<xs:attribute name="host" type="xs:string"></xs:attribute>
+<xs:attribute name="database" type="xs:string"></xs:attribute>
+<xs:attribute name="port" type="xs:int"></xs:attribute>
+<xs:attribute name="vtid" type="xs:int"></xs:attribute>
+<!-- if the vistrail is a file use filename below -->
+<xs:attribute name="filename" type="xs:string"></xs:attribute>
+<!-- this is the workflow version -->
+<xs:attribute name="version" type="xs:int"></xs:attribute>
+<!-- this is the workflow tag -->
+<xs:attribute name="tag" type="xs:string"></xs:attribute>
+<xs:attribute name="url" type="xs:string"></xs:attribute>
+<!--  vtcontent can be a workflow in xml or a .vt file base64 encoded -->
+<xs:attribute name="vtcontent" type="xs:string"></xs:attribute>
+<!--  if execute is true the workflow will be executed -->
+<xs:attribute name="execute" type="xs:boolean"></xs:attribute>
+<!--  if showSpreadsheetOnly is True we will hide the builder -->
+<xs:attribute name="showSpreadsheetOnly" type="xs:boolean"></xs:attribute>
+<!--  if there's database information and a workflow is embedded, it will
+force loading from the db instead of using the emebedded version -->
+<xs:attribute name="forceDB" type="xs:boolean"></xs:attribute>
+<!--  if mashuptrail and mashupVersion are set, VisTrails will execute the
+mashup -->
+<xs:attribute name="mashuptrail" type="xs:string"></xs:attribute>
+<xs:attribute name="mashupVersion" type="xs:int"></xs:attribute>
+</xs:complexType>
+</xs:element>
+
+</xs:schema>
diff --git a/vistrails/db/versions/v1_0_4/schemas/xml/workflow.xsd b/vistrails/db/versions/v1_0_4/schemas/xml/workflow.xsd
new file mode 100644
index 0000000..02af424
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/schemas/xml/workflow.xsd
@@ -0,0 +1,212 @@
+<!--###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+-->
+
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:element name="workflow">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="plugin_data" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="other" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:choice>
+          <xs:element ref="module" minOccurs="0" maxOccurs="1"/>
+          <xs:element ref="abstraction" minOccurs="0" maxOccurs="1"/>
+          <xs:element ref="group" minOccurs="0" maxOccurs="1"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+      <xs:attribute name="vistrail_id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="connection">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="port" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="annotation">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="key" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="plugin_data">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="data" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="other">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="value" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="key" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="module">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="portSpec" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="cache" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="abstraction">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="cache" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+      <xs:attribute name="internalVersion" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="group">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="workflow" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="location" minOccurs="0" maxOccurs="1"/>
+        <xs:element ref="function" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="annotation" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="controlParameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="cache" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="version" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="port">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="moduleId" type="xs:int"/>
+      <xs:attribute name="moduleName" type="xs:string"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="signature" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="location">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="x" type="xs:float"/>
+      <xs:attribute name="y" type="xs:float"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="function">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="controlParameter">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="portSpec">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="portSpecItem" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="optional" type="xs:int"/>
+      <xs:attribute name="depth" type="xs:int"/>
+      <xs:attribute name="sortKey" type="xs:int"/>
+      <xs:attribute name="minConns" type="xs:int"/>
+      <xs:attribute name="maxConns" type="xs:int"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="parameter">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="val" type="xs:string"/>
+      <xs:attribute name="alias" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="portSpecItem">
+    <xs:complexType>
+      <xs:attribute name="id" type="xs:int"/>
+      <xs:attribute name="pos" type="xs:int"/>
+      <xs:attribute name="module" type="xs:string"/>
+      <xs:attribute name="package" type="xs:string"/>
+      <xs:attribute name="namespace" type="xs:string"/>
+      <xs:attribute name="label" type="xs:string"/>
+      <xs:attribute name="default" type="xs:string"/>
+      <xs:attribute name="values" type="xs:string"/>
+      <xs:attribute name="entryType" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/vistrails/db/versions/v1_0_4/specs/all.xml b/vistrails/db/versions/v1_0_4/specs/all.xml
new file mode 100644
index 0000000..4f750e5
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/specs/all.xml
@@ -0,0 +1,4139 @@
+<!--###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+-->
+<objects>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ABSTRACTION +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="abstraction">
+    <layout>
+      <xml name="abstraction" nodeType="xs:element"/>
+      <sql table="abstraction"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="cache" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="namespace" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="package" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(511)"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="internal_version" type="str">
+      <xml name="internalVersion" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="location" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="function" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	          index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ACTION ++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="action">
+    <layout>
+      <xml name="action" nodeType="xs:element"/>
+      <sql table="action"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="prevId" type="long" foreignKey="true" object="action">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="prev_id" type="int"/>
+    </property>
+
+    <property name="date" type="datetime">
+      <xml nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="session" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="user" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <choice name="operation" type="list" mapping="one-to-many">
+      <property name="add" ref="true" object="add">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="delete" ref="true" object="delete">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="change" ref="true" object="change">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+    
+    <property ref="true" object="vistrail" type="long" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ADD +++++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="add">
+    <layout>
+      <xml name="add" nodeType="xs:element"/>
+      <sql table="add_tbl"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="what" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="objectId" type="long" foreignKey="true" discriminator="what">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="object_id" type="int"/>
+    </property>
+
+    <property name="parentObjId" type="long" foreignKey="true"
+	      discriminator="parentObjType">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="par_obj_id" type="int"/>
+    </property>
+
+    <property name="parentObjType" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="par_obj_type" type="char(16)"/>
+    </property>
+    
+    <choice name="data" type="object" discriminator="what">
+      <property ref="true" object="module" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="location" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="annotation" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="controlParameter" mapping="one-to-one">
+        <xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="function" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="connection" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="port" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="parameter" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="portSpec" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="abstraction" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="group" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="other" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="plugin_data" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+
+    <property name="action" type="long" ref="true" object="action" 
+	      mapping="many-to-one" inverse="true">
+      <sql column="action_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ACTION_ANNOTATION +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="actionAnnotation">
+    <layout>
+      <xml nodeType="xs:element"/>
+      <sql table="action_annotation"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="key" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="akey" type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(8191)"/>
+    </property>
+
+    <property name="action_id" type="long" foreignKey="true" object="action">
+      <xml name="actionId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="date" type="datetime">
+      <xml nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="user" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>    
+
+    <property ref="true" type="long" object="vistrail" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+    
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ANNOTATION ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="annotation">
+    <layout>
+      <xml name="annotation" nodeType="xs:element"/>
+      <sql table="annotation"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="key" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="akey" type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="vistrail">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="module">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="workflow_exec">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="module_exec">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group_exec">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="action">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="abstraction">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="mashuptrail">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONTROL PARAMETER +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="controlParameter">
+    <layout>
+      <xml nodeType="xs:element"/>
+      <sql table="control_parameter"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="name" type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="vistrail">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="module">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="abstraction">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+    </choice>
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- VISTRAIL_VARIABLE +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="vistrailVariable">
+    <layout>
+      <xml nodeType="xs:element"/>
+      <sql table="vistrail_variable"/>
+    </layout>
+
+    <property name="name" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="name" type="varchar(255)"/>
+    </property>
+
+    <property name="uuid" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="uuid" type="char(36)"/>
+    </property>
+
+    <property name="package" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="package" type="varchar(255)"/>
+    </property>
+
+    <property name="module" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="module" type="varchar(255)"/>
+    </property>
+
+    <property name="namespace" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="namespace" type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="value" type="varchar(8191)"/>
+    </property>
+
+    <property ref="true" type="long" object="vistrail" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CHANGE ++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="change">
+    <layout>
+      <xml name="change" nodeType="xs:element"/>
+      <sql table="change_tbl"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="what" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="oldObjId" type="long" foreignKey="true" discriminator="what">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="old_obj_id" type="int"/>
+    </property>
+
+    <property name="newObjId" type="long" foreignKey="true" discriminator="what">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="new_obj_id" type="int"/>
+    </property>
+
+    <property name="parentObjId" type="long" foreignKey="true" 
+	      discriminator="parentObjType">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="par_obj_id" type="int"/>
+    </property>
+
+    <property name="parentObjType" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="par_obj_type" type="char(16)"/>
+    </property>
+
+    <choice name="data" type="object" discriminator="what">
+      <property ref="true" object="module" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="location" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="annotation" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+	  <property ref="true" object="controlParameter" mapping="one-to-one">
+        <xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="function" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="connection" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="port" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="parameter" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="portSpec" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="abstraction" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="group" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="other" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+      <property ref="true" object="plugin_data" mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+    
+    <property name="action" type="long" ref="true" object="action" 
+	      mapping="many-to-one" inverse="true">
+      <sql column="action_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONNECTION ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="connection">
+    <layout>
+      <xml name="connection" nodeType="xs:element"/>
+      <sql table="connection_tbl"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="port" type="list" mapping="one-to-many"
+	      index="type">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- DELETE ++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="delete">
+    <layout>
+      <xml name="delete" nodeType="xs:element"/>
+      <sql table="delete_tbl"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="what" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="objectId" type="long" foreignKey="true" discriminator="what">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="object_id" type="int"/>
+    </property>
+
+    <property name="parentObjId" type="long" foreignKey="true" 
+	      discriminator="parentObjType">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="par_obj_id" type="int"/>
+    </property>
+
+    <property name="parentObjType" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="par_obj_type" type="char(16)"/>
+    </property>
+
+    <property name="action" type="long" ref="true" object="action" 
+	      mapping="many-to-one" inverse="true">
+      <sql column="action_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- FUNCTION ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="function">
+    <layout>
+      <xml name="function" nodeType="xs:element"/>
+      <sql table="function"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="pos" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="parameter" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="module">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="abstraction">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="group">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- GROUP +++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="group" parentClass="module">
+    <layout>
+      <xml name="group" nodeType="xs:element"/>
+      <sql table="group_tbl"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="workflow" type="object" mapping="one-to-one" 
+	      expand="false">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="cache" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="namespace" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="package" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(511)"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="location" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="function" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	          index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- LOCATION ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="location">
+    <layout>
+      <xml name="location" nodeType="xs:element"/>
+      <sql table="location"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="x" type="float">
+      <xml nodeType="xs:attribute" type="xs:float"/>
+      <sql type="DECIMAL(18,12)"/>
+    </property>
+
+    <property name="y" type="float">
+      <xml nodeType="xs:attribute" type="xs:float"/>
+      <sql type="DECIMAL(18,12)"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="module">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="abstraction">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="group">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- LOG +++++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="log">
+    <layout>
+      <xml name="log" nodeType="xs:element"/>
+      <sql table="log_tbl"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int" autoInc="true" global="true" globalName="entity_id"/>
+    </property>
+
+    <property name="entity_type" type="str">
+      <sql type="char(16)" global="true" globalName="entity_type"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(16)"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="last_modified" type="datetime">
+      <sql type="datetime"/>
+    </property>
+
+    <property ref="true" object="workflow_exec" cascade="false" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="vistrail_id" type="long" foreignKey="true" object="vistrail">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- MACHINE +++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="machine">
+    <layout>
+      <xml name="machine" nodeType="xs:element"/>
+      <sql table="machine"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="os" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="architecture" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="processor" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="ram" type="int">
+      <xml nodeType="xs:attribute" type="xs:long"/>
+      <sql type="bigint"/>
+    </property>
+
+    <property name="vistrailId" type="long" inverse="true"
+	      foreignKey="true" object="vistrail">
+      <sql column="vt_id" type="int"/>
+    </property>
+
+    <property ref="true" object="workflow_exec" type="long" 
+	      mapping="many-to-one" inverse="true">
+      <sql column="log_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- MODULE ++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="module">
+    <layout>
+      <xml name="module" nodeType="xs:element"/>
+      <sql table="module"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="cache" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="namespace" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="package" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(511)"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="location" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="function" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	      index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="portSpec" type="list" mapping="one-to-many"
+	      index="name:type">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- LOOP_EXEC +++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="loop_exec">
+    <layout>
+      <xml name="loopExec" nodeType="xs:element"/>
+      <sql table="loop_exec"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="ts_start" type="datetime">
+      <xml name="tsStart" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="ts_end" type="datetime">
+      <xml name="tsEnd" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="workflow_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+            
+      <property ref="true" object="module_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property ref="true" object="loop_iteration" type="list"
+            mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- LOOP_ITERATION ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="loop_iteration">
+    <layout>
+      <xml name="loopIteration" nodeType="xs:element"/>
+      <sql table="loop_iteration"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="ts_start" type="datetime">
+      <xml name="tsStart" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="ts_end" type="datetime">
+      <xml name="tsEnd" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="iteration" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="completed" type="int">
+      <xml name="completed" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="error" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <choice name="item_exec" type="list" mapping="one-to-many">
+      <property name="module_exec" ref="true" object="module_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="group_exec" ref="true" object="group_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+      
+      <property name="loop_exec" ref="true" object="loop_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+
+    <property name="parent" ref="true" object="loop_exec"
+            mapping="many-to-one" inverse="true">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- GROUP_EXEC ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="group_exec">
+    <layout>
+      <xml name="groupExec" nodeType="xs:element"/>
+      <sql table="group_exec"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="ts_start" type="datetime">
+      <xml name="tsStart" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="ts_end" type="datetime">
+      <xml name="tsEnd" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="cached" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql nodeType="int"/>
+    </property>
+
+    <property name="module_id" type="long" foreignKey="true" object="module">
+      <xml name="moduleId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="group_name" type="str">
+      <xml name="groupName" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="group_type" type="str">
+      <xml name="groupType" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="completed" type="int">
+      <xml name="completed" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="error" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property name="machine_id" type="long" foreignKey="true" object="machine">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <choice name="item_exec" type="list" mapping="one-to-many">
+      <property name="module_exec" ref="true" object="module_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="group_exec" ref="true" object="group_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="loop_exec" ref="true" object="loop_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="workflow_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="loop_iteration" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <!--<property ref="true" object="workflow_exec" type="long" mapping="many-to-one" 
+	      inverse="true">
+      <sql column="wf_exec_id" type="int"/>
+    </property>-->
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- MODULE_EXEC +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="module_exec">
+    <layout>
+      <xml name="moduleExec" nodeType="xs:element"/>
+      <sql table="module_exec"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="ts_start" type="datetime">
+      <xml name="tsStart" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="ts_end" type="datetime">
+      <xml name="tsEnd" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="cached" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql nodeType="int"/>
+    </property>
+
+    <property name="module_id" type="long" foreignKey="true" object="module">
+      <xml name="moduleId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="module_name" type="str">
+      <xml name="moduleName" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="completed" type="int">
+      <xml name="completed" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="error" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property name="machine_id" type="long" foreignKey="true" object="machine">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="loop_exec" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="workflow_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="group_exec" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+
+      <property ref="true" object="loop_iteration" type="long" 
+		mapping="many-to-one" inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OTHER +++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="other">
+    <layout>
+      <xml name="other" nodeType="xs:element"/>
+      <sql table="other"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="key" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="okey" type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PARAMETER +++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="parameter">
+    <layout>
+      <xml name="parameter" nodeType="xs:element"/>
+      <sql table="parameter"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="pos" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="type" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="val" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="alias" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="function">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PLUGIN DATA +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="plugin_data">
+    <layout>
+      <xml name="plugin_data" nodeType="xs:element"/>
+      <sql table="plugin_data"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="data" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(8191)"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="workflow">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PORT ++++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="port">
+    <layout>
+      <xml name="port" nodeType="xs:element"/>
+      <sql table="port"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="type" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="moduleId" type="long" foreignKey="true" object="module">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="moduleName" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="signature" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(4095)"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="connection" type="long" mapping="many-to-one" 
+		inverse="true">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PORTSPEC ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="portSpec">
+    <layout>
+      <xml name="portSpec" nodeType="xs:element"/>
+      <sql table="port_spec"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="type" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="optional" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="depth" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="sort_key" type="int">
+      <xml name="sortKey" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="portSpecItem" type="list" 
+	      mapping="one-to-many" expandAction="false">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="min_conns" type="int">
+      <xml name="minConns" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="max_conns" type="int">
+      <xml name="maxConns" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+	    mapping="many-to-one">
+      <property ref="true" object="module">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="module_descriptor">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="add">
+	<sql column="parent_id" type="int"/>
+      </property>
+      <property ref="true" object="change">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PORTSPECITEM ++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="portSpecItem">
+    <layout>
+      <xml name="portSpecItem" nodeType="xs:element"/>
+      <sql table="port_spec_item"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="pos" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="module" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="package" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="namespace" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="label" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(4095)"/>
+    </property>
+
+    <property name="default" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="_default" type="varchar(4095)"/>
+    </property>
+
+    <property name="values" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="_values" type="mediumtext"/>
+    </property>
+
+    <property name="entry_type" type="str">
+      <xml name="entryType" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" type="long" object="portSpec" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- MODULE_DESCRIPTOR +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="module_descriptor">
+    <layout>
+      <xml name="moduleDescriptor" nodeType="xs:element"/>
+      <sql table="module_descriptor"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="package" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+	   
+    <property name="namespace" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="package_version" type="str">
+      <xml name="packageVersion" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="base_descriptor_id" type="long" foreignKey="true" 
+	      object="module_descriptor">
+      <xml name="baseDescriptorId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="portSpec" type="list" mapping="one-to-many"
+	      index="name:type">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" type="long" object="package" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+    <!--
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <choice name="parent" type="long" discriminator="parentType" inverse="true" 
+            mapping="many-to-one">
+      <property ref="true" object="registry">
+	<sql column="parent_id" type="int"/>
+      </property>
+      
+      <property ref="true" object="package">
+	<sql column="parent_id" type="int"/>
+      </property>
+    </choice>
+    -->
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PACKAGE +++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="package">
+    <layout>
+      <xml name="package" nodeType="xs:element"/>
+      <sql table="package"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int" autoInc="true"/>
+    </property>
+    
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="identifier" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property name="codepath" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+      
+    <property name="load_configuration" type="int">
+      <xml name="loadConfiguration" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>      
+
+    <property name="description" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property ref="true" object="module_descriptor" type="list" 
+	      mapping="one-to-many" index="name:namespace:version">
+      <xml name="moduleDescriptor" nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" type="long" object="registry" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- REGISTRY ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="registry">
+    <layout>
+      <xml name="registry" nodeType="xs:element"/>
+      <sql table="registry"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int" autoInc="true" global="true" globalName="entity_id"/>
+    </property>
+
+    <property name="entity_type" type="str">
+      <sql type="char(16)" global="true" globalName="entity_type"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(16)"/>
+    </property>
+
+    <property name="root_descriptor_id" type="long" foreignKey="true" 
+	      object="module_descriptor">
+      <xml name="rootDescriptorId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <!-- <xml nodeType="xs:attribute" type="xs:string"/> -->
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="last_modified" type="datetime">
+      <sql type="datetime"/>
+    </property>
+
+    <property ref="true" object="package" type="list"
+	      mapping="one-to-many" index="identifier:version">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- TAG +++++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="tag">
+    <layout>
+      <xml name="tag" nodeType="xs:element"/>
+      <sql table="tag"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true" foreignKey="true" 
+	      object="action">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" type="long" object="vistrail" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+    
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- VISTRAIL ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="vistrail">
+    <layout>
+      <xml name="vistrail" nodeType="xs:element"/>
+      <sql table="vistrail"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int" autoInc="true" global="true" globalName="entity_id"/>
+    </property>
+    
+    <property name="entity_type" type="str">
+      <sql type="char(16)" global="true" globalName="entity_type"/>
+    </property>
+
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(16)"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="last_modified" type="datetime">
+      <sql type="datetime"/>
+    </property>
+
+    <property ref="true" object="action" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="tag" type="list" mapping="one-to-many"
+	      index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="controlParameter" type="list" mapping="one-to-many"
+	      index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="vistrailVariable" type="list" mapping="one-to-many"
+	      index="uuid">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="parameter_exploration" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+    <property ref="true" object="actionAnnotation" type="list" 
+	      mapping="one-to-many" index="action_id:key !key:value">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- WORKFLOW ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="workflow">
+    <layout>
+      <xml name="workflow" nodeType="xs:element"/>
+      <sql table="workflow"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int" autoInc="true" global="true" globalName="entity_id"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str">
+      <sql type="char(16)" global="true" globalName="entity_type"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(16)"/>
+    </property>
+
+    <property name="last_modified" type="datetime">
+      <sql type="datetime"/>
+    </property>
+
+    <choice name="module" type="list" mapping="one-to-many">
+      <property name="module" ref="true" object="module">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="abstraction" ref="true" object="abstraction">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="group" ref="true" object="group">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+    
+    <property ref="true" object="connection" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="plugin_data" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="other" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="vistrail_id" type="long" foreignKey="true" object="vistrail">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" object="group" type="long" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- WORKFLOW_EXEC +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="workflow_exec">
+    <layout>
+      <xml name="workflowExec" nodeType="xs:element"/>
+      <sql table="workflow_exec"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="user" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="ip" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="session" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="vt_version" type="str">
+      <xml name="vtVersion" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="ts_start" type="datetime">
+      <xml name="tsStart" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="ts_end" type="datetime">
+      <xml name="tsEnd" nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="parent_id" type="long">
+      <xml name="parentId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="parent_type" type="str">
+      <xml name="parentType" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="parent_version" type="long">
+      <xml name="parentVersion" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="completed" type="int">
+      <xml name="completed" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="log" type="long" mapping="many-to-one" 
+	      inverse="true">
+      <sql column="log_id" type="int"/>
+    </property>
+    
+    <property ref="true" object="annotation" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="machine" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <choice name="item_exec" type="list" mapping="one-to-many">
+      <property name="module_exec" ref="true" object="module_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="group_exec" ref="true" object="group_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="loop_exec" ref="true" object="loop_exec">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PE_PARAMETER ++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="pe_parameter" className="DBPEParameter">
+    <layout>
+      <xml name="peParameter" nodeType="xs:element"/>
+      <sql table="pe_parameter"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="pos" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="interpolator" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="dimension" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <property ref="true" type="long" object="pe_function" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PE_FUNCTION +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="pe_function" className="DBPEFunction">
+    <layout>
+      <xml name="peFunction" nodeType="xs:element"/>
+      <sql table="pe_function"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="module_id" type="long" foreignKey="true" object="module">
+      <xml name="moduleId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="port_name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="is_alias" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property ref="true" name="parameter" object="pe_parameter" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="parentType" type="str" inverse="true">
+      <sql column="parent_type" type="char(32)"/>
+    </property>
+
+    <property ref="true" type="long" object="parameter_exploration" 
+	      inverse="true" mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PARAMETER_EXPLORATION +++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="parameter_exploration">
+    <layout>
+      <xml name="parameterExploration" nodeType="xs:element"/>
+      <sql table="parameter_exploration"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="action_id" type="long" foreignKey="true" object="action">
+      <xml name="actionId" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="date" type="datetime">
+      <xml nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="user" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="dims" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="layout" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" name="function" object="pe_function" type="list" 
+	      mapping="one-to-many" index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" type="long" object="vistrail" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- MASHUP_ACTION +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="mashup_action">
+    <layout>
+      <xml name="action" nodeType="xs:element"/>
+      <sql table="mashup_action"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="prevId" type="long" foreignKey="true" object="mashup_action">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql column="prev_id" type="int"/>
+    </property>
+
+    <property name="date" type="datetime">
+      <xml nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="user" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property ref="true" object="mashup" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" type="long" object="mashuptrail" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+    
+	<property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+    
+  </object>
+
+  <!--+++++++++++++++++++++++++++++-->
+  <!-- MASHUP_ACTION_ANNOTATION +++-->
+  <!--+++++++++++++++++++++++++++++-->
+
+  <object name="mashup_actionAnnotation">
+    <layout>
+      <xml name="actionAnnotation" nodeType="xs:element"/>
+      <sql table="mashup_action_annotation"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="key" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql column="akey" type="varchar(255)"/>
+     </property>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(8191)"/>
+    </property>
+
+    <property name="action_id" type="long" foreignKey="true" object="mashup_action">
+      <xml name="action_id" nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="date" type="datetime">
+      <xml nodeType="xs:attribute" type="xs:dateTime"/>
+      <sql type="datetime"/>
+    </property>
+
+    <property name="user" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>    
+
+    <property ref="true" type="long" object="mashuptrail" inverse="true" 
+	      mapping="many-to-one">
+      <sql column="parent_id" type="int"/>
+    </property>
+    
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- MASHUPTRAIL +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="mashuptrail">
+    <layout>
+      <xml name="mashuptrail" nodeType="xs:element"/>
+      <sql table="mashuptrail"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <sql type="int" autoInc="true" global="true" globalName="entity_id"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml name="id" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(36)"/>
+    </property>
+    
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(16)"/>
+    </property>
+    
+    <property name="vtVersion" type="long">
+      <xml name="vtVersion" nodeType="xs:attribute" type="xs:int"/>
+      <sql column="vt_version" type="int"/>
+    </property>
+
+    <property name="last_modified" type="datetime">
+      <sql type="datetime"/>
+    </property>
+
+    <property name="action" ref="true" object="mashup_action" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="annotation" type="list" mapping="one-to-many"
+	      index="key">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="actionAnnotation" ref="true" object="mashup_actionAnnotation" type="list" 
+	      mapping="one-to-many" index="action_id:key !key:value">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--+++++++++++++++++++++++++++++-->
+  <!-- MASHUP_ALIAS +++++++++++++++-->
+  <!--+++++++++++++++++++++++++++++-->
+
+  <object name="mashup_alias">
+    <layout>
+      <xml name="alias" nodeType="xs:element"/>
+      <sql table="mashup_alias"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="component" ref="true" object="mashup_component" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+    
+    <property name="parent" ref="true" object="mashup" type="long" 
+	      mapping="many-to-one" inverse="true">
+      <sql column="parent_id" type="int"/>
+    </property>
+    
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- MASHUP_COMPONENT ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="mashup_component">
+    <layout>
+      <xml name="component" nodeType="xs:element"/>
+      <sql table="mashup_component"/>
+    </layout>
+    
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="vtid" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+     <property name="vttype" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="vtparent_type" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="char(32)"/>
+    </property>
+    
+    <property name="vtparent_id" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="vtpos" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="vtmid" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="pos" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="type" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="val" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+    
+    <property name="minVal" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="maxVal" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="stepSize" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="strvaluelist" type="str">
+      <xml name="valueList" nodeType="xs:attribute" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+    
+    <property name="widget" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="seq" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="parent" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property ref="true" object="mashup_alias" type="long" mapping="one-to-one" 
+	      inverse="true">
+      <sql column="alias_id" type="int"/>
+    </property>
+
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- MASHUP ++++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="mashup">
+    <layout>
+      <xml name="mashup" nodeType="xs:element"/>
+      <sql table="mashup"/>
+    </layout>
+
+    <property name="id" type="long" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+    
+    <property name="version" type="long">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+
+    <property name="alias" pluralName="aliases" type= "list" ref="true" 
+              object="mashup_alias" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="type" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(255)"/>
+    </property>
+
+    <property name="vtid" type="long" foreignKey="true" object="vistrail">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="layout" type="str">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="geometry" type="str">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <sql type="mediumtext"/>
+    </property>
+
+    <property name="has_seq" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+      <sql type="int"/>
+    </property>
+    
+    <property name="parent" ref="true" object="mashup_action" type="long" 
+		mapping="one-to-one" inverse="true">
+      <sql column="parent_id" type="int"/>
+    </property>
+    
+    <property name="entity_id" type="long" inverse="true">
+      <sql type="int"/>
+    </property>
+
+    <property name="entity_type" type="str" inverse="true">
+      <sql type="char(16)"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_GRAPH +++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_graph">
+    <layout>
+      <xml name="opmGraph" nodeType="xs:element"/>
+      <!-- <sql table="opm_graph"/> -->
+    </layout>
+
+    <property name="accounts" ref="true" object="opm_accounts" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="processes" ref="true" object="opm_processes" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="artifacts" ref="true" object="opm_artifacts" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="agents" ref="true" object="opm_agents" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="dependencies" ref="true" object="opm_dependencies" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ACCOUNTS ++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_accounts">
+    <layout>
+      <xml name="accounts" nodeType="xs:element"/>
+      <!-- <sql table="accounts"/> -->
+    </layout>
+
+    <property name="account" ref="true" object="opm_account" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="opm_overlaps" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ACCOUNT +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_account">
+    <layout>
+      <xml name="account" nodeType="xs:element"/>
+      <!-- <sql table="account"/> -->
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+    
+    <property name="value" type="str">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_OVERLAPS ++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_overlaps">
+    <layout>
+      <xml name="overlaps" nodeType="xs:element"/>
+      <!-- <sql table="overlaps"/> -->
+    </layout>
+
+    <property ref="true" object="opm_account_id" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ARTIFACTS +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_artifacts">
+    <layout>
+      <xml name="artifacts" nodeType="xs:element"/>
+      <!-- <sql table="artifacts"/> -->
+    </layout>
+
+    <property name="artifact" ref="true" object="opm_artifact" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ARTIFACT_VALUE ++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_artifact_value">
+    <layout>
+      <xml name="value" nodeType="xs:element"/>
+      <!-- <sql table="artifact_value"/> -->
+    </layout>
+    
+    <choice name="value" type="object" mapping="one-to-one">
+      <property ref="true" object="portSpec" type="object" 
+		mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="function" type="object" 
+		mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ARTIFACT ++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_artifact">
+    <layout>
+      <xml name="artifact" nodeType="xs:element"/>
+      <!-- <sql table="artifact"/> -->
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+    
+    <property name="value" ref="true" object="opm_artifact_value" type="object" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_PROCESSES +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_processes">
+    <layout>
+      <xml name="processes" nodeType="xs:element"/>
+      <!-- <sql table="processes"/> -->
+    </layout>
+
+    <property name="process" ref="true" object="opm_process" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_PROCESS_VALUE +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_process_value">
+    <layout>
+      <xml name="value" nodeType="xs:element"/>
+      <!-- <sql table="process_value"/> -->
+    </layout>
+    
+    <choice name="value" type="object" mapping="one-to-one">
+      <property ref="true" object="module_exec" type="object" 
+		mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="group_exec" type="object" 
+		mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="loop_exec" type="object" 
+		mapping="one-to-one">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_PROCESS +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_process">
+    <layout>
+      <xml name="process" nodeType="xs:element"/>
+      <!-- <sql table="process"/> -->
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="value" ref="true" object="opm_process_value" type="object" 
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_AGENTS ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_agents">
+    <layout>
+      <xml name="agents" nodeType="xs:element"/>
+      <!-- <sql table="agents"/> -->
+    </layout>
+
+    <property name="agent" ref="true" object="opm_agent" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_AGENT +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_agent">
+    <layout>
+      <xml name="agent" nodeType="xs:element"/>
+      <!-- <sql table="agent"/> -->
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+    
+    <property name="value" type="str">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type=""/> -->
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_DEPENDENCIES ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="opm_dependencies">
+    <layout>
+      <xml name="causalDependencies" nodeType="xs:element"/>
+      <!-- <sql table="causal_dependencies"/> -->
+    </layout>
+
+    <choice name="dependency" type="list" mapping="one-to-many">
+      <property name="used" ref="true" object="opm_used">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="was_generated_by" ref="true" 
+		object="opm_was_generated_by">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="was_triggered_by" ref="true" 
+		object="opm_was_triggered_by">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="was_derived_from" ref="true" 
+		object="opm_was_derived_from">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property name="was_controlled_by" ref="true" 
+		object="opm_was_controlled_by">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_TIME ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_time">
+    <layout>
+      <xml name="time" nodeType="xs:element"/>
+      <!-- <sql table="time"/> -->
+    </layout>
+
+    <property name="no_later_than" type="datetime">
+      <xml name="noLaterThan" nodeType="xs:attribute" type="xs:dateTime"/>
+      <!-- <sql type="datetime"/> -->
+    </property>
+
+    <property name="no_earlier_than" type="datetime">
+      <xml name="noEarlierThan" nodeType="xs:attribute" type="xs:dateTime"/>
+      <!-- <sql type="datetime"/> -->
+    </property>
+
+    <property name="clock_id" type="str">
+      <xml name="clockId" nodeType="xs:attribute" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ACCOUNT_ID ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_account_id">
+    <layout>
+      <xml name="account" nodeType="xs:element"/>
+      <!-- <sql table="account_id"/> -->
+    </layout>
+
+    <property name="id" type="str" foreignKey="true" object="opm_account">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_PROCESS_ID_CAUSE ++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_process_id_cause">
+    <layout>
+      <xml name="cause" nodeType="xs:element"/>
+      <!-- <sql table="process_id_cause"/> -->
+    </layout>
+
+    <property name="id" type="str" foreignKey="true" object="opm_process">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_PROCESS_ID_EFFECT +++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_process_id_effect">
+    <layout>
+      <xml name="effect" nodeType="xs:element"/>
+      <!-- <sql table="process_id_effect"/> -->
+    </layout>
+
+    <property name="id" type="str" foreignKey="true" object="opm_process">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ARTIFACT_ID_CAUSE +++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_artifact_id_cause">
+    <layout>
+      <xml name="cause" nodeType="xs:element"/>
+      <!-- <sql table="artifact_id_cause"/> -->
+    </layout>
+
+    <property name="id" type="str" foreignKey="true" object="opm_artifact">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ARTIFACT_ID_EFFECT ++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_artifact_id_effect">
+    <layout>
+      <xml name="effect" nodeType="xs:element"/>
+      <!-- <sql table="artifact_id_effect"/> -->
+    </layout>
+
+    <property name="id" type="str" foreignKey="true" object="opm_artifact">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_AGENT_ID ++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_agent_id">
+    <layout>
+      <xml name="agent" nodeType="xs:element"/>
+      <!-- <sql table="agent_id"/> -->
+    </layout>
+
+    <property name="id" type="str" foreignKey="true" object="opm_agent">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_ROLE ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_role">
+    <layout>
+      <xml name="role" nodeType="xs:element"/>
+      <!-- <sql table="role"/> -->
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute"/>
+      <!-- <sql type="varchar(4095)"/> -->
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_USED ++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_used">
+    <layout>
+      <xml name="used" nodeType="xs:element"/>
+      <!-- <sql table="used"/> -->
+    </layout>
+
+    <property name="effect" ref="true" object="opm_process_id_effect"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="role" ref="true" object="opm_role" type="str"
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="cause" ref="true" object="opm_artifact_id_cause"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property ref="true" object="opm_time" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_WAS_GENERATED_BY ++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_was_generated_by">
+    <layout>
+      <xml name="wasGeneratedBy" nodeType="xs:element"/>
+      <!-- <sql table="was_generated_by"/> -->
+    </layout>
+
+    <property name="effect" ref="true" object="opm_artifact_id_effect"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="role" ref="true" object="opm_role" type="str"
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="cause" ref="true" object="opm_process_id_cause"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property ref="true" object="opm_time" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_WAS_CONTROLLED_BY +++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_was_controlled_by">
+    <layout>
+      <xml name="wasControlledBy" nodeType="xs:element"/>
+      <!-- <sql table="was_controlled_by"/> -->
+    </layout>
+
+    <property name="effect" ref="true" object="opm_process_id_effect"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="role" ref="true" object="opm_role" type="str"
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="cause" ref="true" object="opm_agent_id"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="start" ref="true" object="opm_time" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property name="end" ref="true" object="opm_time" type="list" 
+	      mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_WAS_DERIVED_FROM ++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_was_derived_from">
+    <layout>
+      <xml name="wasDerivedFrom" nodeType="xs:element"/>
+      <!-- <sql table="was_derived_from"/> -->
+    </layout>
+
+    <property name="effect" ref="true" object="opm_artifact_id_effect"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="role" ref="true" object="opm_role" type="str"
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="cause" ref="true" object="opm_artifact_id_cause"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property ref="true" object="opm_time" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- OPM_WAS_TRIGGERED_BY ++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="opm_was_triggered_by">
+    <layout>
+      <xml name="wasTriggeredBy" nodeType="xs:element"/>
+      <!-- <sql table="was_triggered_by"/> -->
+    </layout>
+
+    <property name="effect" ref="true" object="opm_process_id_effect"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="role" ref="true" object="opm_role" type="str"
+	      mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="cause" ref="true" object="opm_process_id_cause"
+	      type="str" mapping="one-to-one">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property name="account" ref="true" object="opm_account_id"
+	      type="list" mapping="one-to-many">
+      <xml nodeType="xs:element" type="xs:string"/>
+      <!-- <sql type="varchar(255)"/> -->
+    </property>
+
+    <property ref="true" object="opm_time" type="list" mapping="one-to-many">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_DOCUMENT +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_document">
+    <layout>
+      <xml name="prov:document" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="prov_entity" ref="true" object="prov_entity" type="list" 
+          mapping="one-to-many">
+      <xml name="prov:entity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_activity" ref="true" object="prov_activity" type="list" 
+          mapping="one-to-many">
+      <xml name="prov:activity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_agent" ref="true" object="prov_agent" type="list" 
+          mapping="one-to-many">
+      <xml name="prov:agent" nodeType="xs:element"/>
+    </property>
+    
+    <property name="vt_connection" ref="true" object="vt_connection" type="list" 
+          mapping="one-to-many">
+      <xml name="vt:connection" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_usage" ref="true" object="prov_usage" type="list" 
+          mapping="one-to-many">
+      <xml name="prov:used" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_generation" ref="true" object="prov_generation" type="list" 
+          mapping="one-to-many">
+      <xml name="prov:wasGeneratedBy" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_association" ref="true" object="prov_association" type="list" 
+          mapping="one-to-many">
+      <xml name="prov:wasAssociatedWith" nodeType="xs:element"/>
+    </property>
+    
+    <!--<property name="vt_part" ref="true" object="vt_part" type="list" 
+          mapping="one-to-many">
+      <xml name="vt:isPartOf" nodeType="xs:element"/>
+    </property>-->
+    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_ENTITY +++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_entity">
+    <layout>
+      <xml name="prov:entity" nodeType="xs:element"/>
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml name="prov:id" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+    
+    <property name="prov_type" type="str">
+      <xml name="prov:type" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="prov_label" type="str">
+      <xml name="prov:label" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="prov_value" type="str">
+      <xml name="prov:value" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_id" type="str">
+      <xml name="vt:id" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_type" type="str">
+      <xml name="vt:type" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_desc" type="str">
+      <xml name="vt:desc" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_package" type="str">
+      <xml name="vt:package" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_version" type="str">
+      <xml name="vt:version" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_cache" type="str">
+      <xml name="vt:cache" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_location_x" type="str">
+      <xml name="vt:location_x" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_location_y" type="str">
+      <xml name="vt:location_y" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="is_part_of" ref="true" object="is_part_of" type="str">
+      <xml name="dcterms:isPartOf" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- REF_PROV_ENTITY +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="ref_prov_entity">
+    <layout>
+      <xml name="prov:entity" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="prov_ref" type="str" foreignKey="true" object="prov_entity">
+      <xml name="prov:ref" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- REF_PROV_PLAN +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="ref_prov_plan">
+    <layout>
+      <xml name="prov:plan" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="prov_ref" type="str" foreignKey="true" object="prov_entity">
+      <xml name="prov:ref" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_ACTIVITY +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_activity">
+    <layout>
+      <xml name="prov:activity" nodeType="xs:element"/>
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml name="prov:id" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+    
+    <property name="startTime" type="str">
+      <xml name="prov:startTime" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="endTime" type="str">
+      <xml name="prov:endTime" nodeType="xs:element" type="xs:string"/>
+    </property>
+
+    <property name="vt_id" type="str" primaryKey="true">
+      <xml name="vt:id" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_type" type="str">
+      <xml name="vt:type" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_cached" type="str">
+      <xml name="vt:cached" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_completed" type="str">
+      <xml name="vt:completed" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_machine_id" type="str">
+      <xml name="vt:machine_id" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_error" type="str">
+      <xml name="vt:error" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="is_part_of" ref="true" object="is_part_of" type="str">
+      <xml name="dcterms:isPartOf" nodeType="xs:element" type="xs:string"/>
+    </property>
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- REF_PROV_ACTIVITY +++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="ref_prov_activity">
+    <layout>
+      <xml name="prov:activity" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="prov_ref" type="str" foreignKey="true" object="prov_activity">
+      <xml name="prov:ref" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_AGENT ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_agent">
+    <layout>
+      <xml name="prov:agent" nodeType="xs:element"/>
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml name="prov:id" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <property name="vt_id" type="str">
+      <xml name="vt:id" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="prov_type" type="str">
+      <xml name="prov:type" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="prov_label" type="str">
+      <xml name="prov:label" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_machine_os" type="str">
+      <xml name="vt:machine_os" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_machine_architecture" type="str">
+      <xml name="vt:machine_architecture" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_machine_processor" type="str">
+      <xml name="vt:machine_processor" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_machine_ram" type="str">
+      <xml name="vt:machine_ram" nodeType="xs:element" type="xs:string"/>
+    </property>
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- REF_PROV_AGENT ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+  
+  <object name="ref_prov_agent">
+    <layout>
+      <xml name="prov:agent" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="prov_ref" type="str" foreignKey="true" object="prov_agent">
+      <xml name="prov:ref" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- VT_CONNECTION +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="vt_connection">
+    <layout>
+      <xml name="vt:connection" nodeType="xs:element"/>
+    </layout>
+
+    <property name="id" type="str" primaryKey="true">
+      <xml name="id" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <property name="vt_source" type="str">
+      <xml name="vt:source" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_dest" type="str">
+      <xml name="vt:dest" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_source_port" type="str">
+      <xml name="vt:source_port" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_dest_port" type="str">
+      <xml name="vt:dest_port" nodeType="xs:element" type="xs:string"/>
+    </property>
+      
+    <property name="vt_source_signature" type="str">
+      <xml name="vt:source_signature" nodeType="xs:element" type="xs:string"/>
+    </property>
+    
+    <property name="vt_dest_signature" type="str">
+      <xml name="vt:dest_signature" nodeType="xs:element" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_USAGE ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_usage">
+    <layout>
+      <xml name="prov:used" nodeType="xs:element"/>
+    </layout>
+
+    <!--<property name="id" type="str" primaryKey="true">
+      <xml name="id" nodeType="xs:attribute" type="xs:string"/>
+    </property>-->
+    
+    <property name="prov_activity" ref="true" object="ref_prov_activity" type="str">
+      <xml name="prov:activity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_entity" ref="true" object="ref_prov_entity" type="str">
+      <xml name="prov:entity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_role" type="str">
+      <xml name="prov:role" nodeType="xs:element" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_GENERATION +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_generation">
+    <layout>
+      <xml name="prov:wasGeneratedBy" nodeType="xs:element"/>
+    </layout>
+
+    <!--<property name="id" type="str" primaryKey="true">
+      <xml name="id" nodeType="xs:attribute" type="xs:string"/>
+    </property>-->
+    
+    <property name="prov_entity" ref="true" object="ref_prov_entity" type="str">
+      <xml name="prov:entity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_activity" ref="true" object="ref_prov_activity" type="str">
+      <xml name="prov:activity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_role" type="str">
+      <xml name="prov:role" nodeType="xs:element" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- PROV_ASSOCIATION ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="prov_association">
+    <layout>
+      <xml name="prov:wasAssociatedWith" nodeType="xs:element"/>
+    </layout>
+
+    <!--<property name="id" type="str" primaryKey="true">
+      <xml name="id" nodeType="xs:attribute" type="xs:string"/>
+    </property>-->
+    
+    <property name="prov_activity" ref="true" object="ref_prov_activity" type="str">
+      <xml name="prov:activity" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_agent" ref="true" object="ref_prov_agent" type="str">
+      <xml name="prov:agent" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_plan" ref="true" object="ref_prov_plan" type="str">
+      <xml name="prov:plan" nodeType="xs:element"/>
+    </property>
+    
+    <property name="prov_role" type="str">
+      <xml name="prov:role" nodeType="xs:element" type="xs:string"/>
+    </property>  
+  </object>
+  
+  <!--++++++++++++++++++++++++++-->
+  <!-- IS_PART_OF ++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="is_part_of">
+    <layout>
+      <xml name="dcterms:isPartOf" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="prov_ref" type="str">
+      <xml name="prov:ref" nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- STARTUP +++++++++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="startup">
+    <layout>
+      <xml name="startup" nodeType="xs:element"/>
+    </layout>
+    
+    <property name="version" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <property ref="true" object="configuration" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>
+
+    <property ref="true" object="enabled_packages" type="list" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>    
+
+    <property ref="true" object="disabled_packages" type="list" mapping="one-to-one">
+      <xml nodeType="xs:element"/>
+    </property>    
+
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- ENABLED_PACKAGES ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="enabled_packages">
+    <layout>
+      <xml name="packages" nodeType="xs:element"/>
+    </layout>
+  
+    <property name="package" ref="true" object="startup_package" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- DISABLED_PACKAGES +++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="disabled_packages">
+    <layout>
+      <xml name="disabledpackages" nodeType="xs:element"/>
+    </layout>
+  
+    <property name="package" ref="true" object="startup_package" type="list" 
+	      mapping="one-to-many" index="name">
+      <xml nodeType="xs:element"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- STARTUP_PACKAGE +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="startup_package">
+    <layout>
+      <xml name="package" nodeType="xs:element"/>
+    </layout>
+
+    <property name="name" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+      <sql type="varchar(1023)"/>
+    </property>
+
+    <property ref="true" object="configuration" type="object" mapping="one-to-one">
+      <xml nodeType="xs:element" name="configuration"/>
+    </property>    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIGURATION +++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="configuration">
+    <layout>
+      <xml name="configuration" nodeType="xs:element"/>
+    </layout>
+
+    <property ref="true" object="config_key" type="list" 
+	      mapping="one-to-many">
+      <xml name="key" nodeType="xs:element"/>
+    </property>    
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_KEY ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_key">
+    <layout>
+      <xml name="key" nodeType="xs:element"/>
+    </layout>
+
+    <property name="name" type="str" primaryKey="true">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+
+    <choice name="value" type="object" mapping="one-to-one">
+      <property ref="true" object="config_str">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_int">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_float">
+	<xml nodeType="xs:element"/>
+      </property>
+
+      <property ref="true" object="config_bool">
+	<xml nodeType="xs:element"/>
+      </property>
+      
+      <property ref="true" object="configuration">
+	<xml nodeType="xs:element"/>
+      </property>
+    </choice>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_STR ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_str">
+    <layout>
+      <xml name="str" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_INT ++++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_int">
+    <layout>
+      <xml name="int" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="int">
+      <xml nodeType="xs:attribute" type="xs:int"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_FLOAT ++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_float">
+    <layout>
+      <xml name="float" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="float">
+      <xml nodeType="xs:attribute" type="xs:float"/>
+    </property>
+  </object>
+
+  <!--++++++++++++++++++++++++++-->
+  <!-- CONFIG_BOOL +++++++++-->
+  <!--++++++++++++++++++++++++++-->
+
+  <object name="config_bool">
+    <layout>
+      <xml name="bool" nodeType="xs:element"/>
+    </layout>
+
+    <property name="value" type="str">
+      <xml nodeType="xs:attribute" type="xs:string"/>
+    </property>
+  </object>
+</objects>
diff --git a/vistrails/db/versions/v1_0_4/translate/__init__.py b/vistrails/db/versions/v1_0_4/translate/__init__.py
new file mode 100644
index 0000000..c59e2e5
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/translate/__init__.py
@@ -0,0 +1,39 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+version = '1.0.4'
diff --git a/vistrails/db/versions/v1_0_4/translate/v1_0_3.py b/vistrails/db/versions/v1_0_4/translate/v1_0_3.py
new file mode 100644
index 0000000..2bbef12
--- /dev/null
+++ b/vistrails/db/versions/v1_0_4/translate/v1_0_3.py
@@ -0,0 +1,483 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from vistrails.db.versions.v1_0_4.domain import DBVistrail, DBVistrailVariable, \
+                                      DBWorkflow, DBLog, DBRegistry, \
+                                      DBAdd, DBChange, DBDelete, \
+                                      DBPortSpec, DBPortSpecItem, \
+                                      DBParameterExploration, \
+                                      DBPEParameter, DBPEFunction, \
+                                      IdScope, DBAbstraction, \
+                                      DBModule, DBGroup, DBAnnotation, \
+                                      DBActionAnnotation, DBStartup, \
+                                      DBConfigKey, DBConfigBool, DBConfigStr, \
+                                      DBConfigInt, DBConfigFloat, \
+                                      DBConfiguration, DBStartupPackage, \
+                                      DBLoopIteration, DBLoopExec, \
+                                      DBModuleExec, DBGroupExec
+
+from vistrails.db.services.vistrail import materializeWorkflow
+from xml.dom.minidom import parseString
+from itertools import izip
+import os
+import shutil
+import string
+import tempfile
+from ast import literal_eval
+import unittest
+
+id_scope = None
+
+def translateVistrail(_vistrail):
+    """ Translate old annotation based vistrail variables to new
+        DBVistrailVariable class """
+    global id_scope
+
+    def update_workflow(old_obj, trans_dict):
+        return DBWorkflow.update_version(old_obj.db_workflow, 
+                                         trans_dict, DBWorkflow())
+
+    translate_dict = {'DBGroup': {'workflow': update_workflow}}
+    vistrail = DBVistrail()
+    id_scope = vistrail.idScope
+    vistrail = DBVistrail.update_version(_vistrail, translate_dict, vistrail)
+
+    vistrail.db_version = '1.0.4'
+    return vistrail
+
+def translateWorkflow(_workflow):
+    global id_scope
+    def update_workflow(old_obj, translate_dict):
+        return DBWorkflow.update_version(old_obj.db_workflow, translate_dict)
+    translate_dict = {'DBGroup': {'workflow': update_workflow}}
+
+    workflow = DBWorkflow()
+    id_scope = IdScope(remap={DBAbstraction.vtType: DBModule.vtType, DBGroup.vtType: DBModule.vtType})
+    workflow = DBWorkflow.update_version(_workflow, translate_dict, workflow)
+    workflow.db_version = '1.0.4'
+    return workflow
+
+def translateLog(_log):
+    id_scope = _log.id_scope
+    def update_loop_execs(old_obj, translate_dict):
+        if len(old_obj.db_loop_execs) == 0:
+            return []
+        # create new LoopExec and add existing as LoopIteration's
+        ts_start = None
+        ts_end = None
+        new_iters = []
+        for loop_exec in old_obj.db_loop_execs:
+            item_execs = []
+            for item_exec in loop_exec.db_item_execs:
+                if item_exec.vtType == DBModuleExec.vtType:
+                    item_execs.append(DBModuleExec.update_version(item_exec,
+                                                                  translate_dict))
+                if item_exec.vtType == DBGroupExec.vtType:
+                    item_execs.append(DBGroupExec.update_version(item_exec,
+                                                                 translate_dict))
+                # skip DBLoopExecs
+            new_iter = DBLoopIteration(item_execs=item_execs,
+                                       id=id_scope.getNewId(DBLoopIteration.vtType),
+                                       ts_start=loop_exec.db_ts_start,
+                                       ts_end=loop_exec.db_ts_end,
+                                       iteration=loop_exec.db_iteration,
+                                       completed=loop_exec.db_completed,
+                                       error=loop_exec.db_error)
+            new_iters.append(new_iter)
+            if ts_start is None or ts_start > loop_exec.db_ts_start:
+                ts_start = loop_exec.db_ts_start
+            if ts_end is None or ts_end < loop_exec.db_ts_end:
+                ts_end = loop_exec.db_ts_end
+        return [DBLoopExec(id=id_scope.getNewId(DBLoopExec.vtType),
+                                       ts_start=ts_start,
+                                       ts_end=ts_end,
+                                       loop_iterations=new_iters)]
+
+    def update_item_execs(old_obj, translate_dict):
+        # remove loop_execs and add them as loop_iterations under a single loop_exec
+        new_objs = []
+        ts_start = None
+        ts_end = None
+        new_iters = []
+        for obj in old_obj.db_item_execs:
+            if obj.vtType == DBModuleExec.vtType:
+                new_objs.append(DBModuleExec.update_version(obj,
+                                                            translate_dict))
+            if obj.vtType == DBGroupExec.vtType:
+                new_objs.append(DBGroupExec.update_version(obj,
+                                                           translate_dict))
+            if obj.vtType == DBLoopExec.vtType:
+                item_execs = []
+                for item_exec in obj.db_item_execs:
+                    if item_exec.vtType == DBModuleExec.vtType:
+                        item_execs.append(DBModuleExec.update_version(item_exec,
+                                                                      translate_dict))
+                    if item_exec.vtType == DBGroupExec.vtType:
+                        item_execs.append(DBGroupExec.update_version(item_exec,
+                                                                     translate_dict))
+                    # skip DBLoopExecs
+                new_iter = DBLoopIteration(item_execs=item_execs,
+                                           id=id_scope.getNewId(DBLoopIteration.vtType),
+                                           ts_start=obj.db_ts_start,
+                                           ts_end=obj.db_ts_end,
+                                           iteration=obj.db_iteration,
+                                           completed=obj.db_completed,
+                                           error=obj.db_error)
+                new_iters.append(new_iter)
+                if ts_start is None or ts_start > obj.db_ts_start:
+                    ts_start = obj.db_ts_start
+                if ts_end is None or ts_end < obj.db_ts_end:
+                    ts_end = obj.db_ts_end
+        if len(new_iters):
+            new_objs.append(DBLoopExec(id=id_scope.getNewId(DBLoopExec.vtType),
+                                       ts_start=ts_start,
+                                       ts_end=ts_end,
+                                       loop_iterations=new_iters))
+        return new_objs
+
+        
+        return DBWorkflow.update_version(old_obj.db_workflow, translate_dict)
+    translate_dict = {'DBModuleExec': {'loop_execs': update_loop_execs},
+                      'DBGroupExec': {'item_execs': update_item_execs}}
+    log = DBLog.update_version(_log, translate_dict)
+    log.db_version = '1.0.4'
+    return log
+
+def translateRegistry(_registry):
+    global id_scope
+    translate_dict = {}
+    registry = DBRegistry()
+    id_scope = registry.idScope
+    registry = DBRegistry.update_version(_registry, translate_dict, registry)
+    registry.db_version = '1.0.4'
+    return registry
+
+def translateStartup(_startup):
+    # format is {<old_name>: <new_name>} or
+    # {<old_name>: (<new_name> | None, [conversion_f | None, inner_d | None])
+    # conversion_f is a function that mutates the value and
+    # inner_d recurses the translation for inner configurations
+
+    dot_vt_path = None
+    startup_dir = os.path.dirname(_startup._filename)
+    if os.path.isabs(startup_dir):
+        dot_vt_path = startup_dir
+
+    def change_value(cls, conv_f, _key, t_dict):
+        cls_name = cls.__name__
+        old_t_value = None
+        if cls_name in t_dict:
+            if 'value' in t_dict[cls_name]:
+                old_t_value = t_dict[cls_name]['value']
+        else:
+            t_dict[cls_name] = {}
+        t_dict[cls_name]['value'] = conv_f
+        new_value = cls.update_version(_key.db_value, t_dict)
+        del t_dict[cls_name]['value']
+        if old_t_value is not None:
+            t_dict[cls_name]['value'] = old_t_value
+        if len(t_dict[cls_name]) < 1:
+            del t_dict[cls_name]
+        return new_value
+
+    def invert_bool(_key, t_dict):
+        def invert_value(_value, t):
+            return unicode(not (_value.db_value.lower() == 'true'))
+        return change_value(DBConfigBool, invert_value, _key, t_dict)
+
+    def use_dirname(_key, t_dict):
+        def get_dirname(_value, t):
+            dir_name = os.path.dirname(_value.db_value)
+            if os.path.isabs(dir_name) and dir_name.startswith(dot_vt_path):
+                dir_name = dir_name[len(dot_vt_path)+1:]
+                if not dir_name.strip():
+                    dir_name = "logs"
+            return dir_name
+        return change_value(DBConfigStr, get_dirname, _key, t_dict)
+
+    def update_dirname(_key, t_dict):
+        def change_dirname(_value, t):
+            abs_path = _value.db_value
+            if os.path.isabs(abs_path) and abs_path.startswith(dot_vt_path):
+                return abs_path[len(dot_vt_path)+1:]
+            return abs_path
+        return change_value(DBConfigStr, change_dirname, _key, t_dict)
+
+    def pdf_bool_to_str(_value):
+        s_val = "PNG"
+        if _value.db_value.lower() == "true":
+            s_val = "PDF"
+        return DBConfigStr(value=s_val)
+
+    t = {'alwaysShowDebugPopup': 'showDebugPopups',
+         'autosave': 'autoSave',
+         'errorOnConnectionTypeerror': 'showConnectionErrors',
+         'errorOnVariantTypeerror': 'showVariantErrors',
+         'interactiveMode': ('batch', invert_bool),
+         'logFile': ('logDir', use_dirname),
+         'logger': None, # DELETE
+         'maxMemory': None,
+         'minMemory': None,
+         'nologger': ('executionLog', invert_bool),
+         'pythonPrompt': None,
+         'reviewMode': None, # unknown what this was/is
+         'shell': ('shell', None, {'font_face': 'fontFace',
+                                   'font_size': 'fontSize'}),
+         'showMovies': None,
+         'showSpreadsheetOnly': ('showWindow', invert_bool),
+         'spreadsheetDumpCells': 'outputDirectory',
+         'upgradeOn': 'upgrades',
+         'useCache': 'cache',
+         'verbosenessLevel': 'debugLevel',
+         'webRepositoryLogin': 'webRespositoryUser',
+         'evolutionGraph': 'withVersionTree',
+         'workflowGraph': 'withWorkflow',
+         # 'workflowInfo': 'outputWorkflowInfo',
+         'workflowInfo': 'outputDirectory',
+         'executeWorkflows': 'execute',
+
+         'thumbs': ('thumbs', None,
+                    {'cacheDirectory': ('cacheDir', update_dirname)}),
+         'abstractionsDirectory': ('subworkflowsDir', update_dirname),
+         'userPackageDirectory': ('userPackageDir', update_dirname),
+         'temporaryDirectory': 'temporaryDir',
+         'dataDirectory': 'dataDir',
+         'fileDirectory': 'fileDir',
+         'packageDirectory': 'packageDir',
+
+         }
+
+    # these are moving to package configurations
+    t_package = {
+         'spreadsheetDumpPDF': ('spreadsheet', 'dumpfileType', pdf_bool_to_str),
+         'fixedSpreadsheetCells': ('spreadsheet', 'fixedCellSize'),
+    }
+
+    def get_key_name_update(new_name):
+        def update_key_name(_key, t_dict):
+            return new_name
+        return update_key_name
+
+    def update_config_keys(_config, t_dict):
+        # just update __startup_translate__ as we recurse,
+        # update_key_name and update_key_value take care of the rest
+        cur_t = t_dict['__startup_translate__']
+        cur_t_pkg = t_dict['__startup_translate_pkg__']
+        new_keys = []
+        for key in _config.db_config_keys:
+            to_delete = False
+            new_name = None
+            conv_f = None
+            inner_t = None
+            if key.db_name in cur_t:
+                t_obj = cur_t[key.db_name]
+                if type(t_obj) == tuple:
+                    new_name = t_obj[0]
+                    if len(t_obj) > 1:
+                        conv_f = t_obj[1]
+                    if len(t_obj) > 2:
+                        inner_t = t_obj[2]
+                elif t_obj is None:
+                    to_delete = True
+                else:
+                    new_name = t_obj
+
+            if key.db_name in cur_t_pkg:
+                updated_key = DBConfigKey.update_version(key, t_dict)
+                pkg_t = cur_t_pkg[key.db_name]
+                pkg_name = pkg_t[0]
+                key_name = pkg_t[1]
+                config_dict = t_dict['__startup_package_config__']
+
+                if pkg_name not in config_dict:
+                    config_dict[pkg_name] = []
+                if len(pkg_t) > 2:
+                    value_f = pkg_t[2]
+                    new_value = value_f(key.db_value)
+                else:
+                    # have to update version here?
+                    new_value = updated_key.db_value
+                config_dict[pkg_name].append(DBConfigKey(name=key_name,
+                                                         value=new_value))
+
+            # if we have already set a key, don't override the new
+            # setting in general (may want to if swapping existing
+            # names, but this should be the exception)
+            elif (not to_delete and
+                (new_name == key.db_name or
+                 new_name not in _config.db_config_keys_name_index)):
+                # always overwrite DBConfigKey settings so recursion
+                # doesn't wrap over itself
+                key_t_dict = {}
+                if new_name is not None and new_name != key.db_name:
+                    key_t_dict['name'] = get_key_name_update(new_name)
+                if conv_f is not None:
+                    key_t_dict['value'] = conv_f
+                old_t_name = None
+                old_t_value = None
+                if len(key_t_dict) > 0:
+                    if 'DBConfigKey' in t_dict:
+                        if 'name' in t_dict['DBConfigKey']:
+                            old_t_name = t_dict['DBConfigKey']['name']
+                            del t_dict['DBConfigKey']['name']
+                        if 'value' in t_dict['DBConfigKey']:
+                            old_t_value = t_dict['DBConfigKey']['value']
+                            del t_dict['DBConfigKey']['value']
+                        t_dict['DBConfigKey'].update(key_t_dict)
+                    else:
+                        t_dict['DBConfigKey'] = key_t_dict
+                if inner_t is not None:
+                    t_dict['__startup_translate__'] = inner_t
+                new_keys.append(DBConfigKey.update_version(key, t_dict))
+                if inner_t is not None:
+                    t_dict['__startup_translate__'] = cur_t
+                if len(key_t_dict) > 0:
+                    if 'name' in t_dict['DBConfigKey']:
+                        del t_dict['DBConfigKey']['name']
+                    if 'value' in t_dict['DBConfigKey']:
+                        del t_dict['DBConfigKey']['value']
+                    if old_t_name is not None:
+                        t_dict['DBConfigKey']['name'] = old_t_name
+                    if old_t_value is not None:
+                        t_dict['DBConfigKey']['value'] = old_t_value
+                    if len(t_dict['DBConfigKey']) < 1:
+                        del t_dict['DBConfigKey']
+        return new_keys
+
+    def update_package_config(_startup_pkg, t_dict):
+        _config = _startup_pkg.db_configuration
+        package_config = t_dict['__startup_package_config__']
+        if _config is not None:
+            config = DBConfiguration.update_version(_config, t_dict)
+            if _startup_pkg.db_name in package_config:
+                for new_key in package_config[_startup_pkg.db_name]:
+                    if new_key.db_name in config.db_config_keys_name_index:
+                        # already have, don't replace new setting
+                        continue
+                    else:
+                        config.db_add_config_key(new_key)
+                del package_config[_startup_pkg.db_name]
+            return config
+        return None
+
+    # need to recurse both key name changes and key value changes
+    # (could also change types...)
+    translate_dict = {'DBConfiguration': {'config_keys': update_config_keys},
+                      'DBStartupPackage': {'configuration':
+                                           update_package_config},
+                      '__startup_translate__': t,
+                      '__startup_translate_pkg__': t_package,
+                      '__startup_package_config__': dict()}
+    startup = DBStartup()
+    startup = DBStartup.update_version(_startup, translate_dict, startup)
+
+    # add any translations to packages, creating startup_pkg and
+    # configuration if necessary
+    for pkg, keys in translate_dict['__startup_package_config__'].iteritems():
+        if pkg in startup.db_enabled_packages.db_packages_name_index:
+            s_pkg = startup.db_enabled_packages.db_packages_name_index[pkg]
+        elif pkg in startup.db_disabled_packages.db_packages_name_index:
+            s_pkg = startup.db_disabled_packages.db_packages_name_index[pkg]
+        else:
+            s_pkg = DBStartupPackage(name=pkg)
+            startup.db_disabled_packages.db_add_package(s_pkg)
+        if s_pkg.db_configuration is None:
+            s_pkg.db_configuration = DBConfiguration(config_keys=keys)
+        else:
+            for new_key in keys:
+                if new_key.db_name not in s_pkg.db_configuration:
+                    # only add if new setting doesn't already exist
+                    s_pkg.db_configuration.db_add_config_key(new_key)
+
+    startup.db_version = '1.0.4'
+    return startup
+
+class TestTranslate(unittest.TestCase):
+    def test_startup_update(self):
+        from vistrails.db.services.io import open_startup_from_xml
+        from vistrails.core.system import vistrails_root_directory
+        import os
+
+        startup_tmpl = os.path.join(vistrails_root_directory(),
+                                    'tests', 'resources',
+                                    'startup-0.1.xml.tmpl')
+        f = open(startup_tmpl, 'r')
+        template = string.Template(f.read())
+
+        startup_dir = tempfile.mkdtemp(prefix="vt_startup")
+        startup_fname = os.path.join(startup_dir, "startup.xml")
+        with open(startup_fname, 'w') as f:
+            f.write(template.substitute({'startup_dir': startup_dir}))
+        try:
+            # FIXME need to generate startup from local path
+            startup = open_startup_from_xml(startup_fname)
+            name_idx = startup.db_configuration.db_config_keys_name_index
+            self.assertNotIn('nologger', name_idx)
+            self.assertIn('executionLog', name_idx)
+            self.assertFalse(
+                name_idx['executionLog'].db_value.db_value.lower() == 'true')
+            self.assertNotIn('showMovies', name_idx)
+            self.assertIn('logDir', name_idx)
+            self.assertEqual(name_idx['logDir'].db_value.db_value, 'logs')
+            self.assertIn('userPackageDir', name_idx)
+            self.assertEqual(name_idx['userPackageDir'].db_value.db_value,
+                             'userpackages')
+            self.assertIn('thumbs', name_idx)
+            thumbs_name_idx = \
+                    name_idx['thumbs'].db_value.db_config_keys_name_index
+            self.assertIn('cacheDir', thumbs_name_idx)
+            self.assertEqual(thumbs_name_idx['cacheDir'].db_value.db_value,
+                             '/path/to/thumbs')
+            self.assertIn('subworkflowsDir', name_idx)
+            self.assertEqual(name_idx['subworkflowsDir'].db_value.db_value,
+                             'subworkflows')
+
+            # note: have checked with spreadsheet removed from all
+            # packages list, too
+            # TODO: make this a permanent test (new template?)
+            self.assertNotIn('fixedSpreadsheetCells', name_idx)
+            enabled_names = startup.db_enabled_packages.db_packages_name_index
+            self.assertIn('spreadsheet', enabled_names)
+            spreadsheet_config = enabled_names['spreadsheet'].db_configuration
+            self.assertIsNotNone(spreadsheet_config)
+            spreadsheet_name_idx = spreadsheet_config.db_config_keys_name_index
+            self.assertIn('fixedCellSize', spreadsheet_name_idx)
+            self.assertTrue(spreadsheet_name_idx['fixedCellSize'].db_value.db_value.lower() == "true")
+            self.assertIn('dumpfileType', spreadsheet_name_idx)
+            self.assertEqual(spreadsheet_name_idx['dumpfileType'].db_value.db_value, "PNG")
+        finally:
+            shutil.rmtree(startup_dir)
diff --git a/vistrails/gui/__init__.py b/vistrails/gui/__init__.py
index fac3164..5e49c53 100644
--- a/vistrails/gui/__init__.py
+++ b/vistrails/gui/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/gui/application.py b/vistrails/gui/application.py
index 005b964..1d596ba 100644
--- a/vistrails/gui/application.py
+++ b/vistrails/gui/application.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,23 +37,31 @@
 initializations to the theme, packages and the builder...
 
 """
+from __future__ import division
+
+from ast import literal_eval
+import os.path
+import getpass
+import re
+import sys
+import StringIO
+
 from PyQt4 import QtGui, QtCore, QtNetwork
+
 from vistrails.core.application import VistrailsApplicationInterface, \
     get_vistrails_application, set_vistrails_application
-from vistrails.core import command_line
 from vistrails.core import debug
 from vistrails.core import system
 from vistrails.core.application import APP_SUCCESS, APP_FAIL, APP_DONE
+from vistrails.core.db.io import load_vistrail
 from vistrails.core.db.locator import FileLocator, DBLocator
 import vistrails.core.requirements
+from vistrails.core.vistrail.controller import VistrailController
 from vistrails.db import VistrailsDBException
-import vistrails.db.services.io
+from vistrails.db.services.io import test_db_connection
 from vistrails.gui import qt
 import vistrails.gui.theme
-import os.path
-import getpass
-import re
-import sys
+
 
 ################################################################################
 
@@ -63,7 +72,9 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
     there will be only one instance of the application during VisTrails
     
     """
-    
+
+    use_event_filter = system.systemType in ['Darwin']
+
     def __call__(self):
         """ __call__() -> VistrailsApplicationSingleton
         Return self for calling method
@@ -83,7 +94,7 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
         QtGui.QApplication.__init__(self, sys.argv)
         VistrailsApplicationInterface.__init__(self)
 
-        if system.systemType in ['Darwin']:
+        if self.use_event_filter:
             self.installEventFilter(self)
         self.builderWindow = None
         # local notifications
@@ -98,7 +109,7 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
         self.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus)
         qt.allowQObjects()
 
-    def run_single_instance(self):
+    def run_single_instance(self, args):
         # code for single instance of the application
         # based on the C++ solution available at
         # http://wiki.qtcentre.org/index.php?title=SingleApplication
@@ -120,11 +131,11 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                     try:
                         os.remove(self._unique_key)
                     except OSError, e:
-                        debug.critical("Couldn't remove socket: %s (%s)" % (
-                                       self._unique_key, e))
+                        debug.critical("Couldn't remove socket: %s" %
+                                       self._unique_key, e)
 
                 else:
-                    if self.found_another_instance_running(local_socket):
+                    if self.found_another_instance_running(local_socket, args):
                         return APP_DONE # success, we should shut down
                     else:
                         return APP_FAIL  # error, we should shut down
@@ -166,9 +177,9 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
 
         return None
 
-    def found_another_instance_running(self, local_socket):
+    def found_another_instance_running(self, local_socket, args):
         debug.critical("Found another instance of VisTrails running")
-        msg = bytes(sys.argv[1:])
+        msg = bytes(args)
         debug.critical("Will send parameters to main instance %s" % msg)
         res = self.send_message(local_socket, msg)
         if res is True:
@@ -180,29 +191,36 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
             debug.critical("Main instance reports: %s" % res)
             return False
 
-    def init(self, optionsDict=None):
+    def init(self, optionsDict=None, args=[]):
         """ VistrailsApplicationSingleton(optionDict: dict)
                                           -> VistrailsApplicationSingleton
         Create the application with a dict of settings
         
         """
         vistrails.gui.theme.initializeCurrentTheme()
-        VistrailsApplicationInterface.init(self, optionsDict)
+        VistrailsApplicationInterface.init(self, optionsDict, args)
+        
+        if self.temp_configuration.check('jobInfo') or \
+           self.temp_configuration.check('jobList'):
+            self.temp_configuration.batch = True
 
         # singleInstance configuration
         singleInstance = self.temp_configuration.check('singleInstance')
         if singleInstance:
-            finished = self.run_single_instance()
+            finished = self.run_single_instance(args)
             if finished is not None:
                 return finished
 
-        interactive = self.temp_configuration.check('interactiveMode')
+        interactive = not self.temp_configuration.check('batch')
         if interactive:
             self.setIcon()
             self.createWindows()
             self.processEvents()
+            
+        # self.vistrailsStartup.init()
+        self.package_manager.initialize_packages(
+                report_missing_dependencies=not self.startup.first_run)
 
-        self.vistrailsStartup.init()
         # ugly workaround for configuration initialization order issue
         # If we go through the configuration too late,
         # The window does not get maximized. If we do it too early,
@@ -212,7 +230,7 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                 self.builderWindow.showMaximized()
             if self.temp_configuration.check('dbDefault'):
                 self.builderWindow.setDBDefault(True)
-        self._python_environment = self.vistrailsStartup.get_python_environment()
+
         self._initialized = True
 
         # default handler installation
@@ -376,9 +394,9 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
             for m in self.notifications[notification_id]:
                 try:
                     m(*args)
-                except Exception:
-                    import traceback
-                    traceback.print_exc()
+                except Exception, e:
+                    debug.unexpected_exception(e)
+                    debug.print_exc()
         notifications = {}
 
         current_window = self.builderWindow
@@ -391,9 +409,9 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                 for m in notifications[notification_id]:
                     try:
                         m(*args)
-                    except Exception:
-                        import traceback
-                        traceback.print_exc()
+                    except Exception, e:
+                        debug.unexpected_exception(e)
+                        debug.print_exc()
 
         if current_window is not None:
             current_view = current_window.current_view
@@ -407,9 +425,9 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                 for m in notifications[notification_id]:
                     try:
                         m(*args)
-                    except Exception:
-                        import traceback
-                        traceback.print_exc()
+                    except Exception, e:
+                        debug.unexpected_exception(e)
+                        debug.print_exc()
 
     def showBuilderWindow(self):
         # in some systems (Linux and Tiger) we need to make both calls
@@ -433,12 +451,11 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
         self.builderWindow.link_registry()
         
         self.process_interactive_input()
-        if not self.temp_configuration.showSpreadsheetOnly:
+        if self.temp_configuration.showWindow:
             self.showBuilderWindow()
         else:
             self.builderWindow.hide()
         self.builderWindow.create_first_vistrail()
-        self.builderWindow.check_running_jobs()
 
     def noninteractiveMode(self):
         """ noninteractiveMode() -> None
@@ -446,28 +463,27 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
         
         """
         usedb = False
-        if self.temp_db_options.host:
+        passwd = ''
+        if self.temp_configuration.check('host'):
             usedb = True
-            passwd = ''
-        if usedb and self.temp_db_options.user:
-            if self.temp_db_options.user:
-                db_config = dict((x, self.temp_db_options.__dict__[x])
-                                 for x in ['host', 'port', 
-                                           'db', 'user'])
+        if usedb and self.temp_configuration.check('user'):
+            db_config = dict((x, self.temp_configuration.check(x))
+                             for x in ['host', 'port', 
+                                       'db', 'user'])
+            try:
+                test_db_connection(db_config)
+            except VistrailsDBException:
+                passwd = \
+                    getpass.getpass("Connecting to %s:%s. Password for user '%s':" % (
+                                    db_config['host'],
+                                    db_config['db'],
+                                    db_config['user']))
+                db_config['passwd'] = passwd
                 try:
-                    vistrails.db.services.io.test_db_connection(db_config)
+                    test_db_connection(db_config)
                 except VistrailsDBException:
-                    passwd = \
-                        getpass.getpass("Connecting to %s:%s. Password for user '%s':" % (
-                                        self.temp_db_options.host,
-                                        self.temp_db_options.db,
-                                        self.temp_db_options.user))
-                    db_config['passwd'] = passwd
-                    try:
-                        vistrails.db.services.io.test_db_connection(db_config)
-                    except VistrailsDBException:
-                        debug.critical("Cannot login to database")
-                        return False
+                    debug.critical("Cannot login to database")
+                    return False
     
         if self.input:
             w_list = []
@@ -480,14 +496,15 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                 if not usedb:
                     locator = FileLocator(os.path.abspath(f_name))
                 else:
-                    locator = DBLocator(host=self.temp_db_options.host,
-                                        port=self.temp_db_options.port,
-                                        database=self.temp_db_options.db,
-                                        user=self.temp_db_options.user,
-                                        passwd=passwd,
-                                        obj_id=f_name,
-                                        obj_type=None,
-                                        connection_id=None)
+                    locator = DBLocator(
+                           host=self.temp_configuration.check('host'),
+                           port=self.temp_configuration.check('port') or 3306,
+                           database=self.temp_configuration.check('db'),
+                           user=self.temp_configuration.check('user'),
+                           passwd=passwd,
+                           obj_id=f_name,
+                           obj_type=None,
+                           connection_id=None)
                     if not locator.is_valid():
                         #here there is a problem: as we allow execution from 
                         #command line with VisTrails already running, we need
@@ -498,19 +515,22 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                             ok = locator.update_from_console()
                         if not ok:
                             debug.critical("Cannot login to database")
+                if self.temp_configuration.check('jobList'):
+                    return self.printJobs(locator)
+                if self.temp_configuration.check('jobInfo'):
+                    return self.printJob(locator, version)
+
                 w_list.append((locator, version))
                 vt_list.append(locator)
             import vistrails.core.console_mode
-            if self.temp_db_options.parameters == None:
-                self.temp_db_options.parameters = ''
-            
+
             errs = []
             if self.temp_configuration.check('workflowGraph'):
                 workflow_graph = self.temp_configuration.workflowGraph
                 results = vistrails.core.console_mode.get_wf_graph(w_list, workflow_graph,
-                                     self.temp_configuration.spreadsheetDumpPDF)
+                                                                   self.temp_configuration.graphsAsPdf)
                 for r in results:
-                    if r[0] == False:
+                    if r[0] is False:
                         errs.append("Error generating workflow graph: %s" % \
                                     r[1])
                         debug.critical("*** Error in get_wf_graph: %s" % r[1])
@@ -518,36 +538,33 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
             if self.temp_configuration.check('evolutionGraph'):
                 evolution_graph = self.temp_configuration.evolutionGraph
                 results = vistrails.core.console_mode.get_vt_graph(vt_list, evolution_graph,
-                                     self.temp_configuration.spreadsheetDumpPDF)
+                                                                   self.temp_configuration.graphsAsPdf)
                 for r in results:
-                    if r[0] == False:
+                    if r[0] is False:
                         errs.append("Error generating vistrail graph: %s" % \
                                     r[1])
                         debug.critical("*** Error in get_vt_graph: %s" % r[1])
                 
-            if self.temp_configuration.check('workflowInfo'):
-                workflow_info = self.temp_configuration.workflowInfo
+            if self.temp_configuration.check('outputDirectory'):
+                output_dir = self.temp_configuration.outputDirectory
             else:
-                workflow_info = None
+                output_dir = None
 
             extra_info = None
-            if self.temp_configuration.check('spreadsheetDumpCells'):
+            if self.temp_configuration.check('outputDirectory'):
                 extra_info = \
-                {'pathDumpCells': self.temp_configuration.spreadsheetDumpCells}
-            if self.temp_configuration.check('spreadsheetDumpPDF'):
-                if extra_info is None:
-                    extra_info = {}
-                extra_info['pdf'] = self.temp_configuration.spreadsheetDumpPDF
-
+                {'pathDumpCells': self.temp_configuration.outputDirectory}
             if self.temp_configuration.check('parameterExploration'):
                 errs.extend(
                     vistrails.core.console_mode.run_parameter_explorations(
                         w_list, extra_info=extra_info))
             else:
-                errs.extend(vistrails.core.console_mode.run(w_list,
-                                      self.temp_db_options.parameters,
-                                      workflow_info, update_vistrail=True,
-                                      extra_info=extra_info))
+                errs.extend(vistrails.core.console_mode.run(
+                        w_list,
+                        self.temp_configuration.check('parameters')
+                            or '',
+                        output_dir, update_vistrail=True,
+                        extra_info=extra_info))
             if len(errs) > 0:
                 for err in errs:
                     debug.critical("*** Error in %s:%s:%s -- %s" % err)
@@ -557,6 +574,41 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
             debug.warning("no input vistrails provided")
             return True
 
+    def printJobs(self, locator):
+        (v, abstractions, thumbnails, mashups)  = load_vistrail(locator)
+        controller = VistrailController(v, locator, abstractions, thumbnails,
+                                        mashups, auto_save=False)
+        text = "### Workflows with jobs ###\n"
+        text += "workflow | start date | status\n"
+        text += '\n'.join(
+            ["%s %s %s" %(j.version,
+                          j.start,
+                          "FINISHED" if j.completed() else "RUNNING")
+             for i, j in controller.jobMonitor.workflows.iteritems()])
+        print text
+        return text
+
+    def printJob(self, locator, version):
+        (v, abstractions, thumbnails, mashups)  = load_vistrail(locator)
+        controller = VistrailController(v, locator, abstractions, thumbnails,
+                                        mashups, auto_save=False)
+        text = "### Jobs in workflow ###\n"
+        text += "name | start date | status\n"
+        workflow = [wf for wf in controller.jobMonitor.workflows.itervalues()
+                    if wf.version == int(version)]
+        if len(workflow) < 1:
+            text = "No job for workflow with id %s" % version
+            print text
+            return text
+        workflow = workflow[0]
+        text += '\n'.join(
+            ["%s %s %s" %(i.name,
+                          i.start,
+                          "FINISHED" if i.finished else "RUNNING")
+             for i in workflow.jobs.values()])
+        print text
+        return text
+
     def setIcon(self):
         """ setIcon() -> None
         Setup Vistrail Icon
@@ -598,7 +650,7 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
 
         # self.builderWindow = QBuilderWindow()
         self.builderWindow = QVistrailsWindow()
-        if not self.temp_configuration.showSpreadsheetOnly:
+        if self.temp_configuration.showWindow:
             # self.builderWindow.show()
             # self.setActiveWindow(self.builderWindow)
             pass
@@ -615,12 +667,13 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
     def eventFilter(self, o, event):
         """eventFilter(obj,event)-> boolean
         This will filter all create events and will set on the WA_MacMetalStyle
-        attribute of a QWidget. It will also filter the FileOpen events on a Mac
+        attribute of a QWidget. It will also filter the FileOpen events on Mac.
         
         """
-        metalstyle = self.temp_configuration.check('useMacBrushedMetalStyle')
+        metalstyle = hasattr(self, 'temp_configuration') and \
+                     self.temp_configuration.check('useMacBrushedMetalStyle')
         if metalstyle:
-            if QtCore.QT_VERSION < 0x40500:    
+            if QtCore.QT_VERSION < 0x40500:
                 create_event = QtCore.QEvent.Create
                 mac_attribute = QtCore.Qt.WA_MacMetalStyle
             else:
@@ -647,21 +700,26 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                                local_socket.errorString())
                 return
             byte_array = local_socket.readAll()
-            self.temp_db_options = None
             self.temp_configuration.workflowGraph = None
-            self.temp_configuration.workflowInfo = None
             self.temp_configuration.evolutionGraph = None
+            self.temp_configuration.outputDirectory = None
             self.temp_configuration.spreadsheetDumpPDF = False
-            self.temp_configuration.spreadsheetDumpCells = None
-            self.temp_configuration.executeWorkflows = False
-            self.temp_configuration.interactiveMode = True
-            
+            self.temp_configuration.execute = False
+            self.temp_configuration.batch = False
+
+            output = None
             try:
+                # redirect stdout
+                old_stdout = sys.stdout
+                sys.stdout = StringIO.StringIO()
                 result = self.parse_input_args_from_other_instance(str(byte_array))
+                output = sys.stdout.getvalue()
+                sys.stdout.close()
+                sys.stdout = old_stdout
             except Exception, e:
-                import traceback
-                debug.critical("Unknown error: %s" % str(e))
-                result = traceback.format_exc()
+                debug.unexpected_exception(e)
+                debug.critical("Unknown error", e)
+                result = debug.format_exc()
             if None == result:
                 result = True
             if True == result:
@@ -670,6 +728,8 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
                 result = "Command Failed"
             elif type(result) == list:
                 result = '\n'.join(result[1])
+            if result == "Command Completed" and output:
+                result += '\n' + output
             self.shared_memory.lock()
             local_socket.write(bytes(result))
             self.shared_memory.unlock()
@@ -693,8 +753,8 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
             return False
         byte_array = local_socket.readAll()
         result = str(byte_array)
-        debug.log("Other instance processed input (%s)"%result)
-        if result != 'Command Completed':
+        print "Other instance processed input (%s)" % result
+        if not result.startswith('Command Completed'):
             debug.critical(result)
         else:
             local_socket.disconnectFromServer()
@@ -706,19 +766,17 @@ class VistrailsApplicationSingleton(VistrailsApplicationInterface,
         options_re = re.compile(r"^(\[('([^'])*', ?)*'([^']*)'\])|(\[\s?\])$")
         if options_re.match(msg):
             #it's safe to eval as a list
-            args = eval(msg)
+            args = literal_eval(msg)
             if isinstance(args, list):
-                #print "args from another instance %s"%args
                 try:
-                    command_line.CommandLineParser.init_options(args)
+                    self.read_options(args)
                 except SystemExit:
                     debug.critical("Invalid options: %s" % ' '.join(args))
                     return False
-                self.readOptions()
-                interactive = self.temp_configuration.check('interactiveMode')
+                interactive = not self.temp_configuration.check('batch')
                 if interactive:
                     result = self.process_interactive_input()
-                    if not self.temp_configuration.showSpreadsheetOnly:
+                    if self.temp_configuration.showWindow:
                         # in some systems (Linux and Tiger) we need to make both calls
                         # so builderWindow is activated
                         self.builderWindow.raise_()
@@ -737,8 +795,8 @@ def linux_default_application_set():
     For Linux - checks if a handler is set for .vt and .vtl files.
     """
     command = ['xdg-mime', 'query', 'filetype',
-               os.path.join(system.vistrails_examples_directory(),
-                            'terminator.vt')]
+               os.path.join(system.vistrails_root_directory(),
+                            'tests', 'resources', 'terminator.vt')]
     try:
         output = []
         result = system.execute_cmdline(command, output)
@@ -771,7 +829,7 @@ def linux_update_default_application():
     output = []
     try:
         result = system.execute_cmdline(command, output)
-    except OSError, e:
+    except OSError:
         result = None
     if result != 0:
         debug.warning("Error running xdg-mime")
@@ -781,7 +839,7 @@ def linux_update_default_application():
     output = []
     try:
         result = system.execute_cmdline(command, output)
-    except OSError, e:
+    except OSError:
         result = None
     if result != 0:
         debug.warning("Error running update-mime-database")
@@ -797,7 +855,7 @@ def linux_update_default_application():
     output = []
     try:
         result = system.execute_cmdline(command, output)
-    except OSError, e:
+    except OSError:
         result = None
     if result != 0:
         debug.warning("Error running xdg-icon-resource")
@@ -825,7 +883,7 @@ MimeType=application/x-vistrails
     output = []
     try:
         result = system.execute_cmdline(command, output)
-    except OSError, e:
+    except OSError:
         result = None
     if result != 0:
         debug.warning("Error running update-desktop-database")
@@ -834,7 +892,7 @@ MimeType=application/x-vistrails
 # The initialization must be explicitly signalled. Otherwise, any
 # modules importing vis_application will try to initialize the entire
 # app.
-def start_application(optionsDict=None):
+def start_application(optionsDict=None, args=[]):
     """Initializes the application singleton."""
     VistrailsApplication = get_vistrails_application()
     if VistrailsApplication:
@@ -842,7 +900,7 @@ def start_application(optionsDict=None):
         return
     VistrailsApplication = VistrailsApplicationSingleton()
     set_vistrails_application(VistrailsApplication)
-    x = VistrailsApplication.init(optionsDict)
+    x = VistrailsApplication.init(optionsDict, args)
     return x
 
 def stop_application():
diff --git a/vistrails/gui/application_server.py b/vistrails/gui/application_server.py
index 241d771..85687a5 100644
--- a/vistrails/gui/application_server.py
+++ b/vistrails/gui/application_server.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This is the application for vistrails when running as a server. """
+from __future__ import division
+
 import Queue
 import base64
 import hashlib
@@ -55,9 +58,7 @@ from PyQt4 import QtGui, QtCore
 import SocketServer
 from SimpleXMLRPCServer import SimpleXMLRPCServer
 from datetime import date, datetime
-from time import strptime
 
-from vistrails.core.configuration import get_vistrails_configuration
 from vistrails.core.application import VistrailsApplicationInterface
 import vistrails.gui.theme
 import vistrails.core.application
@@ -66,15 +67,12 @@ from vistrails.core.db.locator import DBLocator, ZIPFileLocator, FileLocator
 from vistrails.core.db import io
 import vistrails.core.db.action
 
-from vistrails.core.utils import InstanceObject
 from vistrails.core.vistrail.vistrail import Vistrail
-from vistrails.core import command_line
 from vistrails.core import system
 from vistrails.core.modules.module_registry import get_module_registry as module_registry
 from vistrails.core import interpreter
 from vistrails.core.packagemanager import get_package_manager
 from vistrails.core.thumbnails import ThumbnailCache
-import vistrails.core.system
 import vistrails.db.services.io
 import gc
 
@@ -83,7 +81,7 @@ import vistrails.core.console_mode
 
 from vistrails.db.versions import currentVersion
 
-ElementTree = vistrails.core.system.get_elementtree_library()
+ElementTree = system.get_elementtree_library()
 
 
 
@@ -92,8 +90,6 @@ class StoppableXMLRPCServer(SimpleXMLRPCServer):
     """This class allows a server to be stopped by a external request"""
     #accessList contains the list of ip addresses and hostnames that can send
     #request to this server. Change this according to your server
-    global accessList
-
     allow_reuse_address = True
     def __init__(self, addr, logger):
         self.logger = logger
@@ -347,6 +343,7 @@ class RequestHandler(object):
                         "Not all vistrail instances are free, please try again."], 1]
                 proxies.append(self.proxies_queue.get())
             for proxy in proxies:
+                result, s = 'Please contact the server admin', 0
                 try:
                     if codepath and status is not None:
                         result, s = proxy.get_server_packages(codepath, status)
@@ -545,6 +542,7 @@ class RequestHandler(object):
         config['db'] = db_name
         config['user'] = db_write_user
         config['passwd'] = db_write_pass
+        conn = None
         try:
             conn = vistrails.db.services.io.open_db_connection(config)
             vistrails.db.services.io.delete_entity_from_db(conn,'vistrail', vt_id)
@@ -552,7 +550,7 @@ class RequestHandler(object):
             return (1, 1)
         except Exception, e:
             self.server_logger.error(str(e))
-            if conn:
+            if conn is not None:
                 vistrails.db.services.io.close_db_connection(conn)
             return (str(e), 0)
 
@@ -642,23 +640,16 @@ class RequestHandler(object):
                             obj_type=None,
                             connection_id=None)
         (vistrail, abstractions , thumbnails, mashups)  = io.load_vistrail(locator)
-        from core.vistrail.controller import VistrailController as BaseController
+        from vistrails.core.vistrail.controller import VistrailController as BaseController
         c = BaseController()
         c.set_vistrail(vistrail, locator, abstractions, thumbnails, mashups)
 
-        # get server packages
-        local_packages = [x.identifier for x in module_registry().package_list]
-        version_id = 0
-        version_tag = 0
-
-        from db.domain import IdScope
-        from core.vistrail.connection import Connection
-        from core.vistrail.module import Module
-        from core.vistrail.port import Port
+        from vistrails.core.vistrail.connection import Connection
+        from vistrails.core.vistrail.module import Module
+        from vistrails.core.vistrail.port import Port
 
         # get last pipeline
-        workflow = False
-        if (vt_tag == ''):
+        if vt_tag == '':
             version = vistrail.get_latest_version()#-1;
         else:
             version = int(vt_tag)
@@ -670,22 +661,20 @@ class RequestHandler(object):
         id_scope = vistrail.idScope
         if workflow:
             # if doesnt have VTKWebView and vtkRenderer
-            if ("vtkRenderer" not in [x.name for x in workflow.module_list]):
+            if "vtkRenderer" not in [x.name for x in workflow.module_list]:
                 return (str("Doesn't have vtkRenderer"), 1)
 
             # if already have VTKWebView, execute it
-            if ("VTKWebView" not in [x.name for x in workflow.module_list]):
+            if "VTKWebView" not in [x.name for x in workflow.module_list]:
                 # else, add VTKWebView to vtkRenderer and execute it
                 renderer = workflow.module_list[[x.name for x in workflow.module_list].index('vtkRenderer')]
 
-                action_list = []
-
                 mWeb = Module(id=id_scope.getNewId(Module.vtType),
                            name='VTKWebView',
                            package='edu.utah.sci.vistrails.vtWebGL',
                            functions=[])
                 mWeb.version = '0.0.2'
-                workflow.add_module(mWeb);
+                workflow.add_module(mWeb)
                 # create connection from render to web
                 source = Port(id=id_scope.getNewId(Port.vtType),
                               type='source',
@@ -704,7 +693,7 @@ class RequestHandler(object):
                 workflow.add_connection(c1)
                 workflow.validate()
 
-            c.current_pipeline = workflow;
+            c.current_pipeline = workflow
             (results, x) = c.execute_current_workflow()
             if len(results[0].errors.values()) > 0:
                 print "> ERROR: ", results[0].errors
@@ -721,14 +710,15 @@ class RequestHandler(object):
             self.server_logger.info(xml_medley)
             xml_string = xml_medley.replace('\\"','"')
             root = ElementTree.fromstring(xml_string)
+            medley = None
             try:
                 medley = MedleySimpleGUI.from_xml(root)
-            except:
+                self.server_logger.debug("%s medley: %s"%(medley._type, medley._name))
+            except Exception:
                 #even if this error occurred there's still a chance of
                 # recovering from it... (the server can find cached images)
                 self.server_logger.error("couldn't instantiate medley")
 
-            self.server_logger.debug("%s medley: %s"%(medley._type, medley._name))
             result = ""
             subdir = hashlib.sha224(xml_string).hexdigest()
             path_to_images = \
@@ -753,12 +743,10 @@ class RequestHandler(object):
             if extra_info is None:
                 extra_info = {}
 
-            if extra_info.has_key('pathDumpCells'):
-                if extra_info['pathDumpCells']:
-                    extra_path = extra_info['pathDumpCells']
-            else:
+            if not extra_info.has_key('pathDumpCells'):
                 extra_info['pathDumpCells'] = path_to_images
 
+            ok = False
             if not self.path_exists_and_not_empty(extra_info['pathDumpCells']):
                 if not os.path.exists(extra_info['pathDumpCells']):
                     os.mkdir(extra_info['pathDumpCells'])
@@ -777,7 +765,7 @@ class RequestHandler(object):
                     workflow = medley._version
                     sequence = False
                     for (k,v) in medley._alias_list.iteritems():
-                        if v._component._seq == True:
+                        if v._component._seq:
                             sequence = True
                             val = XMLObject.convert_from_str(v._component._minVal,
                                                              v._component._spec)
@@ -799,7 +787,7 @@ class RequestHandler(object):
                                 try:
                                     gc.collect()
                                     results = \
-                                      vistrails.core.console_mode.run_and_get_results( \
+                                      vistrails.core.console_mode.run_and_get_results(
                                                     [(locator,int(workflow))],
                                                     s_alias,
                                                     update_vistrail=False,
@@ -822,7 +810,6 @@ class RequestHandler(object):
                                     self.server_logger.info("renaming files")
                                     for root, dirs, file_names in os.walk(extra_info['pathDumpCells']):
                                         break
-                                    s = []
                                     for f in file_names:
                                         if f.lower().endswith(".png"):
                                             fmask = "%s_"+mask+"%s"
@@ -847,7 +834,7 @@ class RequestHandler(object):
                             self.server_logger.info("Not sequence aliases: %s"% s_alias)
                         try:
                             results = \
-                               vistrails.core.console_mode.run_and_get_results( \
+                               vistrails.core.console_mode.run_and_get_results(
                                                 [(locator,int(workflow))],
                                                     s_alias,
                                                     extra_info=extra_info)
@@ -864,11 +851,11 @@ class RequestHandler(object):
                                     ok = False
                                     result += str(errors[i])
 
-                    self.server_logger.info( "success?  %s"% ok)
+                    self.server_logger.info("success?  %s" % ok)
 
                 elif medley._type == 'visit':
                     cur_dir = os.getcwd()
-                    os.chdir(self.temp_configuration.spreadsheetDumpCells)
+                    os.chdir(self.temp_configuration.outputDirectory)
                     if medley._id == 6:
                         session_file = 'crotamine.session'
                     elif medley._id == 7:
@@ -948,14 +935,14 @@ class RequestHandler(object):
                 self.server_logger.info("returning %s" % result)
                 return result
             except xmlrpclib.ProtocolError, err:
-                    err_msg = ("A protocol error occurred\n"
-                               "URL: %s\n"
-                               "HTTP/HTTPS headers: %s\n"
-                               "Error code: %d\n"
-                               "Error message: %s\n") % (err.url, err.headers,
-                                                         err.errcode, err.errmsg)
-                    self.server_logger.error(err_msg)
-                    return (str(err), 0)
+                err_msg = ("A protocol error occurred\n"
+                           "URL: %s\n"
+                           "HTTP/HTTPS headers: %s\n"
+                           "Error code: %d\n"
+                           "Error message: %s\n") % (err.url, err.headers,
+                                                     err.errcode, err.errmsg)
+                self.server_logger.error(err_msg)
+                return (str(err), 0)
             except Exception, e:
                 self.server_logger.error(str(e))
                 return (str(e), 0)
@@ -963,6 +950,9 @@ class RequestHandler(object):
         extra_info = {}
         extra_info['pathDumpCells'] = path_to_figures
         self.server_logger.debug(path_to_figures)
+        # TODO: really want to push this into spreadsheet settings,
+        # perhaps the issue here is getting global access to package
+        # configuration?
         extra_info['pdf'] = pdf
         self.server_logger.debug("pdf: %s" % pdf)
         # execute workflow
@@ -975,7 +965,7 @@ class RequestHandler(object):
 
             result = ''
             if vt_tag !='':
-                version = vt_tag;
+                version = vt_tag
             try:
                 locator = DBLocator(host=host,
                                     port=int(port),
@@ -985,17 +975,15 @@ class RequestHandler(object):
                                     obj_id=int(vt_id),
                                     obj_type=None,
                                     connection_id=None)
-                results = []
                 self.server_logger.info("run_and_get_results(%s,%s,%s,%s,%s)" % \
                             (locator, version, parameters, True, extra_info))
                 try:
-                    results = \
-                    vistrails.core.console_mode.run_and_get_results([(locator,
-                                                          int(version))],
-                                                          parameters,
-                                                          update_vistrail=True,
-                                                          extra_info=extra_info,
-                                                          reason="Server Pipeline Execution")
+                    results = vistrails.core.console_mode.run_and_get_results(
+                            [(locator, int(version))],
+                            parameters,
+                            update_vistrail=True,
+                            extra_info=extra_info,
+                            reason="Server Pipeline Execution")
                 except Exception, e:
                     self.server_logger.error("workflow execution failed:")
                     self.server_logger.error(str(e))
@@ -1392,7 +1380,7 @@ class RequestHandler(object):
             vt_id = long(vt_id)
             subdir = 'vistrails'
             filepath = os.path.join(media_dir, 'graphs', subdir)
-            base_fname = "graph_%s.png" % (vt_id)
+            base_fname = "graph_%s.png" % vt_id
             filename = os.path.join(filepath,base_fname)
             if ((not os.path.exists(filepath) or
                 (os.path.exists(filepath) and not os.path.exists(filename)) or
@@ -1481,7 +1469,7 @@ class RequestHandler(object):
             vt_id = long(vt_id)
             subdir = 'vistrails'
             filepath = os.path.join(media_dir, 'graphs', subdir)
-            base_fname = "graph_%s.pdf" % (vt_id)
+            base_fname = "graph_%s.pdf" % vt_id
             filename = os.path.join(filepath,base_fname)
             if ((not os.path.exists(filepath) or
                 (os.path.exists(filepath) and not os.path.exists(filename)) or
@@ -1733,12 +1721,13 @@ class RequestHandler(object):
             v = locator.load().vistrail
             for elem, tag in v.get_tagMap().iteritems():
                 action_map = v.actionMap[long(elem)]
+                thumbnail_fname = ""
                 if v.get_thumbnail(elem):
-                    thumbnail_fname = os.path.join(
-                        get_vistrails_configuration().thumbs.cacheDirectory,
-                        v.get_thumbnail(elem))
-                else:
-                    thumbnail_fname = ""
+                    thumbnail_dir = system.get_vistrails_directory(
+                        "thumbs.cacheDir")
+                    if thumbnail_dir is not None:
+                        thumbnail_fname = os.path.join(thumbnail_dir,
+                                                       v.get_thumbnail(elem))
                 if not thumbnail_fname or is_local:
                     result.append({'id': elem, 'name': tag,
                                    'notes': v.get_notes(elem) or '',
@@ -1794,9 +1783,9 @@ class XMLObject(object):
                 elif type == 'bool':
                     return bool_conv(value)
                 elif type == 'date':
-                    return date(*strptime(value, '%Y-%m-%d')[0:3])
+                    return date(*system.time_strptime(value, '%Y-%m-%d')[0:3])
                 elif type == 'datetime':
-                    return datetime(*strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
+                    return datetime(*system.time_strptime(value, '%Y-%m-%d %H:%M:%S')[0:6])
         return None
 
     @staticmethod
@@ -1805,7 +1794,7 @@ class XMLObject(object):
             if type == 'date':
                 return value.isoformat()
             elif type == 'datetime':
-                return value.strftime('%Y-%m-%d %H:%M:%S')
+                return system.strftime(value, '%Y-%m-%d %H:%M:%S')
             else:
                 return str(value)
         return ''
@@ -1833,11 +1822,11 @@ class MedleySimpleGUI(XMLObject):
         self._vtid = vtid
         self._type = t
 
-        if has_seq == None:
+        if has_seq is None:
             self._has_seq = False
             if isinstance(self._alias_list, dict):
                 for v in self._alias_list.itervalues():
-                    if v._component._seq == True:
+                    if v._component._seq:
                         self._has_seq = True
         else:
             self._has_seq = has_seq
@@ -1936,9 +1925,12 @@ class AliasSimpleGUI(XMLObject):
         id = AliasSimpleGUI.convert_from_str(data, 'long')
         data = node.get('name', None)
         name = AliasSimpleGUI.convert_from_str(data, 'str')
+        component = None
         for child in node.getchildren():
             if child.tag == "component":
                 component = ComponentSimpleGUI.from_xml(child)
+        if component is None:
+            raise RuntimeError("Missing component tag")
         alias = AliasSimpleGUI(id,name,component)
         return alias
 
@@ -2101,9 +2093,6 @@ class VistrailsServerSingleton(VistrailsApplicationInterface,
         self.rpcserver = None
         self.pingserver = None
         self.images_url = "http://vistrails.sci.utah.edu/medleys/images/"
-        self.temp_xml_rpc_options = InstanceObject(server=None,
-                                                   port=None,
-                                                   log_file=None)
         qt.allowQObjects()
 
     def is_running_gui(self):
@@ -2251,27 +2240,25 @@ class VistrailsServerSingleton(VistrailsApplicationInterface,
                                    "Please populate it with the correct values and use it" %
                                    (filename, new_filename))
 
-    def init(self, optionsDict=None):
+    def init(self, optionsDict=None, args=[]):
         """ init(optionDict: dict) -> boolean
         Create the application with a dict of settings
 
         """
-        VistrailsApplicationInterface.init(self,optionsDict)
-
-        self.vistrailsStartup.init()
-        self.server_logger = self.make_logger(self.temp_xml_rpc_options.log_file,
-                                              self.temp_xml_rpc_options.port)
-        self.load_config(self.temp_xml_rpc_options.config_file)
-        self.start_other_instances(self.temp_xml_rpc_options.instances)
-        self._python_environment = self.vistrailsStartup.get_python_environment()
+        VistrailsApplicationInterface.init(self,optionsDict, args)
+
+        # self.vistrailsStartup.init()
+        self.server_logger = self.make_logger(self.temp_configuration.check('rpcLogFile'),
+                                              self.temp_configuration.check('rpcPort'))
+        self.load_config(self.temp_configuration.check('rpcConfig'))
+        self.start_other_instances(self.temp_configuration.check('rpcInstances'))
         self._initialized = True
         return True
 
     def start_other_instances(self, number):
-        global virtual_display, script_file
         self.others = []
-        host = self.temp_xml_rpc_options.server
-        port = self.temp_xml_rpc_options.port
+        host = self.temp_configuration.check('rpcServer')
+        port = self.temp_configuration.check('rpcPort')
         virt_disp = int(virtual_display)
         for x in xrange(number):
             port += 1   # each instance needs one port space for now
@@ -2279,7 +2266,7 @@ class VistrailsServerSingleton(VistrailsApplicationInterface,
             virt_disp += 1
             args = [script_file,":%s"%virt_disp,host,str(port),'0', '0']
             try:
-                p = subprocess.Popen(args)
+                subprocess.Popen(args)
                 time.sleep(20)
                 self.others.append("http://%s:%s"%(host,port))
             except Exception, e:
@@ -2304,39 +2291,46 @@ class VistrailsServerSingleton(VistrailsApplicationInterface,
         via xml-rpc.
         """
 
-        self.server_logger.info("Server is running on http://%s:%s"%(self.temp_xml_rpc_options.server,
-                                                   self.temp_xml_rpc_options.port))
-        if self.temp_xml_rpc_options.multithread:
-            self.rpcserver = ThreadedXMLRPCServer((self.temp_xml_rpc_options.server,
-                                                   self.temp_xml_rpc_options.port),
-                                                  self.server_logger)
+        self.server_logger.info("Server is running on http://%s:%s"%(
+                                   self.temp_configuration.check('rpcServer'),
+                                   self.temp_configuration.check('rpcPort')))
+        if self.temp_configuration.check('multithread'):
+            self.rpcserver = ThreadedXMLRPCServer(
+                                  (self.temp_configuration.check('rpcServer'),
+                                   self.temp_configuration.check('rpcPort')),
+                                  self.server_logger)
             self.server_logger.info("    multithreaded instance")
         else:
-            self.rpcserver = StoppableXMLRPCServer((self.temp_xml_rpc_options.server,
-                                                   self.temp_xml_rpc_options.port),
-                                                   self.server_logger)
+            self.rpcserver = StoppableXMLRPCServer(
+                                  (self.temp_configuration.check('rpcServer'),
+                                   self.temp_configuration.check('rpcPort')),
+                                  self.server_logger)
             """
-            self.pingserver = StoppableXMLRPCServer((self.temp_xml_rpc_options.server,
-                                                    self.temp_xml_rpc_options.port-1),
-                                                    self.server_logger)
+            self.pingserver = StoppableXMLRPCServer(
+                                 (self.temp_configuration.check('rpcServer'),
+                                  self.temp_configuration.check('rpcPort')-1),
+                                 self.server_logger)
             """
             self.server_logger.info("    singlethreaded instance")
         #self.rpcserver.register_introspection_functions()
         self.rpcserver.register_instance(RequestHandler(self.server_logger,
                                                         self.others))
         if self.pingserver:
-            self.pingserver.register_instance(RequestHandler(self.server_logger, []))
-            self.server_logger.info("Status XML RPC Server is listening on http://%s:%s"% \
-                            (self.temp_xml_rpc_options.server,
-                             self.temp_xml_rpc_options.port-1))
+            self.pingserver.register_instance(RequestHandler(
+                                                      self.server_logger, []))
+            self.server_logger.info(
+                       "Status XML RPC Server is listening on http://%s:%s"% \
+                            (self.temp_configuration.check('rpcServer'),
+                             self.temp_configuration.check('rpcPort')-1))
             self.pingserver.register_function(self.quit_server, "quit")
             self.pingserver.serve_forever()
             self.pingserver.serve_close()
 
         self.rpcserver.register_function(self.quit_server, "quit")
-        self.server_logger.info("Vistrails XML RPC Server is listening on http://%s:%s"% \
-                        (self.temp_xml_rpc_options.server,
-                         self.temp_xml_rpc_options.port))
+        self.server_logger.info(
+                    "Vistrails XML RPC Server is listening on http://%s:%s"% \
+                        (self.temp_configuration.check('rpcServer'),
+                         self.temp_configuration.check('rpcPort')))
         self.rpcserver.serve_forever()
         self.rpcserver.server_close()
         return 0
@@ -2348,53 +2342,10 @@ class VistrailsServerSingleton(VistrailsApplicationInterface,
         self.rpcserver.stop = True
         return result
 
-    def setupOptions(self, args=None):
-        """ setupOptions() -> None
-        Check and store all command-line arguments
-
-        """
-        add = command_line.CommandLineParser.add_option
-
-        add("-T", "--xml_rpc_server", action="store", dest="rpcserver",
-            help="hostname or ip address where this xml rpc server will work")
-        add("-R", "--xml_rpc_port", action="store", type="int", default=8080,
-            dest="rpcport", help="database port")
-        add("-L", "--xml_rpc_log_file", action="store", dest="rpclogfile",
-            default=os.path.join(system.vistrails_root_directory(),
-                                 'rpcserver.log'),
-            help="log file for XML RPC server")
-        add("-O", "--xml_rpc_instances", action="store", type='int', default=0,
-            dest="rpcinstances",
-            help="number of other instances that vistrails should start")
-        add("-M", "--multithreaded", action="store_true",
-            default = None, dest='multithread',
-            help="server will start a thread for each request")
-        add("-C", "--config-file", action="store", dest = "rpcconfig",
-            default=os.path.join(system.vistrails_root_directory(),
-                                 'server.cfg'),
-            help="config file for server connection options")
-        VistrailsApplicationInterface.setupOptions(self, args)
-
-    def readOptions(self):
-        """ readOptions() -> None
-        Read arguments from the command line
-
-        """
-        get = command_line.CommandLineParser().get_option
-        self.temp_xml_rpc_options = InstanceObject(server=get('rpcserver'),
-                                                   port=get('rpcport'),
-                                                   log_file=get('rpclogfile'),
-                                                   instances=get('rpcinstances'),
-                                                   multithread=get('multithread'),
-                                                   config_file=get('rpcconfig'))
-        VistrailsApplicationInterface.readOptions(self)
-
-
-
 # The initialization must be explicitly signalled. Otherwise, any
 # modules importing vis_application will try to initialize the entire
 # app.
-def start_server(optionsDict=None):
+def start_server(optionsDict=None, args=[]):
     """Initializes the application singleton."""
     global VistrailsServer
     if VistrailsServer:
@@ -2403,8 +2354,7 @@ def start_server(optionsDict=None):
     VistrailsServer = VistrailsServerSingleton()
     vistrails.gui.theme.initializeCurrentTheme()
     vistrails.core.application.set_vistrails_application(VistrailsServer)
-    x = VistrailsServer.init(optionsDict)
-    if x == True:
+    if VistrailsServer.init(optionsDict, args):
         return 0
     else:
         return 1
@@ -2413,7 +2363,6 @@ VistrailsServer = None
 
 def stop_server():
     """Stop and finalize the application singleton."""
-    global VistrailsServer
     VistrailsServer.save_configuration()
     VistrailsServer.destroy()
     VistrailsServer.deleteLater()
diff --git a/vistrails/gui/base_view.py b/vistrails/gui/base_view.py
index 29fbcd5..4d8cf81 100644
--- a/vistrails/gui/base_view.py
+++ b/vistrails/gui/base_view.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 class BaseView(object):
diff --git a/vistrails/gui/bundles/__init__.py b/vistrails/gui/bundles/__init__.py
index fac3164..5e49c53 100644
--- a/vistrails/gui/bundles/__init__.py
+++ b/vistrails/gui/bundles/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/gui/bundles/installbundle.py b/vistrails/gui/bundles/installbundle.py
index 021bf7a..faac3df 100644
--- a/vistrails/gui/bundles/installbundle.py
+++ b/vistrails/gui/bundles/installbundle.py
@@ -1,48 +1,52 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Module with utilities to try and install a bundle if possible."""
+from __future__ import division
+
 from vistrails.core import get_vistrails_application
 from vistrails.core.configuration import get_vistrails_configuration, \
     get_vistrails_persistent_configuration
 from vistrails.core import debug
-from vistrails.core.system import get_executable_path
+from vistrails.core.system import executable_is_in_path, get_executable_path
 from vistrails.core.system import vistrails_root_directory, systemType
 from vistrails.gui.bundles.utils import guess_system, guess_graphical_sudo
 import vistrails.gui.bundles.installbundle # this is on purpose
 from vistrails.gui.requirements import qt_available
+import imp
 import os
 import subprocess
 import sys
@@ -51,7 +55,9 @@ import sys
 
 pip_installed = True
 try:
-    import pip
+    imp.find_module('pip')
+    # Here we do not actually import pip, to avoid pip issue #1314
+    # https://github.com/pypa/pip/issues/1314
 except ImportError:
     pip_installed = False
 
@@ -130,7 +136,7 @@ def linux_debian_install(package_name):
                            '/gui/bundles/linux_debian_install.py')
     else:
         cmd = '%s install -y' % ('aptitude'
-                                 if get_executable_path('aptitude')
+                                 if executable_is_in_path('aptitude')
                                  else 'apt-get')
 
     return run_install_command(qt, cmd, package_name)
@@ -154,7 +160,7 @@ def linux_fedora_install(package_name):
 def pip_install(package_name):
     hide_splash_if_necessary()
 
-    if get_executable_path('pip'):
+    if executable_is_in_path('pip'):
         cmd = '%s install' % shell_escape(get_executable_path('pip'))
     else:
         cmd = shell_escape(sys.executable) + ' -m pip install'
diff --git a/vistrails/gui/bundles/linux_debian_install.py b/vistrails/gui/bundles/linux_debian_install.py
index 12edef9..e7bc507 100755
--- a/vistrails/gui/bundles/linux_debian_install.py
+++ b/vistrails/gui/bundles/linux_debian_install.py
@@ -1,40 +1,44 @@
 #!/usr/bin/env python
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # Installs a package through APT, showing progress.
+from __future__ import division
+
 import apt
 import apt_pkg
 import locale
@@ -46,10 +50,6 @@ from apt.progress.base import InstallProgress, OpProgress, AcquireProgress
 
 from PyQt4 import QtCore, QtGui
 
-if __name__ != '__main__':
-    import vistrails.tests
-    raise vistrails.tests.NotModule('This should not be imported as a module')
-
 
 package_name = sys.argv[1]
 
@@ -170,8 +170,8 @@ class Window(QtGui.QWidget):
         geometry = desktop.screenGeometry(self)
         h = 200
         w = 300
-        self.setGeometry(geometry.left() + (geometry.width() - w)/2,
-                         geometry.top() + (geometry.height() - h)/2,
+        self.setGeometry(geometry.left() + (geometry.width() - w)//2,
+                         geometry.top() + (geometry.height() - h)//2,
                          w, h)
         self.setWindowTitle('VisTrails APT interface')
         lbl = QtGui.QLabel(self)
diff --git a/vistrails/gui/bundles/linux_fedora_install.py b/vistrails/gui/bundles/linux_fedora_install.py
index a950763..87739dc 100755
--- a/vistrails/gui/bundles/linux_fedora_install.py
+++ b/vistrails/gui/bundles/linux_fedora_install.py
@@ -1,35 +1,37 @@
 #!/usr/bin/env python
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -186,13 +188,11 @@
 # window.show()
 # print app.exec_()
 # sys.exit(0)
+from __future__ import division
+
 import os
 import sys
 
-if __name__ != '__main__':
-    from vistrails.tests import NotModule
-    raise NotModule('This should not be imported as a module')
-
 sys.exit(os.system('yum -y install ' + ' '.join(sys.argv[1:])))
 
 ################################################################################
diff --git a/vistrails/gui/bundles/utils.py b/vistrails/gui/bundles/utils.py
index 0209958..b7ac00a 100644
--- a/vistrails/gui/bundles/utils.py
+++ b/vistrails/gui/bundles/utils.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Utility functions for core.bundles"""
+from __future__ import division
+
 from vistrails.core import debug
 import vistrails.core.system
 import os
@@ -78,7 +81,7 @@ def guess_graphical_sudo():
     else:
         debug.warning("Could not find a graphical sudo-like command.")
 
-        if vistrails.core.system.get_executable_path('sudo'):
+        if vistrails.core.system.executable_is_in_path('sudo'):
             debug.warning("Will use regular sudo")
             return "sudo -E %s", False
         else:
@@ -116,7 +119,7 @@ def _guess_suse():
     try:
         tokens = open('/etc/SuSE-release').readline()[-1].split()
         return tokens[0] == 'SUSE'
-    except:
+    except (IOError, IndexError):
         return False
 _system_guesser.add_test(_guess_suse, 'linux-suse')
 
@@ -140,11 +143,15 @@ _system_guesser.add_test(_guess_windows, 'windows')
 ##############################################################################
 
 def guess_system():
-    """guess_system will try to identify which system you're running. Result
-will be a string describing the system. This is more discriminating than
-Linux/OSX/Windows: We'll try to figure out whether you're running SuSE, Debian,
-Ubuntu, RedHat, fink, darwinports, etc.
+    """guess_system will try to identify which system you're
+    running. Result will be a string describing the system. This is
+    more discriminating than Linux/OSX/Windows: We'll try to figure
+    out whether you're running SuSE, Debian, Ubuntu, RedHat, fink,
+    darwinports, etc.
+
+    Currently, we only support SuSE, Debian, Ubuntu and
+    Fedora. However, we only have actual bundle installing for Debian,
+    Ubuntu and Fedora.
 
-Currently, we only support SuSE, Debian, Ubuntu and Fedora. However, we only
-have actual bundle installing for Debian, Ubuntu and Fedora."""
+    """
     return _system_guesser.guess_system()
diff --git a/vistrails/gui/collection/__init__.py b/vistrails/gui/collection/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/gui/collection/__init__.py
+++ b/vistrails/gui/collection/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/gui/collection/explorer.py b/vistrails/gui/collection/explorer.py
index a02724e..970f1ae 100644
--- a/vistrails/gui/collection/explorer.py
+++ b/vistrails/gui/collection/explorer.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core import debug
@@ -159,7 +162,7 @@ def getConnectionInfo(connectionList, id):
     conn = connectionList.get_connection(id)
     key = str(conn.id) + "." + conn.name + "." + conn.host
     passwd = DBLocator.keyChain.get_key(key)
-    if conn != None:
+    if conn is not None:
         config = {'id': conn.id,
                   'name': conn.name,
                   'host': conn.host,
@@ -180,19 +183,18 @@ def checkConnection(connectionList):
     if conn_id != -1:
         conn = connectionList.get_connection(conn_id)
         config = getConnectionInfo(connectionList, conn_id)
-        if config != None:
+        if config is not None:
+            config_name = config['name']
+            config_id = config['id']
             try:
-                config_name = config['name']
-                del config['name']
-                config_id = config['id']
-                del config['id']
                 test_db_connection(config)
             except VistrailsDBException:
                 # assume connection is wrong
-                config['name'] = config_name
-                config['id'] = config_id
                 config["create"] = False
                 showConnConfig(connectionList, **config)
+            else:
+                del config['name']
+                del config['id']
 
 class QDBWidget(QtGui.QWidget):
     """ Custom widget for handling the showConnConfig """
@@ -369,10 +371,8 @@ class ExecutionSearchWidget(QtGui.QSplitter):
         config = self.config
         if conn.dbtype == 'MySQL':
             #removing extra keyword arguments for MySQldb
-            config_name = config['name']
-            del config['name']
-            config_id = config['id']
-            del config['id']
+            config_name = config.pop('name')
+            config_id = config.pop('id')
             
         wf_exec_list = runLogQuery(config,
                                 vistrail=self.vistrail, version=self.version,
@@ -646,10 +646,8 @@ class WorkflowSearchWidget(QtGui.QSplitter):
         config = self.config
         if conn.dbtype == 'MySQL':
             #removing extra keyword arguments for MySQldb
-            config_name = config['name']
-            del config['name']
-            config_id = config['id']
-            del config['id']
+            config_name = config.pop('name')
+            config_id = config.pop('id')
             
         workflow_list = runWorkflowQuery(config,
                                 vistrail=self.vistrail, version=self.version,
diff --git a/vistrails/gui/collection/vis_log.py b/vistrails/gui/collection/vis_log.py
index 69cf5a4..33503bb 100644
--- a/vistrails/gui/collection/vis_log.py
+++ b/vistrails/gui/collection/vis_log.py
@@ -1,43 +1,46 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This modules builds a widget to visualize workflow execution logs """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.vistrail.pipeline import Pipeline
 from vistrails.core.log.module_exec import ModuleExec
 from vistrails.core.log.group_exec import GroupExec
-from vistrails.core.log.loop_exec import LoopExec
+from vistrails.core.log.loop_exec import LoopExec, LoopIteration
 from vistrails.core.log.workflow_exec import WorkflowExec
 from vistrails.gui.pipeline_view import QPipelineView
 from vistrails.gui.theme import CurrentTheme
@@ -52,44 +55,38 @@ import vistrails.core.db.io
 
 class QExecutionItem(QtGui.QTreeWidgetItem):
     """
-    QExecutionListWidget is a widget containing a list of workflow executions.
-    
+    QExecutionItem represents a workflow or module execution.
+
     """
-    def __init__(self, execution, parent=None):
+    def __init__(self, execution, parent=None, prev=None):
         QtGui.QTreeWidgetItem.__init__(self, parent)
         self.execution = execution
         execution.item = self
-
-        # find parent workflow or group
-        if parent is not None:
-            while (parent.parent() is not None and
-                   not isinstance(parent.execution, GroupExec)):
-                parent = parent.parent()
-            self.wf_execution = parent.execution
-        else:
-            self.wf_execution = execution
+        self.modules = []
+        self.wf_item = prev or self
 
         if isinstance(execution, WorkflowExec):
             for item_exec in execution.item_execs:
-                QExecutionItem(item_exec, self)
+                QExecutionItem(item_exec, self, self)
             if execution.completed == -2:
                 brush = CurrentTheme.SUSPENDED_MODULE_BRUSH
             elif execution.completed == 1:
                 brush = CurrentTheme.SUCCESS_MODULE_BRUSH
             else:
                 brush = CurrentTheme.ERROR_MODULE_BRUSH
-                
+
             if execution.db_name:
                 self.setText(0, execution.db_name)
             else:
                 self.setText(0, 'Version #%s' % execution.parent_version )
-        if isinstance(execution, ModuleExec):
+        elif isinstance(execution, ModuleExec):
+            prev.modules.append(self)
             for loop_exec in execution.loop_execs:
-                QExecutionItem(loop_exec, self)
+                QExecutionItem(loop_exec, self, prev)
             if execution.completed == 1:
                 if execution.error:
                     brush = CurrentTheme.ERROR_MODULE_BRUSH
-                    self.wf_execution.completed = -1
+                    self.wf_item.execution.completed = -1
                 elif execution.cached:
                     brush = CurrentTheme.NOT_EXECUTED_MODULE_BRUSH
                 else:
@@ -99,12 +96,16 @@ class QExecutionItem(QtGui.QTreeWidgetItem):
             else:
                 brush = CurrentTheme.ERROR_MODULE_BRUSH
             self.setText(0, '%s' % execution.module_name)
-        if isinstance(execution, GroupExec):
+        elif isinstance(execution, GroupExec):
+            prev.modules.append(self)
             for item_exec in execution.item_execs:
-                QExecutionItem(item_exec, self)
+                if isinstance(item_exec, LoopExec):
+                    QExecutionItem(item_exec, self, prev)
+                else:
+                    QExecutionItem(item_exec, self, self)
             if execution.completed == 1:
                 if execution.error:
-                    self.wf_execution.completed = -1
+                    self.wf_item.execution.completed = -1
                     brush = CurrentTheme.ERROR_MODULE_BRUSH
                 elif execution.cached:
                     brush = CurrentTheme.NOT_EXECUTED_MODULE_BRUSH
@@ -115,12 +116,17 @@ class QExecutionItem(QtGui.QTreeWidgetItem):
             else:
                 brush = CurrentTheme.ERROR_MODULE_BRUSH
             self.setText(0, 'Group')
-        if isinstance(execution, LoopExec):
+        elif isinstance(execution, LoopExec):
+            for iteration in execution.loop_iterations:
+                QExecutionItem(iteration, self, prev)
+            brush = CurrentTheme.MODULE_BRUSH
+            self.setText(0, 'Loop')
+        elif isinstance(execution, LoopIteration):
             for item_exec in execution.item_execs:
-                QExecutionItem(item_exec, self)
+                QExecutionItem(item_exec, self, prev)
             if execution.completed == 1:
                 if execution.error:
-                    self.wf_execution.completed = -1
+                    self.wf_item.execution.completed = -1
                     brush = CurrentTheme.ERROR_MODULE_BRUSH
                 else:
                     brush = CurrentTheme.SUCCESS_MODULE_BRUSH
@@ -128,14 +134,31 @@ class QExecutionItem(QtGui.QTreeWidgetItem):
                 brush = CurrentTheme.SUSPENDED_MODULE_BRUSH
             else:
                 brush = CurrentTheme.ERROR_MODULE_BRUSH
-            self.setText(0, 'Loop #%s' % execution.db_iteration)
-        self.setText(1, '%s' % execution.ts_start)
-        self.setText(2, '%s' % execution.ts_end)
+            self.setText(0, 'Iteration #%s' % execution.iteration)
+
+        self.setText(1, execution.ts_start.strftime(
+                    '%H:%M %d/%m').replace(' 0', ' ').replace('/0', '/'))
+        self.setData(1, QtCore.Qt.UserRole, str(execution.ts_start))
+        #self.setText(2, '%s' % execution.ts_end) end is hidden
         pixmap = QtGui.QPixmap(10,10)
         pixmap.fill(brush.color())
         icon = QtGui.QIcon(pixmap)
         self.setIcon(0, icon)
 
+
+    def __lt__( self, other ):
+
+        tree = self.treeWidget()
+        if ( not tree ):
+            column = 0
+        else:
+            column = tree.sortColumn()
+
+        if column != 1: # only use special sorting for date
+            return super(QExecutionItem, self).__lt__(other)
+
+        return self.data(1, QtCore.Qt.UserRole) < other.data(1, QtCore.Qt.UserRole)
+
 class QExecutionListWidget(QtGui.QTreeWidget):
     """
     QExecutionListWidget is a widget containing a list of workflow executions.
@@ -144,15 +167,17 @@ class QExecutionListWidget(QtGui.QTreeWidget):
     def __init__(self, parent=None):
         QtGui.QTreeWidget.__init__(self, parent)
         self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
-        self.setColumnCount(3)
-        self.setHeaderLabels(['Pipeline', 'Start', 'End'])
+        self.setColumnCount(2)
+        self.setHeaderLabels(['Pipeline', 'Start']) # end is hidden
+        self.header().setDefaultSectionSize(200)
         self.sortByColumn(1, QtCore.Qt.AscendingOrder)
         self.setSortingEnabled(True)
 
     def set_log(self, log=None):
         self.clear()
-        for execution in log:
-            self.addTopLevelItem(QExecutionItem(execution))
+        if log is not None:
+            for execution in log:
+                self.addTopLevelItem(QExecutionItem(execution))
 
     def add_workflow_exec(self, workflow_exec):
         # mark as recent
@@ -218,8 +243,9 @@ class QLegendWidget(QtGui.QWidget):
 class QLogDetails(QtGui.QWidget, QVistrailsPaletteInterface):
     def __init__(self, parent=None):
         QtGui.QWidget.__init__(self, parent)
+        self.controller = None
         self.execution = None
-        self.parentExecution = None
+        self.parentItem = None
         self.set_title("Log Details")
         self.legend = QLegendWidget()
         self.executionList = QExecutionListWidget()
@@ -261,9 +287,15 @@ class QLogDetails(QtGui.QWidget, QVistrailsPaletteInterface):
                                                self.openVersionAction)
 
     def openVersion(self):
-        if not hasattr(self.parentExecution, 'item'):
+
+        parent = self.executionList.selectedItems()
+        if len(parent) != 1:
             return
-        version = self.parentExecution.item.wf_execution.parent_version
+        parent = parent[0]
+        while not isinstance(parent.execution, WorkflowExec):
+            parent = parent.parent()
+
+        version = parent.execution.parent_version
         from vistrails.gui.vistrails_window import _app
         _app.get_current_view().version_selected(version, True)
         self.controller.recompute_terse_graph()
@@ -289,39 +321,45 @@ class QLogDetails(QtGui.QWidget, QVistrailsPaletteInterface):
         if self.isDoubling:
             self.isDoubling = False
             return
-        if isinstance(item.wf_execution, GroupExec):
+        if isinstance(item.wf_item, GroupExec):
             self.backButton.show()
         else:
             self.backButton.hide()
-        self.notify_app(item.wf_execution, item.execution)
+        self.notify_app(item.wf_item, item.execution)
 
-    def notify_app(self, wf_execution, execution):
+    def notify_app(self, wf_item, execution):
         # make sure it is only called once
         if self.isUpdating:
             return
         self.isUpdating = True
         from vistrails.gui.vistrails_window import _app
-        _app.notify("execution_changed", wf_execution, execution)
+        _app.notify("execution_changed", wf_item, execution)
         self.isUpdating = False
 
     def set_controller(self, controller):
         #print '@@@@ QLogDetails calling set_controller'
+        if self.controller == controller:
+            return
+
         self.controller = controller
         self.executionList.controller = self.controller
-        if not hasattr(self.controller, 'loaded_workflow_execs'):
-            self.controller.loaded_workflow_execs = {}
-            for e in self.controller.read_log().workflow_execs:
-                # set workflow names
-                e.db_name = controller.get_pipeline_name(e.parent_version)
-                self.controller.loaded_workflow_execs[e] = e
-        self.log = self.controller.loaded_workflow_execs
+        if self.controller is not None:
+            if not hasattr(self.controller, 'loaded_workflow_execs'):
+                self.controller.loaded_workflow_execs = {}
+                for e in self.controller.read_log().workflow_execs:
+                    # set workflow names
+                    e.db_name = controller.get_pipeline_name(e.parent_version)
+                    self.controller.loaded_workflow_execs[e] = e
+            self.log = self.controller.loaded_workflow_execs
+        else:
+            self.log = None
         self.executionList.set_log(self.log)
 
-    def execution_changed(self, wf_execution, execution):
+    def execution_changed(self, wf_item, execution):
         if not execution:
             return
         self.execution = execution
-        self.parentExecution = wf_execution
+        self.parentItem = wf_item
         text = ''
         if hasattr(execution, 'item') and \
            not execution.item == self.executionList.currentItem():
@@ -334,8 +372,9 @@ class QLogDetails(QtGui.QWidget, QVistrailsPaletteInterface):
             text += 'User: %s\n' % execution.user
         if hasattr(execution, 'cached'):
             text += 'Cached: %s\n' % ("Yes" if execution.cached else 'No')
-        text += 'Completed: %s\n' % {'0':'No', '1':'Yes'}.get(
-                                    str(execution.completed), 'No')
+        if hasattr(execution, 'completed'):
+            text += 'Completed: %s\n' % {'0':'No', '1':'Yes'}.get(
+                                        str(execution.completed), 'No')
         if hasattr(execution, 'error') and execution.error:
             text += 'Error: %s\n' % execution.error
         annotations = execution.db_annotations \
@@ -351,16 +390,16 @@ class QLogDetails(QtGui.QWidget, QVistrailsPaletteInterface):
         if self.isDoubling:
             self.isDoubling = False
             return
-        if isinstance(item.wf_execution, GroupExec):
+        if isinstance(item.wf_item, GroupExec):
             self.backButton.show()
         else:
             self.backButton.hide()
-        self.notify_app(item.wf_execution, item.execution)
+        self.notify_app(item.wf_item, item.execution)
 
     def doubleClick(self, item, col):
         # only difference here is that we should show contents of GroupExecs 
         self.isDoubling = True
-        if isinstance(item.wf_execution, GroupExec):
+        if isinstance(item.wf_item, GroupExec):
             self.backButton.show()
         else:
             self.backButton.hide()
@@ -368,13 +407,13 @@ class QLogDetails(QtGui.QWidget, QVistrailsPaletteInterface):
             # use itself as the workflow
             self.notify_app(item.execution, item.execution)
         else:
-            self.notify_app(item.wf_execution, item.execution)
+            self.notify_app(item.wf_item, item.execution)
 
     def goBack(self):
-        if not isinstance(self.parentExecution, GroupExec):
+        if not isinstance(self.parentItem.execution, GroupExec):
             self.backButton.hide()
-        self.notify_app(self.parentExecution.item.wf_execution,
-                        self.parentExecution)
+        self.notify_app(self.parentItem.item.wf_item,
+                        self.parentItem)
 
     def update_selection(self):
         if hasattr(self.execution, 'item') and \
@@ -388,10 +427,8 @@ class QLogView(QPipelineView):
         self.set_title("Provenance")
         self.log = None
         self.execution = None
-        self.parentExecution = None
+        self.parentItem = None
         self.isUpdating = False
-        # self.exec_to_wf_map = {}
-        # self.workflow_execs = []
         # Hook shape selecting functions
         self.connect(self.scene(), QtCore.SIGNAL("moduleSelected"),
                      self.moduleSelected)
@@ -409,19 +446,18 @@ class QLogView(QPipelineView):
              'publishPaper': [('setEnabled', False, False)],
             })
 
-    def notify_app(self, wf_execution, execution):
+    def notify_app(self, wf_item, execution):
         # make sure it is only called once
         if self.isUpdating:
             return
         self.isUpdating = True
         from vistrails.gui.vistrails_window import _app
-        _app.notify("execution_changed", wf_execution, execution)
+        _app.notify("execution_changed", wf_item, execution)
         self.isUpdating = False
 
 
     def set_controller(self, controller):
         QPipelineView.set_controller(self, controller)
-        #print "@@@ set_controller called", id(self.controller), len(self.controller.vistrail.actions)
         if not hasattr(self.controller, 'loaded_workflow_execs'):
             self.controller.loaded_workflow_execs = {}
             for e in self.controller.read_log().workflow_execs:
@@ -440,18 +476,17 @@ class QLogView(QPipelineView):
         """ moduleSelected(id: int, selectedItems: [QGraphicsItem]) -> None
         """
         if len(selectedItems)!=1 or id==-1:
-            if self.execution != self.parentExecution:
-                self.notify_app(self.parentExecution, self.parentExecution)
-#            self.moduleUnselected()
+            if self.execution != self.parentItem.execution:
+                self.notify_app(self.parentItem, self.parentItem.execution)
             return
 
         item = selectedItems[0]
         if hasattr(item,'execution') and item.execution:
             if self.execution != item.execution:
                 item = self.scene().selectedItems()[0]
-                self.notify_app(self.parentExecution, item.execution)
-        elif self.execution != self.parentExecution:
-                self.notify_app(self.parentExecution, self.parentExecution)
+                self.notify_app(self.parentItem, item.execution)
+        elif self.execution != self.parentItem.execution:
+            self.notify_app(self.parentItem, self.parentItem.execution)
 
     def set_exec_by_id(self, exec_id):
         if not self.log:
@@ -462,7 +497,7 @@ class QLogView(QPipelineView):
         except ValueError:
             return False
         if len(workflow_execs):
-            self.notify_app(workflow_execs[0], workflow_execs[0])
+            self.notify_app(workflow_execs[0].item, workflow_execs[0])
             return True
         return False
 
@@ -472,7 +507,7 @@ class QLogView(QPipelineView):
         workflow_execs = [e for e in self.log
                           if str(e.ts_start) == str(exec_date)]
         if len(workflow_execs):
-            self.notify_app(workflow_execs[0], workflow_execs[0])
+            self.notify_app(workflow_execs[0].item, workflow_execs[0])
             return True
         return False
 
@@ -484,46 +519,33 @@ class QLogView(QPipelineView):
 
             return self.controller.vistrail.getPipeline(version)
         if isinstance(execution, GroupExec):
-            parent = execution.item.wf_execution
+            parent = execution.item.wf_item.execution
             parent_pipeline = self.get_execution_pipeline(parent)
             return parent_pipeline.db_get_module_by_id(
                                    execution.db_module_id).pipeline
 
-    def execution_changed(self, wf_execution, execution):
+    def execution_changed(self, wf_item, execution):
         self.execution = execution
-        if self.parentExecution != wf_execution:
-            self.parentExecution = wf_execution
-            self.pipeline = self.get_execution_pipeline(wf_execution)
+        if self.parentItem != wf_item:
+            self.parentItem = wf_item
+            self.pipeline = self.get_execution_pipeline(wf_item.execution)
             self.update_pipeline()
         self.update_selection()
 
-        # if idx < len(self.workflow_execs) and idx >= 0:
-        #     self.execution = self.workflow_execs[idx]
-        # else:
-        #     self.execution = None
-
-        # self.currentItem = self.workflow_execs[idx]
-        # self.execution = item.execution
-        # self.workflowExecution = item
-        # while self.workflowExecution.parent():
-        #     self.workflowExecution = self.workflowExecution.parent()
-        # self.workflowExecution = self.workflowExecution.execution
-        # self.parentExecution = item
-        # while self.parentExecution.execution.__class__ not in \
-        #         [WorkflowExec, LoopExec, GroupExec]:
-        #     self.parentExecution = self.parentExecution.parent()
-        # self.parentExecution = self.parentExecution.execution
-        # self.showExecution()
-
     def update_pipeline(self):
-        #print "ACTIONS!"
-        #print "#### controller", id(self.controller)
         scene = self.scene()
         scene.clearItems()
         self.pipeline.validate(False)
         
-        module_execs = dict([(e.module_id, e) 
-                             for e in self.parentExecution.item_execs])
+        modules = [(e.execution.module_id, e.execution) for e in self.parentItem.modules
+                                                   if hasattr(e.execution, 'module_id')]
+        modules.reverse()
+        module_execs = {}
+        for id, m in modules:
+            if id not in module_execs:
+                module_execs[id] = []
+            module_execs[id].append(m)
+
         # controller = DummyController(self.pipeline)
         scene.controller = self.controller
         self.moduleItems = {}
@@ -531,7 +553,7 @@ class QLogView(QPipelineView):
             module = self.pipeline.modules[m_id]
             brush = CurrentTheme.PERSISTENT_MODULE_BRUSH
             if m_id in module_execs:
-                e = module_execs[m_id]
+                e = module_execs[m_id][-1]
                 if e.completed == 1:
                     if e.error:
                         brush = CurrentTheme.ERROR_MODULE_BRUSH
@@ -548,9 +570,9 @@ class QLogView(QPipelineView):
             item.controller = self.controller
             self.moduleItems[m_id] = item
             if m_id in module_execs:
-                e = module_execs[m_id]
-                item.execution = e
-                e.module = item
+                for e in module_execs[m_id]:
+                    item.execution = e
+                    e.module = item
             else:
                 item.execution = None
         connectionItems = []
@@ -571,8 +593,8 @@ class QLogView(QPipelineView):
         self.isUpdating = True
         module = None
         if (isinstance(self.execution, ModuleExec) or \
-            (isinstance(self.execution, GroupExec) and
-             self.execution == self.parentExecution)) and \
+            isinstance(self.execution, GroupExec)) and \
+            hasattr(self.execution, 'module') and \
           not self.execution.module.isSelected():
             self.execution.module.setSelected(True)
             module = self.execution.module
diff --git a/vistrails/gui/collection/workspace.py b/vistrails/gui/collection/workspace.py
index 97b0896..0f64fb3 100644
--- a/vistrails/gui/collection/workspace.py
+++ b/vistrails/gui/collection/workspace.py
@@ -1,49 +1,52 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 import glob
 from itertools import chain
 import os
 from datetime import datetime
-from time import strptime
 from vistrails.core.thumbnails import ThumbnailCache
 from vistrails.core import debug
 from vistrails.core.collection import Collection, MashupEntity, ThumbnailEntity, \
     VistrailEntity, WorkflowEntity, WorkflowExecEntity, ParameterExplorationEntity
 from vistrails.core.db.locator import FileLocator
+from vistrails.core.system import time_strptime
 from vistrails.db.services.locator import UntitledLocator
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
 from vistrails.gui.theme import CurrentTheme
@@ -120,6 +123,7 @@ class QCollectionWidget(QtGui.QTreeWidget):
 
         locator.update_from_gui(self)
         open_vistrail(locator, **args)
+        self.setItemSelected(widget_item, True)
 
     def contextMenuEvent(self, event):
         item = self.itemAt(event.pos())
@@ -205,7 +209,7 @@ class QCollectionWidget(QtGui.QTreeWidget):
     def add_file(self):
         s = QtGui.QFileDialog.getOpenFileName(
                     self, "Choose a file",
-                    "", "Vistrail files (*.vt *.xml)");
+                    "", "Vistrail files (*.vt *.xml)")
         if str(s):
             locator = FileLocator(str(s))
             url = locator.to_url()
@@ -217,7 +221,7 @@ class QCollectionWidget(QtGui.QTreeWidget):
     def add_dir(self):
         s = QtGui.QFileDialog.getExistingDirectory(
                     self, "Choose a directory",
-                    "", QtGui.QFileDialog.ShowDirsOnly);
+                    "", QtGui.QFileDialog.ShowDirsOnly)
         if str(s):
             self.update_from_directory(str(s))
         
@@ -238,7 +242,7 @@ class QCollectionWidget(QtGui.QTreeWidget):
                 url = locator.to_url()
                 entity = self.collection.updateVistrail(url)
                 self.collection.add_to_workspace(entity)
-            except:
+            except Exception:
                 debug.critical("Failed to add file '%s'" % filename)
         progress.setValue(len(filenames))
         self.collection.commit()
@@ -344,8 +348,8 @@ class QBrowserWidgetItem(QtGui.QTreeWidgetItem):
                     pixmap = QtGui.QPixmap(path)
                     if pixmap and not pixmap.isNull():
                         self.setIcon(0, QtGui.QIcon(pixmap.scaled(16, 16)))
-                    tooltip += """<br/><img border=0 src='%(path)s'/>
-                        """ % {'path':path}
+                    tooltip += "<br/><img border=0 src='%(path)s'/>" % \
+                               {'path': path}
             elif child.type_id == WorkflowEntity.type_id:
                 # is a pipeline
                 # only show tagged items
@@ -393,7 +397,6 @@ class QBrowserWidgetItem(QtGui.QTreeWidgetItem):
 class QWorkflowEntityItem(QBrowserWidgetItem):
     def get_vistrail(self):
         parent = self.parent()
-        QVistrailEntityItem
         while parent and type(parent) != QVistrailEntityItem:
             parent = parent.parent()
         return parent
@@ -475,7 +478,7 @@ class QExplorerWidgetItem(QtGui.QTreeWidgetItem):
         if sort_col in set([4]):
             return int(self.text(sort_col)) < int(other.text(sort_col))
         elif sort_col in set([2,3]):
-            return datetime(*strptime(str(self.text(sort_col)), '%d %b %Y %H:%M:%S')[0:6]) < datetime(*strptime(str(other.text(sort_col)), '%d %b %Y %H:%M:%S')[0:6])
+            return datetime(*time_strptime(str(self.text(sort_col)), '%d %b %Y %H:%M:%S')[0:6]) < datetime(*time_strptime(str(other.text(sort_col)), '%d %b %Y %H:%M:%S')[0:6])
         return QtGui.QTreeWidgetItem.__lt__(self, other)
 
     def refresh_object(self):
@@ -797,7 +800,7 @@ class QVistrailList(QtGui.QTreeWidget):
         Expand/Collapse top-level item when the mouse is pressed
         
         """
-        if item and item.parent() == None:
+        if item and item.parent() is None:
             self.setItemExpanded(item, not self.isItemExpanded(item))
             
     def search_result_selected(self, view, version):
@@ -859,7 +862,7 @@ class QVistrailList(QtGui.QTreeWidget):
                 try:
                     version = \
                         view.controller.vistrail.get_version_number(version)
-                except:
+                except Exception:
                     version = None
             if self.searchMode:
                 self.search_result_selected(view, version)
@@ -1185,7 +1188,10 @@ class QVistrailList(QtGui.QTreeWidget):
             item.pe_to_item[pe_entity.url] = childItem
             item.paramExplorationsItem.setHidden(not len(item.pe_to_item))
 
-        self.make_tree(item) if self.isTreeView else self.make_list(item)
+        if self.isTreeView:
+            self.make_tree(item)
+        else:
+            self.make_list(item)
 
     def execution_updated(self):
         """ Add new executions to workflow """
@@ -1289,7 +1295,10 @@ class QVistrailList(QtGui.QTreeWidget):
         item.mashupsItem.setHidden(not item.mashupsItem.childCount())
         item.paramExplorationsItem.setHidden(
                              not item.paramExplorationsItem.childCount())
-        self.make_tree(item) if self.isTreeView else self.make_list(item)
+        if self.isTreeView:
+            self.make_tree(item)
+        else:
+            self.make_list(item)
         self.item_changed(item, None)
         self.updateHideExecutions()
 
@@ -1320,7 +1329,10 @@ class QVistrailList(QtGui.QTreeWidget):
         if entity and not self.collection.is_temp_entity(entity) and \
                 not vistrail_window.is_abstraction:
             item = QVistrailEntityItem(entity)
-            self.make_tree(item) if self.isTreeView else self.make_list(item)
+            if self.isTreeView:
+                self.make_tree(item)
+            else:
+                self.make_list(item)
             self.closedFilesItem.addChild(item)
             item.setText(0, entity.name)
         self.updateHideExecutions()
diff --git a/vistrails/gui/common_widgets.py b/vistrails/gui/common_widgets.py
index d49c8cd..789c505 100644
--- a/vistrails/gui/common_widgets.py
+++ b/vistrails/gui/common_widgets.py
@@ -1,45 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This common widgets using on the interface of VisTrails. These are
 only simple widgets in term of coding and additional features. It
 should have no interaction with VisTrail core"""
+from __future__ import division
+
+import os
+
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import pyqtSlot, pyqtSignal
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.modules.constant_configuration import StandardConstantWidget
-from vistrails.core.system import systemType
+from vistrails.core.system import systemType, set_vistrails_data_directory
 ################################################################################
 
 class QToolWindow(QtGui.QDockWidget):
@@ -477,46 +482,7 @@ class QStringEdit(QtGui.QFrame):
                                                      '(*.*)')
         if fileName:
             self.setText(fileName)
-        
-###############################################################################
 
-class MultiLineWidget(StandardConstantWidget):
-    def __init__(self, contents, contentType, parent=None):
-        """__init__(contents: str, contentType: str, parent: QWidget) ->
-                                             StandardConstantWidget
-        Initialize the line edit with its contents. Content type is limited
-        to 'int', 'float', and 'string'
-        
-        """
-        StandardConstantWidget.__init__(self, parent)
-
-    def update_parent(self):
-        pass
-     
-    def keyPressEvent(self, event):
-        """ keyPressEvent(event) -> None       
-        If this is a string line edit, we can use Ctrl+Enter to enter
-        the file name
-
-        """
-        k = event.key()
-        s = event.modifiers()
-        if ((k == QtCore.Qt.Key_Enter or k == QtCore.Qt.Key_Return) and
-            s & QtCore.Qt.ShiftModifier):
-            event.accept()
-            if self.contentIsString and self.multiLines:
-                fileNames = QtGui.QFileDialog.getOpenFileNames(self,
-                                                               'Use Filename '
-                                                               'as Value...',
-                                                               self.text(),
-                                                               'All files '
-                                                               '(*.*)')
-                fileName = fileNames.join(',')
-                if fileName:
-                    self.setText(fileName)
-                    return
-        QtGui.QLineEdit.keyPressEvent(self,event)
-        
 ###############################################################################
 
 class QSearchEditBox(QtGui.QComboBox):
@@ -714,101 +680,6 @@ class QSearchBox(QtGui.QWidget):
 
 ###############################################################################
 
-class QTabBarDetachButton(QtGui.QAbstractButton):
-    """QTabBarDetachButton is a special button to be added to a tab
-    
-    """
-    def __init__(self, parent):
-        QtGui.QAbstractButton.__init__(self)
-        self.setFocusPolicy(QtCore.Qt.NoFocus)
-        self.setCursor(QtCore.Qt.ArrowCursor)
-        self.setToolTip("Detach Tab")
-        self.setIcon(CurrentTheme.DETACH_TAB_ICON)
-        self.activePixmap = self.icon().pixmap(self.sizeHint(),
-                                               mode=QtGui.QIcon.Active)
-        self.normalPixmap = self.icon().pixmap(self.sizeHint(),
-                                               mode=QtGui.QIcon.Normal)
-        
-        self.resize(self.sizeHint())
-        
-    def sizeHint(self):
-        self.ensurePolished()
-        size = QtCore.QSize()
-        if not self.icon().isNull():
-            iconSize = self.style().pixelMetric(QtGui.QStyle.PM_SmallIconSize, 
-                                                None, self)
-            sz = self.icon().actualSize(QtCore.QSize(iconSize, iconSize))
-            size = max(sz.width(), sz.height())
-        
-        return QtCore.QSize(size, size)
-    
-    def enterEvent(self, event):
-        if self.isEnabled():
-            icon = QtGui.QIcon(self.activePixmap)
-            self.setIcon(icon)
-            self.update()
-        else:
-            icon = QtGui.QIcon(self.normalPixmap)
-            self.setIcon(icon)
-        QtGui.QAbstractButton.enterEvent(self, event)
-        
-    def leaveEvent(self, event):
-        icon = QtGui.QIcon(self.normalPixmap)
-        self.setIcon(icon)
-        if self.isEnabled():
-            self.update()
-        QtGui.QAbstractButton.leaveEvent(self, event)
-        
-    def closePosition(self):
-        tb = self.parent()
-        if isinstance(tb, QtGui.QTabBar):
-            close_position = self.style().styleHint(QtGui.QStyle.SH_TabBar_CloseButtonPosition,
-                                                  None, tb)
-            return close_position
-        return -1
-    
-    def otherPosition(self):
-        tb = self.parent()
-        if isinstance(tb, QtGui.QTabBar):
-            close_position = self.closePosition()
-            if close_position == QtGui.QTabBar.LeftSide:
-                position = QtGui.QTabBar.RightSide
-            else:
-                position = QtGui.QTabBar.LeftSide
-            return position
-        return -1
-            
-    def paintEvent(self, event):
-        p = QtGui.QPainter(self)
-        opt = QtGui.QStyleOptionToolButton()
-        opt.init(self)
-        opt.state |= QtGui.QStyle.State_AutoRaise
-        if (self.isEnabled() and self.underMouse() and 
-            not self.isChecked() and not self.isDown()):
-            opt.state |= QtGui.QStyle.State_Raised
-        if self.isChecked():
-            opt.state |= QtGui.QStyle.State_On
-        if self.isDown():
-            opt.state |= QtGui.QStyle.State_Sunken
-        tb = self.parent()
-        if isinstance(tb, QtGui.QTabBar):
-            index = tb.currentIndex()
-            position = self.otherPosition()
-            if tb.tabButton(index, position) == self:
-                opt.state |= QtGui.QStyle.State_Selected
-            opt.icon = self.icon()
-            opt.subControls = QtGui.QStyle.SC_None
-            opt.activeSubControls = QtGui.QStyle.SC_None
-            opt.features = QtGui.QStyleOptionToolButton.None
-            opt.arrowType = QtCore.Qt.NoArrow
-            size = self.style().pixelMetric(QtGui.QStyle.PM_SmallIconSize, 
-                                                None, self)
-            opt.iconSize = QtCore.QSize(size,size)
-            self.style().drawComplexControl(QtGui.QStyle.CC_ToolButton, opt, p, 
-                                            self)
-
-###############################################################################
-
 class QMouseTabBar(QtGui.QTabBar):
     """QMouseTabBar is a QTabBar that emits a signal when a tab
     receives a mouse event. For now only doubleclick events are
@@ -835,3 +706,114 @@ class QDockPushButton(QtGui.QPushButton):
         QtGui.QPushButton.__init__(self, text, parent) 
         if systemType in ['Darwin']:
             self.setMinimumHeight(32)
+
+class QPathChooserToolButton(QtGui.QToolButton):
+    """
+    QPathChooserToolButton is a toolbar button that opens a browser for
+    paths.  The lineEdit is updated with the pathname that is selected.
+    
+    emits pathChanged when the path is changed
+
+    """
+    pathChanged = pyqtSignal()
+
+    def __init__(self, parent=None, lineEdit=None, toolTip=None,
+                 defaultPath=None):
+        """
+        PathChooserToolButton(parent: QWidget, 
+                              lineEdit: StandardConstantWidget) ->
+                 PathChooserToolButton
+
+        """
+        QtGui.QToolButton.__init__(self, parent)
+        self.setIcon(QtGui.QIcon(
+                self.style().standardPixmap(QtGui.QStyle.SP_DirOpenIcon)))
+        self.setIconSize(QtCore.QSize(12,12))
+        if toolTip is None:
+            toolTip = 'Open a path chooser'
+        self.defaultPath = defaultPath
+        self.setToolTip(toolTip)
+        self.setAutoRaise(True)
+        self.lineEdit = lineEdit
+        self.connect(self,
+                     QtCore.SIGNAL('clicked()'),
+                     self.runDialog)
+
+    def setPath(self, path):
+        """
+        setPath() -> None
+
+        """
+        if self.lineEdit and path:
+            self.lineEdit.setText(path)
+            self.pathChanged.emit()
+    
+    def getDefaultText(self):
+        return self.lineEdit.text() or self.defaultPath
+
+    def openChooser(self):
+        path = QtGui.QFileDialog.getOpenFileName(self,
+                                                 'Select Path...',
+                                                 self.getDefaultText(),
+                                                 'All files '
+                                                 '(*.*)')
+        return self.setDataDirectory(path)
+
+    def runDialog(self):
+        path = self.openChooser()
+        self.setPath(path)
+
+    def setDataDirectory(self, path):
+        if path:
+            absPath = os.path.abspath(str(QtCore.QFile.encodeName(path)))
+            dirName = os.path.dirname(absPath)
+            set_vistrails_data_directory(dirName)
+            return absPath
+        return path
+
+class QFileChooserToolButton(QPathChooserToolButton):
+    def __init__(self, parent=None, lineEdit=None, toolTip=None,
+                 defaultPath=None):
+        if toolTip is None:
+            toolTip = "Open a file chooser dialog"
+        QPathChooserToolButton.__init__(self, parent, lineEdit, toolTip,
+                                        defaultPath)
+
+    def openChooser(self):
+        path = QtGui.QFileDialog.getOpenFileName(self,
+                                                 'Select File...',
+                                                 self.getDefaultText(),
+                                                 'All files '
+                                                 '(*.*)')
+        return self.setDataDirectory(path)
+
+class QDirectoryChooserToolButton(QPathChooserToolButton):
+    def __init__(self, parent=None, lineEdit=None, toolTip=None,
+                 defaultPath=None):
+        if toolTip is None:
+            toolTip = "Open a directory chooser dialog"
+        QPathChooserToolButton.__init__(self, parent, lineEdit, toolTip,
+                                       defaultPath)
+
+    def openChooser(self):
+        path = QtGui.QFileDialog.getExistingDirectory(self,
+                                                      'Select Directory...',
+                                                      self.getDefaultText())
+        return self.setDataDirectory(path)
+
+class QOutputPathChooserToolButton(QPathChooserToolButton):
+    def __init__(self, parent=None, lineEdit=None, toolTip=None,
+                 defaultPath=None):
+        if toolTip is None:
+            toolTip = "Open a path chooser dialog"
+        QPathChooserToolButton.__init__(self, parent, lineEdit, toolTip,
+                                       defaultPath)
+    
+    def openChooser(self):
+        path = QtGui.QFileDialog.getSaveFileName(self,
+                                                 'Select Output Location...',
+                                                 self.getDefaultText(),
+                                                 'All files (*.*)')
+        return self.setDataDirectory(path)
+    
+    
diff --git a/vistrails/gui/configuration.py b/vistrails/gui/configuration.py
index bd6ee61..f89c298 100644
--- a/vistrails/gui/configuration.py
+++ b/vistrails/gui/configuration.py
@@ -1,52 +1,56 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """Widgets to display/edit configuration objects."""
+from __future__ import division
+
 import os
 import os.path
 from PyQt4 import QtGui, QtCore
 
-from vistrails.core import debug
 from vistrails.core.configuration import ConfigurationObject, \
-                               get_vistrails_configuration
+    ConfigFieldParent, ConfigPath, \
+    get_vistrails_configuration, find_simpledoc
 
 from vistrails.core.thumbnails import ThumbnailCache
-from vistrails.gui.common_widgets import QSearchTreeWindow, QSearchTreeWidget
+from vistrails.gui.common_widgets import QSearchTreeWindow, QSearchTreeWidget, \
+    QDirectoryChooserToolButton
 from vistrails.gui.utils import YES_BUTTON, NO_BUTTON, show_question, show_warning
 
-import vistrails.core.system
+from vistrails.core import system
 
 ##############################################################################
 
@@ -228,11 +232,10 @@ class QConfigurationTreeWindow(QSearchTreeWindow):
 
 class QConfigurationWidget(QtGui.QWidget):
 
-    def __init__(self, parent, persistent_config, temp_config, status_bar):
+    def __init__(self, parent, persistent_config, temp_config):
         QtGui.QWidget.__init__(self, parent)
         layout = QtGui.QVBoxLayout(self)
         self.setLayout(layout)
-        self._status_bar = status_bar
 
         self._tree = QConfigurationTreeWindow(self, persistent_config,
                                               temp_config)
@@ -243,697 +246,394 @@ class QConfigurationWidget(QtGui.QWidget):
     def configuration_changed(self, persistent_config, temp_config):
         self._tree.treeWidget.create_tree(persistent_config, temp_config)
 
-class QGeneralConfiguration(QtGui.QWidget):
-    """
-    QGeneralConfiguration is a widget for showing a few general preferences
-    that can be set with widgets.
-
-    """
-    def __init__(self, parent, persistent_config, temp_config):
-        """
-        QGeneralConfiguration(parent: QWidget, 
-        configuration_object: ConfigurationObject) -> None
-
-        """
+class QConfigurationWidgetItem(object):
+    def __init__(self, key, field, callback_f):
+        self.key = key
+        self.field = field
+        self.change_callback_f = callback_f
+        self._desc = None
+
+    def get_desc(self):
+        if self._desc is not None:
+            return self._desc
+
+        options = self.get_widget_options()
+        if "label" in options:
+            return options["label"]
+        return ""
+
+    def set_desc(self, desc=None):
+        self._desc = desc
+
+    def get_label_text(self):
+        return self.get_desc()
+
+    def set_value(self, value, signal=True):
+        raise NotImplementedError("Subclass needs to implement this method")
+
+    def value_changed(self, value):
+        self.change_callback_f(self, self.key, self.field, value)
+
+    def get_widget_options(self):
+        options = {}
+        if self.field.widget_options is not None:
+            options = self.field.widget_options
+        return options
+
+class QConfigurationCheckBox(QtGui.QCheckBox, QConfigurationWidgetItem):
+    def __init__(self, key, field, callback_f, parent=None):
+        QtGui.QCheckBox.__init__(self, parent)
+        QConfigurationWidgetItem.__init__(self, key, field, callback_f)
+        self.setText(self.get_desc())
+        self.toggled.connect(self.value_changed)
+
+    def set_value(self, value, signal=True):
+        if not signal:
+            self.toggled.disconnect(self.value_changed)
+        self.setChecked(value)
+        if not signal:
+            self.toggled.connect(self.value_changed)
+
+    def get_label_text(self):
+        return ""
+
+class QConfigurationLineEdit(QtGui.QLineEdit, QConfigurationWidgetItem):
+    def __init__(self, key, field, callback_f, parent=None):
+        QtGui.QLineEdit.__init__(self, parent)
+        QConfigurationWidgetItem.__init__(self, key, field, callback_f)
+        self.setMinimumWidth(200)
+        self.editingFinished.connect(self.value_changed)
+
+    def value_changed(self):
+        QConfigurationWidgetItem.value_changed(self, self.text())
+
+    def set_value(self, value, signal=True):
+        if value is None:
+            value = ""
+        if not signal:
+            self.editingFinished.disconnect(self.value_changed)
+        self.setText(unicode(value))
+        if not signal:
+            self.editingFinished.connect(self.value_changed)
+
+class QConfigurationLineEditButton(QtGui.QWidget, QConfigurationWidgetItem):
+    def __init__(self, key, field, callback_f, button, parent=None):
         QtGui.QWidget.__init__(self, parent)
-        layout = QtGui.QVBoxLayout()
-        layout.setMargin(10)
-        layout.setSpacing(10)
-        self.setLayout(layout)
-        self._configuration = None
-        self._temp_configuration = None
-        self.create_default_widgets(self, layout)
-        self.create_default_handler_button(self, layout)
-        self.create_other_widgets(self, layout)
-        self.update_state(persistent_config, temp_config)
-        self.connect_default_signals()
-        self.connect_other_signals()
-        
-    def connect_default_signals(self):
-        
-        # We need to connect only one of the radio buttons signal because
-        # only one of them will be checked at a time
-        
-        #Auto save signals
-        self.connect(self._autosave_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.temp_autosave_changed)
-        self.connect(self._autosave_always,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.autosave_changed)
-        
-        #Read and Write to database signals
-        self.connect(self._db_connect_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.temp_db_connect_changed)
-        self.connect(self._db_connect_always,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.db_connect_changed)
-        
-        #Caching signals
-        self.connect(self._use_cache_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.temp_use_cache_changed)
-        self.connect(self._use_cache_always,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.use_cache_changed)
-        
-        #Other signals
-        self.connect(self._splash_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.splash_changed)
-        self.connect(self._maximize_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.maximize_changed)
-        self.connect(self._multi_head_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.multi_head_changed)
-
-    def connect_other_signals(self):
-        if vistrails.core.system.systemType in ['Darwin']:
-            self.connect(self._use_metal_style_cb,
-                         QtCore.SIGNAL('stateChanged(int)'),
-                         self.metalstyle_changed)
-
-    def create_default_widgets(self, parent, layout):
-        """create_default_widgets(parent: QWidget, layout: QLayout)-> None
-        Creates default widgets in parent
-        
-        """
-        #Auto save
-        autosave_gb = QtGui.QGroupBox(parent)
-        autosave_gb.setTitle('Automatically save vistrails')
-        glayout = QtGui.QHBoxLayout()
-        parent._autosave_always = QtGui.QRadioButton("Always")
-        parent._autosave_never = QtGui.QRadioButton("Never")
-        parent._autosave_cb = QtGui.QCheckBox("Yes (for this session only)")
-        glayout.addWidget(parent._autosave_always)
-        glayout.addWidget(parent._autosave_never)
-        glayout.addWidget(parent._autosave_cb)
-        autosave_gb.setLayout(glayout)
-        layout.addWidget(autosave_gb)
-
-        #Read and Write to database
-        db_connect_gb = QtGui.QGroupBox(parent)
-        db_connect_gb.setTitle('Read/Write to database by default')
-        glayout = QtGui.QHBoxLayout()
-        parent._db_connect_always = QtGui.QRadioButton("Always")
-        parent._db_connect_never = QtGui.QRadioButton("Never")
-        parent._db_connect_cb = QtGui.QCheckBox("Yes (for this session only)")
-        glayout.addWidget(parent._db_connect_always)
-        glayout.addWidget(parent._db_connect_never)
-        glayout.addWidget(parent._db_connect_cb)
-        db_connect_gb.setLayout(glayout)
-        layout.addWidget(db_connect_gb)
-        
-        #Caching
-        use_cache_gb = QtGui.QGroupBox(parent)
-        use_cache_gb.setTitle('Cache execution results')
-        glayout = QtGui.QHBoxLayout()
-        parent._use_cache_always = QtGui.QRadioButton("Always")
-        parent._use_cache_never = QtGui.QRadioButton("Never")
-        parent._use_cache_cb = QtGui.QCheckBox("Yes (for this session only)")
-        glayout.addWidget(parent._use_cache_always)
-        glayout.addWidget(parent._use_cache_never)
-        glayout.addWidget(parent._use_cache_cb)
-        use_cache_gb.setLayout(glayout)
-        layout.addWidget(use_cache_gb)
-
-        parent._splash_cb = QtGui.QCheckBox(parent)
-        parent._splash_cb.setText('Show splash dialog on startup*')
-        layout.addWidget(parent._splash_cb)
-
-        parent._maximize_cb = QtGui.QCheckBox(parent)
-        parent._maximize_cb.setText('Maximize windows on startup*')
-        layout.addWidget(parent._maximize_cb)
-
-        parent._multi_head_cb = QtGui.QCheckBox(parent)
-        parent._multi_head_cb.setText('Use multiple displays on startup*')
-        layout.addWidget(parent._multi_head_cb)
-
-    def create_default_handler_button(self, parent, layout):
-        if vistrails.core.system.systemType == 'Linux':
-            from vistrails.gui.application import linux_default_application_set
-            from vistrails.core.application import get_vistrails_application
-
-            group = QtGui.QGroupBox(u"Open .vt .vtl files with VisTrails")
-            layout.addWidget(group)
-            layout2 = QtGui.QHBoxLayout()
-            group.setLayout(layout2)
-
-            if linux_default_application_set():
-                label = u".vt .vtl has a handler set"
-            else:
-                label = u".vt .vtl has no handler"
-            self._handler_status = QtGui.QLabel(label)
-
-            def set_dont_ask(state):
-                self._configuration.handlerDontAsk = bool(state)
-                self._temp_configuration.handlerDontAsk = bool(state)
-                self.emit(QtCore.SIGNAL('configuration_changed'),
-                        'handlerDontAsk', bool(state))
-            self._handler_dont_ask = QtGui.QCheckBox(u"Don't ask at startup")
-            self.connect(self._handler_dont_ask,
-                         QtCore.SIGNAL('stateChanged(int)'),
-                         set_dont_ask)
-
-            def install():
-                app = get_vistrails_application()
-                if app.ask_update_default_application(False):
-                    self._handler_status.setText(u".vt .vtl has a handler set")
-            install_button = QtGui.QPushButton(u"Install handler")
-            self.connect(install_button, QtCore.SIGNAL('clicked()'),
-                         install)
-
-            layout2.addWidget(self._handler_status)
-            layout2.addWidget(self._handler_dont_ask)
-            layout2.addWidget(install_button)
-
-    def create_other_widgets(self, parent, layout):
-        """create_other_widgets(parent: QWidget, layout: QLayout)-> None
-        Creates system specific widgets in parent
-        
-        """
-        if vistrails.core.system.systemType in ['Darwin']:
-            parent._use_metal_style_cb = QtGui.QCheckBox(parent)
-            parent._use_metal_style_cb.setText('Use brushed metal appearance*')
-            layout.addWidget(parent._use_metal_style_cb)
-
-        layout.addStretch()
-        label = QtGui.QLabel("* It requires restarting VisTrails for these \
-changes to take effect")
-        layout.addWidget(label)
-
-    def update_state(self, persistent_config, temp_config):
-        """ update_state(configuration: VistrailConfiguration) -> None
-        
-        Update the dialog state based on a new configuration
-        """
-        
-        self._configuration = persistent_config
-        self._temp_configuration = temp_config
+        QConfigurationWidgetItem.__init__(self, key, field, callback_f)
 
-        #Autosave
-        if self._configuration.has('autosave'):
-            if self._configuration.autosave == True:
-                self._autosave_always.setChecked(True)
-                self._autosave_never.setChecked(False)
-                self._autosave_cb.setText("No (for this session only)")
-                self._autosave_cb.setChecked(
-                                     not self._temp_configuration.autosave)
-                    
-            else:
-                self._autosave_always.setChecked(False)
-                self._autosave_never.setChecked(True)
-                self._autosave_cb.setText("Yes (for this session only)")        
-                self._autosave_cb.setChecked(self._temp_configuration.autosave)
-        
-        #Read/Write from DB by default   
-        if self._configuration.has('dbDefault'):
-            if self._configuration.dbDefault == True:
-                self._db_connect_always.setChecked(True)
-                self._db_connect_never.setChecked(False)
-                self._db_connect_cb.setText("No (for this session only)")
-                self._db_connect_cb.setChecked(
-                                        not self._temp_configuration.dbDefault)
-                    
-            else:
-                self._db_connect_always.setChecked(False)
-                self._db_connect_never.setChecked(True)
-                self._db_connect_cb.setText("Yes (for this session only)")        
-                self._db_connect_cb.setChecked(
-                                        self._temp_configuration.dbDefault)
-        #Caching 
-        if self._configuration.has('useCache'):
-            if self._configuration.useCache == True:
-                self._use_cache_always.setChecked(True)
-                self._use_cache_never.setChecked(False)
-                self._use_cache_cb.setText("No (for this session only)")
-                self._use_cache_cb.setChecked(
-                                        not self._temp_configuration.useCache)
-                    
-            else:
-                self._use_cache_always.setChecked(False)
-                self._use_cache_never.setChecked(True)
-                self._use_cache_cb.setText("Yes (for this session only)")        
-                self._use_cache_cb.setChecked(self._temp_configuration.useCache)
-        
-        if self._configuration.has('showSplash'):
-            self._splash_cb.setChecked(self._configuration.showSplash)
-        if self._configuration.has('maximizeWindows'):
-            self._maximize_cb.setChecked(self._configuration.maximizeWindows)
-        if self._configuration.has('multiHeads'):
-            self._multi_head_cb.setChecked(self._configuration.multiHeads)
-
-        #Default handler
-        if vistrails.core.system.systemType == 'Linux':
-            from vistrails.gui.application import \
-                linux_default_application_set, linux_update_default_application
-
-            if linux_default_application_set():
-                self._handler_status.setText(u".vt .vtl has a handler set")
-            else:
-                self._handler_status.setText(u".vt .vtl has no handler")
+        layout = QtGui.QHBoxLayout()
+        layout.setMargin(0)
+        layout.setSpacing(5)
 
-            self._handler_dont_ask.setChecked(
-                    self._configuration.check('handlerDontAsk'))
+        self.line_edit = QtGui.QLineEdit()
+        self.line_edit.setMinimumWidth(200)
+        layout.addWidget(self.line_edit)
 
-        #other widgets
-        self.update_other_state()
-
-    def update_other_state(self):
-        """ update_state(configuration: VistrailConfiguration) -> None
-        
-        Update the dialog state based on a new configuration
-        """
-        if vistrails.core.system.systemType in ['Darwin']:
-            self._use_metal_style_cb.setChecked(
-                self._configuration.check('useMacBrushedMetalStyle'))
-            
-    def autosave_changed(self, on):
-        """ autosave_changed(on: bool) -> None
-        
-        """
-        debug.log("auto_save_changed")
-        if self._autosave_always.isChecked() == True:
-            value = True
-            self._autosave_cb.setText("No (for this session only)")
-            self._autosave_cb.setChecked(False)
-        else:
-            value = False
-            self._autosave_cb.setText("Yes (for this session only)")
-            self._autosave_cb.setChecked(False)
-            
-        self._configuration.autosave = value
-        self._temp_configuration.autosave = value
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
-        
-    def temp_autosave_changed(self, on):
-        """ temp_autosave_changed(on: int) -> None
-        
-        """
-        debug.log("temp_auto_save_changed")
-        value = bool(on)
-        if self._autosave_cb.text() == "No (for this session only)":
-            value = not bool(on)
-        
-        self._temp_configuration.autosave = value
-
-    def db_connect_changed(self, on):
-        """ db_connect_changed(on: int) -> None
-
-        """
-        if self._db_connect_always.isChecked() == True:
-            value = True
-            self._db_connect_cb.setText("No (for this session only)")
-            self._db_connect_cb.setChecked(False)
-        else:
-            value = False
-            self._db_connect_cb.setText("Yes (for this session only)")
-            self._db_connect_cb.setChecked(False)
-            
-        self._configuration.dbDefault = value
-        self._temp_configuration.dbDefault = value
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
-        
-    def temp_db_connect_changed(self, on):
-        """ temp_db_connect_changed(on: int) -> None
-
-        """
-        debug.log("temp_db_connect_changed")
-        value = bool(on)
-        if self._db_connect_cb.text() == "No (for this session only)":
-            value = not bool(on)
-        
-        self._temp_configuration.dbDefault = value
-
-    def use_cache_changed(self, on):
-        """ use_cache_changed(on: int) -> None
-
-        """
-        if self._use_cache_always.isChecked() == True:
-            value = True
-            self._use_cache_cb.setText("No (for this session only)")
-            self._use_cache_cb.setChecked(False)
-        else:
-            value = False
-            self._use_cache_cb.setText("Yes (for this session only)")
-            self._use_cache_cb.setChecked(False)
-            
-        self._configuration.useCache = value
-        self._temp_configuration.useCache = value
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
-        
-    def temp_use_cache_changed(self, on):
-        """ temp_use_cache_changed(on: int) -> None
+        if button is not None:
+            layout.addWidget(button)
+        self.setLayout(layout)
 
-        """
-        debug.log("temp_use_cache_changed")
-        value = bool(on)
-        if self._use_cache_cb.text() == "No (for this session only)":
-            value = not bool(on)
-        
-        self._temp_configuration.useCache = value
+        self.line_edit.editingFinished.connect(self.value_changed)
+
+    def add_button(self, button):
+        self.layout().addWidget(button)
+
+    def value_changed(self):
+        QConfigurationWidgetItem.value_changed(self, self.line_edit.text())
+
+    def set_value(self, value, signal=True):
+        if value is None:
+            value = ""
+        if not signal:
+            self.line_edit.editingFinished.disconnect(self.value_changed)
+        self.line_edit.setText(unicode(value))
+        if not signal:
+            self.line_edit.editingFinished.connect(self.value_changed)
+
+class QConfigurationPathEdit(QConfigurationLineEditButton):
+    def __init__(self, key, field, callback_f, 
+                 button_cls=QDirectoryChooserToolButton, parent=None):
+        QConfigurationLineEditButton.__init__(self, key, field, callback_f,
+                                              None, parent)
+        button = button_cls(self, self.line_edit)
+        self.add_button(button)
+
+class QConfigurationThumbnailCache(QConfigurationLineEditButton):
+    def __init__(self, key, field, callback_f, parent=None):
+        button = QtGui.QPushButton("Clear...")
+        button.setAutoDefault(False)
+        button.clicked.connect(self.clear_clicked)
+        QConfigurationLineEditButton.__init__(self, key, field, callback_f, 
+                                              button, parent)
+
+    def clear_clicked(self, checked=False):
+        thumbnail_dir = system.get_vistrails_directory("thumbs.cacheDir")
+        res = show_question('VisTrails',
+                            ("All files in %s will be removed. "
+                             "Are you sure? " % thumbnail_dir),
+                            buttons = [YES_BUTTON,NO_BUTTON],
+                            default = NO_BUTTON)
+        if res == YES_BUTTON:
+            ThumbnailCache.getInstance().clear()
 
-    def splash_changed(self, on):
-        """ splash_changed(on: int) -> None
+class QConfigurationLabelButton(QtGui.QWidget, QConfigurationWidgetItem):
+    def __init__(self, key, field, callback_f, label=None, button=None, 
+                 parent=None):
+        QtGui.QWidget.__init__(self, parent)
+        QConfigurationWidgetItem.__init__(self, key, field, callback_f)
 
-        """
-        self._configuration.showSplash = bool(on)
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
+        layout = QtGui.QHBoxLayout()
+        layout.setMargin(0)
+        layout.setSpacing(5)
 
-    def maximize_changed(self, on):
-        """ maximize_changed(on: int) -> None
+        if label is not None:
+            self.label = label
+            layout.addWidget(self.label)
 
-        """
-        self._configuration.maximizeWindows = bool(on)
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
+        if button is not None:
+            self.button = button
+            layout.addWidget(self.button)
+        self.setLayout(layout)
 
-    def multi_head_changed(self, on):
-        """ multi_head_changed(on: int) -> None
+    def add_button(self, button):
+        self.button = button
+        self.layout().addWidget(self.button)
 
-        """
-        self._configuration.multiHeads = bool(on)
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
+    def add_label(self, label):
+        self.label = label
+        self.layout().insertWidget(0, self.label)
 
-    def metalstyle_changed(self, on):
-        """ metalstyle_changed(on: int) -> None
-        
-        """
-        self._configuration.useMacBrushedMetalStyle = bool(on)
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
+    def set_value(self, value, signal=True):
+        # nothing to do here
+        pass
 
-class QThumbnailConfiguration(QtGui.QWidget):
-    """
-    QThumbnailConfiguration is a widget for showing a few thumbnail related 
-    preferences that can be set with widgets.
-
-    """
-    def __init__(self, parent, persistent_config, temp_config):
-        """
-        QThumbnailConfiguration(parent: QWidget, 
-        configuration_object: ConfigurationObject) -> None
+class QConfigurationLinuxHandler(QConfigurationLabelButton):
+    def __init__(self, key, field, callback_f, parent=None):
+        from vistrails.gui.application import linux_default_application_set
+        if linux_default_application_set():
+            label = QtGui.QLabel(".vt, .vtl handlers installed")
+            button = None
+        else:
+            label = QtGui.QLabel(".vt, .vtl handlers not installed")
+        button = QtGui.QPushButton("Install...")
+        button.setAutoDefault(False)
+        button.clicked.connect(self.install_clicked)
+        QConfigurationLabelButton.__init__(self, key, field, callback_f, 
+                                           label, button, parent)
+
+    def install_clicked(self, checked=False):
+        from vistrails.core.application import get_vistrails_application
+        app = get_vistrails_application()
+        if app.ask_update_default_application(False):
+            self.label.setText(".vt, .vtl handlers installed")
+
+class QConfigurationComboBox(QtGui.QComboBox, QConfigurationWidgetItem):
+    def __init__(self, key, field, callback_f, parent=None):
+        QtGui.QComboBox.__init__(self, parent)
+        QConfigurationWidgetItem.__init__(self, key, field, callback_f)
+
+        inv_remap = None
+        options = self.get_widget_options()
+        if "allowed_values" in options:
+            values = options["allowed_values"]
+            if "remap" in options:
+                remap = options["remap"]
+                inv_remap = dict((v, k) for (k, v) in remap.iteritems())
+                entries = [remap[v] for v in values]
+            else:
+                entries = values
+            for entry in entries:
+                self.addItem(entry)
+
+        self.currentIndexChanged[int].connect(self.value_changed)
+
+    def set_value(self, value, signal=True):
+        options = self.get_widget_options()
+        if not signal:
+            self.currentIndexChanged[int].disconnect(self.value_changed)
+        if value is not None and "allowed_values" in options:
+            if "remap" in options:
+                remap = options["remap"]
+                cur_text = remap[value]
+            else:
+                cur_text = value
+            self.setCurrentIndex(self.findText(cur_text))
+        else:
+            self.setCurrentIndex(-1)
+        if not signal:
+            self.currentIndexChanged[int].connect(self.value_changed)
 
-        """
+class QConfigurationPane(QtGui.QWidget):
+    def __init__(self, parent, persistent_config, temp_config, cat_fields):
         QtGui.QWidget.__init__(self, parent)
-        self._configuration = None
-        self._temp_configuration = None
-        self._cache = ThumbnailCache.getInstance()
-        self.create_widgets()
-        self.update_state(persistent_config, temp_config)
-        self.connect_signals()
-    
-    def create_widgets(self):
-        """create_widgets()-> None
-        Creates widgets
-        
-        """
-        layout = QtGui.QVBoxLayout()
+        layout = QtGui.QFormLayout()
         layout.setMargin(10)
-        layout.setSpacing(10)
+        layout.setSpacing(4)
         self.setLayout(layout)
-        
-        #Auto save
-        autosave_gb = QtGui.QGroupBox(self)
-        autosave_gb.setTitle('Automatically save thumbnails in .vt files')
-        glayout = QtGui.QHBoxLayout()
-        self._autosave_always = QtGui.QRadioButton("Always")
-        self._autosave_never = QtGui.QRadioButton("Never")
-        self._autosave_cb = QtGui.QCheckBox("Yes (for this session only)")
-        glayout.addWidget(self._autosave_always)
-        glayout.addWidget(self._autosave_never)
-        glayout.addWidget(self._autosave_cb)
-        autosave_gb.setLayout(glayout)
-        layout.addWidget(autosave_gb)
-        
-        #Thumbnails for tagged versions only
-        tagsonly_gb = QtGui.QGroupBox(self)
-        tagsonly_gb.setTitle('Keep thumbnails of tagged versions only')
-        glayout = QtGui.QHBoxLayout()
-        self._tagsonly_always = QtGui.QRadioButton("Always")
-        self._tagsonly_never = QtGui.QRadioButton("Never")
-        self._tagsonly_cb = QtGui.QCheckBox("Yes (for this session only)")
-        glayout.addWidget(self._tagsonly_always)
-        glayout.addWidget(self._tagsonly_never)
-        glayout.addWidget(self._tagsonly_cb)
-        tagsonly_gb.setLayout(glayout)
-        layout.addWidget(tagsonly_gb)
-        
-        #Show thumbnails on mouser hover events
-        mouse_hover_gb = QtGui.QGroupBox(self)
-        mouse_hover_gb.setTitle('Show thumbnails as tooltips on mouse \
-hovering tree nodes')
-        glayout = QtGui.QHBoxLayout()
-        self._mouse_hover_always = QtGui.QRadioButton("Always")
-        self._mouse_hover_never = QtGui.QRadioButton("Never")
-        self._mouse_hover_cb = QtGui.QCheckBox("Yes (for this session only)")
-        glayout.addWidget(self._mouse_hover_always)
-        glayout.addWidget(self._mouse_hover_never)
-        glayout.addWidget(self._mouse_hover_cb)
-        mouse_hover_gb.setLayout(glayout)
-        layout.addWidget(mouse_hover_gb)
-        
-        hlayout = QtGui.QHBoxLayout()
-        cache_label = QtGui.QLabel(self)
-        cache_label.setText('Limit thumbnail cache size to ')
-        
-        self._thumbs_cache_sb = QtGui.QSpinBox(self)
-        self._thumbs_cache_sb.setRange(10,128)
-        self._thumbs_cache_sb.setValue(10)
-        self._thumbs_cache_sb.setSuffix('MB')
-        self._thumbs_cache_sb.stepBy(5)
-        
-        self._clear_thumbs_cache_btn = QtGui.QPushButton(self)
-        self._clear_thumbs_cache_btn.setText("Clear Cache")
-        
-        hlayout.addWidget(cache_label)
-        hlayout.addWidget(self._thumbs_cache_sb)
-        hlayout.addWidget(self._clear_thumbs_cache_btn)
-        layout.addLayout(hlayout)
-        
-        hlayout = QtGui.QHBoxLayout()
-        cache_label2 = QtGui.QLabel(self)
-        cache_label2.setText("Cache Directory:")
-        self._thumbs_cache_directory_edt = QtGui.QLineEdit(self)
-        self._thumbs_cache_directory_btn = QtGui.QPushButton("...", self)
-        hlayout.addWidget(cache_label2)
-        hlayout.addWidget(self._thumbs_cache_directory_edt)
-        hlayout.addWidget(self._thumbs_cache_directory_btn)
-        layout.addLayout(hlayout)
-        layout.addStretch()
-
-    def connect_signals(self):
-        # We need to connect only one of the radio buttons signal because
-        # only one of them will be checked at a time
-        
-        #Auto save signals
-        self.connect(self._autosave_always,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.autosave_changed)
-        self.connect(self._autosave_cb,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.temp_autosave_changed)
-        
-        #Thumbnails for tagged versions only signals
-        self.connect(self._tagsonly_always,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.tagsonly_changed)
-        self.connect(self._tagsonly_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.temp_tagsonly_changed)
-        
-        #Show thumbnails on mouser hover events signals
-        self.connect(self._mouse_hover_always,
-                     QtCore.SIGNAL('toggled(bool)'),
-                     self.mouse_hover_changed)
-        self.connect(self._mouse_hover_cb,
-                     QtCore.SIGNAL('stateChanged(int)'),
-                     self.temp_mouse_hover_changed)
-        
-        #Other widget signals
-        self.connect(self._thumbs_cache_sb,
-                     QtCore.SIGNAL('valueChanged(int)'),
-                     self.thumbs_cache_changed)
-        self.connect(self._clear_thumbs_cache_btn,
-                     QtCore.SIGNAL('clicked()'),
-                     self.clear_thumbs_cache_pressed)
-        self.connect(self._thumbs_cache_directory_edt,
-                     QtCore.SIGNAL('editingFinished()'),
-                     self.thumbs_cache_directory_changed)
-        self.connect(self._thumbs_cache_directory_btn,
-                     QtCore.SIGNAL('clicked()'),
-                     self.show_directory_chooser)
-        
-    def update_state(self, persistent_config, temp_config):
-        """ update_state(persistent_config, temp_config: VistrailConfiguration) 
-                                     -> None
-        Update the dialog state based on a new configuration
-        
-        """
         self._configuration = persistent_config
         self._temp_configuration = temp_config
-        #Auto save
-        if self._configuration.has('thumbs'):
-            if self._configuration.thumbs.has('autoSave'):
-                if self._configuration.autosave == True:
-                    self._autosave_always.setChecked(True)
-                    self._autosave_never.setChecked(False)
-                    self._autosave_cb.setText("No (for this session only)")
-                    self._autosave_cb.setChecked(
-                                not self._temp_configuration.thumbs.autoSave)
-                    
-                else:
-                    self._autosave_always.setChecked(False)
-                    self._autosave_never.setChecked(True)
-                    self._autosave_cb.setText("Yes (for this session only)")        
-                    self._autosave_cb.setChecked(
-                                self._temp_configuration.thumbs.autoSave)
-            #Thumbnails for tagged versions only    
-            if self._configuration.thumbs.has('tagsOnly'):
-                if self._configuration.thumbs.tagsOnly == True:
-                    self._tagsonly_always.setChecked(True)
-                    self._tagsonly_never.setChecked(False)
-                    self._tagsonly_cb.setText("No (for this session only)")
-                    self._tagsonly_cb.setChecked(
-                                not self._temp_configuration.thumbs.tagsOnly)
-                    
-                else:
-                    self._tagsonly_always.setChecked(False)
-                    self._tagsonly_never.setChecked(True)
-                    self._tagsonly_cb.setText("Yes (for this session only)")        
-                    self._tagsonly_cb.setChecked(
-                                    self._temp_configuration.thumbs.tagsOnly)
-            #Show thumbnails on mouser hover events
-            if self._configuration.thumbs.has('mouseHover'):
-                if self._configuration.thumbs.mouseHover == True:
-                    self._mouse_hover_always.setChecked(True)
-                    self._mouse_hover_never.setChecked(False)
-                    self._mouse_hover_cb.setText("No (for this session only)")
-                    self._mouse_hover_cb.setChecked(
-                                not self._temp_configuration.thumbs.mouseHover)
-                    
+
+        self._fields = {}
+        self._field_layouts = {}
+
+        for category, fields in cat_fields:
+            self.process_fields(layout, fields, category)
+            spacer_widget = QtGui.QWidget()
+            spacer_layout = QtGui.QVBoxLayout()
+            spacer_layout.setMargin(0)
+            spacer_layout.addSpacing(15)
+            spacer_widget.setLayout(spacer_layout)
+            layout.addRow("", spacer_widget)
+
+    def process_fields(self, layout, fields, category, parent_fields=[], 
+                       prev_field=None, prefix=""):
+        for field in fields:
+            if isinstance(field, ConfigFieldParent):
+                self.process_fields(layout, field.sub_fields, category,
+                                    parent_fields, prev_field,
+                                    prefix="%s%s." % (prefix, field.name))
+            else:
+                if field.depends_on is not None:
+                    if field.depends_on not in parent_fields:
+                        if field.depends_on == prev_field:
+                            parent_fields.append(prev_field)
+                        else:
+                            raise Exception("Dependent field %s should "
+                                            "follow parent." % field.name)
+                    parent_idx = parent_fields.index(field.depends_on)
+                    parent_fields = parent_fields[:parent_idx+1]
+                    indent = 4 * len(parent_fields)
                 else:
-                    self._mouse_hover_always.setChecked(False)
-                    self._mouse_hover_never.setChecked(True)
-                    self._mouse_hover_cb.setText("Yes (for this session only)")        
-                    self._mouse_hover_cb.setChecked(
-                                self._temp_configuration.thumbs.mouseHover)
-            # Other widgets
-            if self._configuration.thumbs.has('cacheSize'):
-                self._thumbs_cache_sb.setValue(
-                    self._configuration.thumbs.cacheSize)
-            if self._configuration.thumbs.has('cacheDirectory'):
-                self._thumbs_cache_directory_edt.setText(
-                    self._configuration.thumbs.cacheDirectory)
-                
-    def autosave_changed(self, on):
-        """ autosave_changed(on: bool) -> None
-        
-        """
-        debug.log("thumbs_auto_save_changed")
-        if self._autosave_always.isChecked() == True:
-            value = True
-            self._autosave_cb.setText("No (for this session only)")
-            self._autosave_cb.setChecked(False)
+                    parent_fields = []
+                    indent = 0
+                self.add_field(layout, field, category, prefix=prefix, 
+                               indent=indent)
+                prev_field = field.name
+                category = ""
+
+    def add_field(self, base_layout, field, category="", startup_only=False,
+                  prefix="", indent=0):
+        label_widget = QtGui.QWidget()
+        label_layout = QtGui.QHBoxLayout()
+        label_layout.setMargin(0)
+        label_layout.setSpacing(5)
+        label_widget.setLayout(label_layout)
+
+        config_key = "%s%s" % (prefix, field.name)
+        if self._temp_configuration.is_unset(config_key):
+            config_val = None
         else:
-            value = False
-            self._autosave_cb.setText("Yes (for this session only)")
-            self._autosave_cb.setChecked(False)
-            
-        self._configuration.thumbs.autoSave = value
-        self._temp_configuration.thumbs.autoSave = value
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
-        
-    def temp_autosave_changed(self, on):
-        """ temp_autosave_changed(on: int) -> None
-        
-        """
-        debug.log("thumbs_temp_auto_save_changed")
-        value = bool(on)
-        if self._autosave_cb.text() == "No (for this session only)":
-            value = not bool(on)
-        
-        self._temp_configuration.thumbs.autoSave = value
-
-    def tagsonly_changed(self, on):
-        """ tagsonly_changed(on: bool) -> None
-        
-        """
-        debug.log("thumbs_tagsonly_changed")
-        if self._tagsonly_always.isChecked() == True:
-            value = True
-            self._tagsonly_cb.setText("No (for this session only)")
-            self._tagsonly_cb.setChecked(False)
+            config_val = self._temp_configuration.get_deep_value(config_key)
+        if self._configuration.is_unset(config_key):
+            perm_config_val = None
         else:
-            value = False
-            self._tagsonly_cb.setText("Yes (for this session only)")
-            self._tagsonly_cb.setChecked(False)
+            perm_config_val = self._configuration.get_deep_value(config_key)
+
+        icon = self.style().standardIcon(QtGui.QStyle.SP_MessageBoxWarning)
+        label = QtGui.QLabel()
+        label.setPixmap(icon.pixmap(14,14))
+        label.setToolTip("This option has been changed for this session")
+        label_layout.addWidget(label, 0, QtCore.Qt.AlignCenter)
             
-        self._configuration.thumbs.tagsOnly = value
-        self._temp_configuration.thumbs.tagsOnly = value
-        
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
-        
-    def temp_tagsonly_changed(self, on):
-        """ temp_tagsonly_changed(on: int) -> None
-        
-        """
-        debug.log("thumbs_temp_tagsonly_changed")
-        value = bool(on)
-        if self._tagsonly_cb.text() == "No (for this session only)":
-            value = not bool(on)
-        
-        self._temp_configuration.thumbs.tagsOnly = value
-        
-    def mouse_hover_changed(self, on):
-        """ mouse_hover_changed(on: bool) -> None
-        
-        """
-        debug.log("thumbs_mouse_hover_changed")
-        if self._mouse_hover_always.isChecked() == True:
-            value = True
-            self._mouse_hover_cb.setText("No (for this session only)")
-            self._mouse_hover_cb.setChecked(False)
+        space = 0
+        if not startup_only and config_val == perm_config_val:
+            space = (label.sizeHint().width() +
+                     label_layout.spacing() * (indent + 1))
+            label.hide()
+        elif indent > 0:
+            space = label_layout.spacing() * indent
+
+        if space > 0:
+            spacer = QtGui.QSpacerItem(space, label.sizeHint().height())
+            label_layout.insertSpacerItem(0, spacer)
+
+        config_desc = find_simpledoc(config_key)
+        widget_type = field.widget_type
+        if widget_type is None:
+            if field.val_type == bool:
+                widget_type = "checkbox"
+            elif field.val_type == ConfigPath:
+                widget_type = "pathedit"
+            else:
+                widget_type = "lineedit"
+
+        if widget_type == "combo":
+            widget = QConfigurationComboBox(config_key, field,
+                                            self.field_changed)
+        elif widget_type == "lineedit":
+            widget = QConfigurationLineEdit(config_key, field,
+                                            self.field_changed)
+        elif widget_type == "pathedit":
+            widget = QConfigurationPathEdit(config_key, field,
+                                            self.field_changed)
+        elif widget_type == "thumbnailcache":
+            widget = QConfigurationThumbnailCache(config_key, field,
+                                                  self.field_changed)
+        elif widget_type == "linuxext":
+            widget = QConfigurationLinuxHandler(config_key, field,
+                                                self.field_changed)
         else:
-            value = False
-            self._mouse_hover_cb.setText("Yes (for this session only)")
-            self._mouse_hover_cb.setChecked(False)
-            
-        self._configuration.thumbs.mouseHover = value
-        self._temp_configuration.thumbs.mouseHover = value
-        
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, bool(on))
-        
-    def temp_mouse_hover_changed(self, on):
-        """ temp_mouse_hover_changed(on: int) -> None
-        
-        """
-        debug.log("thumbs_temp_mouse_hover_changed")
-        value = bool(on)
-        if self._mouse_hover_cb.text() == "No (for this session only)":
-            value = not bool(on)
-        
-        self._temp_configuration.thumbs.mouseHover = value
-        
-    def thumbs_cache_changed(self, v):
-        """ thumbs_cache_changed(v: int) -> None
-        
-        """
-        self._configuration.thumbs.cacheSize = v
-        self._temp_configuration.thumbs.cacheSize = v
-        self.emit(QtCore.SIGNAL('configuration_changed'),
-                  None, v)
-        
+            config_val = bool(config_val)
+            widget = QConfigurationCheckBox(config_key, field,
+                                            self.field_changed)
+        widget.set_value(config_val, False)
+
+        label_text = widget.get_label_text()
+        if not label_text and category:
+            label_text = category
+        if label_text:
+            label = QtGui.QLabel(label_text + ":")
+            label_layout.addWidget(label)
+
+        base_layout.addRow(label_widget, widget)
+        self._field_layouts[config_key] = (base_layout, base_layout.rowCount())
+
+    def field_changed(self, widget, config_key, field, val):
+        config_val = self._configuration.get_deep_value(config_key)
+        if config_val != self._temp_configuration.get_deep_value(config_key):
+            retval = QtGui.QMessageBox.question(
+                self, 
+                "Change Setting",
+                "This configuration value has been temporarily changed. "
+                "If you change it, it will be changed permanently.  Do you "
+                "want to continue?", 
+                QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Ok,
+                QtGui.QMessageBox.Ok)
+            if retval != QtGui.QMessageBox.Ok:
+                # revert widget's value
+                widget.set_value(self._temp_configuration.get_deep_value(
+                    config_key))
+                return
+            # need to update hbox to reflect change...
+            form_layout, row = self._field_layouts[config_key]
+            label_layout = form_layout.itemAt(row, QtGui.QFormLayout.LabelRole).widget().layout()
+            leading_item = label_layout.itemAt(0)
+            if isinstance(leading_item.widget(), QtGui.QLabel):
+                label = leading_item.widget()
+                spacer = QtGui.QSpacerItem(label.sizeHint().width() + \
+                                           label_layout.spacing(),
+                                           label.sizeHint().height())
+                label_layout.insertSpacerItem(0, spacer)
+            else:
+                spacer = leading_item
+                label = label_layout.itemAt(1).widget()
+                spacer.changeSize((spacer.sizeHint().width() +
+                                   label.sizeHint().width() +
+                                   label_layout.spacing()),
+                                  label.sizeHint().height())
+            label.hide()
+        # FIXME
+        if False:
+            QtGui.QMessageBox.information(
+                self, "Change Setting",
+                "You must restart VisTrails for this setting to take effect.")
+
+        setattr(self._temp_configuration, config_key, val)
+        setattr(self._configuration, config_key, val)
+
+# TODO: Make sure this functionality (Move and Clear Cache) is preserved
+
+class QThumbnailConfiguration(QtGui.QWidget):
     def thumbs_cache_directory_changed(self):
         """ thumbs_cache_changed(v: int) -> None
         
@@ -949,31 +649,4 @@ hovering tree nodes')
         else:
             show_warning('VisTrails', 'The directory specified does not exist.')
             self._thumbs_cache_directory_edt.setText(old_folder)
-            
-    def show_directory_chooser(self):
-        """show_directory_chooser() -> None
-        Shows a dialog for choosing a directory 
-        
-        """
-        dir = QtGui.QFileDialog.getExistingDirectory(
-                  self,
-                  "Choose a new directory for storing thumbnail chache files",
-                  "",
-                  QtGui.QFileDialog.ShowDirsOnly)
-        if dir:
-            self._thumbs_cache_directory_edt.setText(dir)
-            self.thumbs_cache_directory_changed()
-            
-    def clear_thumbs_cache_pressed(self):
-        """clear_thumbs_cache_pressed() -> None
-        Will delete all files in thumbs.cacheDirectory if user clicks yes
-        
-        """
-        res = show_question('VisTrails',
-                  "All files in %s will be removed. Are you sure? " % (
-                            self._temp_configuration.thumbs.cacheDirectory),
-                  buttons = [YES_BUTTON,NO_BUTTON],
-                  default = NO_BUTTON)
-        if res == YES_BUTTON:
-            self._cache.clear()
- 
+
diff --git a/vistrails/gui/controlflow_assist.py b/vistrails/gui/controlflow_assist.py
index 4662d2d..0d3e27d 100644
--- a/vistrails/gui/controlflow_assist.py
+++ b/vistrails/gui/controlflow_assist.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 
 QControlFlowAssistDialog
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core import debug
@@ -159,13 +162,14 @@ class QControlFlowAssistDialog(QtGui.QDialog):
         
         # Create and connect InputPort for each of the inputs to force it to exist on group
         offset = {}
-        [offset.__setitem__(module, halfwidth+65) for module, portspec, connections, halfwidth in input_ports_info]
+        for module, portspec, connections, halfwidth in input_ports_info:
+            offset.__setitem__(module, halfwidth+65)
         for input_module, input_portspec, input_connections, halfwidth in input_ports_info:
             # Remove function calls to selected input ports
             try:
                 function_pos = [f.name for f in input_module.functions].index(input_portspec.name)
                 self.controller.delete_method(function_pos, input_module.id)
-            except:
+            except Exception:
                 pass
             # Disconnect connections to selected input ports
             for connection in input_connections:
@@ -243,13 +247,13 @@ psrc_module = self.moduleInfo['pipeline'].modules[self.moduleInfo['moduleId']]
 input_ports = [p.name for p in psrc_module.input_port_specs if p.name not in ['UseCartesianProduct', 'UserDefinedInputList']]
 InputPort = input_ports
 OutputPort = '%s'
-custom_input_list = self.forceGetInputFromPort('UserDefinedInputList', [])
+custom_input_list = self.force_get_input('UserDefinedInputList', [])
 if custom_input_list:
     InputList = custom_input_list
 else:
-    cartesian_product = self.forceGetInputFromPort('UseCartesianProduct', False)
+    cartesian_product = self.force_get_input('UseCartesianProduct', False)
     if cartesian_product:
-        input_lists = [self.getInputFromPort(input_ports[x]) for x in xrange(len(input_ports))]
+        input_lists = [self.get_input(input_ports[x]) for x in xrange(len(input_ports))]
         InputList = [[]]
         pools = map(tuple, input_lists)
         for pool in pools:
@@ -257,15 +261,15 @@ else:
     else:
         # Dot Product
         InputList = []
-        length = len(self.getInputFromPort(input_ports[0]))
+        length = len(self.get_input(input_ports[0]))
         if len(input_ports) > 1:
             for p in input_ports[1:]:
-                if len(self.getInputFromPort(p)) != length:
+                if len(self.get_input(p)) != length:
                     fail('One or more of the input lists have different lengths.')
         for x in xrange(length):
             element_list = []
             for p in input_ports:
-                element_list.append(self.getInputFromPort(p)[x])
+                element_list.append(self.get_input(p)[x])
             InputList.append(element_list)
     # Compact list format used when only one input port present
     if len(input_ports) == 1:
diff --git a/vistrails/gui/debug.py b/vistrails/gui/debug.py
index cc67d13..c731172 100644
--- a/vistrails/gui/debug.py
+++ b/vistrails/gui/debug.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import cgi
 import logging
 from PyQt4 import QtCore, QtGui
@@ -55,17 +58,6 @@ class DebugView(QtGui.QWidget, QVistrailsPaletteInterface):
            import gui.debug
            gui.debug.watch_signal(my_signal)
      """
-    #Singleton technique
-    # _instance = None
-    # class DebugViewSingleton():
-    #     def __call__(self, *args, **kw):
-    #         if DebugView._instance is None:
-    #             obj = DebugView(*args, **kw)
-    #             DebugView._instance = obj
-    #         return DebugView._instance
-        
-    # getInstance = DebugViewSingleton()
-
     def __init__(self, parent=None):
         QtGui.QWidget.__init__(self, parent)
         ui = logging.StreamHandler(debugStream(self.write))
@@ -298,7 +290,7 @@ class DebugView(QtGui.QWidget, QVistrailsPaletteInterface):
         item.setForeground(CurrentTheme.DEBUG_COLORS[msgs[0]])
         self.list.setItemHidden(item, not self.levels[msgs[0]].isChecked())
         alwaysShowDebugPopup = getattr(get_vistrails_configuration(),
-                                       'alwaysShowDebugPopup',
+                                       'showDebugPopups',
                                        False)
         if msgs[0] == 'CRITICAL':
             if self.isVisible() and not alwaysShowDebugPopup:
diff --git a/vistrails/gui/debugger.py b/vistrails/gui/debugger.py
index 00d4a98..ae542c5 100644
--- a/vistrails/gui/debugger.py
+++ b/vistrails/gui/debugger.py
@@ -1,38 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
+from vistrails.core.modules.vistrails_module import ModuleError
 import vistrails.core.system
 import copy
 import sys
@@ -85,24 +89,28 @@ class QDebugger(QtGui.QWidget, QVistrailsPaletteInterface):
         Update the debugger.  If the update requires querying modules for input
         changes, update_vals should be set to True
         """
-        pipeline = self.controller.current_pipeline
-        if pipeline is None:
-            return
-
         self.inspector.clear_modules()
-        for module in pipeline.module_list:
-            if module.is_breakpoint or module.is_watched:
-                self.inspector.add_module(module)
-        if update_vals:
-            (module_objects, _, _) = \
-                self.vistrails_interpreter.find_persistent_entities(pipeline)
-            for m_id in self.inspector.modules:
-                if m_id in module_objects and module_objects[m_id] is not None:
-                    self.inspector.update_values(m_id, module_objects[m_id])
-                elif module_objects[m_id] is None:
-                    edges = pipeline.graph.edges_to(m_id)
-                    self.inspector.update_inputs(m_id, module_objects, edges,
-                                                  pipeline.connections)
+        if self.controller is not None:
+            pipeline = self.controller.current_pipeline
+            if pipeline is None:
+                return
+
+            for module in pipeline.module_list:
+                if module.is_breakpoint or module.is_watched:
+                    self.inspector.add_module(module)
+            if update_vals:
+                (module_objects, _, _) = \
+                    self.vistrails_interpreter.find_persistent_entities(
+                        pipeline)
+                for m_id in self.inspector.modules:
+                    if (m_id in module_objects and 
+                            module_objects[m_id] is not None):
+                        self.inspector.update_values(m_id, module_objects[m_id])
+                    elif module_objects[m_id] is None:
+                        edges = pipeline.graph.edges_to(m_id)
+                        self.inspector.update_inputs(m_id, module_objects, 
+                                                     edges,
+                                                      pipeline.connections)
 
     def closeEvent(self, e):
         """closeEvent(e) -> None
@@ -199,7 +207,7 @@ class QObjectInspector(QtGui.QTreeWidget):
         if display_vals:
             p_item.setText(1, str(port_value))
         else:
-            typestr = str(port_val.__class__)
+            typestr = str(port_value.__class__)
             typestr = typestr.split('.')
             typestr = typestr[len(typestr)-1]
             typestr = typestr[0:len(typestr)-2]
@@ -216,7 +224,7 @@ class QObjectInspector(QtGui.QTreeWidget):
         inputs_item.setText(1, "")
         for port_name in m.inputPorts:
             try:
-                port_val = m.getInputListFromPort(port_name)
+                port_val = m.get_input_list(port_name)
                 if len(port_val) == 1:
                     port_val = port_val[0]
             except ModuleError:
diff --git a/vistrails/gui/extras/__init__.py b/vistrails/gui/extras/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/gui/extras/__init__.py
+++ b/vistrails/gui/extras/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/gui/extras/core/__init__.py b/vistrails/gui/extras/core/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/gui/extras/core/__init__.py
+++ b/vistrails/gui/extras/core/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/gui/extras/core/db/__init__.py b/vistrails/gui/extras/core/db/__init__.py
index acfc9d2..5474457 100644
--- a/vistrails/gui/extras/core/db/__init__.py
+++ b/vistrails/gui/extras/core/db/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
\ No newline at end of file
diff --git a/vistrails/gui/extras/core/db/locator.py b/vistrails/gui/extras/core/db/locator.py
index 8413fd7..d3d0cc1 100644
--- a/vistrails/gui/extras/core/db/locator.py
+++ b/vistrails/gui/extras/core/db/locator.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.configuration import get_vistrails_persistent_configuration, \
     get_vistrails_configuration
 from vistrails.gui.open_db_window import QOpenDBWindow, QConnectionDBSetupWindow
@@ -96,7 +99,7 @@ def get_db_connection_from_gui(parent, id, name, host, port, user, passwd,
                 config['name'] = str(dialog.nameEdt.text())
                 config['id'] = dialog.id
             except VistrailsDBException, e:
-                debug.critical('VisTrails DB Exception',  str(e))
+                debug.critical('VisTrails DB Exception',  e)
                 config['succeeded'] = False
         return config
     #check if the information is already there
@@ -147,8 +150,8 @@ def get_load_file_locator_from_gui(parent, obj_type):
         return None
     filename = os.path.abspath(str(QtCore.QFile.encodeName(fileName)))
     dirName = os.path.dirname(filename)
-    setattr(get_vistrails_persistent_configuration(), 'fileDirectory', dirName)
-    setattr(get_vistrails_configuration(), 'fileDirectory', dirName)
+    setattr(get_vistrails_persistent_configuration(), 'fileDir', dirName)
+    setattr(get_vistrails_configuration(), 'fileDir', dirName)
     vistrails.core.system.set_vistrails_file_directory(dirName)
     return FileLocator(filename)
 
@@ -189,8 +192,8 @@ def get_save_file_locator_from_gui(parent, obj_type, locator=None):
         if msg.exec_() == QtGui.QMessageBox.No:
             return None
     dirName = os.path.dirname(f)
-    setattr(get_vistrails_persistent_configuration(), 'fileDirectory', dirName)
-    setattr(get_vistrails_configuration(), 'fileDirectory', dirName)
+    setattr(get_vistrails_persistent_configuration(), 'fileDir', dirName)
+    setattr(get_vistrails_configuration(), 'fileDir', dirName)
     vistrails.core.system.set_vistrails_file_directory(dirName)
     return FileLocator(f)
    
diff --git a/vistrails/gui/graphics_view.py b/vistrails/gui/graphics_view.py
index 39171f3..77251d7 100644
--- a/vistrails/gui/graphics_view.py
+++ b/vistrails/gui/graphics_view.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,6 +40,8 @@ QInteractiveGraphicsScene
 QInteractiveGraphicsView
 QPIPGraphicsView
 """
+from __future__ import division
+
 from vistrails.core import debug
 from PyQt4 import QtCore, QtGui
 from vistrails.gui.theme import CurrentTheme
@@ -93,7 +96,7 @@ class QInteractiveGraphicsScene(QtGui.QGraphicsScene):
         self.sceneBoundingRect = QtCore.QRectF()
         self.multiSelecting = False
         
-    def updateSceneBoundingRect(self, keep_square=True):
+    def updateSceneBoundingRect(self, keep_square=False):
         """ updateSceneBoundingRect() -> None        
         Compute the actual bounding rect of all shapes, then update
         the scene rect to be much wider for panning
@@ -213,7 +216,7 @@ class QInteractiveGraphicsScene(QtGui.QGraphicsScene):
             pixmap.save(filename)
             self.setBackgroundBrush(brush)
         except Exception, e:
-            debug.critical("Exception: %s"%str(e))
+            debug.critical("Exception saving to PNG", e)
 
 class QInteractiveGraphicsView(QtGui.QGraphicsView):
     """
@@ -234,8 +237,9 @@ class QInteractiveGraphicsView(QtGui.QGraphicsView):
         self.setRenderHints (QtGui.QPainter.Antialiasing |
                              QtGui.QPainter.TextAntialiasing |
                              QtGui.QPainter.SmoothPixmapTransform)
-        self.scaleMax = 1000
-        self.scaleRatio = self.scaleMax/5
+        self.scaleMax = 2000
+        self.scaleRatio = self.scaleMax/10
+        self.scaleOffset = 700
         self.currentScale = self.scaleMax/2
         self.startScroll = (0,0)
         self.lastPos = QtCore.QPoint(0,0)
@@ -273,6 +277,7 @@ class QInteractiveGraphicsView(QtGui.QGraphicsView):
                 changeFlags = pinch.changeFlags()
                 if changeFlags & QtGui.QPinchGesture.ScaleFactorChanged:
                     if self.gestureStartScale is None:
+                        self.computeScale()
                         self.gestureStartScale = self.currentScale
                     newScale = self.gestureStartScale + self.scaleMax * \
                         math.log(pinch.property("scaleFactor"))/2
@@ -405,13 +410,14 @@ class QInteractiveGraphicsView(QtGui.QGraphicsView):
                 # super(QInteractiveGraphicsView, self).mousePressEvent(e)
         else:
             if buttons & QtCore.Qt.RightButton:
+                self.computeScale()
                 if item is None:
                     self.setCursorState(2)
-                    self.computeScale()
                 else:
                     QtGui.QGraphicsView.mousePressEvent(self, e)
             elif buttons & QtCore.Qt.MidButton:
                 self.setCursorState(3)
+                self.computeScale()
                 self.startScroll = (self.horizontalScrollBar().value(),
                                     self.verticalScrollBar().value())
             self.lastPos = QtCore.QPoint(QtGui.QCursor.pos())
@@ -517,9 +523,10 @@ class QInteractiveGraphicsView(QtGui.QGraphicsView):
         """ updateMatrix() -> None
         Update the view matrix with the current scale
         
-        """        
+        """
         matrix = QtGui.QMatrix()
-        power = float(self.currentScale-self.scaleMax/2)/self.scaleRatio
+        power = float(self.currentScale - self.scaleMax/2 - self.scaleOffset
+                      )/self.scaleRatio
         scale = pow(2.0, power)
         matrix.scale(scale, scale)
         self.setMatrix(matrix)
@@ -530,7 +537,8 @@ class QInteractiveGraphicsView(QtGui.QGraphicsView):
         
         """
         self.currentScale = (math.log(self.matrix().m11(), 2.0)*
-                             self.scaleRatio + self.scaleMax/2)
+                             self.scaleRatio + self.scaleMax/2 +
+                             self.scaleOffset)
 
     def setPIPScene(self, scene):
         """ setPIPScene(scene: QGraphicsScene) -> None        
@@ -594,6 +602,7 @@ class QInteractiveGraphicsView(QtGui.QGraphicsView):
 
     def zoomToFit(self):
         self.scene().fitToView(self, True)
+        self.computeScale()
 
     def zoomIn(self):
         self.setUpdatesEnabled(False)
diff --git a/vistrails/gui/job_monitor.py b/vistrails/gui/job_monitor.py
index 5e61032..3dc450c 100644
--- a/vistrails/gui/job_monitor.py
+++ b/vistrails/gui/job_monitor.py
@@ -1,70 +1,109 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
+import time
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core import debug, configuration
-from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
+from vistrails.core.modules.vistrails_module import ModuleSuspended
 from vistrails.gui import theme
-from vistrails.core.db.locator import BaseLocator
 from vistrails.gui.common_widgets import QDockPushButton
+from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
+
 
 refresh_states = [('Off', 0), ('10 sec', 10),
                   ('1 min', 60), ('10 min', 600),
                   ('1 hour', 3600)]
 
+
 class QNumberValidator(QtGui.QIntValidator):
+    """Variant of QIntValidator that rejects Intermediate values.
+
+    Intermediate strings are strings that could be the left part of an
+    Acceptable string.
+    """
     def validate(self, input, pos):
         result = QtGui.QIntValidator.validate(self, input, pos)
         if len(input) and result[0] == QtGui.QIntValidator.Intermediate:
             return (QtGui.QIntValidator.Invalid, pos)
         return result
 
+
+class QJobTree(QtGui.QTreeWidget):
+    def __init__(self, parent=None):
+        QtGui.QTreeWidget.__init__(self, parent)
+        self.setContentsMargins(0, 0, 0, 0)
+        self.setColumnCount(2)
+        self.header().setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
+        self.header().setResizeMode(1, QtGui.QHeaderView.Stretch)
+        self.header().close()
+        self.setExpandsOnDoubleClick(False)
+        self.controller = None
+
+    def contextMenuEvent(self, event):
+        item = self.itemAt(event.pos())
+        menu = QtGui.QMenu(self)
+        if item and isinstance(item, QJobItem):
+            act = QtGui.QAction("View Standard &Output", self)
+            act.setStatusTip("View Standard Output in new window")
+            QtCore.QObject.connect(act,
+                                   QtCore.SIGNAL("triggered()"),
+                                   item.stdout)
+            menu.addAction(act)
+            act = QtGui.QAction("View Standard &Error", self)
+            QtCore.QObject.connect(act,
+                                   QtCore.SIGNAL("triggered()"),
+                                   item.stderr)
+            menu.addAction(act)
+            menu.exec_(event.globalPos())
+
 class QJobView(QtGui.QWidget, QVistrailsPaletteInterface):
     def __init__(self, parent=None):
         QtGui.QWidget.__init__(self, parent)
 
         self.timer_id = None
+        self.updating_now = False
+        self.widgets = {}
 
-        self.workflowItems = {}
         self.layout = QtGui.QVBoxLayout()
-#        self.layout.setContentsMargins(5, 5, 0, 0)
 
         buttonsLayout = QtGui.QHBoxLayout()
-        #buttonsLayout.setMargin(5)
-        #buttonsLayout.setSpacing(5)
         run_now = QDockPushButton("Check now")
         run_now.setToolTip("Check all jobs now")
         run_now.clicked.connect(self.timerEvent)
@@ -75,46 +114,67 @@ class QJobView(QtGui.QWidget, QVistrailsPaletteInterface):
         self.interval = QtGui.QComboBox()
         for text, seconds in refresh_states:
             self.interval.addItem(text, seconds)
-            self.interval.editTextChanged.connect(self.set_refresh)
-        self.interval.setEditable(True)
-        self.interval.setCurrentIndex(self.interval.findText('10 min'))
         self.interval.setCompleter(None)
+        self.interval.setEditable(True)
+        self.interval.editTextChanged.connect(self.set_refresh)
         self.interval.setValidator(QNumberValidator())
+        conf = configuration.get_vistrails_configuration()
+        self.interval.setEditText(str(conf.jobCheckInterval))
         buttonsLayout.addWidget(self.interval)
 
-        self.autorun = QtGui.QCheckBox("Run When Ready")
-        self.autorun.setToolTip("Automatically re-execute the workflow when jobs have completed")
+        self.autorun = QtGui.QCheckBox("Automatic re-execution")
+        self.autorun.setToolTip("Automatically re-execute workflow when jobs "
+                                "complete")
+        self.connect(self.autorun, QtCore.SIGNAL('toggled(bool)'),
+                     self.autorunToggled)
+        self.autorun.setChecked(conf.jobAutorun)
         buttonsLayout.addWidget(self.autorun)
 
-        self.rerun = QtGui.QCheckBox("Run To Check")
-        self.rerun.setToolTip("Automatically re-execute workflows that does not provide a status check method")
-        buttonsLayout.addWidget(self.rerun)
-
         buttonsLayout.addStretch(1)
         self.layout.addLayout(buttonsLayout)
 
-        self.jobView = QtGui.QTreeWidget()
-        self.jobView.setContentsMargins(0, 0, 0, 0)
-        self.jobView.setColumnCount(2)
-        self.jobView.setHeaderLabels(['Job', 'Message'])
-        self.jobView.header().setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
-        self.jobView.header().setResizeMode(1, QtGui.QHeaderView.Stretch)
-        self.jobView.setExpandsOnDoubleClick(False)
-        self.connect(self.jobView,
-                     QtCore.SIGNAL('itemDoubleClicked(QTreeWidgetItem *, int)'),
-                     self.item_selected)
+        self.jobView = QJobTree()
+        self.jobView.itemDoubleClicked.connect(self.item_clicked)
         self.layout.addWidget(self.jobView)
 
         self.setLayout(self.layout)
+
         self.setWindowTitle('Running Jobs')
         self.resize(QtCore.QSize(800, 600))
-        self.updating_now = False
 
+    def set_controller(self, controller):
+        # check if a controller has been closed
+        from vistrails.gui.vistrails_window import _app
+        controllers = [view.controller for view in _app.getAllViews()]
+        for c in self.widgets.keys():
+            if c not in controllers:
+                self.jobView.takeTopLevelItem(self.jobView.indexOfTopLevelItem(self.widgets[c]))
+                del self.widgets[c]
+
+        if not controller:
+            return
+
+        # check if controller has been added
+        if controller not in self.widgets and controller in controllers:
+            item = QVistrailItem(controller)
+            self.jobView.addTopLevelItem(item)
+            self.jobView.expandAll()
+            self.widgets[controller] = item
+            if item.childCount() > 0:
+                self.set_visible(True)
+
+    def autorunToggled(self, value):
+        conf = configuration.get_vistrails_configuration()
+        conf.jobAutorun = value
 
     def set_refresh(self, refresh=0):
+        """Changes the timer time.
+
+        Called when the QComboBox self.interval changes. Updates the
+        configuration and restarts the timer.
+        """
         self.updating_now = True
         refresh = str(refresh) if refresh else '0'
-        # changes the timer time
         if refresh in dict(refresh_states):
             refresh = dict(refresh_states)[refresh]
             self.interval.setEditText(str(refresh))
@@ -128,260 +188,419 @@ class QJobView(QtGui.QWidget, QVistrailsPaletteInterface):
             if self.timer_id:
                 self.killTimer(self.timer_id)
                 self.timer_id = None
+        conf = configuration.get_vistrails_persistent_configuration()
+        conf.jobCheckInterval = refresh
         self.updating_now = False
-                
+
     def update_jobs(self):
-        # check all jobs
-        for workflow in self.workflowItems.values():
-            # jobs without a queue can also be checked
-            if not workflow.has_queue:
-                if self.rerun.isChecked():
-                    workflow.execute()
-                continue
-            if workflow.workflowFinished:
-                continue
-            for job in workflow.jobs.itervalues():
-                if job.jobFinished:
-                    continue
-                try:
-                    # call queue
-                    job.jobFinished = job.queue.finished()
-                    # old version of BatchQ needs to call .val()
-                    if not isinstance(job.jobFinished, bool):
-                        job.jobFinished = job.jobFinished.val()
-                    if job.jobFinished:
-                        job.setText(1, "Finished")
-                except Exception, e:
-                    debug.critical("Error checking job %s: %s" %
-                                   (workflow.name, str(e)))
-                if job.jobFinished:
-                    job.setIcon(0, theme.get_current_theme().JOB_FINISHED)
-                workflow.countJobs()
-            workflow.workflowFinished = len(workflow.jobs) == \
-                         sum(j.jobFinished for j in workflow.jobs.itervalues())
-            if workflow.workflowFinished:
-                workflow.setIcon(0, theme.get_current_theme().JOB_FINISHED)
-                workflow.setText(1, "Finished")
-            workflow.countJobs()
-            if workflow.workflowFinished:
-                if self.autorun.isChecked():
+        """Called via a timer.
+
+        Checks jobs for all workflows both with and without monitors.
+        """
+        for i in xrange(self.jobView.topLevelItemCount()):
+            vistrail = self.jobView.topLevelItem(i)
+            jm = vistrail.jobMonitor
+            for workflow_item in vistrail.workflowItems.values():
+                workflow = workflow_item.workflow
+                # jobs without a handle can also be checked
+                if not workflow_item.has_handle:
+                    # restart job and execute
+                    jm.startWorkflow(workflow)
                     self.updating_now = False
-                    workflow.execute()
+                    workflow_item.execute()
                     self.updating_now = True
                     continue
-                ret = QtGui.QMessageBox.information(self, "Job Ready",
-                        'Pending Jobs in workflow "%s" have finished, '
-                        'continue execution now?' % workflow.name,
-                        QtGui.QMessageBox.Ok, QtGui.QMessageBox.Cancel)
-                if ret == QtGui.QMessageBox.Ok:
-                    self.updating_now = False
-                    workflow.execute()
-                    self.updating_now = True
+                if workflow_item.workflowFinished:
+                    continue
+                for job in workflow_item.jobs.itervalues():
+                    if job.jobFinished:
+                        continue
+                    try:
+                        # call monitor
+                        job.jobFinished = jm.isDone(job.handle)
+                        if job.jobFinished:
+                            job.setText(1, "Finished")
+                    except Exception, e:
+                        debug.critical("Error checking job %s: %s" %
+                                       (workflow_item.text(0), e))
+                workflow_item.updateJobs()
+                if workflow_item.workflowFinished:
+                    if self.autorun.isChecked():
+                        jm.startWorkflow(workflow)
+                        self.updating_now = False
+                        workflow_item.execute()
+                        self.updating_now = True
+                        continue
+                    ret = QtGui.QMessageBox.information(self, "Job Ready",
+                            'Pending Jobs in workflow "%s" have finished, '
+                            'continue execution now?' % workflow_item.text(0),
+                            QtGui.QMessageBox.Ok, QtGui.QMessageBox.Cancel)
+                    if ret == QtGui.QMessageBox.Ok:
+                        jm.startWorkflow(workflow)
+                        self.updating_now = False
+                        workflow_item.execute()
+                        self.updating_now = True
 
     def timerEvent(self, id=None):
         if self.updating_now:
             return
         self.updating_now = True
-        self.update_jobs()
-        self.updating_now = False
+        try:
+            self.update_jobs()
+        finally:
+            self.updating_now = False
 
     def keyPressEvent(self, event):
         if event.key() in [QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]:
-            items = self.jobView.selectedItems()
-            if len(items) == 1:
-                index = self.jobView.indexOfTopLevelItem(items[0])
-                if index>=0:
-                    self.delete_job(items[0].controller, items[0].version)
+            for item in self.jobView.selectedItems():
+                if isinstance(item, QWorkflowItem):
+                    item.parent().controller.set_changed(True)
+                    item.parent().jobMonitor.deleteWorkflow(item.workflow.id)
+                elif isinstance(item, QJobItem):
+                    # find parent
+                    parent = item.parent()
+                    while not isinstance(parent, QWorkflowItem):
+                        parent = parent.parent()
+                    parent.parent().controller.set_changed(True)
+                    parent.parent().jobMonitor.deleteJob(item.job.id)
         else:
             QtGui.QWidget.keyPressEvent(self, event)
 
-    def add_job(self, controller, error, prev='', workflow=None):
-        """ Adds job recursively """
-        added = False
-        if not prev:
-            if controller.vistrail.locator:
-                name = controller.vistrail.locator.short_name
-            else:
-                name = 'Untitled.vt'
-            version_id = controller.current_version
-            if (name, version_id) not in self.workflowItems:
-                workflow = QWorkflowItem(controller, error, self.jobView)
-                self.jobView.addTopLevelItem(workflow)
-                self.workflowItems[(name, version_id)] = workflow
-
-                # save job to configuration
-                if controller.vistrail.locator:
-                    conf = configuration.get_vistrails_configuration()
-                    if not conf.has('runningJobsList') or not conf.runningJobsList:
-                        conf_jobs = []
-                    else:
-                        conf_jobs = conf.runningJobsList.split(';')
-                    if not conf_jobs:
-                        conf_jobs = []
-                    url = controller.vistrail.locator.to_url()
-                    if '?' in url:
-                        url += '&workflow=%d' % version_id
-                    else:
-                        url += '?workflow=%d' % version_id
-                    if not url in conf_jobs:
-                        conf_jobs.append(str(url))
-                        conf.runningJobsList = ';'.join(conf_jobs)
-                        configuration.get_vistrails_persistent_configuration(
-                                      ).runningJobsList = conf.runningJobsList
-            else:
-                workflow = self.workflowItems[(name, version_id)]
-        job_name = ((prev+'.') if prev else '') + error.module.__class__.__name__
-
-        if not error.children:
-            if not error.queue:
-                # We allow jobs without queue objects, but they will
-                # have to be checked by re-executing the entire workflow
-                workflow.has_queue = False
-                workflow.setIcon(0, theme.get_current_theme().JOB_SCHEDULED)
-                workflow.setToolTip(0, 'To check this workflow it must be re-executed. Make sure "Run To Check" is checked.')
-
-                #return False
-            # remove any previous instance of this job, if name is shorter
-            if id(error) in workflow.jobs and \
-               len(job_name) > len(workflow.jobs[id(error)].text(0)):
-                workflow.takeChild(workflow.indexOfChild(
-                  workflow.jobs[id(error)]))
-                del workflow.jobs[id(error)]
-            # if we did not keep an already existing job, add it
-            if id(error) not in workflow.jobs:
-                job = QJobItem(job_name, error)
-                workflow.addChild(job)
-                workflow.jobs[id(error)] = job
-                workflow.countJobs()
-                return True
-        else:
-            for child in error.children:
-                result = self.add_job(controller, child, job_name, workflow)
-                if result:
-                    added = True
-        return added
-                        
-    def delete_job(self, controller, version_id=None, all=False):
-        if all:
-            for k in self.workflowItems.keys():
-                workflow = self.workflowItems[k]
-                if workflow.controller is controller:
-                    self.jobView.takeTopLevelItem(
-                        self.jobView.indexOfTopLevelItem(
-                            self.workflowItems[k]))
-                    del self.workflowItems[k]
-            return
-        if not version_id:
-            version_id = controller.current_version
-        if controller.locator:
-            conf = configuration.get_vistrails_configuration()
-            if not conf.has('runningJobsList') or not conf.runningJobsList:
-                conf_jobs = []
-            else:
-                conf_jobs = conf.runningJobsList.split(';')
-            if not conf_jobs:
-                conf_jobs = []
-            url = controller.locator.to_url()
-            if '?' in url:
-                url += '&workflow=%s' % version_id
-            else:
-                url += '?workflow=%s' % version_id
-            if url in conf_jobs:
-                conf_jobs.remove(url)
-                conf.runningJobsList = ';'.join(conf_jobs)
-                configuration.get_vistrails_persistent_configuration(
-                    ).runningJobsList = conf.runningJobsList
-            name = controller.vistrail.locator.short_name
-        else:
-            name = 'Untitled.vt'
-        if (name, version_id) in self.workflowItems:
-            self.jobView.takeTopLevelItem(
-                self.jobView.indexOfTopLevelItem(
-                    self.workflowItems[(name, version_id)]))
-            del self.workflowItems[(name, version_id)]
-
-    def item_selected(self, item):
+    def item_clicked(self, item):
+        """Item activated.
+        """
         if isinstance(item, QWorkflowItem):
             item.goto()
 
+
+class QVistrailItem(QtGui.QTreeWidgetItem):
+    """A vistrail with running workflows.
+
+    This top-level item can have QWorkflowItem's as children.
+    """
+    def __init__(self, controller, parent=None):
+        self.controller = controller
+        self.jobMonitor = controller.jobMonitor
+        self.jobMonitor.setCallback(self)
+        self.locator = controller.vistrail.locator
+        QtGui.QTreeWidgetItem.__init__(self, parent,
+                                       [self.locator.short_name, ''])
+        self.setIcon(0, theme.get_current_theme().HISTORY_ICON)
+        self.setToolTip(0, self.locator.to_url())
+        self.workflowItems = {}
+        self.load_running_jobs()
+
     def load_running_jobs(self):
+        """Loads the current jobs from the JSON file.
+        """
+        workflows = self.jobMonitor.workflows
+        # update gui
+        for workflow in workflows.itervalues():
+            if workflow.id not in self.workflowItems:
+                workflow_item = QWorkflowItem(workflow, self)
+                self.workflowItems[workflow.id] = workflow_item
+                for job in workflow.jobs.itervalues():
+                    if job.id not in workflow_item.jobs:
+                        workflow_item.jobs[job.id] = QJobItem(job, workflow_item)
+                        workflow_item.updateJobs()
+
+    def startWorkflow(self, workflow):
+        """Empty callback.
+        """
+
+    def addJob(self, job):
+        """ addJob(self, job: job.Module) -> None
+        Callback, adds or updates a job in the interface.
+        """
+
+        workflow = self.jobMonitor.currentWorkflow()
+        if workflow.id not in self.workflowItems:
+            workflow_item = QWorkflowItem(workflow, self)
+            workflow_item.setExpanded(True)
+            self.workflowItems[workflow.id] = workflow_item
+
+        workflow_item = self.workflowItems[workflow.id]
+        if job.id not in workflow_item.jobs:
+            workflow_item.jobs[job.id] = QJobItem(job, workflow_item)
+        workflow_item.updateJobs()
+
+    def deleteWorkflow(self, id):
+        """ deleteWorkflow(id: str) -> None
+        Callback, deletes a workflow.
+        """
+        self.takeChild(self.indexOfChild(self.workflowItems[id]))
+        del self.workflowItems[id]
+
+    def deleteJob(self, id):
+        """ deleteJob(id: str, parent_id: str) -> None
+        Callback, deletes a a single job from all workflows.
+
+        """
+
+        for workflow_item in self.workflowItems.itervalues():
+            if id in workflow_item.jobs:
+                job_item = workflow_item.jobs[id]
+                job_item.parent().takeChild(job_item.parent().indexOfChild(job_item))
+            del workflow_item.jobs[id]
+            workflow_item.updateJobs()
+
+    def addJobRec(self, obj, parent_id=None):
+        """addJobRec(obj: ModuleSuspended, parent_id: signature)  -> None
+
+           Recursively adds jobs that are executed by other modules like
+           Groups and Maps. This is only for display purposes.
+        """
+        workflow = self.jobMonitor.currentWorkflow()
+        workflow_item = self.workflowItems[workflow.id]
+        # top down. Base is assumed to have been added already
+        base = (workflow_item.intermediates[parent_id] if parent_id is not None
+                                                       else workflow_item)
+        id = obj.module.signature
+        if obj.children:
+            # add parent items and their children
+            if id not in workflow_item.intermediates:
+                parent_item = QParentItem(id, obj.name, base)
+                parent_item.setExpanded(True)
+                workflow_item.intermediates[id] = parent_item
+
+            for child in obj.children:
+                self.addJobRec(child, id)
+        elif obj.module.signature in workflow.jobs:
+            # this is an already existing new-style job
+            job = workflow_item.jobs[obj.module.signature]
+            job.handle = obj.handle
+            # need to force takeChild
+            base.addChild(job.parent().takeChild(job.parent().indexOfChild(job)))
+        elif id in workflow.jobs:
+            # this is an already existing old-style job
+            job = workflow_item.jobs[id]
+            job.handle = obj.handle
+            # need to force takeChild
+            base.addChild(job.parent().takeChild(job.parent().indexOfChild(job)))
+
+    def finishWorkflow(self, workflow):
+        """Callback, updates workflow status.
+        """
+        workflow = self.jobMonitor.currentWorkflow()
+        # untangle parents
+        for parent in workflow.parents.itervalues():
+            self.addJobRec(parent)
+
+        workflowItem = self.workflowItems.get(workflow.id, None)
+        if workflowItem:
+            workflowItem.updateJobs()
+            QJobView.instance().set_visible(True)
+
+    def checkJob(self, module, id, handle):
+        """ checkJob(module: VistrailsModule, id: str, handle: object)
+        Callback, checks if job has completed.
+        """
+        workflow = self.jobMonitor.currentWorkflow()
+        if not workflow:
+            if not handle or not self.jobMonitor.isDone(handle):
+                raise ModuleSuspended(module, 'Job is running',
+                                      handle=handle)
+        workflow_item = self.workflowItems[workflow.id]
+        item = workflow_item.jobs.get(id, None)
+        item.setText(0, item.job.name)
+        # we should check the status using the JobHandle and show dialog
+        # get current view progress bar and hijack it
+        if handle:
+            item.handle = handle
+        workflow = self.jobMonitor.currentWorkflow()
+        workflow_item = self.workflowItems.get(workflow.id, None)
+        workflow_item.updateJobs()
+        progress = self.controller.progress
+
         conf = configuration.get_vistrails_configuration()
-        if conf.has('runningJobsList') and conf.runningJobsList:
-            for url in conf.runningJobsList.split(';'):
-                loc, version = url.split('?')
-                locator = BaseLocator.from_url(loc)
-                msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Question,
-                                           "Running Job Found",
-                                           "Running Job Found:\n    %s\n"
-                                           "Continue now?" % url)
-                msgBox.addButton("Later", msgBox.ActionRole)
-                delete = msgBox.addButton("Delete", msgBox.ActionRole)
-                yes = msgBox.addButton("Yes", msgBox.ActionRole)
-                msgBox.exec_()
-                if msgBox.clickedButton() == yes:
-                    from vistrails.gui.vistrails_window import _app
-                    _app.open_vistrail_without_prompt(locator,
-                                                   int(version.split('=')[1]))
-                    _app.get_current_view().execute()
-                if msgBox.clickedButton() == delete:
-                    conf_jobs = conf.runningJobsList.split(';')
-                    conf_jobs.remove(url)
-                    conf.runningJobsList = ';'.join(conf_jobs)
-                    configuration.get_vistrails_persistent_configuration(
-                                      ).runningJobsList = conf.runningJobsList
-        else:
-            conf.runningJobsList = ''
-            configuration.get_vistrails_persistent_configuration(
-                                      ).runningJobsList = conf.runningJobsList
+        interval = conf.jobCheckInterval
+        if interval and not conf.jobAutorun and not progress.suspended:
+            # we should keep checking the job
+            if handle:
+                # wait for module to complete
+                labelText = (("Running external job %s\n"
+                                       "Started %s\n"
+                                       "Press Cancel to suspend")
+                                       % (item.job.name,
+                                          item.job.start))
+                progress.setLabelText(labelText)
+                while not self.jobMonitor.isDone(handle):
+                    i = 0
+                    while i < interval:
+                        i += 1
+                        time.sleep(1)
+                        QtCore.QCoreApplication.processEvents()
+                        if progress.wasCanceled():
+                            # this does not work, need to create a new progress dialog
+                            #progress.goOn()
+                            new_progress = progress.__class__(progress.parent())
+                            new_progress.setMaximum(progress.maximum())
+                            new_progress.setValue(progress.value())
+                            new_progress.setLabelText(labelText)
+                            new_progress.setMinimumDuration(0)
+                            new_progress.suspended = True
+                            self.controller.progress = new_progress
+                            progress.hide()
+                            progress.deleteLater()
+                            progress = new_progress
+                            progress.show()
+                            QtCore.QCoreApplication.processEvents()
+                            raise ModuleSuspended(module,
+                                       'Interrupted by user, job'
+                                       ' is still running', handle=handle)
+                return
+        if not handle or not self.jobMonitor.isDone(handle):
+            raise ModuleSuspended(module, 'Job is running', handle=handle)
 
 
 class QWorkflowItem(QtGui.QTreeWidgetItem):
-    """ The workflow that was suspended """
-    def __init__(self, controller, error, parent):
-        if controller.vistrail.locator:
-            self.name = "%s:%s" % (controller.vistrail.locator.short_name,
-                                    controller.get_pipeline_name())
-        else:
-            self.name = "Untitled.vt:%s" % controller.get_pipeline_name()
-            
-        QtGui.QTreeWidgetItem.__init__(self, parent,
-                    [self.name, error if isinstance(error, str) else error.msg])
-        self.setToolTip(0, "Double-Click to View Pipeline")
-        self.setToolTip(1, error if isinstance(error, str) else error.msg)
-        
-        self.controller = controller
-        self.version = controller.current_version
-        self.has_queue = True
-        self.setIcon(0, theme.get_current_theme().JOB_CHECKING)
+    """A workflow with jobs.
+
+    This item can have child items.
+    """
+    def __init__(self, workflow, parent):
+        QtGui.QTreeWidgetItem.__init__(self, parent, ['', ''])
+        self.workflow = workflow
+        self.has_handle = True
+        self.setIcon(0, theme.get_current_theme().PIPELINE_ICON)
+        self.setIcon(1, theme.get_current_theme().JOB_CHECKING)
         self.workflowFinished = False
         self.jobs = {}
-        from vistrails.gui.vistrails_window import _app
-        self.view = _app.get_current_view()
-    
-    def countJobs(self):
-        count = self.childCount()
-        finished = sum([self.child(i).jobFinished for i in xrange(count)])
-        self.setText(0, "%s (%s/%s)" % (self.name, finished, count))
+        self.intermediates = {}
+        self.updateJobs()
+
+    def updateJobs(self):
+        """ Updates name and job states
+        """
+        name = self.parent().controller.get_pipeline_name(
+                                                        self.workflow.version)
+        self.setText(0, name)
+        self.setToolTip(0, 'Double-Click to View Pipeline "%s" with id %s' %
+                           (name, self.workflow.version))
+        self.setToolTip(1, "Log id: %s" % self.workflow.id)
+        self.has_handle = True
+        for job in self.jobs.itervalues():
+            job.updateJob()
+            if not job.job.finished and not job.handle:
+                self.has_handle = False
+        count = len(self.jobs)
+        finished = sum([job.jobFinished for job in self.jobs.values()])
+        self.setText(1, "(%s/%s)" % (finished, count))
+        self.workflowFinished = (finished == count)
+        if self.workflowFinished:
+            self.setIcon(1, theme.get_current_theme().JOB_FINISHED)
+        elif not self.has_handle:
+            self.setIcon(1, theme.get_current_theme().JOB_SCHEDULED)
+        else:
+            self.setIcon(1, theme.get_current_theme().JOB_CHECKING)
 
     def goto(self):
+        """ Shows this pipeline
+
+        """
         from vistrails.gui.vistrails_window import _app
-        _app.change_view(self.view)
-        self.view.version_selected(self.version, True, double_click=True)
-    
+        view = _app.getViewFromLocator(self.parent().controller.locator)
+        _app.change_view(view)
+        view.version_selected(self.workflow.version, True, double_click=True)
+        return view
+
     def execute(self):
-        self.goto()
-        self.view.execute()
+        """ Shows and executes this pipeline
+        """
+        self.goto().execute()
+
 
 class QJobItem(QtGui.QTreeWidgetItem):
-    """ The module that was suspended """
-    def __init__(self, name, error, parent=None):
-        QtGui.QTreeWidgetItem.__init__(self, parent, [name, error.msg])
-        self.setToolTip(1, error.msg)
-        self.queue = error.queue
-        if self.queue:
-            self.setIcon(0, theme.get_current_theme().JOB_CHECKING)
-            self.setToolTip(0, "This Job has a method to check if it has finished.")
+    """A pending job, i.e. a single module that was suspended.
+
+    These will be either under a QWorkflowItem or a QParentItem.
+    """
+    def __init__(self, job, parent=None):
+        QtGui.QTreeWidgetItem.__init__(self, parent, [job.name,
+                                                      job.description()])
+        self.setToolTip(1, job.description())
+        self.job = job
+        # This is different from job.jobFinished after job finishes
+        self.jobFinished = self.job.finished
+        self.handle = None
+        self.updateJob()
+
+    def updateJob(self):
+        if self.job.finished:
+            self.jobFinished = self.job.finished
+        self.setText(1, self.job.parameters.get('__message__',
+                        "Finished" if self.jobFinished else "Running"))
+        if self.jobFinished:
+            self.setIcon(1, theme.get_current_theme().JOB_FINISHED)
+            self.setToolTip(0, "This Job Has Finished")
+        elif self.handle:
+            self.setIcon(1, theme.get_current_theme().JOB_SCHEDULED)
+            self.setToolTip(0, "This Job is Running and Scheduled for Checking")
         else:
-            self.setIcon(0, theme.get_current_theme().JOB_SCHEDULED)
-            self.setToolTip(0, 'To check this job the workflow must be re-executed. Make sure "Run To Check" is checked.')
-        self.jobFinished = False
+            self.setIcon(1, theme.get_current_theme().JOB_CHECKING)
+            self.setToolTip(0, "This Job is Running")
+        self.setToolTip(1, self.job.id)
+
+    def stdout(self):
+        if self.handle:
+            sp = LogMonitor("Standard Output for " + self.job.name,
+                            self.handle)
+            sp.exec_()
+
+    def stderr(self):
+        if self.handle:
+            sp = ErrorMonitor("Standard Output for " + self.job.name,
+                              self.handle)
+            sp.exec_()
+
+
+class QParentItem(QtGui.QTreeWidgetItem):
+    """A composite job, i.e. a module whose child suspended.
+    """
+    def __init__(self, id, name, parent=None):
+        QtGui.QTreeWidgetItem.__init__(self, parent, [name, ''])
+        self.id = id
+        self.setToolTip(0, self.id)
+
+
+class LogMonitor(QtGui.QDialog):
+    """Displays the content of a Job's standard_output().
+    """
+    def __init__(self, name, handle, parent=None):
+        QtGui.QDialog.__init__(self, parent)
+        self.handle = handle
+        self.resize(700, 400)
+        self.setWindowTitle(name)
+
+        layout = QtGui.QVBoxLayout()
+        self.setLayout(layout)
+        self.text = QtGui.QTextEdit('')
+        self.update_text()
+        self.text.setReadOnly(True)
+        self.text.setLineWrapMode(QtGui.QTextEdit.NoWrap)
+        layout.addWidget(self.text)
+        buttonLayout = QtGui.QHBoxLayout()
+
+        close = QtGui.QPushButton('Close', self)
+        close.setFixedWidth(100)
+        buttonLayout.addWidget(close)
+        self.connect(close, QtCore.SIGNAL('clicked()'),
+                     self, QtCore.SLOT('close()'))
+
+        update = QtGui.QPushButton('Update', self)
+        update.setFixedWidth(100)
+        buttonLayout.addWidget(update)
+        self.connect(update, QtCore.SIGNAL('clicked()'),
+                     self.update_text)
+
+        layout.addLayout(buttonLayout)
+
+    def update_text(self):
+        self.text.setPlainText(self.handle.standard_output())
+
+
+class ErrorMonitor(LogMonitor):
+    """Displays the content of a job's standard_error().
+    """
+    def update_text(self):
+        self.text.setPlainText(self.handle.standard_error())
diff --git a/vistrails/gui/mashups/__init__.py b/vistrails/gui/mashups/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/gui/mashups/__init__.py
+++ b/vistrails/gui/mashups/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/gui/mashups/alias_inspector.py b/vistrails/gui/mashups/alias_inspector.py
index c017488..39fb988 100644
--- a/vistrails/gui/mashups/alias_inspector.py
+++ b/vistrails/gui/mashups/alias_inspector.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -45,13 +46,15 @@ QListEditDialog
 QListEditItemDelegate
 
 """
+from __future__ import division
+
 import copy
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import pyqtSignal, pyqtSlot
 from vistrails.core.mashup.alias import Alias
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.system import get_vistrails_basic_pkg_id
-from vistrails.gui.modules import get_widget_class
+from vistrails.gui.modules.utils import get_widget_class
 from vistrails.gui.modules.constant_configuration import StandardConstantWidget
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.utils import show_warning
@@ -268,14 +271,14 @@ class QAliasDetailsWidget(QtGui.QWidget):
             return
         if new_alias in self.table.aliases.keys():
             show_warning("Mashup",
-                         """Label name %s already exists. 
-Please type a different name. """ % new_alias)
+                         "Label name %s already exists. "
+                         "Please type a different name." % new_alias)
             self.name_edit.setText(old_alias)
             self.name_edit.setFocus()
         elif new_alias == '':
             show_warning("Mashup",
-                         """Variables with empty name are not allowed. 
-Please type a unique name. """ % new_alias)
+                         "Variables with empty name are not allowed. "
+                         "Please type a unique name.")
             self.name_edit.setText(old_alias)
             self.name_edit.setFocus()
         else:
@@ -431,8 +434,8 @@ Please type a unique name. """ % new_alias)
         else:
             idn = p.identifier
         reg = get_module_registry()
-        p_module = reg.get_module_by_name(idn, p.type, p.namespace)
-        widget_type = get_widget_class(p_module)
+        p_descriptor = reg.get_descriptor_by_name(idn, p.type, p.namespace)
+        widget_type = get_widget_class(p_descriptor)
         p.strValue = alias.component.val
         return widget_type(p, parent)
     
diff --git a/vistrails/gui/mashups/alias_list.py b/vistrails/gui/mashups/alias_list.py
index 98e3e3a..31ecf03 100644
--- a/vistrails/gui/mashups/alias_list.py
+++ b/vistrails/gui/mashups/alias_list.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -42,6 +43,8 @@ QAliasListItem
 QAliasList
 
 """
+from __future__ import division
+
 import copy
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import pyqtSlot, pyqtSignal
diff --git a/vistrails/gui/mashups/alias_parameter_view.py b/vistrails/gui/mashups/alias_parameter_view.py
index 888b254..3e42933 100644
--- a/vistrails/gui/mashups/alias_parameter_view.py
+++ b/vistrails/gui/mashups/alias_parameter_view.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -38,6 +39,8 @@ of parameters
 
 QAliasParameterView
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import pyqtSignal, pyqtSlot
 from vistrails.core.inspector import PipelineInspector
diff --git a/vistrails/gui/mashups/controller.py b/vistrails/gui/mashups/controller.py
index 17a12b0..099eb4f 100644
--- a/vistrails/gui/mashups/controller.py
+++ b/vistrails/gui/mashups/controller.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4.QtCore import QObject, pyqtSignal, pyqtSlot
 
 from vistrails.core.mashup.controller import MashupController as BaseController
diff --git a/vistrails/gui/mashups/mashup_app.py b/vistrails/gui/mashups/mashup_app.py
index 0678354..5d1b171 100644
--- a/vistrails/gui/mashups/mashup_app.py
+++ b/vistrails/gui/mashups/mashup_app.py
@@ -1,54 +1,57 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import pyqtSignal
 
-from vistrails.gui.mashups.mashups_widgets import (QAliasSliderWidget, QDropDownWidget,
-                                         QAliasNumericStepperWidget)
+from vistrails.core import debug
+from vistrails.gui.mashups.mashups_widgets import QAliasNumericStepperWidget, \
+    QAliasSliderWidget, QDropDownWidget
 from vistrails.gui.utils import show_warning, TestVisTrailsGUI
 
-spreadsheet = __import__('vistrails.packages.spreadsheet', globals(), locals(), 
-                         ['spreadsheet_controller'], -1) 
-spreadsheetController = spreadsheet.spreadsheet_controller.spreadsheetController
+from vistrails.packages.spreadsheet.spreadsheet_controller import \
+    spreadsheetController
 
 
 class QMashupAppMainWindow(QtGui.QMainWindow):
     #signals
     appWasClosed = pyqtSignal(QtGui.QMainWindow)
-    
-    def __init__(self, parent=None, vistrail_view=None, dumpcells=False, 
+
+    def __init__(self, parent=None, vistrail_view=None, dumpcells=False,
                  controller=None, version=-1):
         """ QMashupAppMainWindow()
         Initialize an app window from a mashup.
@@ -58,7 +61,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         QtGui.QMainWindow.__init__(self, parent)
         self.vtkCells = []
         self.setStatusBar(QtGui.QStatusBar(self))
-    
+
         # Central widget
         centralWidget = QtGui.QWidget()
         self.mainLayout = QtGui.QVBoxLayout()
@@ -99,14 +102,14 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         # Show here to make sure XDisplay info is correct (for VTKCell)
         self.show()
 
-        spreadsheetController.setEchoMode(True)        
+        spreadsheetController.setEchoMode(True)
         #will run to get Spreadsheet Cell events
         (cellEvents, errors) = self.runAndGetCellEvents(useDefaultValues=True)
         if cellEvents:
             self.numberOfCells = len(cellEvents)
             self.initCells(cellEvents)
         if len(errors) > 0:
-            show_warning("VisTrails::Mashup Preview", 
+            show_warning("VisTrails::Mashup Preview",
                          "There was a problem executing the pipeline: %s." %
                          errors)
         # Construct the controllers for aliases
@@ -114,17 +117,17 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         self.cellControls = {}
         self.aliasWidgets = {}
         self.initControls()
-        
-        if self.currentMashup.layout != None:
+
+        if self.currentMashup.layout is not None:
             self.restoreState(QtCore.QByteArray.fromPercentEncoding(
                                 QtCore.QByteArray(self.currentMashup.layout)))
-        
-        if self.currentMashup.geometry != None:
+
+        if self.currentMashup.geometry is not None:
             self.restoreGeometry(QtCore.QByteArray.fromPercentEncoding(
                               QtCore.QByteArray(self.currentMashup.geometry)))
         else:
             self.resize(self.sizeHint())
-                    
+
         # Constructing buttons
         buttonDock = QCustomDockWidget('Control Buttons', self)
         buttonWidget = QtGui.QWidget(buttonDock)
@@ -182,7 +185,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             sequenceLayout.addWidget(self.cb_loop_sequence)
             buttonLayout.addLayout(sequenceLayout, 0, 0, QtCore.Qt.AlignRight)
         buttonLayout.addWidget(self.cb_auto_update, 0, 1, QtCore.Qt.AlignLeft)
-        buttonLayout.addWidget(self.cb_keep_camera, 0, 2, 1, 2, QtCore.Qt.AlignLeft) 
+        buttonLayout.addWidget(self.cb_keep_camera, 0, 2, 1, 2, QtCore.Qt.AlignLeft)
         if self.sequenceOption:
             buttonLayout.addWidget(self.loopButton, 1, 1, QtCore.Qt.AlignRight)
             self.loopButton.setEnabled(False)
@@ -198,34 +201,34 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         buttonDock.setWidget(buttonWidget)
         self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, buttonDock)
         self.controlDocks["__buttons__"] = buttonDock
-        
-        self.saveAllAct = QtGui.QAction("S&ave Combined", self, 
+
+        self.saveAllAct = QtGui.QAction("S&ave Combined", self,
                                         shortcut=QtGui.QKeySequence.SelectAll,
-                                        statusTip="Save combined images to disk", 
+                                        statusTip="Save combined images to disk",
                                         triggered=self.saveAllEvent)
-        self.saveAct = QtGui.QAction("&Save Each", self, 
+        self.saveAct = QtGui.QAction("&Save Each", self,
                                      shortcut=QtGui.QKeySequence.Save,
-                                     statusTip="Save separate images to disk", 
+                                     statusTip="Save separate images to disk",
                                      triggered=self.saveEventAction)
         self.showBuilderAct = QtGui.QAction("VisTrails Main Window", self,
                                             statusTip="Show VisTrails Main Window",
                                             triggered=self.showBuilderWindow)
         self.createMenus()
         self.lastExportPath = ''
-                    
+
     def createMenus(self):
         self.fileMenu = self.menuBar().addMenu("&File")
         self.fileMenu.addAction(self.saveAct)
         self.fileMenu.addAction(self.saveAllAct)
-        
+
         self.viewMenu = self.menuBar().addMenu("&View")
         self.viewMenu.addAction(self.editingModeAct)
-        
+
         self.windowMenu = self.menuBar().addMenu("&Window")
         self.windowMenu.addAction(self.showBuilderAct)
-        
+
     def runAndGetCellEvents(self, useDefaultValues=False):
-        spreadsheetController.setEchoMode(True)        
+        spreadsheetController.setEchoMode(True)
         #will run to get Spreadsheet Cell events
         cellEvents = []
         errors = []
@@ -234,13 +237,13 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             if res:
                 cellEvents = spreadsheetController.getEchoCellEvents()
         except Exception, e:
-            import traceback
-            print "Executing pipeline failed:", str(e), traceback.format_exc()
+            debug.unexpected_exception(e)
+            print "Executing pipeline failed:", debug.format_exc()
         finally:
             spreadsheetController.setEchoMode(False)
-            
+
         return (cellEvents, errors)
-    
+
     def updateCells(self, info=None):
         # check if we should create a sequence
         if self.cb_loop_sequence.isChecked():
@@ -258,7 +261,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         #self.SaveCamera()
         for i in xrange(self.numberOfCells):
             camera = []
-            if (hasattr(self.cellWidgets[i],"getRendererList") and 
+            if (hasattr(self.cellWidgets[i],"getRendererList") and
                 self.cb_keep_camera.isChecked()):
                 for ren in self.cellWidgets[i].getRendererList():
                     camera.append(ren.GetActiveCamera())
@@ -281,7 +284,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
                 for i in xrange(self.numberOfCells):
                     self.cellWidgets[i].setPlayerFrame(slider.value())
             return
-        
+
         if not interactive:
             for i in xrange(self.numberOfCells):
                 self.cellWidgets[i].clearHistory()
@@ -311,7 +314,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             # show the result
             self.updateRenderedCells(value if interactive else 0)
             self.is_executing = True
-                
+
             if value >= slider.maximum():
                 break
             value += slider.singleStep()
@@ -319,14 +322,14 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         self.is_executing = False
         slider.setValue(old_value)
         self.loopButton.setEnabled(True)
-        
+
     def updateRenderedCells(self, value):
         """ Show the cell specified by slider info
         """
         self.is_executing = True
         for i in xrange(self.numberOfCells):
             camera = []
-            if (hasattr(self.cellWidgets[i],"getRendererList") and 
+            if (hasattr(self.cellWidgets[i],"getRendererList") and
                 self.cb_keep_camera.isChecked()):
                 for ren in self.cellWidgets[i].getRendererList():
                     camera.append(ren.GetActiveCamera())
@@ -361,7 +364,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
                     cell.startPlayer()
                 else:
                     cell.stopPlayer()
-            
+
 
     def timerEvent(self, event):
         if self.steps:
@@ -389,23 +392,23 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             self.editing = not self.editing
         if not self.editing:
             self.saveSettings()
-               
+
     def saveSettings(self):
         layout = self.saveState().toPercentEncoding()
         geom = self.saveGeometry().toPercentEncoding()
-            
+
         self.currentMashup.layout = layout
         self.currentMashup.geometry = geom
-        
+
         self.controller.setChanged(True)
-        
+
         #self.controller.writeMashuptrail()
-   
+
     def closeEvent(self, event):
         self.saveSettings()
         self.appWasClosed.emit(self)
         event.accept()
-        
+
     def auto_update_changed(self, state):
         if state == QtCore.Qt.Unchecked:
             self.updateButton.setEnabled(True)
@@ -432,23 +435,23 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
                     cell._player.raise_()
                     cell._player.show()
                     cell.hide()
-        
+
     def loop_int_changed(self, state):
-            self.loopButton.setEnabled(False)
-            
+        self.loopButton.setEnabled(False)
+
     def saveAll(self):
         for w in self.widgets:
             w.saveAll(self.dumpcells)
-            
+
     def saveEach(self):
         for w in self.widgets:
             w.saveEach(self.dumpcells, self.frameNo)
-        
+
     def saveEventAction(self, checked):
         self.saveEvent()
-          
+
     def saveEvent(self, folder=None):
-        if folder == None:
+        if folder is None:
             folder = QtGui.QFileDialog.getExistingDirectory(self,
                                                         "Save images to...",
                                                         self.lastExportPath,
@@ -457,9 +460,9 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             self.dumpcells = str(folder)
             self.saveEach()
             self.lastExportPath = str(folder)
-            
+
     def saveAllEvent(self, folder=None):
-        if folder == None:
+        if folder is None:
             folder = QtGui.QFileDialog.getExistingDirectory(self,
                                                         "Save images to...",
                                                         self.lastExportPath,
@@ -467,11 +470,10 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         if folder:
             self.dumpcells = str(folder)
             self.saveAll()
-            self.lastExportPath
-    
+
     def saveAndExport(self, clicked=True):
         self.saveAll()
-        
+
     def initCells(self, cellEvents):
         cellLayout = QtGui.QHBoxLayout()
         self.mainLayout.addLayout(cellLayout, self.numberOfCells * 2)
@@ -492,47 +494,46 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             return vtkCells
         for cellWidget in self.vtkCells:
             cellWidget.getSelectedCellWidgets = getSelectedCellWidgets
-      
+
     def initControls(self):
         if len(self.currentMashup.alias_list) == 0:
             return
-        
+
         #Constructing alias controls
         self.controlDocks = {}
         self.cellControls = {}
         self.toolbuttons = {}
-        
+
         row = 0
         for alias in self.currentMashup.alias_list:
             dock = QCustomDockWidget(alias.name, #"Control for '%s'" % aliasName,
                                       self)
             vtparam = self.controller.getVistrailParam(alias)
-            
+
             if alias.component.widget == 'slider':
                 aliasWidget = QAliasSliderWidget(alias, vtparam, dock)
-                # enables looping of 
+                # enables looping of
                 if alias.component.seq:
                     self.sequenceOption = aliasWidget
 
-
             elif alias.component.widget == 'numericstepper':
                 aliasWidget = QAliasNumericStepperWidget(alias, vtparam, dock)
             else:
                 aliasWidget = QDropDownWidget(alias, vtparam, dock)
-            
+
             aliasWidget.setSizePolicy(QtGui.QSizePolicy.Preferred,
                                           QtGui.QSizePolicy.Maximum)
             self.connect(aliasWidget,
                              QtCore.SIGNAL("contentsChanged"),
                              self.widget_changed)
-                
+
             dock.setWidget(aliasWidget)
             self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
             self.controlDocks[alias.name] = dock
             self.cellControls[alias.name] = aliasWidget.value
             row += 1
             self.aliasWidgets[alias.name] = aliasWidget
-        
+
         # Added a stretch space
         stretchDock = QCustomDockWidget('Stretch Space', self)
         stretch = QtGui.QWidget()
@@ -541,14 +542,14 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
         stretchDock.setWidget(stretch)
         self.addDockWidget(QtCore.Qt.RightDockWidgetArea, stretchDock)
         self.controlDocks["_stretch_"] = stretchDock
-            
+
     def widget_changed(self, info):
         if self.cb_auto_update.isChecked() and not self.is_executing:
             self.updateCells(info)
-        
-            
+
+
     def run(self, useDefaultValues=False):
-        
+
         # Building the list of parameter values
         params = []
         if useDefaultValues:
@@ -563,7 +564,7 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
                 else:
                     val =str(edit.text())
                 params.append((alias.component.vttype, alias.component.vtid,
-                              val))    
+                              val))
         results = self.controller.execute(params)[0]
         result = results[0]
         (objs, errors, executed) = (result.objects, result.errors,
@@ -573,16 +574,16 @@ class QMashupAppMainWindow(QtGui.QMainWindow):
             print errors
             return (False, errors)
         return (True, [])
-    
+
     def showBuilderWindow(self):
         from vistrails.gui.vistrails_window import _app
         _app.show()
-            
+
 class QCustomDockWidget(QtGui.QDockWidget):
     def __init__(self, title, parent=None):
         QtGui.QDockWidget.__init__(self, title, parent)
         self.setObjectName(title)
-        self.setFeatures(QtGui.QDockWidget.DockWidgetClosable | 
+        self.setFeatures(QtGui.QDockWidget.DockWidgetClosable |
                          QtGui.QDockWidget.DockWidgetMovable)
         self.emptyTitleBar = QtGui.QWidget()
         self.titleBarVisible = True
@@ -590,7 +591,7 @@ class QCustomDockWidget(QtGui.QDockWidget):
 
     def showTitleBar(self):
         self.titleBarVisible = True
-        self.setFeatures(QtGui.QDockWidget.DockWidgetClosable | 
+        self.setFeatures(QtGui.QDockWidget.DockWidgetClosable |
                          QtGui.QDockWidget.DockWidgetMovable)
         self.setMaximumHeight(524287)
         self.setTitleBarWidget(None)
@@ -611,12 +612,24 @@ class QCustomDockWidget(QtGui.QDockWidget):
 
 
 class TestMashupApp(TestVisTrailsGUI):
+    def setUp(self):
+        super(TestMashupApp, self).setUp()
+        try:
+            import vtk
+        except ImportError:
+            self.skipTest("VTK is not available")
+        from vistrails.tests.utils import enable_package
+        enable_package('org.vistrails.vistrails.vtk')
 
     def test_load_mashup(self):
+        import vistrails.api
         import vistrails.core.system
-        filename = (vistrails.core.system.vistrails_root_directory() + 
+        filename = (vistrails.core.system.vistrails_root_directory() +
                     '/tests/resources/spx_loop.vt')
         view = vistrails.api.open_vistrail_from_file(filename)
+        # Execute workflow to trigger upgrades
+        view.controller.execute_current_workflow()
+        view.controller.flush_delayed_actions()
         id = "d5026457-de6c-11e2-b074-3c07543dba07"
         mashup = view.get_mashup_from_mashuptrail_id(id, "loop")
         self.assert_(mashup)
diff --git a/vistrails/gui/mashups/mashup_view.py b/vistrails/gui/mashups/mashup_view.py
index 29a3367..bebca17 100644
--- a/vistrails/gui/mashups/mashup_view.py
+++ b/vistrails/gui/mashups/mashup_view.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
-from PyQt4.QtCore import pyqtSignal, pyqtSlot
+from PyQt4.QtCore import pyqtSlot
 from vistrails.core.data_structures.bijectivedict import Bidict
+from vistrails.core import debug
 from vistrails.gui.base_view import BaseView
 from vistrails.gui.mashups.mashups_manager import MashupsManager
 from vistrails.gui.mashups.alias_list import QAliasListPanel
@@ -139,7 +143,8 @@ class QMashupView(QtGui.QMainWindow, BaseView):
                                         QtCore.SIGNAL('vistrailChanged()'),
                                         self.mshpControllerVistrailChanged)
                 except Exception, e:
-                    print str(e)
+                    debug.unexpected_exception(e)
+                    debug.print_exc()
             self.controller.flush_delayed_actions()
             self.vtversion = self.controller.current_version
             self.mshpController = self.manager.createMashupController(self.controller,
@@ -273,10 +278,11 @@ class QMashupView(QtGui.QMainWindow, BaseView):
         (pid, pname) = self.mshpController.findFirstTaggedParent(self.mshpController.currentVersion)
         if pid >= 1:
             res = show_question("VisTrails::Mashups", 
-                """You've decided to keep a modified version of '%s'.
-Would you like to update it (this will move the tag to the current version)?
-Click on No to create a new tag.""" %pname,
-                [CANCEL_BUTTON, YES_BUTTON, NO_BUTTON], 0)
+                                "You've decided to keep a modified version "
+                                "of '%s'. Would you like to update it (this "
+                                "will move the tag to the current version)? "
+                                "Click on No to create a new tag." % pname,
+                                [CANCEL_BUTTON, YES_BUTTON, NO_BUTTON], 0)
             if res == YES_BUTTON:
                 #move tag
                 self.mshpController.moveTag(pid, 
diff --git a/vistrails/gui/mashups/mashups_inspector.py b/vistrails/gui/mashups/mashups_inspector.py
index 2590210..d8c8c14 100644
--- a/vistrails/gui/mashups/mashups_inspector.py
+++ b/vistrails/gui/mashups/mashups_inspector.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import pyqtSignal, pyqtSlot
 import vistrails.core.system
diff --git a/vistrails/gui/mashups/mashups_manager.py b/vistrails/gui/mashups/mashups_manager.py
index 80df3e4..59ce2c0 100644
--- a/vistrails/gui/mashups/mashups_manager.py
+++ b/vistrails/gui/mashups/mashups_manager.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import base64
 import copy
 import os
@@ -60,14 +63,12 @@ ElementTree = get_elementtree_library()
 
 class MashupsManager(object):
     _instance = None
-    class MashupsManagerSingleton(object):
-        def __call__(self, *args, **kw):
-            if MashupsManager._instance is None:
-                obj = MashupsManager(*args, **kw)
-                MashupsManager._instance = obj
-            return MashupsManager._instance
-    
-    getInstance = MashupsManagerSingleton()
+    @staticmethod
+    def getInstance(*args, **kwargs):
+        if MashupsManager._instance is None:
+            obj = MashupsManager(*args, **kwargs)
+            MashupsManager._instance = obj
+        return MashupsManager._instance
 
     def __init__(self):
         if not MashupsManager._instance:
@@ -118,7 +119,7 @@ class MashupsManager(object):
                         MashupsManager.addMashuptrailtoVistrailController(vt_controller,
                                                                           mashuptrail)    
                         
-                    elif res == 'Move':
+                    else:  # res == 'Move'
                         # we will move the parent trail and validate all mashups
                         # for the current pipeline to make sure they will be 
                         # executable for the current version
diff --git a/vistrails/gui/mashups/mashups_widgets.py b/vistrails/gui/mashups/mashups_widgets.py
index ff7c002..22e001c 100644
--- a/vistrails/gui/mashups/mashups_widgets.py
+++ b/vistrails/gui/mashups/mashups_widgets.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.system import get_vistrails_basic_pkg_id
 from vistrails.gui.theme import CurrentTheme
-from vistrails.gui.modules import get_widget_class
+from vistrails.gui.modules.utils import get_widget_class
 from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin, \
     StandardConstantWidget
 from vistrails.core.modules.module_registry import get_module_registry
@@ -77,6 +80,7 @@ class QAliasSliderWidget(QtGui.QWidget):
 ###############################################################################        
 
 class QSliderWidget(ConstantWidgetMixin, QtGui.QSlider):
+    contentsChanged = QtCore.pyqtSignal(tuple)
     def __init__(self, param, parent=None):
         QtGui.QSlider.__init__(self, QtCore.Qt.Horizontal, parent)
         ConstantWidgetMixin.__init__(self, param.strValue)
@@ -180,6 +184,7 @@ class QAliasNumericStepperWidget(QtGui.QWidget):
         
 ###############################################################################
 class QNumericStepperIntegerWidget(ConstantWidgetMixin, QtGui.QSpinBox):
+    contentsChanged = QtCore.pyqtSignal(object, object)
     def __init__(self, param, parent=None):
         QtGui.QSpinBox.__init__(self, parent)
         ConstantWidgetMixin.__init__(self, param.strValue)
@@ -208,6 +213,7 @@ class QNumericStepperIntegerWidget(ConstantWidgetMixin, QtGui.QSpinBox):
 ###############################################################################
 
 class QNumericStepperFloatWidget(ConstantWidgetMixin, QtGui.QDoubleSpinBox):
+    contentsChanged = QtCore.pyqtSignal(tuple)
     def __init__(self, param, parent=None):
         QtGui.QDoubleSpinBox.__init__(self, parent)
         ConstantWidgetMixin.__init__(self, param.strValue)
@@ -325,9 +331,9 @@ class QDropDownWidget(QtGui.QWidget):
         else:
             idn = self.vtparam.identifier
         reg = get_module_registry()
-        p_module = reg.get_module_by_name(idn, self.vtparam.type, 
-                                          self.vtparam.namespace)
-        widget_type = get_widget_class(p_module)
+        p_descriptor = reg.get_descriptor_by_name(idn, self.vtparam.type,
+                                                  self.vtparam.namespace)
+        widget_type = get_widget_class(p_descriptor)
         if val:
             self.vtparam.strValue = val
         return widget_type(self.vtparam, parent)
diff --git a/vistrails/gui/merge_gui.py b/vistrails/gui/merge_gui.py
index 49ee8a1..bdc0f72 100644
--- a/vistrails/gui/merge_gui.py
+++ b/vistrails/gui/merge_gui.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
 import os
 import vistrails.api
@@ -290,7 +293,7 @@ class resolve_thumbs(QtGui.QWidget):
         self.value = CHOICE_OWN_ALL
         self.close()
 
-class MergeGUI:
+class MergeGUI(object):
     @staticmethod
     def resolveTags(a, b, text):
         exm = resolve_tags(a, b, text)
diff --git a/vistrails/gui/module_annotation.py b/vistrails/gui/module_annotation.py
index fb6ec4a..bab88a0 100644
--- a/vistrails/gui/module_annotation.py
+++ b/vistrails/gui/module_annotation.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,8 +40,9 @@ QKeyValueDelegate
 QModuleAnnotation
 QModuleAnnotationTable
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
-from vistrails.gui.common_widgets import QToolWindowInterface
 from vistrails.core import debug
 
 ################################################################################
diff --git a/vistrails/gui/module_configuration.py b/vistrails/gui/module_configuration.py
index b34f4c3..90445c5 100644
--- a/vistrails/gui/module_configuration.py
+++ b/vistrails/gui/module_configuration.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 the user selects a module's "Edit Configuration"
 
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.modules.module_registry import get_module_registry, \
     ModuleRegistryException
@@ -49,8 +52,7 @@ class QConfigurationWidget(QtGui.QWidget):
         QtGui.QWidget.__init__(self, parent)
         self.setLayout(QtGui.QVBoxLayout())
         self.widget = None
-        #self.setFocusPolicy(QtCore.Qt.StrongFocus)
-        
+
     def setUpWidget(self, widget):
         self.widget = widget
         self.layout().addWidget(self.widget)
@@ -58,14 +60,14 @@ class QConfigurationWidget(QtGui.QWidget):
     def clear(self):
         """ clear() -> None
         Clear and delete widget in the layout
-        
+
         """
-        if self.widget:
+        if self.widget is not None:
             self.widget.setVisible(False)
             self.layout().removeWidget(self.widget)
             self.widget.deleteLater()
-        self.widget = None
-        
+            self.widget = None
+
     def askToSaveChanges(self):
         if self.widget:
             return self.widget.askToSaveChanges()
@@ -95,14 +97,19 @@ class QModuleConfiguration(QtGui.QScrollArea, QVistrailsPaletteInterface):
         self.hasChanges = False
         
     def set_controller(self, controller):
+        if self.controller == controller:
+            return
         self.controller = controller
-        self.scene = controller.current_pipeline_scene
+        if self.controller is not None:
+            self.scene = controller.current_pipeline_scene
 
-        selected_ids = self.scene.get_selected_module_ids() 
-        modules = [controller.current_pipeline.modules[i] 
-                   for i in selected_ids]
-        if len(modules) == 1:
-            self.updateModule(modules[0])
+            selected_ids = self.scene.get_selected_module_ids() 
+            modules = [controller.current_pipeline.modules[i] 
+                       for i in selected_ids]
+            if len(modules) == 1:
+                self.updateModule(modules[0])
+            else:
+                self.updateModule(None)
         else:
             self.updateModule(None)
 
@@ -114,13 +121,6 @@ class QModuleConfiguration(QtGui.QScrollArea, QVistrailsPaletteInterface):
         self.confWidget.setVisible(False)
         self.confWidget.clear()
         if module and self.controller:
-            # if module.has_annotation_with_key('__desc__'):
-            #     label = module.get_annotation_by_key('__desc__').value.strip()
-            #     title = '%s (%s) Module Configuration'%(label,
-            #                                             module.name)
-            # else:
-            #     title = '%s Module Configuration'%module.name
-            # self.setWindowTitle(title)
             registry = get_module_registry()
             getter = registry.get_configuration_widget
             widgetType = None
diff --git a/vistrails/gui/module_documentation.py b/vistrails/gui/module_documentation.py
index ef5df24..2278636 100644
--- a/vistrails/gui/module_documentation.py
+++ b/vistrails/gui/module_documentation.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,6 +38,8 @@ dialog, which displays the available documentation for a given VisTrails module.
 
 QModuleDocumentation
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.modules.module_registry import ModuleRegistryException
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
@@ -76,14 +79,17 @@ class QModuleDocumentation(QtGui.QDialog, QVistrailsPaletteInterface):
         self.update_descriptor()
 
     def set_controller(self, controller):
-        scene = controller.current_pipeline_scene
-        selected_ids = scene.get_selected_module_ids() 
-        modules = [controller.current_pipeline.modules[i] 
-                   for i in selected_ids]
-        if len(modules) == 1:
-            self.update_module(modules[0])
+        if controller is not None:
+            scene = controller.current_pipeline_scene
+            selected_ids = scene.get_selected_module_ids() 
+            modules = [controller.current_pipeline.modules[i] 
+                       for i in selected_ids]
+            if len(modules) == 1:
+                self.update_module(modules[0])
+            else:
+                self.update_module(None)
         else:
-            self.update_module(None)
+            self.update_descriptor()
 
     def update_module(self, module=None):
         descriptor = None
diff --git a/vistrails/gui/module_info.py b/vistrails/gui/module_info.py
index b35c1a7..3c2df74 100644
--- a/vistrails/gui/module_info.py
+++ b/vistrails/gui/module_info.py
@@ -1,54 +1,115 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
+from vistrails.core.configuration import get_vistrails_configuration, \
+                                         get_vistrails_persistent_configuration
+from vistrails.core.system import systemType, vistrails_root_directory
 from vistrails.core.utils import versions_increasing
 from vistrails.gui.common_widgets import QDockPushButton
 from vistrails.gui.module_annotation import QModuleAnnotationTable
-from vistrails.gui.ports_pane import PortsList
+from vistrails.gui.ports_pane import PortsList, letterIcon
+from vistrails.gui.version_prop import QVersionProp
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
 
+import os
+
 class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
     def __init__(self, parent=None, flags=QtCore.Qt.Widget):
         QtGui.QWidget.__init__(self, parent, flags)
+        self.ports_visible = True
+        self.types_visible = True
+
         self.build_widget()
         self.controller = None
         self.module = None
         self.pipeline_view = None # pipeline_view
         self.read_only = False
         self.is_updating = False
+        self.addButtonsToToolbar()
+
+    def addButtonsToToolbar(self):
+        # button for toggling executions
+        eye_open_icon = \
+            QtGui.QIcon(os.path.join(vistrails_root_directory(),
+                                 'gui/resources/images/eye.png'))
+
+        self.portVisibilityAction = QtGui.QAction(eye_open_icon,
+                                        "Show/hide port visibility toggle buttons",
+                                        None,
+                                        triggered=self.showPortVisibility)
+        self.portVisibilityAction.setCheckable(True)
+        self.portVisibilityAction.setChecked(True)
+        self.toolWindow().toolbar.insertAction(self.toolWindow().pinAction,
+                                               self.portVisibilityAction)
+        self.showTypesAction = QtGui.QAction(letterIcon('T'),
+                                        "Show/hide type information",
+                                        None,
+                                        triggered=self.showTypes)
+        self.showTypesAction.setCheckable(True)
+        self.showTypesAction.setChecked(True)
+        self.toolWindow().toolbar.insertAction(self.toolWindow().pinAction,
+                                               self.showTypesAction)
+        self.showEditsAction = QtGui.QAction(
+                 QtGui.QIcon(os.path.join(vistrails_root_directory(),
+                                          'gui/resources/images/pencil.png')),
+                 "Show/hide parameter widgets",
+                 None,
+                 triggered=self.showEdits)
+        self.showEditsAction.setCheckable(True)
+        self.showEditsAction.setChecked(
+            get_vistrails_configuration().check('showInlineParameterWidgets'))
+        self.toolWindow().toolbar.insertAction(self.toolWindow().pinAction,
+                                               self.showEditsAction)
+
+    def showPortVisibility(self, checked):
+        self.ports_visible = checked
+        self.update_module(self.module)
+
+    def showTypes(self, checked):
+        self.types_visible = checked
+        self.update_module(self.module)
+
+    def showEdits(self, checked):
+        get_vistrails_configuration().showInlineParameterWidgets = checked
+        get_vistrails_persistent_configuration().showInlineParameterWidgets = checked
+        scene = self.controller.current_pipeline_scene
+        scene.setupScene(self.controller.current_pipeline)
 
     def build_widget(self):
         name_label = QtGui.QLabel("Name:")
@@ -58,13 +119,12 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
         self.name_edit.setMinimumSize(50, 22)
         type_label = QtGui.QLabel("Type:")
         self.type_edit = QtGui.QLabel("")
-        # self.type_edit.setReadOnly(True)
         package_label = QtGui.QLabel("Package:")
         self.package_edit = QtGui.QLabel("")
-        # self.package_edit.setReadOnly(True)
+        namespace_label = QtGui.QLabel("Namespace:")
+        self.namespace_edit = QtGui.QLabel("")
         id = QtGui.QLabel("Id:")
         self.module_id = QtGui.QLabel("")
-        # self.module_id.setReadOnly(True)
         self.configure_button = QDockPushButton("Configure")
         self.connect(self.configure_button, QtCore.SIGNAL('clicked()'),
                      self.configure)
@@ -90,6 +150,7 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
         add_line(name_label, self.name_edit)
         add_line(type_label, self.type_edit)
         add_line(package_label, self.package_edit)
+        add_line(namespace_label, self.namespace_edit)
         add_line(id, self.module_id)
         h_layout = QtGui.QHBoxLayout()
         h_layout.setMargin(2)
@@ -100,6 +161,9 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
         layout.addLayout(h_layout)
         
         self.tab_widget = QtGui.QTabWidget()
+        # keep from overflowing on mac
+        if systemType in ['Darwin']:
+            self.tab_widget.tabBar().setStyleSheet('font-size: 12pt')
         # this causes a crash when undocking the palette in Mac OS X
         # see https://bugreports.qt-project.org/browse/QTBUG-16851
         # self.tab_widget.setDocumentMode(True)
@@ -115,7 +179,7 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
 
         layout.setAlignment(QtCore.Qt.AlignTop)
         self.setLayout(layout)
-        self.setWindowTitle('Module Information')
+        self.setWindowTitle('Module Info')
 
     def setReadOnly(self, read_only):
         if read_only != self.read_only:
@@ -124,27 +188,52 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
                 widget.setReadOnly(read_only)
 
     def set_controller(self, controller):
+        if self.controller == controller:
+            return
         self.controller = controller
         for ports_list in self.ports_lists:
             ports_list.set_controller(controller)
         self.annotations.set_controller(controller)
 
-        scene = self.controller.current_pipeline_scene
-        selected_ids = scene.get_selected_module_ids() 
-        modules = [self.controller.current_pipeline.modules[i] 
-                   for i in selected_ids]
-        if len(modules) == 1:
-            self.update_module(modules[0])
+        if self.controller is not None:
+            scene = self.controller.current_pipeline_scene
+            selected_ids = scene.get_selected_module_ids() 
+            modules = [self.controller.current_pipeline.modules[i] 
+                       for i in selected_ids]
+            if len(modules) == 1:
+                self.update_module(modules[0])
+            else:
+                self.update_module(None)
         else:
-            self.update_module(None)
+            self.update_module()
+
+    def set_visible(self, enabled):
+        if enabled and \
+           self.module is None and \
+           not self.toolWindow().isFloating() and \
+           not QVersionProp.instance().toolWindow().isFloating() and \
+           not self.toolWindow().visibleRegion().isEmpty():
+            QVersionProp.instance().set_visible(True)
+        else:
+            super(QModuleInfo, self).set_visible(enabled)
+
 
     def update_module(self, module=None):
+        for plist in self.ports_lists:
+            plist.types_visible = self.types_visible
+            plist.ports_visible = self.ports_visible
         self.module = module
         for ports_list in self.ports_lists:
             ports_list.update_module(module)
         self.annotations.updateModule(module)
 
         if module is None:
+            # We show the version properties tab if both are tabified and
+            # self is visible
+            if not self.toolWindow().isFloating() and \
+               not QVersionProp.instance().toolWindow().isFloating() and \
+               not self.toolWindow().visibleRegion().isEmpty():
+                QVersionProp.instance().set_visible(True)
             self.name_edit.setText("")
             if not versions_increasing(QtCore.QT_VERSION_STR, '4.7.0'):
                 self.name_edit.setPlaceholderText("")
@@ -152,8 +241,15 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
             self.type_edit.setText("")
             # self.type_edit.setEnabled(False)
             self.package_edit.setText("")
+            self.namespace_edit.setText("")
             self.module_id.setText("")
         else:
+            # We show self  if both are tabified and
+            # the version properties tab is visible
+            if not self.toolWindow().isFloating() and \
+               not QVersionProp.instance().toolWindow().isFloating() and \
+               not QVersionProp.instance().toolWindow().visibleRegion().isEmpty():
+                self.set_visible(True)
             if module.has_annotation_with_key('__desc__'):
                 label = module.get_annotation_by_key('__desc__').value.strip()
             else:
@@ -163,13 +259,14 @@ class QModuleInfo(QtGui.QWidget, QVistrailsPaletteInterface):
                                                      '4.7.0'):
                 self.name_edit.setPlaceholderText(self.module.name)
 
-            # self.name_edit.setEnabled(True)
             self.type_edit.setText(self.module.name)
-            # self.type_edit.setEnabled(True)
             self.package_edit.setText(self.module.package)
-            # self.package_edit.setEnabled(True)
+            if self.module.namespace is not None:
+                self.namespace_edit.setText(self.module.namespace.replace('|',
+                                                                          '/'))
+            else:
+                self.namespace_edit.setText('')
             self.module_id.setText('%d' % self.module.id)
-            # self.module_id.setEnabled(True)
 
     def name_editing_finished(self):
         # updating module may trigger a second call so we check for that
diff --git a/vistrails/gui/module_options.py b/vistrails/gui/module_options.py
new file mode 100644
index 0000000..408967b
--- /dev/null
+++ b/vistrails/gui/module_options.py
@@ -0,0 +1,536 @@
+###############################################################################
+
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+""" This file contains a dialog for editing options for how the given
+    VisTrails module is executed.
+
+QModuleOptions
+"""
+from __future__ import division
+
+from PyQt4 import QtCore, QtGui
+from vistrails.core.vistrail.module_control_param import ModuleControlParam
+from vistrails.gui.theme import CurrentTheme
+from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
+
+import json
+import unittest
+
+###############################################################################
+
+class QModuleOptions(QtGui.QDialog, QVistrailsPaletteInterface):
+    """
+    QModuleIteration is a dialog for editing module looping options.
+
+    """
+    def __init__(self, parent=None):
+        """ 
+        QModuleIteration(parent)
+        -> None
+
+        """
+        QtGui.QDialog.__init__(self, parent)
+        self.setWindowTitle("Module Execution Options")
+        self.createButtons()
+        self.update_module()
+
+    def createButtons(self):
+        """ createButtons() -> None
+        Create and connect signals to Ok & Cancel button
+        
+        """
+        self.controller = None
+        self.state_changed = False
+        self.module = None
+        self.setLayout(QtGui.QVBoxLayout())
+        # self.layout().addStrut()
+        layout = QtGui.QHBoxLayout()
+        type_group = QtGui.QButtonGroup(self) # Number group
+        layout.addWidget(QtGui.QLabel("Port list combination method:"))
+        self.pairwiseButton = QtGui.QRadioButton("Pairwise")
+        self.pairwiseButton.setToolTip("Execute multiple looped input ports pairwise:"
+                                       " [(A, B), (C, D)] -> [(A, C), (B, D)]")
+        type_group.addButton(self.pairwiseButton)
+        layout.addWidget(self.pairwiseButton)
+        layout.setStretch(0, 0)
+        self.cartesianButton = QtGui.QRadioButton("Cartesian")
+        self.cartesianButton.setToolTip("Execute multiple looped input ports using cartesian product:"
+                                       " [(A, B), (C, D)] -> [(A, C), (A, D), (B, C), (B, D)]")
+        self.cartesianButton.setChecked(True)
+        type_group.addButton(self.cartesianButton)
+        layout.addWidget(self.cartesianButton)
+        layout.setStretch(1, 0)
+        self.customButton = QtGui.QRadioButton("Custom")
+        self.customButton.setToolTip("Build a custom combination using pairwise/cartesian functions")
+        type_group.addButton(self.customButton)
+        layout.addWidget(self.customButton)
+        layout.setStretch(2, 0)
+        layout.addStretch(1)
+        self.layout().addLayout(layout)
+        self.layout().setStretch(0, 0)
+
+        self.portCombiner = QPortCombineTreeWidget()
+        self.layout().addWidget(self.portCombiner)
+        self.portCombiner.setVisible(False)
+        
+        whileLayout = QtGui.QVBoxLayout()
+
+        self.whileButton = QtGui.QCheckBox("While Loop")
+        self.whileButton.setToolTip('Repeatedly execute module until a specified output port has a false value')
+        whileLayout.addWidget(self.whileButton)
+        whileLayout.setStretch(0, 0)
+
+        layout = QtGui.QHBoxLayout()
+        self.condLabel = QtGui.QLabel("Condition output port:")
+        layout.addWidget(self.condLabel)
+        layout.setStretch(0, 0)
+        self.condEdit = QtGui.QLineEdit()
+        self.condEdit.setToolTip('Name of output port containing the condition of the loop')
+        layout.addWidget(self.condEdit)
+        layout.setStretch(1, 1)
+        whileLayout.addLayout(layout)
+        whileLayout.setStretch(1, 0)
+
+        layout = QtGui.QHBoxLayout()
+        self.maxLabel = QtGui.QLabel("Max iterations:")
+        layout.addWidget(self.maxLabel)
+        layout.setStretch(0, 0)
+        self.maxEdit = QtGui.QLineEdit()
+        self.maxEdit.setValidator(QtGui.QIntValidator())
+        self.maxEdit.setToolTip('Fail after this number of iterations have been reached (default=20)')
+        layout.addWidget(self.maxEdit)
+        layout.setStretch(1, 1)
+        whileLayout.addLayout(layout)
+        whileLayout.setStretch(2, 0)
+
+        layout = QtGui.QHBoxLayout()
+        self.delayLabel = QtGui.QLabel("Delay:")
+        layout.addWidget(self.delayLabel)
+        layout.setStretch(0, 0)
+        self.delayEdit = QtGui.QLineEdit()
+        self.delayEdit.setValidator(QtGui.QDoubleValidator(self))
+        self.delayEdit.setToolTip('Delay between iterations in fractions of seconds')
+        layout.addWidget(self.delayEdit)
+        layout.setStretch(1, 1)
+        whileLayout.addLayout(layout)
+        whileLayout.setStretch(2, 0)
+
+        layout = QtGui.QHBoxLayout()
+        self.feedInputLabel = QtGui.QLabel("Feedback Input port:")
+        layout.addWidget(self.feedInputLabel)
+        layout.setStretch(0, 0)
+        self.feedInputEdit = QtGui.QLineEdit()
+        self.feedInputEdit.setToolTip('Name of input port to feed the value from last iteration')
+        layout.addWidget(self.feedInputEdit)
+        layout.setStretch(1, 1)
+        whileLayout.addLayout(layout)
+        whileLayout.setStretch(3, 0)
+
+        layout = QtGui.QHBoxLayout()
+        self.feedOutputLabel = QtGui.QLabel("Feedback Output port:")
+        layout.addWidget(self.feedOutputLabel)
+        layout.setStretch(0, 0)
+        self.feedOutputEdit = QtGui.QLineEdit()
+        self.feedOutputEdit.setToolTip('Name of output port to feed to next iteration')
+        layout.addWidget(self.feedOutputEdit)
+        layout.setStretch(1, 1)
+        whileLayout.addLayout(layout)
+        whileLayout.setStretch(4, 0)
+
+        whileLayout.addStretch(1)
+        self.layout().addLayout(whileLayout)
+
+        self.jobCacheButton = QtGui.QCheckBox("Cache Output Persistently")
+        self.jobCacheButton.setToolTip('Cache the module results persistently to disk. (outputs must be constants)')
+        self.layout().addWidget(self.jobCacheButton)
+        self.layout().setStretch(2, 0)
+
+        self.layout().addStretch(1)
+        self.buttonLayout = QtGui.QHBoxLayout()
+        self.buttonLayout.setMargin(5)
+        self.saveButton = QtGui.QPushButton('&Save', self)
+        self.saveButton.setFixedWidth(100)
+        self.saveButton.setEnabled(False)
+        self.buttonLayout.addWidget(self.saveButton)
+        self.resetButton = QtGui.QPushButton('&Reset', self)
+        self.resetButton.setFixedWidth(100)
+        self.resetButton.setEnabled(False)
+        self.buttonLayout.addWidget(self.resetButton)
+        self.layout().addLayout(self.buttonLayout)
+        self.connect(self.saveButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.saveTriggered)
+        self.connect(self.resetButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.resetTriggered)        
+        self.layout().setStretch(3, 0)
+        self.update_module()
+        self.pairwiseButton.toggled.connect(self.stateChanged)
+        self.cartesianButton.toggled.connect(self.stateChanged)
+        self.customButton.toggled.connect(self.stateChanged)
+        self.customButton.toggled.connect(self.customToggled)
+        self.portCombiner.itemChanged.connect(self.stateChanged)
+        self.whileButton.toggled.connect(self.stateChanged)
+        self.whileButton.toggled.connect(self.whileToggled)
+        self.condEdit.textChanged.connect(self.stateChanged)
+        self.maxEdit.textChanged.connect(self.stateChanged)
+        self.delayEdit.textChanged.connect(self.stateChanged)
+        self.feedInputEdit.textChanged.connect(self.stateChanged)
+        self.feedOutputEdit.textChanged.connect(self.stateChanged)
+        self.jobCacheButton.toggled.connect(self.stateChanged)
+
+    def sizeHint(self):
+        """ sizeHint() -> QSize
+        Return the recommended size of the configuration window
+        
+        """
+        return QtCore.QSize(512, 256)
+
+    def saveTriggered(self, checked = False):
+        """ saveTriggered(checked: bool) -> None
+        Update vistrail controller and module when the user click Ok
+        
+        """
+        if self.updateVistrail():
+            self.saveButton.setEnabled(False)
+            self.resetButton.setEnabled(False)
+            self.state_changed = False
+            self.emit(QtCore.SIGNAL("stateChanged"))
+            self.emit(QtCore.SIGNAL('doneConfigure'), self.module.id)
+            
+    def resetTriggered(self, checked = False):
+        self.update_module(self.module)
+
+    def stateChanged(self, state=False, other=None):
+        self.saveButton.setEnabled(True)
+        self.resetButton.setEnabled(True)
+        self.state_changed = True
+
+    def customToggled(self, state=False):
+        self.portCombiner.setVisible(state)
+
+    def whileToggled(self, state=False):
+        if state:
+            self.condEdit.setVisible(True)
+            self.maxEdit.setVisible(True)
+            self.delayEdit.setVisible(True)
+            self.feedInputEdit.setVisible(True)
+            self.feedOutputEdit.setVisible(True)
+            self.condLabel.setVisible(True)
+            self.maxLabel.setVisible(True)
+            self.delayLabel.setVisible(True)
+            self.feedInputLabel.setVisible(True)
+            self.feedOutputLabel.setVisible(True)
+            self.condEdit.setText('')
+            self.maxEdit.setText('')
+            self.delayEdit.setText('')
+            self.feedInputEdit.setText('')
+            self.feedOutputEdit.setText('')
+        else:
+            self.condEdit.setVisible(False)
+            self.maxEdit.setVisible(False)
+            self.delayEdit.setVisible(False)
+            self.feedInputEdit.setVisible(False)
+            self.feedOutputEdit.setVisible(False)
+            self.condLabel.setVisible(False)
+            self.maxLabel.setVisible(False)
+            self.delayLabel.setVisible(False)
+            self.feedInputLabel.setVisible(False)
+            self.feedOutputLabel.setVisible(False)
+    
+    def closeEvent(self, event):
+        self.askToSaveChanges()
+        event.accept()
+
+    def set_controller(self, controller):
+        self.controller = controller
+        if not controller:
+            return
+        scene = controller.current_pipeline_scene
+        selected_ids = scene.get_selected_module_ids() 
+        modules = [controller.current_pipeline.modules[i] 
+                   for i in selected_ids]
+        if len(modules) == 1:
+            self.update_module(modules[0])
+        else:
+            self.update_module(None)
+
+    def update_module(self, module=None):
+        self.module = module
+        if not module:
+            self.pairwiseButton.setEnabled(False)
+            self.cartesianButton.setEnabled(False)
+            self.customButton.setEnabled(False)
+            self.whileButton.setEnabled(False)
+            self.condEdit.setVisible(False)
+            self.maxEdit.setVisible(False)
+            self.delayEdit.setVisible(False)
+            self.feedInputEdit.setVisible(False)
+            self.feedOutputEdit.setVisible(False)
+            self.condLabel.setVisible(False)
+            self.maxLabel.setVisible(False)
+            self.delayLabel.setVisible(False)
+            self.feedInputLabel.setVisible(False)
+            self.feedOutputLabel.setVisible(False)
+            self.portCombiner.setVisible(False)
+            self.jobCacheButton.setEnabled(False)
+            self.state_changed = False
+            self.saveButton.setEnabled(False)
+            self.resetButton.setEnabled(False)
+            return
+        # set defaults
+        self.pairwiseButton.setEnabled(True)
+        self.cartesianButton.setEnabled(True)
+        self.cartesianButton.setChecked(True)
+        self.customButton.setEnabled(True)
+
+        self.whileButton.setEnabled(True)
+        self.whileButton.setChecked(False)
+        self.condEdit.setVisible(False)
+        self.maxEdit.setVisible(False)
+        self.delayEdit.setVisible(False)
+        self.feedInputEdit.setVisible(False)
+        self.feedOutputEdit.setVisible(False)
+        self.condLabel.setVisible(False)
+        self.maxLabel.setVisible(False)
+        self.delayLabel.setVisible(False)
+        self.feedInputLabel.setVisible(False)
+        self.feedOutputLabel.setVisible(False)
+        self.portCombiner.setVisible(False)
+        self.portCombiner.setDefault(module)
+        self.jobCacheButton.setEnabled(True)
+        self.jobCacheButton.setChecked(False)
+        if module.has_control_parameter_with_name(ModuleControlParam.LOOP_KEY):
+            type = module.get_control_parameter_by_name(ModuleControlParam.LOOP_KEY).value
+            self.pairwiseButton.setChecked(type=='pairwise')
+            self.cartesianButton.setChecked(type=='cartesian')
+            self.customButton.setChecked(type not in ['pairwise', 'cartesian'])
+            self.portCombiner.setVisible(type not in ['pairwise', 'cartesian'])
+            if type not in ['pairwise', 'cartesian']:
+                self.portCombiner.setValue(type)
+        if module.has_control_parameter_with_name(ModuleControlParam.WHILE_COND_KEY) or \
+           module.has_control_parameter_with_name(ModuleControlParam.WHILE_MAX_KEY):
+            self.whileButton.setChecked(True)
+        if module.has_control_parameter_with_name(ModuleControlParam.WHILE_COND_KEY):
+            cond = module.get_control_parameter_by_name(ModuleControlParam.WHILE_COND_KEY).value
+            self.condEdit.setText(cond)
+        if module.has_control_parameter_with_name(ModuleControlParam.WHILE_MAX_KEY):
+            max = module.get_control_parameter_by_name(ModuleControlParam.WHILE_MAX_KEY).value
+            self.maxEdit.setText(max)
+        if module.has_control_parameter_with_name(ModuleControlParam.WHILE_DELAY_KEY):
+            delay = module.get_control_parameter_by_name(ModuleControlParam.WHILE_DELAY_KEY).value
+            self.delayEdit.setText(delay)
+        if module.has_control_parameter_with_name(ModuleControlParam.WHILE_INPUT_KEY):
+            input = module.get_control_parameter_by_name(ModuleControlParam.WHILE_INPUT_KEY).value
+            self.feedInputEdit.setText(input)
+        if module.has_control_parameter_with_name(ModuleControlParam.WHILE_OUTPUT_KEY):
+            output = module.get_control_parameter_by_name(ModuleControlParam.WHILE_OUTPUT_KEY).value
+            self.feedOutputEdit.setText(output)
+        if module.has_control_parameter_with_name(ModuleControlParam.JOB_CACHE_KEY):
+            jobCache = module.get_control_parameter_by_name(ModuleControlParam.JOB_CACHE_KEY).value
+            self.jobCacheButton.setChecked(jobCache.lower()=='true')
+        self.state_changed = False
+        self.saveButton.setEnabled(False)
+        self.resetButton.setEnabled(False)
+
+    def updateVistrail(self):
+        values = []
+        if self.pairwiseButton.isChecked():
+            value = 'pairwise'
+        elif self.cartesianButton.isChecked():
+            value = 'cartesian'
+        else:
+            value = self.portCombiner.getValue()
+        values.append((ModuleControlParam.LOOP_KEY, value))
+        _while = self.whileButton.isChecked()
+        values.append((ModuleControlParam.WHILE_COND_KEY,
+                       _while and self.condEdit.text()))
+        values.append((ModuleControlParam.WHILE_MAX_KEY,
+                       _while and self.maxEdit.text()))
+        values.append((ModuleControlParam.WHILE_DELAY_KEY,
+                       _while and self.delayEdit.text()))
+        values.append((ModuleControlParam.WHILE_INPUT_KEY,
+                       _while and self.feedInputEdit.text()))
+        values.append((ModuleControlParam.WHILE_OUTPUT_KEY,
+                       _while and self.feedOutputEdit.text()))
+        jobCache = self.jobCacheButton.isChecked()
+        values.append((ModuleControlParam.JOB_CACHE_KEY,
+                       [False, 'true'][jobCache]))
+        for name, value in values:
+            if value:
+                if (not self.module.has_control_parameter_with_name(name) or
+                        value != self.module.get_control_parameter_by_name(name).value):
+                    if self.module.has_control_parameter_with_name(name):
+                        self.controller.delete_control_parameter(name,
+                                                                 self.module.id)
+                    self.controller.add_control_parameter((name, value),
+                                                          self.module.id)
+            elif self.module.has_control_parameter_with_name(name):
+                self.controller.delete_control_parameter(name, self.module.id)
+        return True
+
+    def activate(self):
+        if self.isVisible() == False:
+            self.show()
+        self.activateWindow()
+
+PORTITEM = 1000
+DOTITEM = 1001
+CROSSITEM = 1002
+class PortItem(QtGui.QTreeWidgetItem):
+    def __init__(self, port_name, parent=None):
+        QtGui.QTreeWidgetItem.__init__(self, parent, PORTITEM)
+        self.setText(0, port_name)
+        self.setFlags(self.flags() & ~QtCore.Qt.ItemIsDropEnabled)
+
+class DotItem(QtGui.QTreeWidgetItem):
+    def __init__(self, parent=None):
+        QtGui.QTreeWidgetItem.__init__(self, parent, DOTITEM)
+        self.setExpanded(True)
+        self.setIcon(0, CurrentTheme.DOT_PRODUCT_ICON)
+        self.setText(0, 'Dot')
+
+class CrossItem(QtGui.QTreeWidgetItem):
+    def __init__(self, parent=None):
+        QtGui.QTreeWidgetItem.__init__(self, parent, CROSSITEM)
+        self.setExpanded(True)
+        self.setIcon(0, CurrentTheme.CROSS_PRODUCT_ICON)
+        self.setText(0, 'Cross')
+
+class QPortCombineTreeWidget(QtGui.QTreeWidget):
+    def __init__(self, parent=None):
+        QtGui.QTreeWidget.__init__(self, parent)
+        self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
+        self.header().hide()
+        self.setExpandsOnDoubleClick(False)
+        self.setItemsExpandable(False)
+        self.setRootIsDecorated(False)
+        self.expandAll()
+        self.setToolTip("Right-click to add dot/cross product. Rearrange "
+                        "items to get suitable order. 'Del' key deletes "
+                        "selected product.")
+
+    def dropEvent(self, event):
+        QtGui.QTreeWidget.dropEvent(self, event)
+        self.expandAll()
+
+    def loadNode(self, parent, node):
+        # populate widget from json struct
+        if isinstance(node, basestring):
+            PortItem(node, parent)
+        else:
+            item = DotItem(parent) if node[0] == 'pairwise' \
+                                   else CrossItem(parent)
+            for i in node[1:]:
+                self.loadNode(item, i)
+        
+    def saveNode(self, item):
+        # populate json struct from widget items
+        if item.type()==PORTITEM:
+            return item.text(0)
+        L = ['pairwise'] if item.type()==DOTITEM else ['cartesian']
+        L.extend([self.saveNode(item.child(i))
+                  for i in xrange(item.childCount())])
+        L = [i for i in L if i is not None]
+        if len(L)<2:
+            L = None
+        return L
+    
+    def setValue(self, value):
+        self.clear()
+        value = json.loads(value)
+        for v in value[1:]:
+            self.loadNode(self.invisibleRootItem(), v)
+    
+    def getValue(self):
+        nodes = [self.topLevelItem(i)
+                 for i in xrange(self.topLevelItemCount())]
+        L = ['cartesian'] # default
+        L.extend([self.saveNode(node) for node in nodes])
+        L = [i for i in L if i is not None]
+        if len(L)<2:
+            L = None
+        return json.dumps(L)
+
+    def setDefault(self, module):
+        self.clear()
+        if not module:
+            return
+        for port_name in module.iterated_ports:
+            PortItem(port_name, self)
+            
+    def contextMenuEvent(self, event):
+        menu = QtGui.QMenu()
+        dotAction = QtGui.QAction(CurrentTheme.DOT_PRODUCT_ICON,
+                                  'Add Pairwise Product', self)
+        dotAction.triggered.connect(self.addDot)
+        menu.addAction(dotAction)
+        crossAction = QtGui.QAction(CurrentTheme.CROSS_PRODUCT_ICON,
+                                    'Add Cartesian Product', self)
+        crossAction.triggered.connect(self.addCross)
+        menu.addAction(crossAction)
+        menu.exec_(event.globalPos())
+        event.accept()
+
+    def addDot(self):
+        DotItem(self)
+
+    def addCross(self):
+        CrossItem(self)
+
+    def keyPressEvent(self, event):
+        """ keyPressEvent(event: QKeyEvent) -> None
+        Capture 'Del', 'Backspace' for deleting items.
+        Ctrl+C, Ctrl+V, Ctrl+A for copy, paste and select all
+        
+        """
+        items = self.selectedItems()
+        if (len(items)==1 and \
+            event.key() in [QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete]) and \
+            type(items[0]) in [DotItem, CrossItem] and\
+            not items[0].childCount():
+            item = items[0]
+            if item.parent():
+                item.parent().takeChild(item.parent().indexOfChild(item))
+            else:
+                self.takeTopLevelItem(self.indexOfTopLevelItem(item))
+        else:
+            QtGui.QTreeWidget.keyPressEvent(self, event)
+
+class TestIterationGui(unittest.TestCase):
+    def testGetSet(self):
+        p = QPortCombineTreeWidget()
+        v = '["cartesian", ["pairwise", "a", "b"], "c"]'
+        p.setValue(v)
+        self.assertEqual(v, p.getValue())
diff --git a/vistrails/gui/module_palette.py b/vistrails/gui/module_palette.py
index 36668f0..1018e4b 100644
--- a/vistrails/gui/module_palette.py
+++ b/vistrails/gui/module_palette.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,6 +40,8 @@ QModulePalette
 QModuleTreeWidget
 QModuleTreeWidgetItem
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core import get_vistrails_application
 from vistrails.core import debug
@@ -50,10 +53,9 @@ from vistrails.gui.common_widgets import (QSearchTreeWindow,
 from vistrails.gui.module_documentation import QModuleDocumentation
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
-import weakref
 
 ################################################################################
-                
+
 class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
     """
     QModulePalette just inherits from QSearchTreeWindow to have its
@@ -66,12 +68,12 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
         self.packages = {}
         self.namespaces = {}
         self.addButtonsToToolBar()
-        
+
     def addButtonsToToolBar(self):
         self.expandAction = QtGui.QAction(CurrentTheme.EXPAND_ALL_ICON,
                                            "Expand All", self.toolWindow().toolbar,
                                            triggered=self.expandAll)
-        
+
         self.collapseAction = QtGui.QAction(CurrentTheme.COLLAPSE_ALL_ICON,
                                            "Collapse All", self.toolWindow().toolbar,
                                            triggered=self.collapseAll)
@@ -79,17 +81,17 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
                                                self.collapseAction)
         self.toolWindow().toolbar.insertAction(self.toolWindow().pinAction,
                                                self.expandAction)
-        
+
     def expandAll(self):
         self.treeWidget.expandAll()
-    
+
     def collapseAll(self):
         self.treeWidget.collapseAll()
 
     def link_registry(self):
         self.updateFromModuleRegistry()
         self.connect_registry_signals()
-        
+
 
     def connect_registry_signals(self):
         app = get_vistrails_application()
@@ -101,44 +103,28 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
         app.register_notification("reg_hide_module", self.hideModule)
         app.register_notification("reg_module_updated", self.switchDescriptors)
 
-        # registry = get_module_registry()
-        # self.connect(registry.signals, registry.signals.new_package_signal,
-        #              self.newPackage)
-        # self.connect(registry.signals, registry.signals.new_module_signal,
-        #              self.newModule)
-        # self.connect(registry.signals, registry.signals.deleted_module_signal,
-        #              self.deletedModule)
-        # self.connect(registry.signals, registry.signals.deleted_package_signal,
-        #              self.deletedPackage)        
-        # self.connect(registry.signals, registry.signals.show_module_signal,
-        #              self.showModule)
-        # self.connect(registry.signals, registry.signals.hide_module_signal,
-        #              self.hideModule)
-        # self.connect(registry.signals, registry.signals.module_updated_signal,
-        #              self.switchDescriptors)
-    
     def createTreeWidget(self):
         """ createTreeWidget() -> QModuleTreeWidget
         Return the search tree widget for this window
-        
+
         """
         self.setWindowTitle('Modules')
         return QModuleTreeWidget(self)
 
     def findModule(self, descriptor):
         moduleName = descriptor.name
-        
+
         items = [x for x in
                  self.treeWidget.findItems(moduleName,
-                                           QtCore.Qt.MatchExactly | 
-                                           QtCore.Qt.MatchWrap | 
+                                           QtCore.Qt.MatchExactly |
+                                           QtCore.Qt.MatchWrap |
                                            QtCore.Qt.MatchRecursive)
                  if not x.is_top_level() and x.descriptor == descriptor]
         if len(items) <> 1:
-            raise VistrailsInternalError("Expected one item (%s), got %d: %s" % 
+            raise VistrailsInternalError("Expected one item (%s), got %d: %s" %
                                          (moduleName,
                                           len(items),
-                                          ";".join(x.descriptor.name 
+                                          ";".join(x.descriptor.name
                                                    for x in items)))
         item = items[0]
         return item
@@ -175,10 +161,14 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
         """ deletedPackage(package):
         A package has been deleted from VisTrails
         """
-        item = self.packages[package.identifier]()        
-        index = self.treeWidget.indexOfTopLevelItem(item)
-        self.treeWidget.takeTopLevelItem(index)
-        del self.packages[package.identifier]
+        try:
+            item = self.packages[package.identifier]
+        except KeyError:
+            pass
+        else:
+            index = self.treeWidget.indexOfTopLevelItem(item)
+            self.treeWidget.takeTopLevelItem(index)
+            del self.packages[package.identifier]
 
     def newPackage(self, package_identifier, prepend=False):
         # prepend places at the front of the list of packages,
@@ -188,19 +178,19 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
             return self.packages[package_identifier]
         registry = get_module_registry()
         package_name = registry.packages[package_identifier].name
-        package_item = \
-            QPackageTreeWidgetItem(None, [package_name])
-        self.packages[package_identifier] = weakref.ref(package_item)
+        package_item = QPackageTreeWidgetItem(None,
+                                              package_name, package_identifier)
+        self.packages[package_identifier] = package_item
         if prepend:
             self.treeWidget.insertTopLevelItem(0, package_item)
         else:
             self.treeWidget.addTopLevelItem(package_item)
         return package_item
-            
+
     def newModule(self, descriptor, recurse=False):
         """ newModule(descriptor: core.modules.module_registry.ModuleDescriptor)
         A new module has been added to VisTrails
-        
+
         """
         if not descriptor.module_abstract(): # and not descriptor.is_hidden:
             # skip abstract modules, they're no longer in the tree
@@ -210,7 +200,7 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
             if package_identifier not in self.packages:
                 package_item = self.newPackage(package_identifier, True)
             else:
-                package_item = self.packages[package_identifier]()
+                package_item = self.packages[package_identifier]
 
             if descriptor.ghost_namespace is not None:
                 namespace = descriptor.ghost_namespace
@@ -235,7 +225,7 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
         """ updateFromModuleRegistry(packageName: str) -> None
         Setup this tree widget to show modules currently inside
         module_registry.registry
-        
+
         """
 
         self.treeWidget.setSortingEnabled(False)
@@ -245,7 +235,6 @@ class QModulePalette(QSearchTreeWindow, QVistrailsPaletteInterface):
         self.newModule(registry.root_descriptor, True)
         self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
         self.treeWidget.setSortingEnabled(True)
-#        self.treeWidget.expandAll()
 
     def sizeHint(self):
         return QtCore.QSize(256, 760)
@@ -254,7 +243,7 @@ class QModuleTreeWidget(QSearchTreeWidget):
     """
     QModuleTreeWidget is a subclass of QSearchTreeWidget to display all
     Vistrails Module
-    
+
     """
     def __init__(self, parent=None):
         """ QModuleTreeWidget(parent: QWidget) -> QModuleTreeWidget
@@ -273,9 +262,9 @@ class QModuleTreeWidget(QSearchTreeWidget):
     def onItemPressed(self, item, column):
         """ onItemPressed(item: QTreeWidgetItem, column: int) -> None
         Expand/Collapse top-level item when the mouse is pressed
-        
+
         """
-        if item and item.parent() == None:
+        if item and item.parent() is None:
             self.setItemExpanded(item, not self.isItemExpanded(item))
 
     def contextMenuEvent(self, event):
@@ -287,34 +276,32 @@ class QModuleTreeWidget(QSearchTreeWidget):
             while p.parent():
                 p = p.parent()
             # get package identifier
-            identifiers = [i for i, j in self.parent().packages.iteritems()
-                           if j == weakref.ref(p)]
-            if identifiers:
-                try:
-                    identifier = identifiers[0]
-                    registry = get_module_registry()
-                    package = registry.packages[identifier]
-                    if package.has_contextMenuName():
-                        name = package.contextMenuName(str(item.text(0)))
-                        if name:
-                            act = QtGui.QAction(name, self)
-                            act.setStatusTip(name)
-                            def callMenu():
-                                if package.has_callContextMenu():
-                                    name = package.callContextMenu(str(item.text(0)))
-
-                            QtCore.QObject.connect(act,
-                                                   QtCore.SIGNAL("triggered()"),
-                                                   callMenu)
-                            menu = QtGui.QMenu(self)
-                            menu.addAction(act)
-                            menu.exec_(event.globalPos())
-                        return
-                except Exception, e:
-                    debug.warning("Got exception trying to display %s's "
-                                  "context menu in the palette: %s: %s" % (
-                                  package.name,
-                                  type(e).__name__, ', '.join(e.args)))
+            assert isinstance(p, QPackageTreeWidgetItem)
+            identifier = p.identifier
+            registry = get_module_registry()
+            package = registry.packages[identifier]
+            try:
+                if package.has_contextMenuName():
+                    name = package.contextMenuName(item.text(0))
+                    if name:
+                        act = QtGui.QAction(name, self)
+                        act.setStatusTip(name)
+                        def callMenu():
+                            if package.has_callContextMenu():
+                                name = package.callContextMenu(item.text(0))
+
+                        QtCore.QObject.connect(act,
+                                               QtCore.SIGNAL("triggered()"),
+                                               callMenu)
+                        menu = QtGui.QMenu(self)
+                        menu.addAction(act)
+                        menu.exec_(event.globalPos())
+                    return
+            except Exception, e:
+                debug.warning("Got exception trying to display %s's "
+                              "context menu in the palette: %s: %s" % (
+                              package.name,
+                              type(e).__name__, ', '.join(e.args)))
 
             item.contextMenuEvent(event, self)
 
@@ -325,7 +312,7 @@ class QModuleTreeWidget(QSearchTreeWidget):
             drag = QtGui.QDrag(self)
             drag.setMimeData(mime_data)
             item = mime_data.items[0]
-            
+
             app = get_vistrails_application()
             pipeline_view = app.builderWindow.get_current_controller().current_pipeline_view
             if hasattr(pipeline_view.scene(), 'add_tmp_module'):
@@ -334,41 +321,41 @@ class QModuleTreeWidget(QSearchTreeWidget):
                 pixmap = pipeline_view.paintModuleToPixmap(module_item)
 
                 drag.setPixmap(pixmap)
-                drag.setHotSpot(QtCore.QPoint(pixmap.width()/2, 
+                drag.setHotSpot(QtCore.QPoint(pixmap.width()/2,
                                               pixmap.height()/2))
                 drag.exec_(actions)
                 pipeline_view.scene().delete_tmp_module()
 
 
 class QModuleTreeWidgetItemDelegate(QtGui.QItemDelegate):
-    """    
+    """
     QModuleTreeWidgetItemDelegate will override the original
     QTreeWidget paint function to draw buttons for top-level item
     similar to QtDesigner. This mimics
     Qt/tools/designer/src/lib/shared/sheet_delegate, which is only a
     private class from QtDesigned.
-    
+
     """
     def __init__(self, view, parent):
         """ QModuleTreeWidgetItemDelegate(view: QTreeView,
                                           parent: QWidget)
                                           -> QModuleTreeWidgetItemDelegate
         Create the item delegate given the tree view
-        
+
         """
         QtGui.QItemDelegate.__init__(self, parent)
         self.treeView = view
-        self.isMac = systemType in ['Darwin']
+        self.isMac = systemType == 'Darwin'
 
     def paint(self, painter, option, index):
         """ painter(painter: QPainter, option QStyleOptionViewItem,
                     index: QModelIndex) -> None
         Repaint the top-level item to have a button-look style
-        
+
         """
         model = index.model()
         if not model.parent(index).isValid():
-            buttonOption = QtGui.QStyleOptionButton()            
+            buttonOption = QtGui.QStyleOptionButton()
             buttonOption.state = option.state
             if self.isMac:
                 buttonOption.state |= QtGui.QStyle.State_Raised
@@ -379,7 +366,7 @@ class QModuleTreeWidgetItemDelegate(QtGui.QItemDelegate):
             buttonOption.features = QtGui.QStyleOptionButton.None
 
             style = self.treeView.style()
-            
+
             style.drawControl(QtGui.QStyle.CE_PushButton,
                               buttonOption,
                               painter,
@@ -396,7 +383,7 @@ class QModuleTreeWidgetItemDelegate(QtGui.QItemDelegate):
 
             if self.treeView.isExpanded(index):
                 branchOption.state |= QtGui.QStyle.State_Open
-                
+
             style.drawPrimitive(QtGui.QStyle.PE_IndicatorBranch,
                                 branchOption,
                                 painter, self.treeView)
@@ -422,9 +409,9 @@ class QModuleTreeWidgetItemDelegate(QtGui.QItemDelegate):
     def sizeHint(self, option, index):
         """ sizeHint(option: QStyleOptionViewItem, index: QModelIndex) -> None
         Take into account the size of the top-level button
-        
+
         """
-        return (QtGui.QItemDelegate.sizeHint(self, option, index) + 
+        return (QtGui.QItemDelegate.sizeHint(self, option, index) +
                 QtCore.QSize(2, 2))
 
 
@@ -432,15 +419,15 @@ class QModuleTreeWidgetItemDelegate(QtGui.QItemDelegate):
 class QModuleTreeWidgetItem(QtGui.QTreeWidgetItem):
     """
     QModuleTreeWidgetItem represents module on QModuleTreeWidget
-    
+
     """
-    
+
     def __init__(self, descriptor, parent, labelList, is_hidden):
         """ QModuleTreeWidgetItem(descriptor: ModuleDescriptor
                                     (or None for top-level),
                                   parent: QTreeWidgetItem
                                   labelList: string)
-                                  -> QModuleTreeWidget                                  
+                                  -> QModuleTreeWidget
         Create a new tree widget item with a specific parent and
         labels
 
@@ -472,10 +459,10 @@ class QModuleTreeWidgetItem(QtGui.QTreeWidgetItem):
         elif d.module_abstract():
             # moduletree widgets for abstract modules are never
             # draggable or enabled
-            flags = flags & ~(QtCore.Qt.ItemIsDragEnabled | 
+            flags = flags & ~(QtCore.Qt.ItemIsDragEnabled |
                               QtCore.Qt.ItemIsSelectable)
         QtGui.QTreeWidgetItem.setFlags(self, flags)
-            
+
     def is_top_level(self):
         return self.descriptor is None
 
@@ -508,15 +495,15 @@ class QModuleTreeWidgetItem(QtGui.QTreeWidgetItem):
         from vistrails_window import _app
         filename = self.descriptor.module.vt_fname
         _app.openAbstraction(filename)
-        
+
     def set_descriptor(self, descriptor):
         self.descriptor = descriptor
         if descriptor:
             descriptor.set_widget(self)
 
 class QNamespaceTreeWidgetItem(QModuleTreeWidgetItem):
-    def __init__(self, parent, labelList):
-        QModuleTreeWidgetItem.__init__(self, None, parent, labelList, False)
+    def __init__(self, parent, name):
+        QModuleTreeWidgetItem.__init__(self, None, parent, [name], False)
         self.setFlags(self.flags() & ~QtCore.Qt.ItemIsDragEnabled)
         self.namespaces = {}
 
@@ -524,21 +511,22 @@ class QNamespaceTreeWidgetItem(QModuleTreeWidgetItem):
         if len(namespace_items) <= 0:
             return self
         namespace_item = namespace_items.pop(0)
-        if namespace_item in self.namespaces and self.namespaces[namespace_item]():
-            item = self.namespaces[namespace_item]()
+        if namespace_item in self.namespaces and self.namespaces[namespace_item]:
+            item = self.namespaces[namespace_item]
         else:
-            item = QNamespaceTreeWidgetItem(self, [namespace_item])
-            self.namespaces[namespace_item] = weakref.ref(item)
+            item = QNamespaceTreeWidgetItem(self, namespace_item)
+            self.namespaces[namespace_item] = item
         return item.get_namespace(namespace_items)
 
     def takeChild(self, index):
         child = self.child(index)
-        if hasattr(self, "namespaces"):
-            if str(child.text(0)) in self.namespaces:
-                del self.namespaces[str(child.text(0))]
+        if child.text(0) in self.namespaces:
+            del self.namespaces[child.text(0)]
         QModuleTreeWidgetItem.takeChild(self, index)
         if self.childCount() < 1 and self.parent():
             self.parent().takeChild(self.parent().indexOfChild(self))
 
 class QPackageTreeWidgetItem(QNamespaceTreeWidgetItem):
-    pass
+    def __init__(self, parent, name, identifier):
+        QNamespaceTreeWidgetItem.__init__(self, parent, name)
+        self.identifier = identifier
diff --git a/vistrails/gui/modules/__init__.py b/vistrails/gui/modules/__init__.py
index e2481ce..c027816 100644
--- a/vistrails/gui/modules/__init__.py
+++ b/vistrails/gui/modules/__init__.py
@@ -1,63 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
-from constant_configuration import StandardConstantWidgetBase
-from query_configuration import BaseQueryWidget
-
-def get_widget_class(module_klass):
-    klass = module_klass.get_widget_class()
-    if klass is None:
-        return StandardConstantWidgetBase
-    if isinstance(klass, tuple):
-        (path, klass_name) = klass
-        module = __import__(path, globals(), locals(), [klass_name])
-        return getattr(module, klass_name)
-    return klass
-
-def get_query_widget_class(module_klass):
-    klass = module_klass.get_query_widget_class()
-    if klass is None:
-        class DefaultQueryWidget(BaseQueryWidget):
-            def __init__(self, param, parent=None):
-                BaseQueryWidget.__init__(self, get_widget_class(module_klass), 
-                                         ["==", "!="],
-                                         param, parent)
-        return DefaultQueryWidget
-    if isinstance(klass, tuple):
-        (path, klass_name) = klass
-        module = __import__(path, globals(), locals(), [klass_name])
-        return getattr(module, klass_name)
-    return klass
+from __future__ import division
 
+pass
diff --git a/vistrails/gui/modules/constant_configuration.py b/vistrails/gui/modules/constant_configuration.py
index 8042f0c..3a47c10 100644
--- a/vistrails/gui/modules/constant_configuration.py
+++ b/vistrails/gui/modules/constant_configuration.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -40,11 +41,14 @@ constants.
 
 """
 
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.utils import any, expression, versions_increasing
 from vistrails.core import system
 from vistrails.gui.theme import CurrentTheme
 
+import copy
 import os
 
 ############################################################################
@@ -59,380 +63,313 @@ def setPlaceholderTextCompat(self, value):
 
 class ConstantWidgetMixin(object):
 
+    # subclasses need to add this signal:
+    # contentsChanged = QtCore.pyqtSignal(tuple)
+
     def __init__(self, contents=None):
+        if not hasattr(self, 'contentsChanged'):
+            raise Exception('ConstantWidget must define contentsChanged signal')
         self._last_contents = contents
+        self.psi = None
 
     def update_parent(self):
         newContents = self.contents()
+        
         if newContents != self._last_contents:
             if self.parent() and hasattr(self.parent(), 'updateMethod'):
                 self.parent().updateMethod()
             self._last_contents = newContents
-            self.emit(QtCore.SIGNAL('contentsChanged'), (self, newContents))
-
-    def setDefault(self, strValue):
-        pass
-
-class StandardConstantWidgetBase(ConstantWidgetMixin):
-    """
-    StandardConstantWidget is a basic widget to be used
-    to edit int/float/string values in VisTrails.
-
-    When creating your own widget, you can subclass from this widget if you
-    need only a QLineEdit or use your own QT widget. There are two things you
-    need to pay attention to:
-
-    1) Re-implement the contents() method so we can get the current value
-       stored in the widget.
-
-    2) When the user is done with configuration, make sure to call
-       update_parent() so VisTrails can pass that information to the Provenance
-       System. In this example we do that on focusOutEvent and when the user
-       presses the return key.
-
-    """
-    def __new__(cls, *args, **kwargs):
-        param = None
-        if len(args) > 0:
-            param = args[0]
-        if 'param' in kwargs:
-            param = kwargs['param']
+            self.contentsChanged.emit((self, newContents))
+
+class ConstantWidgetBase(ConstantWidgetMixin):
+    class FocusFilter(QtCore.QObject):
+        def __init__(self, cwidget):
+            QtCore.QObject.__init__(self, cwidget)
+            self.__cwidget = cwidget
+
+        def eventFilter(self, o, event):
+            if event.type() == QtCore.QEvent.FocusIn:
+                self.__cwidget._focus_in(event)
+            elif event.type() == QtCore.QEvent.FocusOut:
+                self.__cwidget._focus_out(event)
+            return False
+
+    def __init__(self, param):
         if param is None:
             raise ValueError("Must pass param as first argument.")
-        if param.port_spec_item and param.port_spec_item.entry_type and \
-                param.port_spec_item.entry_type.startswith("enum"):
-            return StandardConstantEnumWidget.__new__(StandardConstantEnumWidget, *args, **kwargs)
-        return StandardConstantWidget.__new__(StandardConstantWidget, *args, **kwargs)
-
-    def __init__(self, param, parent=None):
-        """__init__(param: core.vistrail.module_param.ModuleParam,
-                    parent: QWidget)
-
-        Initialize the line edit with its contents. Content type is limited
-        to 'int', 'float', and 'string'
-
-        """
-
         psi = param.port_spec_item
-        if param.strValue:
-            value = param.strValue
-        elif psi and psi.default:
+
+        if not param.strValue and psi and psi.default:
             value = psi.default
         else:
             value = param.strValue
         ConstantWidgetMixin.__init__(self, value)
 
-        # assert param.namespace == None
-        # assert param.identifier == 'org.vistrails.vistrails.basic'
-        if psi and psi.default:
+        self.psi = psi
+        if psi and psi.default and param.strValue == '':
             self.setDefault(psi.default)
-        contents = param.strValue
-        contentType = param.type
-        if contents: # do not replace old default value with empty value
-            self.setText(contents)
-        self._contentType = contentType
-
-    def setDefault(self, default):
-        # Implement this in a subclass!
-        pass
-
-    def contents(self):
-        """contents() -> str
-        Re-implement this method to make sure that it will return a string
-        representation of the value that it will be passed to the module
-        As this is a QLineEdit, we just call text()
-
-        """
-        self.update_text()
-        return str(self.text())
-
-    def setContents(self, strValue, silent=True):
-        """setContents(strValue: str) -> None
-        Re-implement this method so the widget can change its value after 
-        constructed. If silent is False, it will propagate the event back 
-        to the parent.
-        As this is a QLineEdit, we just call setText(strValue)
-        """
-        self.setText(strValue)
-        self.update_text()
-        if not silent:
-            self.update_parent()
-            
-    def update_text(self):
-        """ update_text() -> None
-        Update the text to the result of the evaluation
-
-        """
-        # FIXME: eval should pretty much never be used
-        base = expression.evaluate_expressions(self.text())
-        if self._contentType == 'String':
-            self.setText(base)
         else:
-            try:
-                self.setText(str(eval(str(base), None, None)))
-            except:
-                self.setText(base)
+            self.setContents(param.strValue)
 
+        self.__focus_filter = self.FocusFilter(self)
+        self.installEventFilter(self.__focus_filter)
 
-class StandardConstantWidget(QtGui.QLineEdit, StandardConstantWidgetBase):
-    def __init__(self, param, parent=None):
-        QtGui.QLineEdit.__init__(self, parent)
-        StandardConstantWidgetBase.__init__(self, param, parent)
-        self.connect(self,
-                     QtCore.SIGNAL('returnPressed()'),
-                     self.update_parent)
+    def watchForFocusEvents(self, widget):
+        widget.installEventFilter(self.__focus_filter)
 
     def setDefault(self, value):
-        setPlaceholderTextCompat(self, value)
+        # default to setting the contents silenty
+        self.setContents(value, True)
 
-    def sizeHint(self):
-        metrics = QtGui.QFontMetrics(self.font())
-        width = min(metrics.width(self.text())+10,70)
-        return QtCore.QSize(width, 
-                            metrics.height()+6)
-    
-    def minimumSizeHint(self):
-        return self.sizeHint()
+    def setContents(self, strValue, silent=True):
+        raise NotImplementedError("Subclass must implement this method.")
 
-    ###########################################################################
-    # event handlers
+    def contents(self):
+        raise NotImplementedError("Subclass must implement this method.")
 
-    def focusInEvent(self, event):
+    def eventFilter(self, o, event):
+        if event.type() == QtCore.QEvent.FocusIn:
+            self._focus_in(event)
+        elif event.type() == QtCore.QEvent.FocusOut:
+            self._focus_out(event)
+        return False
+
+    def _focus_in(self, event):
         """ focusInEvent(event: QEvent) -> None
         Pass the event to the parent
 
         """
-        self._contents = str(self.text())
         if self.parent():
             QtCore.QCoreApplication.sendEvent(self.parent(), event)
-        QtGui.QLineEdit.focusInEvent(self, event)
 
-    def focusOutEvent(self, event):
+    def _focus_out(self, event):
         self.update_parent()
-        QtGui.QLineEdit.focusOutEvent(self, event)
-        if self.parent():
-            QtCore.QCoreApplication.sendEvent(self.parent(), event)
-
-
-class BaseStringWidget(object): # < virtual QtGui.QWidget
-    def focusInEvent(self, event):
-        if self.parent():
-            QtCore.QCoreApplication.sendEvent(self.parent(), event)
-        super(BaseStringWidget, self).focusInEvent(event)
-
-    def focusOutEvent(self, event):
-        self.parent().update_parent()
-        super(BaseStringWidget, self).focusOutEvent(event)
         if self.parent():
             QtCore.QCoreApplication.sendEvent(self.parent(), event)
 
+class ConstantEnumWidgetBase(ConstantWidgetBase):
+    def __init__(self, param):
+        psi = param.port_spec_item
+        self.setValues(psi.values)
 
-class SingleLineStringWidget(BaseStringWidget, QtGui.QLineEdit):
-    def __init__(self, parent, contents="", default=""):
-        QtGui.QLineEdit.__init__(self, contents, parent)
-        self.setDefault(default)
-
-        self.connect(self,
-                     QtCore.SIGNAL('returnPressed()'),
-                     parent.update_parent)
-
-    def setContents(self, contents):
-        self.setText(expression.evaluate_expressions(contents))
-
-    def contents(self):
-        contents = expression.evaluate_expressions(unicode(self.text()))
-        self.setText(contents)
-        return contents
+        self.setFree(psi.entry_type == "enumFree")
+        self.setNonEmpty(psi.entry_type == "enumNonEmpty")
 
-    def setDefault(self, value):
-        setPlaceholderTextCompat(self, value)
+        ConstantWidgetBase.__init__(self, param)
 
-    def sizeHint(self):
-        metrics = QtGui.QFontMetrics(self.font())
-        width = min(metrics.width(self.text()) + 10, 70)
-        return QtCore.QSize(width,
-                            metrics.height() + 6)
+    def setValues(self, values):
+        raise NotImplementedError("Subclass must implement this method.")
 
-    def minimumSizeHint(self):
-        return self.sizeHint()
+    def setFree(self, is_free):
+        pass
 
+    def setNonEmpty(self, is_non_empty):
+        pass
 
-class MultiLineStringWidget(BaseStringWidget, QtGui.QTextEdit):
-    def __init__(self, parent, contents="", default=""):
-        QtGui.QTextEdit.__init__(self, parent)
-        self.setPlainText(contents)
-        self.setAcceptRichText(False)
-        self.setDefault(default)
+class QGraphicsLineEdit(QtGui.QGraphicsTextItem, ConstantWidgetBase):
+    """ A GraphicsItem version of ConstantWidget
 
-    def setContents(self, contents):
-        self.setPlainText(expression.evaluate_expressions(contents))
+    """
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    def __init__(self, param, parent=None):
+        QtGui.QGraphicsTextItem.__init__(self, parent)
+        self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
+        self.setTabChangesFocus(True)
+        self.setFont(CurrentTheme.MODULE_EDIT_FONT)
+        self.installEventFilter(self)
+        self.offset = 0
+        self.is_valid = True
+        self.document().setDocumentMargin(1)
+        ConstantWidgetBase.__init__(self, param)
+        self.document().contentsChanged.connect(self.ensureCursorVisible)
+
+    def setContents(self, value, silent=False):
+        self.setPlainText(expression.evaluate_expressions(value))
+        if not silent:
+            self.update_parent()
+        block = self.document().firstBlock()
+        w = self.document().documentLayout().blockBoundingRect(block).width()
+        self.offset = max(w - 140, 0)
+        block.layout().lineAt(0).setPosition(QtCore.QPointF(-self.offset,0))
+        self.validate(value)
 
     def contents(self):
         contents = expression.evaluate_expressions(unicode(self.toPlainText()))
         self.setPlainText(contents)
+        self.validate(contents)
         return contents
 
-    def setDefault(self, value):
-        pass # TODO : some magic will be required for this
-
-    def sizeHint(self):
-        metrics = QtGui.QFontMetrics(self.font())
-        width = 70
-        return QtCore.QSize(width,
-                            (metrics.height() + 1) * 3 + 5)
-
-    def minimumSizeHint(self):
-        return self.sizeHint()
-
-
-class StringWidget(QtGui.QWidget, ConstantWidgetMixin):
-    def __new__(cls, *args, **kwargs):
-        param = None
-        if len(args) > 0:
-            param = args[0]
-        if 'param' in kwargs:
-            param = kwargs['param']
-        if param is None:
-            raise ValueError("Must pass param as first argument.")
-        if param.port_spec_item and param.port_spec_item.entry_type and \
-                param.port_spec_item.entry_type.startswith("enum"):
-            # StandardConstantEnumWidget is not related to StringWidget, so
-            # we have to call __init__ as well before returning
-            # That's why there's no __new__ here
-            return StandardConstantEnumWidget(*args, **kwargs)
-        return QtGui.QWidget.__new__(cls, *args, **kwargs)
-
-    def __init__(self, param, parent=None):
-        QtGui.QWidget.__init__(self)
-        self.setLayout(QtGui.QHBoxLayout())
-        self.layout().setMargin(5)
-        self.layout().setSpacing(5)
-
-        self._widget = None
-        self._multiline = None
-        self._default = ""
-
-        self._button = QtGui.QToolButton()
-        self._button.setIcon(CurrentTheme.MULTILINE_STRING_ICON)
-        self._button.setIconSize(QtCore.QSize(12, 12))
-        self._button.setToolTip("Toggle multi-line editor")
-        self._button.setAutoRaise(True)
-        self._button.setSizePolicy(QtGui.QSizePolicy(
-                QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed))
-        self._button.setCheckable(True)
-        self.connect(self._button, QtCore.SIGNAL('toggled(bool)'),
-                     self.switch_multiline)
-        self.layout().addWidget(self._button)
-
-        psi = param.port_spec_item
-        if param.strValue:
-            value = param.strValue
-        elif psi and psi.default:
-            value = psi.default
+    def validate(self, value):
+        try:
+            self.psi and \
+            self.psi.descriptor.module.translate_to_python(value)
+        except Exception, e:
+            self.setToolTip("Invalid value: %s" % str(e))
+            self.is_valid = False
         else:
-            value = param.strValue
-        ConstantWidgetMixin.__init__(self, value)
-
-        # assert param.namespace == None
-        # assert param.identifier == 'edu.utah.sci.vistrails.basic'
-        if psi and psi.default:
-            self.setDefault(psi.default)
-        contents = param.strValue
-        self.setContents(contents)
-
-    def switch_multiline(self, multiline):
-        if multiline != self._multiline:
-            # Doing multiline -> not multiline while the widget contains
-            # line-returns is weird but won't cause loss of data, so I'm not
-            # explicitely disabling it
-            # Not that the multiline widget will pop up again next time if the
-            # user doesn't change the contents
-            self.setContents(self.contents(), multiline=multiline)
+            self.setToolTip("")
+            self.is_valid = True
 
     def setDefault(self, value):
-        self._default = value
-        if self._widget is not None:
-            self._widget.setDefault(value)
+        self.setContents(value, silent=True)
+
+    def boundingRect(self):
+        # calc font height
+        #height = CurrentTheme.MODULE_EDIT_FONT_METRIC.height()
+        height = 11 # hardcoded because fontmetric can give wrong value
+        return QtCore.QRectF(0.0, 0.0, 150, height + 3)
+
+    def eventFilter(self, obj, event):
+        if event.type() == QtCore.QEvent.KeyPress and \
+           event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
+                self.clearFocus()
+                return True
+        result = QtGui.QGraphicsTextItem.eventFilter(self, obj, event)
+        if event.type() in [QtCore.QEvent.KeyPress, QtCore.QEvent.MouseButtonPress, QtCore.QEvent.GraphicsSceneMouseMove]:
+            if not self.hasFocus():
+                self.setFocus()
+            self.ensureCursorVisible()
+        return result
+
+    def ensureCursorVisible(self):
+        block = self.document().firstBlock()
+        line = block.layout().lineAt(0)
+        pos = line.cursorToX(self.textCursor().positionInBlock())
+        cursor = self.document().documentLayout().blockBoundingRect(\
+                                     block).y() + pos[0] - line.position().x()
+        w = self.document().documentLayout().blockBoundingRect(block).width()
+        if cursor - self.offset > 130:
+            self.offset = min(w-140, self.offset + 25)
+        if cursor - self.offset < 20:
+            self.offset = max(0, self.offset - 25)
+        line.setPosition(QtCore.QPointF(-self.offset,0))
+        self.update()
 
-    def contents(self):
-        return self._widget.contents()
-
-    def setContents(self, strValue, silent=True, multiline=None):
-        if multiline is None:
-            multiline = '\n' in strValue
-        if self._multiline is not multiline:
-            self._multiline = multiline
-            if self._widget is not None:
-                self._widget.deleteLater()
-            if not multiline:
-                self._widget = SingleLineStringWidget(self,
-                                                      strValue, self._default)
-            else:
-                self._widget = MultiLineStringWidget(self,
-                                                     strValue, self._default)
-            self._button.setChecked(multiline)
-            self.layout().insertWidget(0, self._widget)
-            self.updateGeometry()
+    def focusOutEvent(self, event):
+        self.update_parent()
+        result = QtGui.QGraphicsTextItem.focusOutEvent(self, event)
+        # show last part of text
+        block = self.document().firstBlock()
+        w = self.document().documentLayout().blockBoundingRect(block).width()
+        self.offset = max(w - 140, 0)
+        block.layout().lineAt(0).setPosition(QtCore.QPointF(-self.offset,0))
+        return result
+
+    def focusInEvent(self, event):
+        result = QtGui.QGraphicsTextItem.focusInEvent(self, event)
+        # set cursor to last if not already set
+        cursor = self.textCursor()
+        cursor.setPosition(self.document().firstBlock().length()-1)
+        self.setTextCursor(cursor)
+        return result
+
+    def paint(self, painter, option, widget):
+        """ Override striped selection border
+            First unset selected and hasfocus flags
+            Then draw custom rect """
+        s = QtGui.QStyle.State_Selected | QtGui.QStyle.State_HasFocus
+        state = s.__class__(option.state) # option.state
+        option.state &= ~s
+        painter.pen().setWidth(1)
+        result = QtGui.QGraphicsTextItem.paint(self, painter, option, widget)
+        option.state = state
+
+        if state & s:
+            color = QtGui.QApplication.palette().color(QtGui.QPalette.Highlight)
+            painter.setPen(QtGui.QPen(color, 0))
+            painter.drawRect(self.boundingRect())
+        elif not self.is_valid:
+            painter.setPen(QtGui.QPen(CurrentTheme.PARAM_INVALID_COLOR, 0))
+            painter.drawRect(self.boundingRect())
         else:
-            self._widget.setContents(strValue)
+            color = QtGui.QApplication.palette().color(QtGui.QPalette.Dark)
+            painter.setPen(QtGui.QPen(color, 0))
+            painter.drawRect(self.boundingRect())
+        return result
+
+class StandardConstantWidget(QtGui.QLineEdit,ConstantWidgetBase):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    GraphicsItem = QGraphicsLineEdit
+    def __init__(self, param, parent=None):
+        QtGui.QLineEdit.__init__(self, parent)
+        ConstantWidgetBase.__init__(self, param)
+        self.connect(self, QtCore.SIGNAL("returnPressed()"), 
+                     self.update_parent)
 
+    def setContents(self, value, silent=False):
+        self.setText(expression.evaluate_expressions(value))
+        self.validate(value)
         if not silent:
             self.update_parent()
 
-    def changeEvent(self, event):
-        """ Hide button when in read-only mode
-        
-        """
-        if event.type() == QtCore.QEvent.EnabledChange:
-            self._button.setVisible(self.isEnabled())
-        return QtGui.QWidget.changeEvent(self, event)
-
-    ###########################################################################
-    # event handlers
+    def contents(self):
+        contents = expression.evaluate_expressions(unicode(self.text()))
+        self.setText(contents)
+        self.validate(contents)
+        return contents
 
-    def focusInEvent(self, event):
-        #self._contents = str(self.contents())
-        if self.parent():
-            QtCore.QCoreApplication.sendEvent(self.parent(), event)
-        super(StringWidget, self).focusInEvent(event)
+    def validate(self, value):
+        try:
+            self.psi and \
+            self.psi.descriptor.module.translate_to_python(value)
+        except Exception, e:
+            # Color background yellow and add tooltip
+            self.setStyleSheet("border:2px dashed %s;" %
+                               CurrentTheme.PARAM_INVALID_COLOR.name())
+            self.setToolTip("Invalid value: %s" % str(e))
+        else:
+            self.setStyleSheet("")
+            self.setToolTip("")
 
-    def focusOutEvent(self, event):
-        self.update_parent()
-        super(StringWidget, self).focusOutEvent(event)
-        if self.parent():
-            QtCore.QCoreApplication.sendEvent(self.parent(), event)
+    def setDefault(self, value):
+        setPlaceholderTextCompat(self, value)
 
+def findEmbeddedParentWidget(widget):
+    """ See showPopup below
 
-class StandardConstantEnumWidget(QtGui.QComboBox, StandardConstantWidgetBase):
+    """
+    if widget.graphicsProxyWidget():
+        return widget
+    elif widget.parentWidget():
+        return findEmbeddedParentWidget(widget.parentWidget())
+    return None
+
+class StandardConstantEnumWidget(QtGui.QComboBox, ConstantEnumWidgetBase):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    GraphicsItem = None
     def __init__(self, param, parent=None):
         QtGui.QComboBox.__init__(self, parent)
-        psi = param.port_spec_item
-        if psi and psi.entry_type == 'enumFree':
+        ConstantEnumWidgetBase.__init__(self, param)
+        self.connect(self,
+                     QtCore.SIGNAL('currentIndexChanged(int)'),
+                     self.update_parent)
+
+    def setValues(self, values):
+        self.addItems(values)
+
+    def setFree(self, is_free):
+        if is_free:
             self.setEditable(True)
             self.setInsertPolicy(QtGui.QComboBox.NoInsert)
             self.connect(self.lineEdit(),
                          QtCore.SIGNAL('returnPressed()'),
                          self.update_parent)
-        self.addItems(psi.values)
-        if psi and (psi.entry_type == "enumEmpty" or 
-                    psi.entry_type == 'enumFree'):
+
+    def setNonEmpty(self, is_non_empty):
+        if not is_non_empty:
             self.setCurrentIndex(-1)
-        StandardConstantWidgetBase.__init__(self, param, parent)
-        self.connect(self,
-                     QtCore.SIGNAL('currentIndexChanged(int)'),
-                     self.update_parent)
 
-    def text(self):
+    def contents(self):
         return self.currentText()
 
-    def setText(self, text):
-        idx = self.findText(text)
+    def setContents(self, strValue, silent=True):
+        idx = self.findText(strValue)
         if idx > -1:
             self.setCurrentIndex(idx)
             if self.isEditable():
-                self.lineEdit().setText(text)
+                self.lineEdit().setText(strValue)
         elif self.isEditable():
-            self.lineEdit().setText(text)
+            self.lineEdit().setText(strValue)
 
     def setDefault(self, value):
         idx = self.findText(value)
@@ -443,84 +380,76 @@ class StandardConstantEnumWidget(QtGui.QComboBox, StandardConstantWidgetBase):
         elif self.isEditable():
             setPlaceholderTextCompat(self.lineEdit(), value)
 
+    def showPopup(self, *args, **kwargs):
+        """ Fixes popup when use in a GraphicsView. See:
+             https://bugreports.qt-project.org/browse/QTBUG-14090
 
-    ###########################################################################
-    # event handlers
+        """
 
-    def focusInEvent(self, event):
-        """ focusInEvent(event: QEvent) -> None
-        Pass the event to the parent
+        QtGui.QComboBox.showPopup(self, *args, **kwargs)
+        parent = findEmbeddedParentWidget(self)
+        if parent:
+            item = parent.graphicsProxyWidget()
+            scene = item.scene()
+            view = None
+            if scene:
+                views = scene.views()
+                for v in views:
+                    if v == QtGui.QApplication.focusWidget():
+                        view = v
+                if not view:
+                    view = views[0]
+            if view:
+                br = item.boundingRect()
+                rightPos = view.mapToGlobal(view.mapFromScene(item.mapToScene(
+                                    QtCore.QPointF(br.width(), br.height()))))
+                pos = view.mapToGlobal(view.mapFromScene(item.mapToScene(
+                                             QtCore.QPointF(0, br.height()))))
+                self.view().parentWidget().move(pos)
+                self.view().parentWidget().setFixedWidth(rightPos.x()-pos.x())
+                self.view().parentWidget().installEventFilter(self)
+
+    def eventFilter(self, o, e):
+        """ See showPopup
 
         """
-        self._contents = str(self.text())
-        if self.parent():
-            QtCore.QCoreApplication.sendEvent(self.parent(), event)
-        QtGui.QComboBox.focusInEvent(self, event)
 
-    def focusOutEvent(self, event):
-        self.update_parent()
-        QtGui.QComboBox.focusOutEvent(self, event)
-        if self.parent():
-            QtCore.QCoreApplication.sendEvent(self.parent(), event)
+        if o.parentWidget() and e.type() == QtCore.QEvent.MouseButtonPress:
+            return True
+        return QtGui.QComboBox.eventFilter(self, o, e)
+
 
 
 ###############################################################################
-# File Constant Widgets
+# Multi-line String Widget
 
-class PathChooserToolButton(QtGui.QToolButton):
-    """
-    PathChooserToolButton is a toolbar button that opens a browser for
-    paths.  The lineEdit is updated with the pathname that is selected.
+class MultiLineStringWidget(QtGui.QTextEdit, ConstantWidgetBase):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    def __init__(self, param, parent=None):
+        QtGui.QTextEdit.__init__(self, parent)
+        self.setAcceptRichText(False)
+        ConstantWidgetBase.__init__(self, param)
 
-    """
-    def __init__(self, parent=None, lineEdit=None, toolTip=None):
-        """
-        PathChooserToolButton(parent: QWidget, 
-                              lineEdit: StandardConstantWidget) ->
-                 PathChooserToolButton
+    def setContents(self, contents):
+        self.setPlainText(expression.evaluate_expressions(contents))
 
-        """
-        QtGui.QToolButton.__init__(self, parent)
-        self.setIcon(QtGui.QIcon(
-                self.style().standardPixmap(QtGui.QStyle.SP_DirOpenIcon)))
-        self.setIconSize(QtCore.QSize(12,12))
-        if toolTip is None:
-            toolTip = 'Open a file chooser'
-        self.setToolTip(toolTip)
-        self.setAutoRaise(True)
-        self.lineEdit = lineEdit
-        self.connect(self,
-                     QtCore.SIGNAL('clicked()'),
-                     self.runDialog)
+    def contents(self):
+        contents = expression.evaluate_expressions(unicode(self.toPlainText()))
+        self.setPlainText(contents)
+        return contents
 
-    def setPath(self, path):
-        """
-        setPath() -> None
+    def sizeHint(self):
+        metrics = QtGui.QFontMetrics(self.font())
+        # On Mac OS X 10.8, the scrollbar doesn't show up correctly
+        # with 3 lines
+        return QtCore.QSize(QtGui.QTextEdit.sizeHint(self).width(),
+                            (metrics.height() + 1) * 4 + 5)
 
-        """
-        if self.lineEdit and path:
-            self.lineEdit.setText(path)
-            self.lineEdit.update_parent()
-            self.parent().update_parent()
-    
-    def openChooser(self):
-        text = self.lineEdit.text() or system.vistrails_data_directory()
-        fileName = QtGui.QFileDialog.getOpenFileName(self,
-                                                     'Use Filename '
-                                                     'as Value...',
-                                                     text,
-                                                     'All files '
-                                                     '(*.*)')
-        if not fileName:
-            return None
-        filename = os.path.abspath(str(QtCore.QFile.encodeName(fileName)))
-        dirName = os.path.dirname(filename)
-        system.set_vistrails_data_directory(dirName)
-        return filename
-
-    def runDialog(self):
-        path = self.openChooser()
-        self.setPath(path)
+    def minimumSizeHint(self):
+        return self.sizeHint()
+
+###############################################################################
+# File Constant Widgets
 
 class PathChooserWidget(QtGui.QWidget, ConstantWidgetMixin):
     """
@@ -529,6 +458,7 @@ class PathChooserWidget(QtGui.QWidget, ConstantWidgetMixin):
     selected.
 
     """    
+    contentsChanged = QtCore.pyqtSignal(tuple)
     def __init__(self, param, parent=None):
         """__init__(param: core.vistrail.module_param.ModuleParam,
         parent: QWidget)
@@ -540,14 +470,20 @@ class PathChooserWidget(QtGui.QWidget, ConstantWidgetMixin):
         layout = QtGui.QHBoxLayout()
         self.line_edit = StandardConstantWidget(param, self)
         self.browse_button = self.create_browse_button()
-        layout.setMargin(5)
+        layout.setMargin(0)
         layout.setSpacing(5)
         layout.addWidget(self.line_edit)
         layout.addWidget(self.browse_button)
         self.setLayout(layout)
 
-    def create_browse_button(self):
-        return PathChooserToolButton(self, self.line_edit)
+    def create_browse_button(self, cls=None):
+        from vistrails.gui.common_widgets import QPathChooserToolButton
+        if cls is None:
+            cls = QPathChooserToolButton
+        button = cls(self, self.line_edit, 
+                     defaultPath=system.vistrails_data_directory())
+        button.pathChanged.connect(self.update_parent)
+        return button
 
     def updateMethod(self):
         if self.parent() and hasattr(self.parent(), 'updateMethod'):
@@ -584,104 +520,40 @@ class PathChooserWidget(QtGui.QWidget, ConstantWidgetMixin):
         if self.parent():
             QtCore.QCoreApplication.sendEvent(self.parent(), event)
 
-class FileChooserToolButton(PathChooserToolButton):
-    def __init__(self, parent=None, lineEdit=None):
-        PathChooserToolButton.__init__(self, parent, lineEdit, 
-                                       "Open a file chooser")
-        
-    def openChooser(self):
-        text = self.lineEdit.text() or system.vistrails_data_directory()
-        fileName = QtGui.QFileDialog.getOpenFileName(self,
-                                                     'Use Filename '
-                                                     'as Value...',
-                                                     text,
-                                                     'All files '
-                                                     '(*.*)')
-        if not fileName:
-            return None
-        filename = os.path.abspath(str(QtCore.QFile.encodeName(fileName)))
-        dirName = os.path.dirname(filename)
-        system.set_vistrails_data_directory(dirName)
-        return filename
-
-
 class FileChooserWidget(PathChooserWidget):
     def create_browse_button(self):
-        return FileChooserToolButton(self, self.line_edit)
-
-
-class DirectoryChooserToolButton(PathChooserToolButton):
-    def __init__(self, parent=None, lineEdit=None):
-        PathChooserToolButton.__init__(self, parent, lineEdit, 
-                                       "Open a directory chooser")
-
-    def openChooser(self):
-        text = self.lineEdit.text() or system.vistrails_data_directory()
-        fileName = QtGui.QFileDialog.getExistingDirectory(self,
-                                                          'Use Directory '
-                                                          'as Value...',
-                                                          text)
-        if not fileName:
-            return None
-        filename = os.path.abspath(str(QtCore.QFile.encodeName(fileName)))
-        dirName = os.path.dirname(filename)
-        system.set_vistrails_data_directory(dirName)
-        return filename
-
+        from vistrails.gui.common_widgets import QFileChooserToolButton
+        return PathChooserWidget.create_browse_button(self, 
+                                                      QFileChooserToolButton)
 
 class DirectoryChooserWidget(PathChooserWidget):
     def create_browse_button(self):
-        return DirectoryChooserToolButton(self, self.line_edit)
-
-class OutputPathChooserToolButton(PathChooserToolButton):
-    def __init__(self, parent=None, lineEdit=None):
-        PathChooserToolButton.__init__(self, parent, lineEdit,
-                                       "Open a path chooser")
-    
-    def openChooser(self):
-        text = self.lineEdit.text() or system.vistrails_data_directory()
-        fileName = QtGui.QFileDialog.getSaveFileName(self,
-                                                     'Save Path',
-                                                     text,
-                                                     'All files (*.*)')
-        if not fileName:
-            return None
-        filename = os.path.abspath(str(QtCore.QFile.encodeName(fileName)))
-        dirName = os.path.dirname(filename)
-        system.set_vistrails_data_directory(dirName)
-        return filename
+        from vistrails.gui.common_widgets import QDirectoryChooserToolButton
+        return PathChooserWidget.create_browse_button(self, 
+                                                QDirectoryChooserToolButton)
 
 class OutputPathChooserWidget(PathChooserWidget):
     def create_browse_button(self):
-        return OutputPathChooserToolButton(self, self.line_edit)
+        from vistrails.gui.common_widgets import QOutputPathChooserToolButton
+        return PathChooserWidget.create_browse_button(self, 
+                                                QOutputPathChooserToolButton)
 
-class BooleanWidget(QtGui.QCheckBox, ConstantWidgetMixin):
+###############################################################################
+# Constant Boolean widget
+
+class BooleanWidget(QtGui.QCheckBox, ConstantWidgetBase):
 
     _values = ['True', 'False']
     _states = [QtCore.Qt.Checked, QtCore.Qt.Unchecked]
 
+    contentsChanged = QtCore.pyqtSignal(tuple)
     def __init__(self, param, parent=None):
         """__init__(param: core.vistrail.module_param.ModuleParam,
                     parent: QWidget)
         Initializes the line edit with contents
         """
         QtGui.QCheckBox.__init__(self, parent)
-
-        psi = param.port_spec_item
-        if param.strValue:
-            value = param.strValue
-        elif psi and psi.default:
-            value = psi.default
-        else:
-            value = param.strValue
-        ConstantWidgetMixin.__init__(self, value)
-
-        if psi and psi.default:
-            self.setDefault(psi.default)
-        if param.strValue:
-            self.setContents(param.strValue)
-
-        self._silent= False
+        ConstantWidgetBase.__init__(self, param)
         self.connect(self, QtCore.SIGNAL('stateChanged(int)'),
                      self.change_state)
         
@@ -689,28 +561,23 @@ class BooleanWidget(QtGui.QCheckBox, ConstantWidgetMixin):
         return self._values[self._states.index(self.checkState())]
 
     def setContents(self, strValue, silent=True):
-        if not strValue:
+        if strValue not in self._values:
             return
-
-        assert strValue in self._values
-        if silent:
-            self._silent = True
         self.setCheckState(self._states[self._values.index(strValue)])
         if not silent:
             self.update_parent()
-        self._silent = False
 
-    def setDefault(self, strValue):
-        self.setContents(strValue)
 
     def change_state(self, state):
-        if not self._silent:
-            self.update_parent()
+        self.update_parent()
 
 ###############################################################################
 # Constant Color widgets
 
+# FIXME ColorChooserButton remains because the parameter exploration
+# code uses it, really should be removed at some point
 class ColorChooserButton(QtGui.QPushButton):
+    contentsChanged = QtCore.pyqtSignal(tuple)
     def __init__(self, parent=None):
         QtGui.QPushButton.__init__(self, parent)
         # self.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
@@ -729,7 +596,7 @@ class ColorChooserButton(QtGui.QPushButton):
         self.setStyleSheet("border: 1px solid black; "
                            "background-color: rgb(%d, %d, %d);" %
                            (qcolor.red(), qcolor.green(), qcolor.blue()))
-        self.repaint()
+        self.update()
         if not silent:
             self.emit(QtCore.SIGNAL("color_selected"))
 
@@ -747,57 +614,103 @@ class ColorChooserButton(QtGui.QPushButton):
         else:
             self.setColor(self.qcolor)
 
+class QColorWidget(QtGui.QToolButton):
+    def __init__(self, parent=None):
+        QtGui.QToolButton.__init__(self, parent)
+        self.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
+        self.setIconSize(QtCore.QSize(26,18))        
+        self.color_str = '1.0,1.0,1.0'
+
+    def colorFromString(self, color_str):
+        color = color_str.split(',')
+        return QtGui.QColor(float(color[0])*255,
+                            float(color[1])*255,
+                            float(color[2])*255)
+
+    def stringFromColor(self, qcolor):
+        return "%s,%s,%s" % (qcolor.redF(), qcolor.greenF(), qcolor.blueF())
+
+    def buildIcon(self, qcolor, qsize):
+        pixmap = QtGui.QPixmap(qsize)
+        pixmap.fill(qcolor)
+        return QtGui.QIcon(pixmap)
+
+    def setColorString(self, color_str, silent=True):
+        if color_str != '':
+            self.color_str = color_str
+            qcolor = self.colorFromString(color_str)
+            self.setIcon(self.buildIcon(qcolor, self.iconSize()))
+            if not silent:
+                self.update_parent()
 
-class ColorWidget(QtGui.QWidget, ConstantWidgetMixin):
-    def __init__(self, param, parent=None):
-        """__init__(param: core.vistrail.module_param.ModuleParam,
-                    parent: QWidget)
+    def setColor(self, qcolor, silent=True):
+        self.setIcon(self.buildIcon(qcolor, self.iconSize()))
+        self.color_str = self.stringFromColor(qcolor)
+        if not silent:
+            self.update_parent()
+
+    def openChooser(self):
         """
-        psi = param.port_spec_item
-        if not param.strValue and psi and psi.default:
-            contents = psi.default
-            self._is_default = True
+        openChooser() -> None
+
+        """
+        qcolor = self.colorFromString(self.color_str)
+        color = QtGui.QColorDialog.getColor(qcolor, self.parent())
+        if color.isValid():
+            self.setColor(color, silent=False)
         else:
-            contents = param.strValue
-            self._is_default = not contents
-        QtGui.QWidget.__init__(self, parent)
-        ConstantWidgetMixin.__init__(self, param.strValue)
-        layout = QtGui.QHBoxLayout()
-        self.color_indicator = ColorChooserButton(self)
-        self.connect(self.color_indicator,
-                     QtCore.SIGNAL("color_selected"),
-                     self.update_parent)
-        self._last_contents = contents
-        layout.setMargin(5)
-        layout.setSpacing(5)
-        layout.addWidget(self.color_indicator)
-        layout.addStretch(1)
-        self.setLayout(layout)
-        self.setContents(contents)
-        
+            self.setColor(qcolor)
+
+class ColorWidget(QColorWidget, ConstantWidgetBase):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    def __init__(self, param, parent=None):
+        QColorWidget.__init__(self, parent)
+        ConstantWidgetBase.__init__(self, param)
+        self.connect(self, QtCore.SIGNAL("clicked()"), self.openChooser)
+
     def contents(self):
-        """contents() -> str
-        Return the string representation of color_indicator
+        return self.color_str
 
-        """
-        return "%s,%s,%s" % (self.color_indicator.qcolor.redF(),
-                             self.color_indicator.qcolor.greenF(),
-                             self.color_indicator.qcolor.blueF())
-        
     def setContents(self, strValue, silent=True):
-        """setContents(strValue: str) -> None
-        Updates the color_indicator to display the color in strValue
-        
-        """
-        if strValue != '':
-            color = strValue.split(',')
-            qcolor = QtGui.QColor(float(color[0])*255,
-                                  float(color[1])*255,
-                                  float(color[2])*255)
-            self.color_indicator.setColor(qcolor, silent)
-        self._is_default = False
-
-    def setDefault(self, strValue):
-        if self._is_default:
-            self.setContents(strValue, True)
-            self._is_default = True
+        self.setColorString(strValue, silent)
+
+class ColorEnumWidget(QColorWidget, ConstantEnumWidgetBase):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    def __init__(self, param, parent=None):
+        QColorWidget.__init__(self, parent)
+        self.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
+        ConstantEnumWidgetBase.__init__(self, param)
+    
+    def setFree(self, is_free):
+        if is_free:
+            self.connect(self, QtCore.SIGNAL("clicked()"), self.openChooser)
+
+    def wasTriggered(self, action):
+        self.setColorString(action.data())
+        self.update_parent()
+
+    def setValues(self, values):
+        menu = QtGui.QMenu()
+        self.action_group = QtGui.QActionGroup(menu)
+        self.action_group.setExclusive(True)
+        self.connect(self.action_group, QtCore.SIGNAL('triggered(QAction*)'),
+                     self.wasTriggered)
+        size = menu.style().pixelMetric(QtGui.QStyle.PM_SmallIconSize)
+        for i, color_str in enumerate(values):
+            qcolor = self.colorFromString(color_str)
+            icon = self.buildIcon(qcolor, QtCore.QSize(size, size))
+            action = menu.addAction(icon, "")
+            action.setIconVisibleInMenu(True)
+            action.setData(color_str)
+            action.setCheckable(True)
+            self.action_group.addAction(action)
+        self.setMenu(menu)
+
+    def contents(self):
+        return self.color_str
+
+    def setContents(self, strValue, silent=True):
+        self.setColorString(strValue)
+        for action in self.action_group.actions():
+            if action.data() == strValue:
+                action.setChecked(True)
diff --git a/vistrails/gui/modules/list_configuration.py b/vistrails/gui/modules/list_configuration.py
index 6b8cd75..41343d8 100644
--- a/vistrails/gui/modules/list_configuration.py
+++ b/vistrails/gui/modules/list_configuration.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core.system import get_vistrails_basic_pkg_id
@@ -103,7 +141,7 @@ class ListConfigurationWidget(StandardModuleConfigurationWidget):
             return
 
         if requested > current:
-            sigstring = '(%s:Module)' % get_vistrails_basic_pkg_id()
+            sigstring = '(%s:Variant)' % get_vistrails_basic_pkg_id()
             add_ports = [('input', 'item%d' % i, sigstring, -1)
                            for i in xrange(current, requested)]
             self.controller.update_ports(self.module.id, [], add_ports)
diff --git a/vistrails/gui/modules/module_configure.py b/vistrails/gui/modules/module_configure.py
index 686533e..77606e7 100644
--- a/vistrails/gui/modules/module_configure.py
+++ b/vistrails/gui/modules/module_configure.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.utils import VistrailsInternalError
 from vistrails.core.vistrail.port import PortEndPoint
diff --git a/vistrails/gui/modules/output_configuration.py b/vistrails/gui/modules/output_configuration.py
new file mode 100644
index 0000000..67d0cb7
--- /dev/null
+++ b/vistrails/gui/modules/output_configuration.py
@@ -0,0 +1,414 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+"""This file specifies the configuration widget for OutputModule and
+its subclasses.
+
+"""
+
+from __future__ import division
+
+from PyQt4 import QtCore, QtGui
+
+from vistrails.core.configuration import ConfigPath, ConfigField
+from vistrails.core.modules.basic_modules import Dictionary
+from vistrails.gui.common_widgets import QDirectoryChooserToolButton
+from vistrails.gui.modules.module_configure import StandardModuleConfigurationWidget
+
+class OutputModuleConfigurationWidget(StandardModuleConfigurationWidget):
+    def __init__(self, module, controller, parent=None):
+        StandardModuleConfigurationWidget.__init__(self, module, controller, 
+                                                   parent)
+        self.update_widget()
+
+    def get_configuration(self):
+        config = {}
+        for f in self.module.functions:
+            if f.name == 'configuration':
+                f_config = Dictionary.translate_to_python(f.params[0].strValue)
+                config.update(f_config)
+        return config
+
+    def set_configuration(self, config):
+        self.controller.update_function(self.module, 'configuration', 
+                                [Dictionary.translate_to_string(config)])
+
+    def update_widget(self):
+        layout = QtGui.QVBoxLayout()
+        config = self.get_configuration()
+
+        self.mode_widgets = []
+        self.found_modes = set()
+        mode_layouts = []
+        for mode in self.module.module_descriptor.module.get_sorted_mode_list():
+            mode_config = None
+            if mode.mode_type in config:
+                mode_config = config[mode.mode_type]
+            # create output mode widget passing current config
+            mode_w = self.build_mode_config(layout, mode, mode_config)
+            mode_layouts.append(mode_w.layout())
+            self.found_modes.add(mode.mode_type)
+            
+        for mode_type, mode_config in config.iteritems():
+            if mode_type not in self.found_modes:
+                mode_w = self.build_mode_config(layout, None, mode_config, 
+                                                title=mode_type)
+                mode_layouts.append(mode_w.layout())
+                self.found_modes.add(mode_type)
+                
+        width = 0
+        for mode_layout in mode_layouts:
+            for row in xrange(mode_layout.rowCount()):
+                item = mode_layout.itemAtPosition(row, 0)
+                if item and item.widget():
+                    width = max(width, item.widget().sizeHint().width())
+        for mode_layout in mode_layouts:
+            mode_layout.setColumnMinimumWidth(0, width)
+
+        # do we want to add a manual config mode for modes that have
+        # neither been set before nor are registered?
+        # DK: not now...
+        layout.addStretch(5)
+        scroll_area = QtGui.QScrollArea()
+        inner_widget =  QtGui.QWidget()
+        inner_widget.setLayout(layout)
+        scroll_area.setWidget(inner_widget)
+        scroll_area.setWidgetResizable(True)
+        self.setLayout(QtGui.QVBoxLayout())
+        self.layout().addWidget(scroll_area, 1)
+        self.layout().addLayout(self.create_buttons())
+        self.layout().setContentsMargins(0,0,0,0)
+
+    def build_mode_config(self, base_layout, mode, mode_config, title=None):
+        mode_widget = OutputModeConfigurationWidget(mode, mode_config, title)
+        mode_widget.fieldChanged.connect(self.field_was_changed)
+        self.mode_widgets.append(mode_widget)
+        base_layout.addWidget(mode_widget, 1)
+        return mode_widget
+
+    def create_buttons(self):
+        """ create_buttons() -> None
+        Create and connect signals to Save & Reset button
+        
+        """
+        buttonLayout = QtGui.QHBoxLayout()
+        buttonLayout.setMargin(5)
+        self.saveButton = QtGui.QPushButton('&Save', self)
+        self.saveButton.setFixedWidth(100)
+        self.saveButton.setEnabled(False)
+        buttonLayout.addWidget(self.saveButton)
+        self.resetButton = QtGui.QPushButton('&Reset', self)
+        self.resetButton.setFixedWidth(100)
+        self.resetButton.setEnabled(False)
+        buttonLayout.addWidget(self.resetButton)
+        self.connect(self.saveButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.save_triggered)
+        self.connect(self.resetButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.reset_triggered)
+        return buttonLayout
+
+    def save_triggered(self):
+        # get values from each widget check if any changed and
+        # then dump the whole dictionary back to the configuration
+        # function
+        config = self.get_configuration()
+        for mode_widget in self.mode_widgets:
+            config.update(mode_widget._changed_config)
+        self.set_configuration(config)
+        self.saveButton.setEnabled(False)
+        self.resetButton.setEnabled(False)
+
+    def reset_triggered(self):
+        config = self.get_configuration()
+        for mode_widget in self.mode_widgets:
+            for config_key, field in mode_widget._changed_fields.iteritems():
+                widget = mode_widget.field_widgets[config_key]
+                mode_type = config_key[0]
+                mode_config = None
+                if mode_type in config:
+                    mode_config = config[mode_type]
+                mode_widget.reset_field(widget, field, mode_config, mode_type)
+        self.saveButton.setEnabled(False)
+        self.resetButton.setEnabled(False)
+
+    def field_was_changed(self, mode_widget):
+        self.saveButton.setEnabled(True)
+        self.resetButton.setEnabled(True)
+
+class OutputModeConfigurationWidget(QtGui.QGroupBox):
+    fieldChanged = QtCore.pyqtSignal(object)
+
+    def __init__(self, mode, mode_config=None, title=None, parent=None):
+        assert(mode is not None or mode_config is not None)
+
+        QtGui.QGroupBox.__init__(self, parent)
+        self.field_widgets = {}
+        self._changed_config = {}
+        self._changed_fields = {}
+
+        if title is not None:
+            self.setTitle(title)
+        elif mode is not None:
+            self.setTitle(mode.mode_type)
+        else:
+            self.setTitle("unknown")
+
+        group_layout = QtGui.QGridLayout()
+        group_layout.setMargin(5)
+        group_layout.setSpacing(5)
+        group_layout.setColumnStretch(1,1)
+
+        if mode is None:
+            for k, v in mode_config.iteritems():
+                dummy_field = ConfigField(k, None, str)
+                self.add_field(group_layout, dummy_field, mode_config,
+                                        k)
+        else:
+            for field in mode.get_config().get_all_fields():
+                self.add_field(group_layout, field, mode_config, 
+                               mode.mode_type)
+        self.setLayout(group_layout)
+
+    # TODO Unify this with code in gui.configuration!
+    def add_field(self, layout, field, mode_config, mode_type, indent=0):
+        config_key = (mode_type, field.name)
+        if mode_config is not None and field.name in mode_config:
+            config_val = mode_config[field.name]
+        else:
+            config_val = field.default_val
+
+        config_desc = field.name
+        widget_type = field.widget_type
+        if widget_type is None:
+            if field.val_type == bool:
+                widget_type = "checkbox"
+            elif field.val_type == ConfigPath:
+                widget_type = "pathedit"
+            else:
+                widget_type = "lineedit"
+
+        if widget_type == "combo":
+            widget = self.add_combo(layout, field, config_key, config_desc, 
+                                    config_val)
+        elif widget_type == "lineedit":
+            widget = self.add_line_edit(layout, field, config_key, config_desc, 
+                               config_val)
+        elif widget_type == "pathedit":
+            widget = self.add_path_edit(layout, field, config_key, config_desc, 
+                                        config_val)
+        else:
+            config_val = bool(config_val)
+            widget = self.add_checkbox(layout, field, config_key, config_desc, 
+                                       config_val)
+        self.field_widgets[config_key] = widget
+
+    def reset_field(self, widget, field, mode_config, mode_type):
+        if mode_config is not None and field.name in mode_config:
+            config_val = mode_config[field.name]
+        else:
+            config_val = field.default_val
+
+        if field.widget_type == "checkbox":
+            config_val = bool(config_val)
+        self.set_value(widget, field, config_val)
+
+    def set_value(self, widget, field, val):
+        widget_type = field.widget_type
+        if widget_type is None:
+            if field.val_type == bool:
+                widget_type = "checkbox"
+            elif field.val_type == ConfigPath:
+                widget_type = "pathedit"
+            else:
+                widget_type = "lineedit"
+
+        if widget_type == "combo":
+            self.set_combo_value(widget, val, field)
+        elif widget_type == "lineedit":
+            self.set_line_edit_value(widget, val)
+        elif widget_type == "pathedit":
+            self.set_path_edit_value(widget, val)
+        else:
+            self.set_checkbox_value(widget, val)
+
+    def add_checkbox(self, layout, field, config_key, config_desc, config_val):
+        cb = QtGui.QCheckBox(config_desc)
+        self.set_checkbox_value(cb, config_val)
+        row = layout.rowCount()
+        layout.addWidget(cb, row, 1)
+
+        def call_field_changed(val):
+            self.field_changed(config_key, field, val, config_val)
+        cb.toggled.connect(call_field_changed)
+        return cb
+
+    def set_checkbox_value(self, cb, config_val):
+        cb.setChecked(config_val)
+
+    def add_line_edit(self, layout, field, config_key, config_desc, config_val):
+        options = {}
+        if field.widget_options is not None:
+            options = field.widget_options
+
+        if "label" in options:
+            label_text = options["label"]
+        else:
+            label_text = config_desc
+        label = QtGui.QLabel(label_text)
+        row = layout.rowCount()
+        layout.addWidget(label, row, 0, QtCore.Qt.AlignRight)
+
+        line_edit = QtGui.QLineEdit()
+        self.set_line_edit_value(line_edit, config_val)
+        layout.addWidget(line_edit, row, 1)
+
+        def call_field_changed():
+            val = line_edit.text()
+            self.field_changed(config_key, field, val, config_val)
+        line_edit.editingFinished.connect(call_field_changed)
+        return line_edit
+
+    def set_line_edit_value(self, line_edit, config_val):
+        if config_val is None:
+            config_val = ""
+        line_edit.setText(unicode(config_val))
+
+    def add_path_edit(self, layout, field, config_key, config_desc, config_val):
+        options = {}
+        if field.widget_options is not None:
+            options = field.widget_options
+
+        path_edit = QtGui.QWidget()
+        if "label" in options:
+            label_text = options["label"]
+        else:
+            label_text = config_desc
+        label = QtGui.QLabel(label_text)
+        row = layout.rowCount()
+        layout.addWidget(label, row, 0, QtCore.Qt.AlignRight)
+
+        sub_layout = QtGui.QHBoxLayout()
+        sub_layout.setMargin(0)
+        sub_layout.setSpacing(5)
+        line_edit = QtGui.QLineEdit()
+        if config_val is None:
+            config_val = ""
+        line_edit.setText(unicode(config_val))
+        sub_layout.addWidget(line_edit)
+        path_edit.line_edit = line_edit
+
+        # if field.val_type == ConfigPath:
+        #     button_cls = QDirectoryChooserToolButton
+        # else:
+        button_cls = QDirectoryChooserToolButton
+        button = button_cls(self, line_edit)
+        sub_layout.addWidget(button)
+        path_edit.setLayout(sub_layout)
+        layout.addWidget(path_edit, row, 1)
+
+        def call_field_changed():
+            val = line_edit.text()
+            self.field_changed(config_key, field, val, config_val)
+        line_edit.editingFinished.connect(call_field_changed)
+        return path_edit
+
+    def set_path_edit_value(self, path_edit, config_val):
+        if config_val is None:
+            config_val = ""
+        path_edit.line_edit.setText(unicode(config_val))
+
+    def add_combo(self, layout, field, config_key, config_desc, config_val):
+        options = {}
+        if field.widget_options is not None:
+            options = field.widget_options
+
+        if "label" in options:
+            label_text = options["label"]
+        else:
+            label_text = config_desc
+        label = QtGui.QLabel(label_text)
+        row = layout.rowCount()
+        layout.addWidget(label, row, 0, QtCore.Qt.AlignRight)
+
+        combo = QtGui.QComboBox()
+        inv_remap = None
+        if "allowed_values" in options:
+            values = options["allowed_values"]
+            if "remap" in options:
+                remap = options["remap"]
+                inv_remap = dict((v, k) for (k, v) in remap.iteritems())
+                entries = [remap[v] for v in values]
+            else:
+                entries = values
+            for entry in entries:
+                combo.addItem(entry)
+        self.set_combo_value(combo, config_val, field)
+        layout.addWidget(combo, row, 1)
+
+        def call_field_changed(val):
+            if inv_remap is not None:
+                val = inv_remap[val]
+            self.field_changed(config_key, field, val, config_val)
+        combo.currentIndexChanged[unicode].connect(call_field_changed)
+        return combo
+
+    def set_combo_value(self, combo, config_val, field):
+        options = {}
+        if field.widget_options is not None:
+            options = field.widget_options
+
+        if "allowed_values" in options:
+            if "remap" in options:
+                remap = options["remap"]
+                cur_text = remap[config_val]
+            else:
+                cur_text = config_val
+            combo.setCurrentIndex(combo.findText(cur_text))
+        else:
+            combo.setCurrentIndex(-1)
+
+    def field_changed(self, config_key, field, val, orig_val):
+        # TODO support arbitrary nesting?
+        try:
+            val = field.from_string(val)
+            if config_key[0] not in self._changed_config:
+                self._changed_config[config_key[0]] = {}
+            self._changed_config[config_key[0]][config_key[1]] = val
+            self._changed_fields[config_key] = field
+            self.fieldChanged.emit(self)
+        except:
+            widget = self.field_widgets[config_key]
+            self.set_value(widget, field, orig_val)
+
diff --git a/vistrails/gui/modules/paramexplore.py b/vistrails/gui/modules/paramexplore.py
index 4c130e5..cfbb7a1 100644
--- a/vistrails/gui/modules/paramexplore.py
+++ b/vistrails/gui/modules/paramexplore.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,34 +38,24 @@ exploration. This allows user-defined constants to be used as dimensions
 in parameter exploration, provided the user implements the appropriate
 API in the classes.
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.modules.basic_modules import Color
+from vistrails.core import debug
 from vistrails.core.modules.paramexplore import IntegerLinearInterpolator, \
    FloatLinearInterpolator, RGBColorInterpolator, HSVColorInterpolator
 
 from vistrails.gui.common_widgets import QStringEdit
 from vistrails.gui.modules.constant_configuration import ColorChooserButton
 from vistrails.gui.modules.python_source_configure import PythonEditor
+from vistrails.gui.modules.utils import get_param_explore_widget_list
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.utils import show_warning
 from vistrails.core.utils import all, unimplemented
 
 ##############################################################################
 
-def get_param_explore_widget_list(module_klass):
-    widget_list = []
-    klass_list = module_klass.get_param_explore_widget_list()
-    for klass in klass_list:
-        if klass is None:
-            pass
-        elif isinstance(klass, tuple):
-            (path, klass_name) = klass
-            module = __import__(path, globals(), locals(), [klass_name])
-            widget_list.append(getattr(module, klass_name))
-        else:
-            widget_list.append(klass)
-    return widget_list
-
 class QParameterEditor(QtGui.QWidget):
     """
     QParameterEditor specifies the method used for interpolating
@@ -88,7 +79,7 @@ class QParameterEditor(QtGui.QWidget):
         hLayout.setSpacing(0)
         self.setLayout(hLayout)
 
-        module = param_info.spec.descriptor.module
+        descriptor = param_info.spec.descriptor
 
         self.stackedEditors = QtGui.QStackedWidget()
         self.stackedEditors.setSizePolicy(QtGui.QSizePolicy.Expanding,
@@ -99,7 +90,7 @@ class QParameterEditor(QtGui.QWidget):
             self._exploration_widgets.append(wd)
             self.stackedEditors.addWidget(wd)
 
-        for widget_class in get_param_explore_widget_list(module):
+        for widget_class in get_param_explore_widget_list(descriptor):
             new_widget = widget_class(param_info, size)
             add_exploration_widget(new_widget)
 
@@ -677,7 +668,6 @@ class QUserFunctionEditor(QtGui.QFrame):
         param_info = self._param_info
         module = param_info.spec.descriptor.module
         def get():
-            import code
             values = []
             d = {}
             try:
@@ -687,11 +677,12 @@ class QUserFunctionEditor(QtGui.QFrame):
             def evaluate(i):
                 try:
                     v = d['value'](i)
-                    if v == None:
+                    if v is None:
                         return module.default_value
                     return v
                 except Exception, e:
-                    return str(e)
+                    debug.unexpected_exception(e)
+                    return debug.format_exception(e)
             return [evaluate(i) for i in xrange(self.size)]
         result = get()
         
diff --git a/vistrails/gui/modules/python_source_configure.py b/vistrails/gui/modules/python_source_configure.py
index 6991781..bfcea2e 100644
--- a/vistrails/gui/modules/python_source_configure.py
+++ b/vistrails/gui/modules/python_source_configure.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.bundles.pyimport import py_import
 import vistrails.core.requirements
 from vistrails.gui.modules.source_configure import SourceConfigurationWidget
diff --git a/vistrails/gui/modules/query_configuration.py b/vistrails/gui/modules/query_configuration.py
index bab5610..d141c75 100644
--- a/vistrails/gui/modules/query_configuration.py
+++ b/vistrails/gui/modules/query_configuration.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: vistrails at sci.utah.edu
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.utils import any, expression
 from vistrails.core import system
diff --git a/vistrails/gui/modules/resources/__init__.py b/vistrails/gui/modules/resources/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/gui/modules/resources/__init__.py
+++ b/vistrails/gui/modules/resources/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/gui/modules/resources/colorconfig.qrc b/vistrails/gui/modules/resources/colorconfig.qrc
new file mode 100644
index 0000000..c738c1b
--- /dev/null
+++ b/vistrails/gui/modules/resources/colorconfig.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>colorwheel.png</file>
+</qresource>
+</RCC>
diff --git a/vistrails/gui/modules/resources/colorconfig_rc.py b/vistrails/gui/modules/resources/colorconfig_rc.py
index eda280c..cef595f 100644
--- a/vistrails/gui/modules/resources/colorconfig_rc.py
+++ b/vistrails/gui/modules/resources/colorconfig_rc.py
@@ -1,44 +1,49 @@
+# -*- coding: utf-8 -*-
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
 # Resource object code
 #
-# Created: Thu Oct 5 21:38:17 2006
-#      by: The Resource Compiler for PyQt (Qt v4.1.3)
+# Created: Thu Mar 20 11:52:37 2014
+#      by: The Resource Compiler for PyQt (Qt v4.8.5)
 #
 # WARNING! All changes made in this file will be lost!
 
+from __future__ import division
+
 from PyQt4 import QtCore
 
 qt_resource_data = b"\
diff --git a/vistrails/gui/modules/resources/colorwheel.png b/vistrails/gui/modules/resources/colorwheel.png
new file mode 100644
index 0000000..71aea38
Binary files /dev/null and b/vistrails/gui/modules/resources/colorwheel.png differ
diff --git a/vistrails/gui/modules/source_configure.py b/vistrails/gui/modules/source_configure.py
index 46ffa62..634d4de 100644
--- a/vistrails/gui/modules/source_configure.py
+++ b/vistrails/gui/modules/source_configure.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core import system, debug
 from vistrails.core.utils import PortAlreadyExists
@@ -87,13 +90,13 @@ class SourceWidget(PortTableConfigurationWidget):
     def createPortTable(self, has_inputs=True, has_outputs=True):
         if has_inputs:
             self.inputPortTable = PortTable(self)
-            labels = ["Input Port Name", "Type"]
+            labels = ["Input Port Name", "Type", "List Depth"]
             self.inputPortTable.setHorizontalHeaderLabels(labels)
             self.inputPortTable.initializePorts(self.module.input_port_specs)
             self.layout().addWidget(self.inputPortTable)
         if has_outputs:
             self.outputPortTable = PortTable(self)
-            labels = ["Output Port Name", "Type"]
+            labels = ["Output Port Name", "Type", "List Depth"]
             self.outputPortTable.setHorizontalHeaderLabels(labels)
             self.outputPortTable.initializePorts(self.module.output_port_specs, 
                                                  True)
@@ -197,21 +200,23 @@ class SourceViewerWidget(SourceWidget):
         
     def createPortTable(self, has_inputs=True, has_outputs=True):
         if has_inputs:
-            self.inputPortTable = QtGui.QTableWidget(1, 2, self)
-            labels = ["Input Port Name", "Type"]
+            self.inputPortTable = QtGui.QTableWidget(1, 3, self)
+            labels = ["Input Port Name", "Type", "List Depth"]
             self.inputPortTable.horizontalHeader().setResizeMode(QtGui.QHeaderView.Interactive)
             self.inputPortTable.horizontalHeader().setMovable(False)
-            self.inputPortTable.horizontalHeader().setStretchLastSection(True)
+            #self.inputPortTable.horizontalHeader().setStretchLastSection(True)
+            self.inputPortTable.horizontalHeader().setResizeMode(1, self.inputPortTable.horizontalHeader().Stretch)
             self.inputPortTable.setHorizontalHeaderLabels(labels)
             self.initializePorts(self.inputPortTable, 
                                  self.module.input_port_specs)
             self.layout().addWidget(self.inputPortTable)
         if has_outputs:
-            self.outputPortTable = QtGui.QTableWidget(1, 2, self)
-            labels = ["Output Port Name", "Type"]
+            self.outputPortTable = QtGui.QTableWidget(1, 3, self)
+            labels = ["Output Port Name", "Type", "List Depth"]
             self.outputPortTable.horizontalHeader().setResizeMode(QtGui.QHeaderView.Interactive)
             self.outputPortTable.horizontalHeader().setMovable(False)
-            self.outputPortTable.horizontalHeader().setStretchLastSection(True)
+            #self.outputPortTable.horizontalHeader().setStretchLastSection(True)
+            self.outputPortTable.horizontalHeader().setResizeMode(1, self.outputPortTable.horizontalHeader().Stretch)
             
             self.outputPortTable.setHorizontalHeaderLabels(labels)
             self.initializePorts(self.outputPortTable, 
@@ -235,12 +240,16 @@ class SourceViewerWidget(SourceWidget):
             sigstring = p.sigstring[1:-1]
             siglist = sigstring.split(':')
             short_name = "%s (%s)" % (siglist[1], siglist[0])
+
             item = QtGui.QTableWidgetItem(p.name)
             item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
             table.setItem(row, 0, item)
             item = QtGui.QTableWidgetItem(short_name)
             item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
             table.setItem(row, 1, item)
+            item = QtGui.QTableWidgetItem(str(p.depth))
+            item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
+            table.setItem(row, 2, item)
             table.setRowCount(table.rowCount()+1)
         
     def fixTableGeometry(self, table):
@@ -363,7 +372,7 @@ class SourceConfigurationWidget(SourceWidget):
             try:
                 code = str(self.codeEditor.toPlainText())
             except UnicodeEncodeError, e:
-                debug.critical('Source Code Editor does not support non-ascii characters', str(e)) 
+                debug.critical('Source Code Editor does not support non-ascii characters', e)
                 return False
             if self.sourceEncode:
                 code = urllib.quote(code)
@@ -377,7 +386,7 @@ class SourceConfigurationWidget(SourceWidget):
                                                        added_ports,
                                                        functions)
         except PortAlreadyExists, e:
-            debug.critical('Port Already Exists %s' % str(e))
+            debug.critical('Port Already Exists %s' % e)
             return False
         return True
     
diff --git a/vistrails/gui/modules/string_configure.py b/vistrails/gui/modules/string_configure.py
index 2757fe7..e875107 100644
--- a/vistrails/gui/modules/string_configure.py
+++ b/vistrails/gui/modules/string_configure.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.bundles.pyimport import py_import
 import vistrails.core.requirements
 from vistrails.gui.modules.source_configure import SourceConfigurationWidget
diff --git a/vistrails/gui/modules/stringformat_configuration.py b/vistrails/gui/modules/stringformat_configuration.py
index 934d24c..db7c7aa 100644
--- a/vistrails/gui/modules/stringformat_configuration.py
+++ b/vistrails/gui/modules/stringformat_configuration.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core.system import get_vistrails_basic_pkg_id
diff --git a/vistrails/gui/modules/tuple_configuration.py b/vistrails/gui/modules/tuple_configuration.py
index 7e42352..a5098a2 100644
--- a/vistrails/gui/modules/tuple_configuration.py
+++ b/vistrails/gui/modules/tuple_configuration.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,6 +40,8 @@ vistrails.gui.modules.module_configure.StandardModuleConfigurationWidget,
 which is also a QWidget.
 
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core import debug
 from vistrails.core.utils import VistrailsInternalError
@@ -53,10 +56,12 @@ from vistrails.gui.utils import show_question, SAVE_BUTTON, DISCARD_BUTTON
 
 class PortTable(QtGui.QTableWidget):
     def __init__(self, parent=None):
-        QtGui.QTableWidget.__init__(self,1,2,parent)
-        self.horizontalHeader().setResizeMode(QtGui.QHeaderView.Interactive)
-        self.horizontalHeader().setMovable(False)
-        self.horizontalHeader().setStretchLastSection(True)
+        QtGui.QTableWidget.__init__(self,1,3,parent)
+        horiz = self.horizontalHeader()
+        horiz.setResizeMode(QtGui.QHeaderView.Interactive)
+        horiz.setMovable(False)
+        #horiz.setStretchLastSection(True)
+        horiz.setResizeMode(1, horiz.Stretch)
         self.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
         self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
         self.delegate = PortTableItemDelegate(self)
@@ -107,6 +112,9 @@ class PortTable(QtGui.QTableWidget):
             sigstring = p.sigstring[1:-1]
             siglist = sigstring.split(':')
             short_name = "%s (%s)" % (siglist[1], siglist[0])
+            model.setData(model.index(self.rowCount()-1, 2),
+                          p.depth,
+                          QtCore.Qt.DisplayRole)
             model.setData(model.index(self.rowCount()-1, 1),
                           sigstring,
                           QtCore.Qt.UserRole)
@@ -125,12 +133,11 @@ class PortTable(QtGui.QTableWidget):
         ports = []
         model = self.model()
         for i in xrange(self.rowCount()):
-            name = model.data(model.index(i, 0),
-                              QtCore.Qt.DisplayRole)
-            sigstring = model.data(model.index(i, 1),
-                                   QtCore.Qt.UserRole)
+            name = model.data(model.index(i, 0), QtCore.Qt.DisplayRole)
+            sigstring = model.data(model.index(i, 1), QtCore.Qt.UserRole)
+            depth = model.data(model.index(i, 2), QtCore.Qt.DisplayRole) or 0
             if name is not None and sigstring is not None:
-                ports.append((name, '(%s)' % sigstring, i))
+                ports.append((name, '(%s)' % sigstring, i, depth))
         return ports
 
 #    def focusOutEvent(self, event):
@@ -172,7 +179,11 @@ class PortTableItemDelegate(QtGui.QItemDelegate):
 
     def createEditor(self, parent, option, index):
         registry = get_module_registry()
-        if index.column()==1: #Port type
+        if index.column()==2: #Depth type
+            spinbox = QtGui.QSpinBox(parent)
+            spinbox.setValue(0)
+            return spinbox
+        elif index.column()==1: #Port type
             combo = CompletingComboBox(parent)
             # FIXME just use descriptors here!!
             variant_desc = registry.get_descriptor_by_name(
@@ -199,14 +210,19 @@ class PortTableItemDelegate(QtGui.QItemDelegate):
             return QtGui.QItemDelegate.createEditor(self, parent, option, index)
 
     def setEditorData(self, editor, index):
-        if index.column()==1:
+        if index.column()==2:
+            data = index.model().data(index, QtCore.Qt.DisplayRole)
+            editor.setValue(data or 0)
+        elif index.column()==1:
             data = index.model().data(index, QtCore.Qt.UserRole)
             editor.setCurrentIndex(editor.findData(data))
         else:
             QtGui.QItemDelegate.setEditorData(self, editor, index)
 
     def setModelData(self, editor, model, index):
-        if index.column()==1:
+        if index.column()==2:
+            model.setData(index, editor.value() or 0, QtCore.Qt.DisplayRole)
+        elif index.column()==1:
             editor.validate_input()
             model.setData(index, editor.itemData(editor.currentIndex()), 
                           QtCore.Qt.UserRole)
@@ -343,10 +359,10 @@ class PortTableConfigurationWidget(StandardModuleConfigurationWidget):
     
     def getPortDiff(self, p_type, port_table):
         if p_type == 'input':
-            old_ports = [(p.name, p.sigstring, p.sort_key)
+            old_ports = [(p.name, p.sigstring, p.sort_key, p.depth)
                          for p in self.module.input_port_specs]
         elif p_type == 'output':
-            old_ports = [(p.name, p.sigstring, p.sort_key) 
+            old_ports = [(p.name, p.sigstring, p.sort_key, p.depth) 
                          for p in self.module.output_port_specs]
         else:
             old_ports = []
@@ -389,7 +405,7 @@ class TupleConfigurationWidget(PortTableConfigurationWidget):
         # Then add a PortTable to our configuration widget
         self.portTable = PortTable(self)
         self.portTable.setHorizontalHeaderLabels(
-            ['Input Port Name', 'Type'])
+            ['Input Port Name', 'Type', 'List Depth'])
         
         # We know that the Tuple module initially doesn't have any
         # input port, we just use the local registry to see what ports
@@ -543,7 +559,7 @@ class UntupleConfigurationWidget(PortTableConfigurationWidget):
             self.controller.update_ports(self.module.id, deleted_ports, 
                                          added_ports)
         except PortAlreadyExists, e:
-            debug.critical('Port Already Exists %s' % str(e))
+            debug.critical('Port Already Exists %s' % e)
             return False
         return True
 
diff --git a/vistrails/gui/modules/utils.py b/vistrails/gui/modules/utils.py
new file mode 100644
index 0000000..d215080
--- /dev/null
+++ b/vistrails/gui/modules/utils.py
@@ -0,0 +1,96 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.modules.utils import load_cls
+from constant_configuration import StandardConstantWidget, \
+    StandardConstantEnumWidget
+from query_configuration import BaseQueryWidget
+
+def get_prefix(reg, descriptor):
+    package = reg.get_package_by_name(descriptor.identifier)
+    return  package.prefix + package.codepath
+
+def get_widget_class(descriptor, widget_type=None, widget_use=None,
+                     return_default=True):        
+    reg = get_module_registry()
+    cls = reg.get_constant_config_widget(descriptor, widget_type, 
+                                         widget_use)
+    prefix = get_prefix(reg, descriptor)
+    if cls is None and return_default:
+        if descriptor.module is not None and \
+           hasattr(descriptor.module, 'get_widget_class'):
+            cls = descriptor.module.get_widget_class()
+        if cls is None:
+            if widget_type == "enum":
+                return StandardConstantEnumWidget
+            else:
+                return StandardConstantWidget
+    return load_cls(cls, prefix)
+        
+def get_query_widget_class(descriptor, widget_type=None):
+    cls = get_widget_class(descriptor, widget_type, "query", False)
+    if cls is None:
+        if descriptor.module is not None and \
+           hasattr(descriptor.module, 'get_query_widget_class'):
+            cls = descriptor.module.get_query_widget_class()
+        if cls is None:
+            class DefaultQueryWidget(BaseQueryWidget):
+                def __init__(self, param, parent=None):
+                    BaseQueryWidget.__init__(self, 
+                                             get_widget_class(descriptor), 
+                                             ["==", "!="],
+                                             param, parent)
+            return DefaultQueryWidget
+        reg = get_module_registry()
+        prefix = get_prefix(reg, descriptor)
+        return load_cls(cls, prefix)
+    return cls
+
+def get_param_explore_widget_list(descriptor, widget_type=None):
+    widget_list = []
+    reg = get_module_registry()
+    prefix = get_prefix(reg, descriptor)
+    cls_list = reg.get_all_constant_config_widgets(descriptor, "paramexp")
+    for cls in cls_list:
+        if cls is None:
+            pass
+        widget_list.append(load_cls(cls, prefix))
+    return widget_list
+
+
diff --git a/vistrails/gui/open_db_window.py b/vistrails/gui/open_db_window.py
index 3a03b49..2886a65 100644
--- a/vistrails/gui/open_db_window.py
+++ b/vistrails/gui/open_db_window.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -42,6 +43,8 @@ QDBObjectListItem
 QConnectionDBSetupWindow
 
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.db import VistrailsDBException
 import vistrails.db.services.io
@@ -379,7 +382,7 @@ class QDBConnectionList(QtGui.QListWidget):
         item = None
         if len(self.selectedItems()) > 0:
             item  = self.selectedItems()[0]
-        if item != None:
+        if item is not None:
             return int(item.id)
         else:
             return -1
@@ -404,7 +407,7 @@ class QDBConnectionList(QtGui.QListWidget):
         """
         conn_id = self.getCurrentItemId()
         config = self.getConnectionInfo(conn_id)
-        if config != None:
+        if config is not None:
             config["create"] = False
             self.parent().showConnConfig(**config)
             
@@ -436,7 +439,7 @@ class QDBConnectionList(QtGui.QListWidget):
         conn = self.__list.get_connection(id)
         key = str(conn.id) + "." + conn.name + "." + conn.host
         passwd = DBLocator.keyChain.get_key(key)
-        if conn != None:
+        if conn is not None:
             config = {'id': conn.id,
                       'name': conn.name,
                       'host': conn.host,
@@ -481,20 +484,13 @@ class QDBConnectionList(QtGui.QListWidget):
         If the connection exists it will update it, else it will add it
 
         """
-        if kwargs.has_key("id"):
-            id = kwargs["id"]
-        if kwargs.has_key("name"):
-            name = kwargs["name"]
-        if kwargs.has_key("host"):
-            host = kwargs["host"]
-        if kwargs.has_key("port"):
-            port = kwargs["port"]
-        if kwargs.has_key("user"):
-            user = kwargs["user"]
-        if kwargs.has_key("passwd"):
-            passwd = kwargs["passwd"]
-        if kwargs.has_key("db"):
-            db = kwargs["db"]
+        id = kwargs["id"]
+        name = kwargs["name"]
+        host = kwargs["host"]
+        port = kwargs["port"]
+        user = kwargs["user"]
+        passwd = kwargs["passwd"]
+        db = kwargs["db"]
 
         conn = DBConnection(id=id,
                             name=name,
@@ -552,10 +548,8 @@ class QDBConnectionList(QtGui.QListWidget):
         config = self.getConnectionInfo(conn_id)
         if conn.dbtype == 'MySQL':
             #removing extra keyword arguments for MySQldb
-            config_name = config['name']
-            del config['name']
-            config_id = config['id']
-            del config['id']
+            config_name = config.pop('name')
+            config_id = config.pop('id')
         vt_list = vistrails.db.services.io.get_db_object_list(config, obj_type)
         if conn.dbtype == 'MySQL':
             config['name'] = config_name
@@ -607,12 +601,11 @@ class QDBObjectList(QtGui.QListWidget):
                     self.addItem(item)
             except VistrailsDBException, e:
                 #show connection setup
-                error = str(e)
-                if "Couldn't get list of vistrails objects" in error:
-                    debug.critical('An error has occurred', error)
+                if "Couldn't get list of vistrails objects" in str(e):
+                    debug.critical('An error has occurred', e)
                     raise e
                 config = parent.connectionList.getConnectionInfo(int(conn_id))
-                if config != None:
+                if config is not None:
                     config["create"] = False
                     if not parent.showConnConfig(**config):
                         raise e
@@ -758,7 +751,7 @@ class QConnectionDBSetupWindow(QtGui.QDialog):
             show_info('Vistrails',"Connection succeeded!")
             
         except Exception, e:
-            debug.critical('An error has occurred', str(e))
+            debug.critical('An error has occurred', e)
 
     def updateButtons(self):
         """updateButtons() -> None
diff --git a/vistrails/gui/paramexplore/__init__.py b/vistrails/gui/paramexplore/__init__.py
index 86c4a06..c027816 100644
--- a/vistrails/gui/paramexplore/__init__.py
+++ b/vistrails/gui/paramexplore/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 pass
diff --git a/vistrails/gui/paramexplore/param_view.py b/vistrails/gui/paramexplore/param_view.py
index bf7b290..0dd1702 100644
--- a/vistrails/gui/paramexplore/param_view.py
+++ b/vistrails/gui/paramexplore/param_view.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,10 +37,11 @@
 
 QParameterView
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.inspector import PipelineInspector
 from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.modules.basic_modules import Constant
 from vistrails.gui.common_widgets import QSearchTreeWindow, QSearchTreeWidget
 from vistrails.gui.paramexplore.pe_pipeline import QAnnotatedPipelineView
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
@@ -78,7 +80,7 @@ class QParameterView(QtGui.QWidget, QVistrailsPaletteInterface):
         QtGui.QWidget.__init__(self, parent)
         self.set_title('Pipeline Methods')
         
-        self.controller = controller
+        self.controller = None
         vLayout = QtGui.QVBoxLayout()
         vLayout.setMargin(0)
         vLayout.setSpacing(5)
@@ -92,6 +94,7 @@ class QParameterView(QtGui.QWidget, QVistrailsPaletteInterface):
         self.treeWidget = self.parameterWidget.treeWidget
 
         self.pipeline_view = QAnnotatedPipelineView()
+        self.pipeline_view.setReadOnlyMode(True)
         vLayout.addWidget(self.pipeline_view)
 
         vLayout.setStretch(0,0)
@@ -100,16 +103,34 @@ class QParameterView(QtGui.QWidget, QVistrailsPaletteInterface):
 
         self.connect(self.toggleUnsetParameters, QtCore.SIGNAL("toggled(bool)"),
                      self.parameterWidget.treeWidget.toggleUnsetParameters)
+        self.set_controller(controller)
 
     def set_controller(self, controller):
+        if self.controller == controller:
+            return
         self.controller = controller
-        self.set_pipeline(self.controller.current_pipeline)
-        self.pipeline_view.setScene(self.controller.current_pipeline_scene)
+        self.pipeline_view.set_controller(controller)
+        if self.controller is not None:
+            self.set_pipeline(controller.current_pipeline)
+        else:
+            self.set_pipeline(None)
 
     def set_pipeline(self, pipeline):
+        if self.controller is None:
+            return
         self.pipeline = pipeline
         self.parameterWidget.set_pipeline(pipeline, self.controller)
+        if pipeline:
+            self.pipeline_view.scene().setupScene(pipeline)
+        else:
+            self.pipeline_view.scene().clear()
         self.pipeline_view.updateAnnotatedIds(pipeline)
+        # this ensures the correct pipeline is set when updating exploration
+        self.get_palette().set_pipeline(pipeline)
+
+    def get_palette(self):
+        from vistrails.gui.paramexplore.pe_inspector import QParamExploreInspector
+        return QParamExploreInspector.instance()
 
 class QParameterWidget(QSearchTreeWindow):
     """
@@ -175,8 +196,8 @@ class QParameterTreeWidget(QSearchTreeWidget):
                                       value=v,
                                       spec=port_spec_item,
                                       is_alias=True)
-                aliasItem = QParameterTreeWidgetItem((alias, [pInfo]),
-                                                     aliasRoot, label)
+                QParameterTreeWidgetItem((alias, [pInfo]),
+                                         aliasRoot, label)
             aliasRoot.setExpanded(True)
 
         vistrailVarsRoot = QParameterTreeWidgetItem(None, self,
@@ -200,7 +221,6 @@ class QParameterTreeWidget(QSearchTreeWidget):
                 if not port_spec:
                     debug.critical("Not port_spec for value in module %s" % module)
                     continue
-                port_spec_items = port_spec.port_spec_items
 
                 if not controller.has_vistrail_variable_with_uuid(
                                         module.get_vistrail_var()):
@@ -217,9 +237,9 @@ class QParameterTreeWidget(QSearchTreeWidget):
                                        spec=port_spec.port_spec_items[pId],
                                        is_alias=False)
                          for pId in xrange(len(port_spec.port_spec_items))]
-                mItem = QParameterTreeWidgetItem((vv.name, pList),
-                                                 vistrailVarsRoot,
-                                                 label)
+                QParameterTreeWidgetItem((vv.name, pList),
+                                         vistrailVarsRoot,
+                                         label)
                 continue
                 
             function_names = {}
@@ -244,7 +264,7 @@ class QParameterTreeWidget(QSearchTreeWidget):
                     
                     try:
                         port_spec = function.get_spec('input')
-                    except Exception, e:
+                    except Exception:
                         debug.critical("get_spec failed: %s %s %s" % \
                                        (module, function, function.sigstring))
                         continue
@@ -257,12 +277,12 @@ class QParameterTreeWidget(QSearchTreeWidget):
                                            is_alias=False)
                              for pId in xrange(len(function.params))]
                     mName = module.name
-                    if moduleItem.parameter!=None:
+                    if moduleItem.parameter is not None:
                         mName += '(%d)' % moduleItem.parameter
                     fName = '%s :: %s' % (mName, function.name)
-                    mItem = QParameterTreeWidgetItem((fName, pList),
-                                                     moduleItem,
-                                                     label)
+                    QParameterTreeWidgetItem((fName, pList),
+                                             moduleItem,
+                                             label)
             # Add available parameters
             if module.is_valid:
                 for port_spec in module.destinationPorts():
@@ -293,12 +313,12 @@ class QParameterTreeWidget(QSearchTreeWidget):
                                            is_alias=False)
                              for pId in xrange(len(port_spec.port_spec_items))]
                     mName = module.name
-                    if moduleItem.parameter!=None:
+                    if moduleItem.parameter is not None:
                         mName += '(%d)' % moduleItem.parameter
                     fName = '%s :: %s' % (mName, port_spec.name)
-                    mItem = QParameterTreeWidgetItem((fName, pList),
-                                                     moduleItem,
-                                                     label, False)
+                    QParameterTreeWidgetItem((fName, pList),
+                                             moduleItem,
+                                             label, False)
             if moduleItem:
                 moduleItem.setExpanded(True)
         self.toggleUnsetParameters(self.showUnsetParameters)
@@ -335,7 +355,7 @@ class QParameterTreeWidgetItemDelegate(QtGui.QItemDelegate):
         
         """
         model = index.model()
-        if model.parent(index).isValid()==False:
+        if not model.parent(index).isValid():
             style = self.treeView.style()
             r = option.rect
             textrect = QtCore.QRect(r.left() + 10,
diff --git a/vistrails/gui/paramexplore/pe_inspector.py b/vistrails/gui/paramexplore/pe_inspector.py
index 692c3c4..1d5dd90 100644
--- a/vistrails/gui/paramexplore/pe_inspector.py
+++ b/vistrails/gui/paramexplore/pe_inspector.py
@@ -1,43 +1,45 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
 
 from vistrails.gui.paramexplore.virtual_cell import QVirtualCellWindow
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
 from vistrails.gui.theme import CurrentTheme
-from pe_view import QParamExploreView 
 
 import weakref
 
@@ -50,6 +52,7 @@ class QParamExploreInspector(QtGui.QWidget, QVistrailsPaletteInterface):
         layout.setMargin(2)
         layout.setSpacing(3)
 
+        self.controller = None
         self.pe_properties = QParamExpProperties()
         p_prop_group = QtGui.QGroupBox(self.pe_properties.windowTitle())
         g_layout = QtGui.QVBoxLayout()
@@ -89,9 +92,14 @@ class QParamExploreInspector(QtGui.QWidget, QVistrailsPaletteInterface):
         self.pe_properties.forwardAction = weakref.proxy(self.forwardAction)
 
     def set_controller(self, controller):
+        if self.controller == controller:
+            return
         self.controller = controller
         self.pe_properties.updateController(controller)
-        self.set_pipeline(self.controller.current_pipeline)
+        if self.controller is not None:
+            self.set_pipeline(self.controller.current_pipeline)
+        else:
+            self.set_pipeline(None)
 
     def set_pipeline(self, pipeline):
         self.pipeline = pipeline
@@ -101,9 +109,6 @@ class QParamExploreInspector(QtGui.QWidget, QVistrailsPaletteInterface):
     def stateChanged(self):
         self.pe_properties.updateVersion()
 
-    def set_exploration(self, pe = None):
-        self.stateChanged()
-
     def backPressed(self):
         self.pe_properties.goBack()
 
diff --git a/vistrails/gui/paramexplore/pe_pipeline.py b/vistrails/gui/paramexplore/pe_pipeline.py
index 951e042..aac921b 100644
--- a/vistrails/gui/paramexplore/pe_pipeline.py
+++ b/vistrails/gui/paramexplore/pe_pipeline.py
@@ -1,44 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This containing a subclassed QGraphicsView that allows View the
 pipeline in a specific way in the parameter exploration window
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.inspector import PipelineInspector
 from vistrails.gui.common_widgets import QToolWindowInterface
-from vistrails.gui.pipeline_view import QPipelineView, QGraphicsModuleItem
+from vistrails.gui.pipeline_view import QPipelineView
 from vistrails.gui.theme import CurrentTheme
 
 ################################################################################
@@ -92,7 +95,8 @@ class QAnnotatedPipelineView(QPipelineView, QToolWindowInterface):
         """
         if pipeline and self.scene():
             self.inspector.inspect_ambiguous_modules(pipeline)
-            self.scene().fitToView(self)
+            self.scene().fitToAllViews(True)
+
 
     @staticmethod
     def drawId(painter, rect, id, align=QtCore.Qt.AlignCenter):
@@ -115,12 +119,12 @@ class QAnnotatedPipelineView(QPipelineView, QToolWindowInterface):
         
         x = rect.left()
         if align & QtCore.Qt.AlignHCenter:
-            x = rect.left() + rect.width()/2-size/2
+            x = rect.left() + rect.width()//2-size//2
         if align & QtCore.Qt.AlignRight:
             x = rect.left() + rect.width()-size
         y = rect.top()
         if align & QtCore.Qt.AlignVCenter:
-            y = rect.top() + rect.height()/2-size/2
+            y = rect.top() + rect.height()//2-size//2
         if align & QtCore.Qt.AlignBottom:
             y = rect.top() + rect.height()-size
             
diff --git a/vistrails/gui/paramexplore/pe_tab.py b/vistrails/gui/paramexplore/pe_tab.py
index 2fd6e48..51258d2 100644
--- a/vistrails/gui/paramexplore/pe_tab.py
+++ b/vistrails/gui/paramexplore/pe_tab.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,14 +37,18 @@
 
 QParameterExplorationTab
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
+from ast import literal_eval
 from xml.dom.minidom import parseString
 from xml.sax.saxutils import escape
 from vistrails.core import debug
 from vistrails.core.interpreter.default import get_default_interpreter
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.param_explore import ActionBasedParameterExploration
-from vistrails.core.system import current_time, get_vistrails_default_pkg_prefix
+from vistrails.core.system import current_time, strftime, \
+    get_vistrails_default_pkg_prefix
 from vistrails.gui.common_widgets import QDockContainer, QToolWindowInterface
 from vistrails.gui.paramexplore.pe_table import QParameterExplorationWidget, QParameterSetEditor
 from vistrails.gui.paramexplore.virtual_cell import QVirtualCellWindow
@@ -127,7 +132,7 @@ class QParameterExplorationTab(QDockContainer, QToolWindowInterface):
         """
         # Construct xml for persisting parameter exploration
         escape_dict = { "'":"'", '"':'"', '\n':'&#xa;' }
-        timestamp = current_time().strftime('%Y-%m-%d %H:%M:%S')
+        timestamp = strftime(current_time(), '%Y-%m-%d %H:%M:%S')
         # TODO: For now, we use the timestamp as the 'name' - Later, we should set 'name' based on a UI input field
         xml = '\t<paramexp dims="%s" layout="%s" date="%s" name="%s">' % (str(self.peWidget.table.label.getCounts()), str(self.virtualCell.getConfiguration()[2]), timestamp, timestamp)
         for i in xrange(self.peWidget.table.layout().count()):
@@ -166,21 +171,20 @@ class QParameterExplorationTab(QDockContainer, QToolWindowInterface):
         # Parse/validate the xml
         try:
             xmlDoc = parseString(xmlString).documentElement
-        except:
+        except Exception:
             debug.critical("Parameter Exploration load failed because of "
                            "invalid XML:\n\n%s" % xmlString)
             return
         # Set the exploration dimensions
-        dims = eval(str(xmlDoc.attributes['dims'].value))
+        dims = literal_eval(xmlDoc.attributes['dims'].value)
         self.peWidget.table.label.setCounts(dims)
         # Set the virtual cell layout
-        layout = eval(str(xmlDoc.attributes['layout'].value))
+        layout = literal_eval(xmlDoc.attributes['layout'].value)
         self.virtualCell.setConfiguration(layout)
         # Populate parameter exploration window with stored functions and aliases
         for f in xmlDoc.getElementsByTagName('function'):
             # Retrieve function attributes
             f_id = long(f.attributes['id'].value)
-            f_name = str(f.attributes['name'].value)
             f_is_alias = (str(f.attributes['alias'].value) == 'True')
             # Search the parameter treeWidget for this function and add it directly
             newEditor = None
@@ -215,7 +219,8 @@ class QParameterExplorationTab(QDockContainer, QToolWindowInterface):
                             elif p_intType == 'List':
                                 p_values = str(p.attributes['values'].value)
                                 # Set internal list structure
-                                interpolator._str_values = eval(p_values)
+                                interpolator._str_values = \
+                                        literal_eval(p_values)
                                 # Update UI list
                                 if interpolator.type == 'String':
                                     interpolator.listValues.setText(p_values)
@@ -264,7 +269,7 @@ class QParameterExplorationTab(QDockContainer, QToolWindowInterface):
         """
         registry = get_module_registry()
         actions = self.peWidget.table.collectParameterActions()
-        spreadsheet_pkg = '%s.spreadsheet' % get_vistrails_default_pkg_prefix()
+        spreadsheet_pkg = 'org.vistrails.vistrails.spreadsheet'
         # Set the annotation to persist the parameter exploration
         # TODO: For now, we just replace the existing exploration - Later we should append them.
         xmlString = "<paramexps>\n" + self.getParameterExploration() + "\n</paramexps>"
diff --git a/vistrails/gui/paramexplore/pe_table.py b/vistrails/gui/paramexplore/pe_table.py
index 895b981..0457304 100644
--- a/vistrails/gui/paramexplore/pe_table.py
+++ b/vistrails/gui/paramexplore/pe_table.py
@@ -1,42 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from getpass import getuser
 
 from PyQt4 import QtCore, QtGui
+from ast import literal_eval
 from xml.dom.minidom import parseString
 from xml.sax.saxutils import escape, unescape
+from vistrails.core.vistrail.module_param import ModuleParam
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.common_widgets import QPromptWidget
 from vistrails.gui.modules.paramexplore import QParameterEditor
@@ -45,7 +50,7 @@ from vistrails.gui.utils import show_warning
 from vistrails.core import debug
 from vistrails.core.modules.basic_modules import Constant
 from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.system import current_time
+from vistrails.core.system import current_time, strftime
 from vistrails.core.paramexplore.param import PEParam
 from vistrails.core.paramexplore.function import PEFunction
 from vistrails.core.vistrail.module import Module as VistrailModule
@@ -118,12 +123,6 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
         
         """
         self.table.setPipeline(pipeline)
-        # Update the UI with the most recent parameter exploration
-        if self.controller:
-            currentVersion = self.controller.current_version
-            pe = self.controller.vistrail.get_paramexp(currentVersion)
-            self.controller.current_parameter_exploration = pe
-            self.setParameterExploration(pe)
 
     def getParameterExplorationOld(self):
         """ getParameterExploration() -> string
@@ -134,7 +133,7 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
         """
         # Construct xml for persisting parameter exploration
         escape_dict = { "'":"'", '"':'"', '\n':'&#xa;' }
-        timestamp = current_time().strftime('%Y-%m-%d %H:%M:%S')
+        timestamp = strftime(current_time(), '%Y-%m-%d %H:%M:%S')
         palette = self.get_palette()
         # TODO: For now, we use the timestamp as the 'name' - Later, we should set 'name' based on a UI input field
         xml = '\t<paramexp dims="%s" layout="%s" date="%s" name="%s">' % (str(self.table.label.getCounts()), str(palette.virtual_cell.getConfiguration()[2]), timestamp, timestamp)
@@ -201,6 +200,8 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
                         value = '%s' % escape(str(interpolator._str_values), escape_dict)
                     elif intType == 'User-defined Function':
                         value ='%s' % escape(interpolator.function, escape_dict)
+                    else:
+                        assert False
                     # Write parameter tag
                     param = PEParam(id=id_scope.getNewId(PEParam.vtType),
                                     pos=paramInfo.pos,
@@ -244,8 +245,11 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
                     name, params = paramInfo
                     if params[0].module_id == f.module_id and \
                        params[0].name == f.port_name and \
-                       params[0].is_alias == f.is_alias:
+                       bool(params[0].is_alias) == bool(f.is_alias):
                         newEditor = self.table.addParameter(paramInfo)
+                        break
+                if newEditor:
+                    break
                         
             # Retrieve params for this function and set their values in the UI
             if newEditor:
@@ -264,19 +268,21 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
                                                   'HSV Interpolation']:
                                 try:
                                     # Set min/max
-                                    i_range = eval('%s' % unescape(p.value,
-                                                               unescape_dict))
+                                    i_range = literal_eval('%s' % unescape(
+                                                           p.value,
+                                                           unescape_dict))
                                     p_min = str(i_range[0])
                                     p_max =str(i_range[1])
                                     interpolator.fromEdit.set_value(p_min)
                                     interpolator.toEdit.set_value(p_max)
-                                except:
+                                except Exception:
                                     pass
                             elif p.interpolator == 'List':
                                 p_values = '%s' % unescape(p.value,
                                                         unescape_dict)
                                 # Set internal list structure
-                                interpolator._str_values = eval(p_values)
+                                interpolator._str_values = \
+                                        literal_eval(p_values)
                                 # Update UI list
                                 if interpolator.type == 'String':
                                     interpolator.listValues.setText(p_values)
@@ -299,23 +305,23 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
         # Parse/validate the xml
         try:
             xmlDoc = parseString(xmlString).documentElement
-        except:
+        except Exception, e:
+            debug.unexpected_exception(e)
             debug.critical("Parameter Exploration load failed because of "
                            "invalid XML:\n\n%s" % xmlString)
             return
         palette = self.get_palette()
         paramView = self.get_param_view()
         # Set the exploration dimensions
-        dims = eval(str(xmlDoc.attributes['dims'].value))
+        dims = literal_eval(xmlDoc.attributes['dims'].value)
         self.table.label.setCounts(dims)
         # Set the virtual cell layout
-        layout = eval(str(xmlDoc.attributes['layout'].value))
+        layout = literal_eval(xmlDoc.attributes['layout'].value)
         palette.virtual_cell.setConfiguration(layout)
         # Populate parameter exploration window with stored functions and aliases
         for f in xmlDoc.getElementsByTagName('function'):
             # Retrieve function attributes
             f_id = long(f.attributes['id'].value)
-            f_name = str(f.attributes['name'].value)
             f_is_alias = (str(f.attributes['alias'].value) == 'True')
             # Search the parameter treeWidget for this function and add it directly
             newEditor = None
@@ -349,12 +355,12 @@ class QParameterExplorationWidget(QtGui.QScrollArea):
                                     p_max = str(p.attributes['max'].value)
                                     interpolator.fromEdit.set_value(p_min)
                                     interpolator.toEdit.set_value(p_max)
-                                except:
+                                except Exception:
                                     pass
                             elif p_intType == 'List':
                                 p_values = str(p.attributes['values'].value)
                                 # Set internal list structure
-                                interpolator._str_values = eval(p_values)
+                                interpolator._str_values = literal_eval(p_values)
                                 # Update UI list
                                 if interpolator.type == 'String':
                                     interpolator.listValues.setText(p_values)
@@ -474,7 +480,7 @@ class QParameterExplorationTable(QPromptWidget):
                 for p in xrange(len(pEditor.info[1])):
                     param = pEditor.info[1][p]
                     widget = pEditor.paramWidgets[p]                    
-                    if (param in ps.info[1] and (not widget.isEnabled())):
+                    if param in ps.info[1] and not widget.isEnabled():
                         widget.setDimension(0)
                         widget.setDuplicate(False)
                         widget.setEnabled(True)
@@ -489,16 +495,16 @@ class QParameterExplorationTable(QPromptWidget):
         """
         # Go through all possible parameter widgets
         counts = self.label.getCounts()
-        for i in xrange(self.layout().count()):
-            pEditor = self.layout().itemAt(i).widget()
+        for wdg in xrange(self.layout().count()):
+            pEditor = self.layout().itemAt(wdg).widget()
             if pEditor and isinstance(pEditor, QParameterSetEditor):
                 for paramWidget in pEditor.paramWidgets:
                     dim = paramWidget.getDimension()
                     if dim in [0, 1, 2, 3]:
-                        se = paramWidget.editor.stackedEditors
+                        stackedEditors = paramWidget.editor.stackedEditors
                         # Notifies editor widgets of size update 
-                        for i in xrange(se.count()):
-                            wd = se.widget(i)
+                        for edit in xrange(stackedEditors.count()):
+                            wd = stackedEditors.widget(edit)
                             if hasattr(wd, 'size_was_updated'):
                                 wd.size_was_updated(counts[dim])
 
@@ -539,7 +545,7 @@ class QParameterExplorationTable(QPromptWidget):
         else:
             self.clear()
         self.pipeline = pipeline
-        self.label.setEnabled(self.pipeline!=None)
+        self.label.setEnabled(self.pipeline is not None)
 
     def collectParameterActions(self):
         """ collectParameterActions() -> list
@@ -570,8 +576,7 @@ class QParameterExplorationTable(QPromptWidget):
                         parentType = paramInfo.parent_dbtype
                         parentId = paramInfo.parent_id
                         function = self.pipeline.db_get_object(parentType,
-                                                               parentId)  
-                        fName = function.name
+                                                               parentId)
                         old_param = self.pipeline.db_get_object(pType,pId)
                         pName = old_param.name
                         pAlias = old_param.alias
@@ -886,7 +891,6 @@ class QParameterWidget(QtGui.QWidget):
         self.label.setFixedWidth(50)
         hLayout.addWidget(self.label)
 
-        registry = get_module_registry()
         module = param.spec.descriptor.module
         assert issubclass(module, Constant)
 
@@ -1002,14 +1006,3 @@ class QDimensionRadioButton(QtGui.QRadioButton):
         
         """
         self.click()
-
-################################################################################
-
-if __name__=="__main__":        
-    import sys
-    import vistrails.gui.theme
-    app = QtGui.QApplication(sys.argv)
-    vistrails.gui.theme.initializeCurrentTheme()
-    vc = QDimensionLabel(CurrentTheme.EXPLORE_SHEET_PIXMAP, 'Hello World')
-    vc.show()
-    sys.exit(app.exec_())
diff --git a/vistrails/gui/paramexplore/pe_view.py b/vistrails/gui/paramexplore/pe_view.py
index 04a88e5..2bd582a 100644
--- a/vistrails/gui/paramexplore/pe_view.py
+++ b/vistrails/gui/paramexplore/pe_view.py
@@ -1,40 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from PyQt4 import QtCore, QtGui
+from __future__ import division
+
+from PyQt4 import QtCore
 
-from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.gui.base_view import BaseView
 from vistrails.gui.paramexplore.pe_table import QParameterExplorationWidget
 from vistrails.gui.theme import CurrentTheme
@@ -93,7 +95,7 @@ class QParamExploreView(QParameterExplorationWidget, BaseView):
     def set_execute_action(self):
         if self.controller and self.controller.vistrail:
             versionId = self.controller.current_version
-            return self.controller.vistrail.get_paramexp(versionId) != None
+            return self.controller.vistrail.get_paramexp(versionId) is not None
         return False
     
     def explore_non_empty(self, on):
diff --git a/vistrails/gui/paramexplore/virtual_cell.py b/vistrails/gui/paramexplore/virtual_cell.py
index ec515e6..a93eea6 100644
--- a/vistrails/gui/paramexplore/virtual_cell.py
+++ b/vistrails/gui/paramexplore/virtual_cell.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This file describe the virtual cell layout widget used in
 Parameter Exploration Tab """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.inspector import PipelineInspector
 from vistrails.gui.common_widgets import QToolWindowInterface
@@ -42,11 +45,6 @@ from vistrails.gui.theme import CurrentTheme
 import copy
 import os.path
 
-# FIXME broke this as Actions have been changed around
-#
-# from core.vistrail.action import AddModuleAction, AddConnectionAction, \
-#      DeleteConnectionAction, ChangeParameterAction
-
 ###############################################################################
 
 def split_camel_case(text):
@@ -158,8 +156,8 @@ def positionPipelines(sheetPrefix, sheetCount, rowCount, colCount,
     for pId in xrange(len(pipelines)):
         root_pipeline = copy.copy(pipelines[pId])
         col = pId % colCount
-        row = (pId / colCount) % rowCount
-        sheet = (pId / (colCount*rowCount)) % sheetCount
+        row = (pId // colCount) % rowCount
+        sheet = (pId // (colCount*rowCount)) % sheetCount
 
         decodedCells = decodeConfiguration(root_pipeline, cells)
         vRCount = (max(c[1] for c in decodedCells) + 1) if len(decodedCells) else 1
@@ -192,7 +190,6 @@ def assembleThumbnails(images, name, background='#000000'):
     maxSheet = max(i[2] for i in images) + 1
     
     w = h = 0
-    sizeX = sizeY = 0
     sheets = []
     painter = QtGui.QPainter()
     
@@ -371,7 +368,7 @@ class QVirtualCellConfiguration(QtGui.QWidget):
         """
         while True:
             item = self.layout().takeAt(0)
-            if item==None:
+            if item is None:
                 break
             self.disconnect(item.widget(),
                             QtCore.SIGNAL('finishedDragAndDrop'),
@@ -426,7 +423,7 @@ class QVirtualCellConfiguration(QtGui.QWidget):
         for i in xrange(len(visibleRows)):
             for c in xrange(self.numCell):
                 label = self.cells[visibleRows[i]][c]
-                if label.type==None:
+                if label.type is None:
                     label.type = ''
                 self.cells[i][c].setCellData(label.type, label.id)
 
@@ -443,7 +440,7 @@ class QVirtualCellConfiguration(QtGui.QWidget):
         for i in xrange(len(visibleCols)):
             for r in xrange(self.numCell):
                 label = self.cells[r][visibleCols[i]]
-                if label.type==None:
+                if label.type is None:
                     label.type = ''
                 self.cells[r][i].setCellData(label.type, label.id)
 
@@ -552,7 +549,7 @@ class QVirtualCellLabel(QtGui.QLabel):
         painter = QtGui.QPainter()
         painter.begin(image)
         painter.setRenderHint(QtGui.QPainter.Antialiasing)
-        if self.type==None:
+        if self.type is None:
             painter.setPen(QtCore.Qt.NoPen)
             painter.setBrush(QtCore.Qt.NoBrush)
         else:
@@ -566,7 +563,7 @@ class QVirtualCellLabel(QtGui.QLabel):
                                             image.height()-1), 25, 25)
 
         painter.setFont(font)
-        if self.type!=None:
+        if self.type is not None:
             painter.drawText(QtCore.QRect(QtCore.QPoint(6, 6), size),
                              QtCore.Qt.AlignCenter | QtCore.Qt.TextWrapAnywhere,
                              split_camel_case(self.type))
diff --git a/vistrails/gui/pipeline_view.py b/vistrails/gui/pipeline_view.py
index a3f85af..a71471f 100644
--- a/vistrails/gui/pipeline_view.py
+++ b/vistrails/gui/pipeline_view.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -45,6 +46,8 @@ QGraphicsModuleItem
 QPipelineScene
 QPipelineView
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.configuration import get_vistrails_configuration
 from vistrails.core import debug
@@ -55,10 +58,13 @@ from vistrails.core.modules.module_registry import get_module_registry, \
 from vistrails.core.system import get_vistrails_basic_pkg_id
 from vistrails.core.vistrail.location import Location
 from vistrails.core.vistrail.module import Module
+from vistrails.core.vistrail.module_function import ModuleFunction
+from vistrails.core.vistrail.module_param import ModuleParam
 from vistrails.core.vistrail.port import PortEndPoint
 from vistrails.core.vistrail.port_spec import PortSpec
 from vistrails.core.interpreter.base import AbortExecution
 from vistrails.core.interpreter.default import get_default_interpreter
+from vistrails.core.utils import VistrailsDeprecation
 from vistrails.gui.base_view import BaseView
 from vistrails.gui.controlflow_assist import QControlFlowAssistDialog
 from vistrails.gui.graphics_view import (QInteractiveGraphicsScene,
@@ -66,6 +72,8 @@ from vistrails.gui.graphics_view import (QInteractiveGraphicsScene,
                                QGraphicsItemInterface)
 from vistrails.gui.module_info import QModuleInfo
 from vistrails.gui.module_palette import QModuleTreeWidget
+from vistrails.gui.modules.utils import get_widget_class
+from vistrails.gui.ports_pane import Parameter
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.utils import getBuilderWindow
 from vistrails.gui.variable_dropbox import QDragVariableLabel
@@ -73,6 +81,8 @@ from vistrails.gui.variable_dropbox import QDragVariableLabel
 import copy
 import math
 import operator
+import string
+import warnings
 
 import vistrails.api
 import vistrails.gui.utils
@@ -301,6 +311,8 @@ class QAbstractGraphicsPortItem(QtGui.QAbstractGraphicsShapeItem):
                                    callback)
             self.removeVarActions.append((removeVarAction, callback))
 
+
+
     def removeVar(self, var_uuid):
         (to_delete_modules, to_delete_conns) = \
             self.controller.get_disconnect_vistrail_vars( \
@@ -501,7 +513,8 @@ class QGraphicsPortPolygonItem(QAbstractGraphicsPortItem):
         for p in points:
             if p[0] is None:
                 x = rect.x() + rect.width()
-            elif p[0] != 0 and p[0] != 1 and p[0] > 0 and p[0] < 1:
+            # can't do +1 (2+ is fine)
+            elif p[0] != 0 and p[0] > 0 and p[0] < 1.0001:
                 x = rect.x() + rect.width() * p[0]
             elif p[0] < 0:
                 x = rect.x() + rect.width() + p[0]
@@ -509,23 +522,22 @@ class QGraphicsPortPolygonItem(QAbstractGraphicsPortItem):
                 x = rect.x() + p[0]
             if p[1] is None:
                 y = rect.y() + rect.height()
-            elif p[1] != 0 and p[1] != 1 and p[1] > 0 and p[1] < 1:
+            elif p[1] != 0 and p[1] > 0 and p[1] < 1.0001:
                 y = rect.y() + rect.height() * p[1]
             elif p[1] < 0:
                 y = rect.y() + rect.height() + p[1]
             else:
                 y = rect.y() + p[1]
 
-            print "adding point", x, y
             if x < rect.x():
                 x = rect.x()
+            # can't do +1 (2+ is fine)
             elif x > (rect.x() + rect.width()):
                 x = rect.x() + rect.width()
             if y < rect.y():
                 y = rect.y()
             elif y > (rect.y() + rect.height()):
                 y = rect.y() + rect.height()
-            print "Adding point", x, y
             new_points.append(QtCore.QPointF(x,y))
         self._polygon = QtGui.QPolygonF(new_points)
     
@@ -611,6 +623,7 @@ class QGraphicsConfigureItem(QtGui.QGraphicsPolygonItem):
         menu.addAction(self.annotateAct)
         menu.addAction(self.viewDocumentationAct)
         menu.addAction(self.changeModuleLabelAct)
+        menu.addAction(self.editLoopingAct)
         menu.addAction(self.setBreakpointAct)
         menu.addAction(self.setWatchedAct)
         menu.addAction(self.runModuleAct)
@@ -639,6 +652,11 @@ class QGraphicsConfigureItem(QtGui.QGraphicsPolygonItem):
         QtCore.QObject.connect(self.viewDocumentationAct,
                                QtCore.SIGNAL("triggered()"),
                                self.viewDocumentation)
+        self.editLoopingAct = QtGui.QAction("Execution Options", self.scene())
+        self.editLoopingAct.setStatusTip("Edit module execution options")
+        QtCore.QObject.connect(self.editLoopingAct,
+                               QtCore.SIGNAL("triggered()"),
+                               self.editLooping)
         self.changeModuleLabelAct = QtGui.QAction("Set Module Label...", self.scene())
         self.changeModuleLabelAct.setStatusTip("Set or remove module label")
         QtCore.QObject.connect(self.changeModuleLabelAct,
@@ -716,6 +734,13 @@ class QGraphicsConfigureItem(QtGui.QGraphicsPolygonItem):
         assert self.moduleId >= 0
         self.scene().open_documentation_window(self.moduleId)
 
+    def editLooping(self):
+        """ editLooping() -> None
+        Show the looping options for the module
+        """
+        assert self.moduleId >= 0
+        self.scene().open_looping_window(self.moduleId)
+
     def changeModuleLabel(self):
         """ changeModuleLabel() -> None
         Show the module label configuration widget
@@ -822,6 +847,8 @@ class QGraphicsConnectionItem(QGraphicsItemInterface,
         Create the shape, initialize its pen and brush accordingly
 
         """
+        self.srcPortItem = srcPortItem
+        self.dstPortItem = dstPortItem
         path = self.create_path(srcPortItem.getPosition(), 
                                 dstPortItem.getPosition())
         QtGui.QGraphicsPathItem.__init__(self, path, parent)
@@ -829,8 +856,6 @@ class QGraphicsConnectionItem(QGraphicsItemInterface,
         # Bump it slightly higher than the highest module
         self.setZValue(max(srcModule.id,
                            dstModule.id) + 0.1)
-        self.srcPortItem = srcPortItem
-        self.dstPortItem = dstPortItem
         self.connectionPen = CurrentTheme.CONNECTION_PEN
         self.connectingModules = (srcModule, dstModule)
         self.ghosted = False
@@ -866,8 +891,9 @@ class QGraphicsConnectionItem(QGraphicsItemInterface,
             painter.setPen(self.connectionPen)
         painter.drawPath(self.path())
 
-    def setupConnection(self, startPos, endPos):
-        path = self.create_path(startPos, endPos)
+    def setupConnection(self, startPos=None, endPos=None):
+        path = self.create_path(startPos or self.startPos,
+                                endPos or self.endPos)
         self.setPath(path)
 
     def create_path(self, startPos, endPos):
@@ -934,8 +960,28 @@ class QGraphicsConnectionItem(QGraphicsItemInterface,
         # self._control_2 = endPos - displacement
 
 
-        path = QtGui.QPainterPath(self.startPos)
-        path.cubicTo(self._control_1, self._control_2, self.endPos)
+        # draw multiple connections depending on list depth
+        def diff(i, depth):
+            return QtCore.QPointF((5.0 + 10.0*i)/depth - 5.0, 0.0)
+        
+        srcParent = self.srcPortItem.parentItem()
+        startDepth = srcParent.module.list_depth + 1 if srcParent else 1
+        dstParent = self.dstPortItem.parentItem()
+        endDepth = dstParent.module.list_depth + 1 if dstParent else 1
+        starts = [diff(i, startDepth) for i in xrange(startDepth)]
+        ends = [diff(i, endDepth) for i in xrange(endDepth)]
+    
+        first = True
+        for start in starts:
+            for end in ends:
+                if first:
+                    path = QtGui.QPainterPath(self.startPos + start)
+                    first = False
+                else:
+                    path.moveTo(self.startPos + start)
+                path.cubicTo(self._control_1, self._control_2,
+                             self.endPos + end)
+            
         return path
 
     def itemChange(self, change, value):
@@ -999,6 +1045,8 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         else:
             self.setFlags(QtGui.QGraphicsItem.ItemIsSelectable |
                           QtGui.QGraphicsItem.ItemIsMovable)
+        self.setAcceptHoverEvents(True)
+        self.setFlag(self.ItemIsFocusable)
         self.setZValue(0)
         self.labelFont = CurrentTheme.MODULE_FONT
         self.labelFontMetric = CurrentTheme.MODULE_FONT_METRIC
@@ -1012,6 +1060,7 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         self.labelRect = QtCore.QRectF()
         self.descRect = QtCore.QRectF()
         self.abstRect = QtCore.QRectF()
+        self.editRect = QtCore.QRectF()
         self.id = -1
         self.label = ''
         self.description = ''
@@ -1031,6 +1080,12 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         self.progressBrush = CurrentTheme.SUCCESS_MODULE_BRUSH
         self.connectionItems = {}
         self._cur_function_names = set()
+        self.function_overview = ''
+        self.show_widgets = get_vistrails_configuration(
+                                         ).check('showInlineParameterWidgets')
+        self.function_widgets = []
+        self.functions_widget = None
+        self.edit_rect = QtCore.QRectF(0.0, 0.0, 0.0, 0.0)
         self.handlePositionChanges = True
 
     def moduleHasChanged(self, core_module):
@@ -1042,15 +1097,19 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                 # m2_has, since m1_has and previous condition
                 m1.db_annotations_key_index['__desc__'].value.strip()!=
                 m2.db_annotations_key_index['__desc__'].value.strip()):
-                return True            
+                return True
             return False
 
         # def module_functions_have_changed(m1, m2):
-        #     f1_names = set([f.name for f in m1.functions])
-        #     f2_names = set([f.name for f in m2.functions])
+        #     f1_names = set(f.name for f in m1.functions)
+        #     f2_names = set(f.name for f in m2.functions)
         #     return (len(f1_names ^ f2_names) > 0)
 
-        if self.scenePos().x() != core_module.center.x or \
+        if self.show_widgets != get_vistrails_configuration(
+                                   ).check('showInlineParameterWidgets') and \
+           core_module.editable_input_ports:
+            return True
+        elif self.scenePos().x() != core_module.center.x or \
                 -self.scenePos().y() != core_module.center.y:
             return True
         elif module_text_has_changed(self.module, core_module):
@@ -1058,6 +1117,15 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         # elif module_functions_have_changed(self.module, core_module):
         #     return True
         else:
+            # check for changed edit widgets
+            if core_module.editable_input_ports != \
+               self.module.editable_input_ports:
+                # shape has changed so we need to recreate the module
+                return True
+
+            # check for deleted edit widgets
+            if self.functions_have_been_deleted(core_module):
+                return True
             # Check for changed ports
             # _db_name because this shows up in the profile.
             cip = sorted([x.key_no_id() for x in self.inputPorts])
@@ -1080,12 +1148,16 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                 return True
         return False
 
+    def functions_have_been_deleted(self, core_module):
+        # check if a visible function has been deleted
+        before = self._cur_function_names
+        after = set(f.name for f in core_module.functions)
+        return (before - after) & core_module.editable_input_ports
+
     def moduleFunctionsHaveChanged(self, core_module):
-        m1 = self.module
         m2 = core_module
-        f1_names = set([f.name for f in m1.functions])
-        f2_names = set([f.name for f in m2.functions])
-        return (len(f1_names ^ f2_names) > 0)
+        f2_names = set(f.name for f in m2.functions)
+        return (len(self._cur_function_names ^ f2_names) > 0)
 
     def update_function_ports(self, core_module=None):
         if core_module is None:
@@ -1095,15 +1167,10 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
             self._cur_function_names = copy.copy(added_functions)
         else:
             before_names = self._cur_function_names
-            after_names = set([f.name for f in core_module.functions])
-            # print "before_names:", before_names
-            # print "after_names:", after_names
+            after_names = set(f.name for f in core_module.functions)
             added_functions = after_names - before_names
             deleted_functions = before_names - after_names
             self._cur_function_names = copy.copy(after_names)
-
-        # print "added_functions:", added_functions
-        # print "deleted_functions:", deleted_functions
         if len(deleted_functions) > 0:
             for function_name in deleted_functions:
                 try:
@@ -1115,9 +1182,7 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                     item = self.getInputPortItem(f_spec)
                     if item is not None:
                         item.disconnect()
-                except:
-                    # import traceback
-                    # traceback.print_exc()
+                except Exception:
                     pass
 
         if len(added_functions) > 0:
@@ -1132,51 +1197,77 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                 item = self.getInputPortItem(f_spec)
                 if item is not None:
                     item.connect()
-        
         self.module = core_module
 
+        
+    def update_function_values(self, core_module):
+        """ Updates widget values if they have changed
+        """
+        for function_widget in self.function_widgets:
+            for f in core_module.functions:
+                if f.name == function_widget.function.name:
+                    value = [p.strValue for p in f.params]
+                    if function_widget.getContents() != value:
+                        function_widget.setContents(value)
+                    continue
+
     def setProgress(self, progress):
         self.progress = progress
         
     def computeBoundingRect(self):
         """ computeBoundingRect() -> None
-        Adjust the module size according to the text size
+        Adjust the module size according to contents
         
         """
+        width = 0
+        height = CurrentTheme.MODULE_LABEL_MARGIN[1]
+        # for each rect: Add height, adjust min width,
+        # set pos to distance to top middle corner, to be adjusted when
+        # paddedRect is known
         labelRect = self.labelFontMetric.boundingRect(self.label)
+        labelRect.moveTo(-labelRect.width()//2, height)
+        height += labelRect.height()
+        padding = labelRect.adjusted(-CurrentTheme.MODULE_LABEL_MARGIN[0], 0,
+                                      CurrentTheme.MODULE_LABEL_MARGIN[2], 0)
+        width = max(width, padding.width())
+
         if self.description:
             self.description = '(' + self.description + ')'
             descRect = self.descFontMetric.boundingRect(self.description)
-            # adjust labelRect in case descRect is wider
-            labelRect = labelRect.united(descRect)
-            descRect.adjust(0, 0, 0, CurrentTheme.MODULE_PORT_MARGIN[3])
-        else:
-            descRect = QtCore.QRectF(0, 0, 0, 0)
-
-        labelRect.translate(-labelRect.center().x(), -labelRect.center().y())
-        self.paddedRect = QtCore.QRectF(
-            labelRect.adjusted(-CurrentTheme.MODULE_LABEL_MARGIN[0],
-                                -CurrentTheme.MODULE_LABEL_MARGIN[1]
-                                -descRect.height()/2,
-                                CurrentTheme.MODULE_LABEL_MARGIN[2],
-                                CurrentTheme.MODULE_LABEL_MARGIN[3]
-                                +descRect.height()/2))
-        
-        self.labelRect = QtCore.QRectF(
-            self.paddedRect.left(),
-            -(labelRect.height()+descRect.height())/2,
-            self.paddedRect.width(),
-            labelRect.height())
-        self.descRect = QtCore.QRectF(
-            self.paddedRect.left(),
-            self.labelRect.bottom(),
-            self.paddedRect.width(),
-            descRect.height())
+            descRect.moveTo(-descRect.width()//2, height)
+            height += descRect.height()
+            padding = descRect.adjusted(-CurrentTheme.MODULE_LABEL_MARGIN[0], 0,
+                                         CurrentTheme.MODULE_LABEL_MARGIN[2], 0)
+            width = max(width, padding.width())
+
+        if self.edit_rect.height():
+            height += CurrentTheme.MODULE_EDIT_MARGIN[1] # top margin
+            editRect = self.edit_rect
+            editRect.moveTo(-editRect.width()//2, height)
+            height += editRect.height()
+            padding = editRect.adjusted(-CurrentTheme.MODULE_EDIT_MARGIN[0], 0,
+                                         CurrentTheme.MODULE_EDIT_MARGIN[2], 0)
+            width = max(width, padding.width())
+            height += CurrentTheme.MODULE_EDIT_MARGIN[3] # bottom edit margin
+
+        height += CurrentTheme.MODULE_LABEL_MARGIN[3] # bottom margin
+
+        # move to final position
+
+        self.paddedRect = QtCore.QRectF(-width/2, -height/2, width, height)
+        labelRect.translate(0, -height//2)
+        self.labelRect = labelRect
+        if self.description:
+            descRect.translate(0, -height//2)
+            self.descRect = descRect
+        if self.edit_rect.height():
+            editRect.translate(0, -height//2)
+            self.editRect = editRect
         self.abstRect = QtCore.QRectF(
             self.paddedRect.left(),
-            -self.labelRect.top()-CurrentTheme.MODULE_PORT_MARGIN[3],
-            labelRect.left()-self.paddedRect.left(),
-            self.paddedRect.bottom()+self.labelRect.top())
+            -self.paddedRect.top()-CurrentTheme.MODULE_LABEL_MARGIN[3],
+            CurrentTheme.MODULE_LABEL_MARGIN[0],
+            CurrentTheme.MODULE_LABEL_MARGIN[3])
 
     def boundingRect(self):
         """ boundingRect() -> QRectF
@@ -1185,7 +1276,7 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         """
         try:
             r = self.paddedRect.adjusted(-2, -2, 2, 2)
-        except:
+        except Exception:
             r = QtCore.QRectF()
         return r
 
@@ -1237,7 +1328,7 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                 port.setGhosted(ghosted)
             for port in self.outputPorts.itervalues():
                 port.setGhosted(ghosted)
-            self._needs_state_udpated = True
+            self._needs_state_updated = True
 
 #             if ghosted:
 #                 self.modulePen = CurrentTheme.GHOSTED_MODULE_PEN
@@ -1317,12 +1408,12 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         # draw module labels
         painter.setPen(self.labelPen)
         painter.setFont(self.labelFont)
-        painter.drawText(self.labelRect, QtCore.Qt.AlignCenter, self.label)
+        painter.drawText(self.labelRect.adjusted(-10,-10,10,10), QtCore.Qt.AlignCenter, self.label)
         if self.module.is_abstraction() and not self.module.is_latest_version():
             painter.drawText(self.abstRect, QtCore.Qt.AlignCenter, '!')
         if self.descRect:
             painter.setFont(self.descFont)
-            painter.drawText(self.descRect, QtCore.Qt.AlignCenter,
+            painter.drawText(self.descRect.adjusted(-10,-10,10,10), QtCore.Qt.AlignCenter,
                              self.description)
 
     def paintToPixmap(self, scale_x, scale_y):
@@ -1363,7 +1454,7 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
             diff = minWidth - self.paddedRect.width() + 1
             self.paddedRect.adjust(-diff/2, 0, diff/2, 0)
 
-    def setupModule(self, module):
+    def setupModule(self, module, read_only=False):
         """ setupModule(module: Module) -> None
         Set up the item to reflect the info in 'module'
         
@@ -1379,6 +1470,17 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
         else:
             self.label = module.label
             self.description = ''
+
+        # Show inline edit widgets
+        if get_vistrails_configuration().check('showInlineParameterWidgets') and \
+            module.is_valid and not read_only and module.editable_input_ports:
+            self.functions_widget = QGraphicsFunctionsWidget(self.module,
+                          self, module.editable_input_ports == set(['value']))
+            set_lod(0.5, self.functions_widget)
+            self.functions_widget.function_changed.connect(self.function_changed)
+            self.function_widgets = self.functions_widget.function_widgets
+            self.edit_rect = self.functions_widget.boundingRect()
+
         self.setToolTip(self.description)
         self.computeBoundingRect()
         self.setPos(module.center.x, -module.center.y)
@@ -1453,7 +1555,7 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
 
         # Update output ports
         [x, y] = self.nextOutputPortPos
-        for port in outputPorts:            
+        for port in reversed(outputPorts):
             self.outputPorts[port] = self.createPortItem(port, x, y)
             x -= t.PORT_WIDTH + t.MODULE_PORT_SPACE
         self.nextOutputPortPos = [x, y]
@@ -1484,10 +1586,30 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
             except ModuleRegistryException, e:
                 error = e
 
+            if self.functions_widget:
+                self.functions_widget.setPos(self.editRect.topLeft())
+
             self.update_function_ports()
+
         else:
             self.setInvalid(True)
-            
+
+    def function_changed(self, name, values):
+        """ Called when a function value has changed by the inline edit widget
+        
+        """
+        controller = self.scene().controller
+        module = controller.current_pipeline.modules[self.module.id]
+        controller.update_function(module, name, values)
+
+        if self.moduleFunctionsHaveChanged(module):
+            self.update_function_ports(module)
+
+        if self.isSelected():
+            from vistrails.gui.vistrails_window import _app
+            module = controller.current_pipeline.modules[self.module.id]
+            _app.notify('module_changed', module)
+
     def create_shape_from_fringe(self, fringe):
         left_fringe, right_fringe = fringe
         if left_fringe[0] != (0.0, 0.0):
@@ -1549,21 +1671,20 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                     port_klass = QGraphicsPortTriangleItem
                     try:
                         kwargs['angle'] = int(shape[8:])
-                    except:
+                    except ValueError:
                         kwargs['angle'] = 0
                 elif shape == "diamond":
                     port_klass = QGraphicsPortDiamondItem
                 elif shape == "circle" or shape == "ellipse":
                     port_klass = QGraphicsPortEllipseItem
             else:
-                is_iterable = False
                 try:
-                    shape.__iter__()
-                    is_iterable = True
+                    iter(shape)
+                except TypeError:
+                    pass
+                else:
                     port_klass = QGraphicsPortPolygonItem
                     kwargs['points'] = shape
-                except:
-                    pass
 
         portShape = port_klass(port, x, y, self.ghosted, self, **kwargs)
         # portShape = QGraphicsPortRectItem(port, x, y, self.ghosted, self)
@@ -1643,7 +1764,6 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
                                            CurrentTheme.MODULE_PORT_SPACE))
                     return item
 
-        debug.log("PORT SIG:" + port.signature)
         if not port.signature or port.signature == '()':
             # or len(port_descs) == 0:
             sigstring = default_sig
@@ -1726,11 +1846,65 @@ class QGraphicsModuleItem(QGraphicsItemInterface, QtGui.QGraphicsItem):
             else:
                 yield (item, True)
 
+    def keyPressEvent(self, event):
+        """ keyPressEvent(event: QKeyEvent) -> None
+        Capture 'Del', 'Backspace' for deleting modules.
+        Ctrl+C, Ctrl+V, Ctrl+A for copy, paste and select all
+        
+        """        
+        if (self.scene().controller and
+            event.key() in [QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete]):
+            if not self.scene().read_only_mode:
+                self.scene().delete_selected_items()
+        else:
+            QtGui.QGraphicsItem.keyPressEvent(self, event)
+
     def mouseReleaseEvent(self, event):
         super(QGraphicsModuleItem, self).mouseReleaseEvent(event)
         if not self.controller.changed and self.controller.has_move_actions():
             self.controller.set_changed(True)
 
+    def hoverEnterEvent(self, event):
+        if QtGui.QApplication.keyboardModifiers() == QtCore.Qt.ControlModifier:
+
+            scene = self.scene()
+            if scene.function_tooltip:
+                scene.removeItem(scene.function_tooltip)
+
+            module = scene.controller.current_pipeline.modules[self.module.id]
+            if module.functions:
+                function_overview = []
+                for f in module.functions:
+                    if len(f.params)>1:
+                        params = ', '.join([p.strValue for p in f.params])
+                    elif len(f.params)>0:
+                        params = f.params[0].strValue
+                    else:
+                        params = ''
+                    if len(params)>100:
+                        params = params[:97] + '...'
+                    function_template = "<b>%s(</b>%s<b>)</b>"
+                    function_overview.append(function_template % (f.name, params))
+                    template = '<html><p style="background:#FFFFFF;">%s</p></html>'
+                self.function_overview = template % '<br/>'.join(function_overview)
+            else:
+                self.function_overview = ''
+
+            scene.function_tooltip = QtGui.QGraphicsTextItem()
+            pos = self.paddedRect.bottomLeft()+self.pos()
+            scene.function_tooltip.setPos(pos)
+            scene.function_tooltip.setAcceptHoverEvents(False)
+            scene.addItem(scene.function_tooltip)
+            scene.function_tooltip.setHtml(self.function_overview)
+            scene.function_tooltip.setZValue(1000000)
+        return QtGui.QGraphicsItem.hoverEnterEvent(self, event)
+
+    def hoverLeaveEvent(self, event):
+        if self.scene().function_tooltip:
+            self.scene().removeItem(self.scene().function_tooltip)
+            self.scene().function_tooltip = None
+        return QtGui.QGraphicsItem.hoverLeaveEvent(self, event)
+
     def itemChange(self, change, value):
         """ itemChange(change: GraphicsItemChange, value: value) -> value
         Capture move event to also move the connections.  Also unselect any
@@ -1886,16 +2060,23 @@ class QPipelineScene(QInteractiveGraphicsScene):
         self._old_module_ids = set()
         self._old_connection_ids = set()
         self._var_selected_port = None
-        self.pipeline = None
         self.read_only_mode = False
         self.current_pipeline = None
         self.current_version = -1
-        self.progress = None
+        self.skip_update = False
+        self.function_tooltip = None
 
         self.tmp_module_item = None
         self.tmp_input_conn = None
         self.tmp_output_conn = None
 
+    def _get_pipeline(self):
+        warnings.warn("Use of deprecated field 'pipeline' replaced by "
+                      "'current_pipeline'",
+                      category=VistrailsDeprecation)
+        return self.current_pipeline
+    pipeline = property(_get_pipeline)
+
     def addModule(self, module, moduleBrush=None):
         """ addModule(module: Module, moduleBrush: QBrush) -> QGraphicsModuleItem
         Add a module to the scene
@@ -1905,9 +2086,10 @@ class QPipelineScene(QInteractiveGraphicsScene):
         if self.controller and self.controller.search:
             moduleQuery = (self.controller.current_version, module)
             matched = self.controller.search.matchModule(*moduleQuery)
+            matched = self.controller.search.matchModule(*moduleQuery)
             moduleItem.setGhosted(not matched)
         moduleItem.controller = self.controller
-        moduleItem.setupModule(module)
+        moduleItem.setupModule(module, self.read_only_mode)
         moduleItem.setBreakpoint(module.is_breakpoint)
         if moduleBrush:
             moduleItem.set_custom_brush(moduleBrush)
@@ -1947,6 +2129,7 @@ class QPipelineScene(QInteractiveGraphicsScene):
             connectionItem.hide()
             var_uuid = srcModule.module.get_vistrail_var()
             dstPortItem.addVistrailVar(var_uuid)
+        self.update_connections([srcModule.id, dstModule.id])
         return connectionItem
 
     def selected_subgraph(self):
@@ -2006,14 +2189,13 @@ class QPipelineScene(QInteractiveGraphicsScene):
             self.removeItem(self.connections[c_id])
         del self.connections[c_id]
         self._old_connection_ids.remove(c_id)
-        
+        self.update_connections([srcModule.id, dstModule.id])
 
     def recreate_module(self, pipeline, m_id):
         """recreate_module(pipeline, m_id): None
 
         Recreates a module on the scene."""
         selected = self.modules[m_id].isSelected()
-
         depending_connections = \
             [c_id for c_id in self.modules[m_id].dependingConnectionItems()]
         # old_depending_connections = self.modules[m_id]._old_connection_ids
@@ -2034,18 +2216,28 @@ class QPipelineScene(QInteractiveGraphicsScene):
                                
         if selected:
             self.modules[m_id].setSelected(True)
-            
+
     def update_module_functions(self, pipeline, m_id):
-        self.modules[m_id].update_function_ports(pipeline.modules[m_id])
+        """ Used by ports_pane to update modules
+
+        """
+        module = pipeline.modules[m_id]
+        if self.modules[m_id].functions_have_been_deleted(module):
+            self.recreate_module(pipeline, m_id)
+            return
+
+        self.modules[m_id].update_function_values(module)
+
+        if self.modules[m_id].moduleFunctionsHaveChanged(module):
+            self.modules[m_id].update_function_ports(module)
 
     def setupScene(self, pipeline):
         """ setupScene(pipeline: Pipeline) -> None
         Construct the scene to view a pipeline
         
         """
-        old_pipeline = self.pipeline
-        self.pipeline = pipeline
-
+        old_pipeline = self.current_pipeline
+        self.current_pipeline = pipeline
         if self.noUpdate: return
         if (pipeline is None or 
             (old_pipeline and not old_pipeline.is_valid) or 
@@ -2053,9 +2245,10 @@ class QPipelineScene(QInteractiveGraphicsScene):
             # clear things
             self.clear()
         if not pipeline: return 
-            
+
         needReset = len(self.items())==0
         try:
+            self.skip_update = True
             new_modules = set(pipeline.modules)
             modules_to_be_added = new_modules - self._old_module_ids
             modules_to_be_deleted = self._old_module_ids - new_modules
@@ -2066,6 +2259,7 @@ class QPipelineScene(QInteractiveGraphicsScene):
             connections_to_be_deleted = self._old_connection_ids - new_connections
             common_connections = new_connections.intersection(self._old_connection_ids)
 
+
             # Check if connections to be added require 
             # optional ports in modules to be visible
             for c_id in connections_to_be_added:
@@ -2099,12 +2293,13 @@ class QPipelineScene(QInteractiveGraphicsScene):
             # Update common modules
             for m_id in common_modules:
                 tm_item = self.modules[m_id]
-                tm = tm_item.module
                 nm = pipeline.modules[m_id]
                 if tm_item.moduleHasChanged(nm):
                     self.recreate_module(pipeline, m_id)
+                    tm_item = self.modules[m_id]
                 elif tm_item.moduleFunctionsHaveChanged(nm):
                     tm_item.update_function_ports(pipeline.modules[m_id])
+                tm_item.update_function_values(pipeline.modules[m_id])
                 if tm_item.isSelected():
                     selected_modules.append(m_id)
                 if self.controller and self.controller.search:
@@ -2134,9 +2329,9 @@ class QPipelineScene(QInteractiveGraphicsScene):
             self.reset_module_colors()
             for m_id in selected_modules:
                 self.modules[m_id].setSelected(True)
+
         except ModuleRegistryException, e:
-            import traceback
-            traceback.print_exc()
+            debug.print_exc()
             views = self.views()
             assert len(views) > 0
             debug.critical("Missing package/module",
@@ -2144,6 +2339,9 @@ class QPipelineScene(QInteractiveGraphicsScene):
                 "in that package)") % (e._identifier, e._name))
             self.clear()
             self.controller.change_selected_version(0)
+        finally:
+            self.skip_update = False
+            self.update_connections()
 
         if needReset and len(self.items())>0:
             self.fitToAllViews()
@@ -2542,7 +2740,7 @@ class QPipelineScene(QInteractiveGraphicsScene):
                         namespace=desc.namespace,
                         )
         module.is_valid = True
-        self.tmp_module_item.setupModule(module)
+        self.tmp_module_item.setupModule(module, True)
         self.addItem(self.tmp_module_item)
         self.tmp_module_item.hide()
         self.tmp_module_item.update()
@@ -2550,6 +2748,19 @@ class QPipelineScene(QInteractiveGraphicsScene):
         
         return self.tmp_module_item
 
+    def update_connections(self, modules=None):
+        if self.skip_update:
+            return
+        if (self.controller.current_pipeline and
+            self.controller.current_pipeline.is_valid):
+            for module_id, list_depth in \
+                    self.controller.current_pipeline.mark_list_depth(modules):
+                if module_id in self.modules:
+                    self.modules[module_id].module.list_depth = list_depth
+        for c in self.connections.itervalues():
+            c.setupConnection()
+
+    
     def delete_tmp_module(self):
         if self.tmp_module_item is not None:
             self.removeItem(self.tmp_module_item)
@@ -2669,8 +2880,8 @@ class QPipelineScene(QInteractiveGraphicsScene):
         Capture 'Del', 'Backspace' for deleting modules.
         Ctrl+C, Ctrl+V, Ctrl+A for copy, paste and select all
         
-        """        
-        if (self.controller and
+        """
+        if (not self.focusItem() and self.controller and
             event.key() in [QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete]):
             if not self.read_only_mode:
                 self.delete_selected_items()
@@ -2865,6 +3076,13 @@ class QPipelineScene(QInteractiveGraphicsScene):
         from vistrails.gui.vistrails_window import _app
         _app.show_documentation()
 
+    def open_looping_window(self, id):
+        """ open_looping_window(int) -> None
+        Opens the modal module looping options window for module with given id
+        """
+        from vistrails.gui.vistrails_window import _app
+        _app.show_looping_options()
+
     def toggle_breakpoint(self, id):
         """ toggle_breakpoint(int) -> None
         Toggles the breakpoint attribute for the module with given id
@@ -2942,14 +3160,15 @@ class QPipelineScene(QInteractiveGraphicsScene):
     ##########################################################################
     # Execution reporting API
 
-    def cancel_progress(self):
+    def check_progress_canceled(self):
         """Checks if the user have canceled the execution and takes
            appropriate action
         """
-        if self.progress.wasCanceled():
-            if self.progress._progress_canceled:
+        p = self.controller.progress
+        if p.wasCanceled():
+            if p._progress_canceled:
                 # It has already been confirmed in a progress update
-                self.progress._progress_canceled = False
+                p._progress_canceled = False
                 raise AbortExecution("Execution aborted by user")
             r = QtGui.QMessageBox.question(self.parent(),
                 'Execution Paused',
@@ -2959,7 +3178,7 @@ class QPipelineScene(QInteractiveGraphicsScene):
             if r == QtGui.QMessageBox.Yes:
                 raise AbortExecution("Execution aborted by user")
             else:
-                self.progress.goOn()
+                p.goOn()
 
     def set_module_success(self, moduleId):
         """ set_module_success(moduleId: int) -> None
@@ -2976,8 +3195,8 @@ class QPipelineScene(QInteractiveGraphicsScene):
         
         """
         QtGui.QApplication.postEvent(self,
-                                     QModuleStatusEvent(moduleId, 1, error,
-                                                      errorTrace = errorTrace))
+                                     QModuleStatusEvent(moduleId, 1, error.msg,
+                                                        errorTrace=errorTrace))
         QtCore.QCoreApplication.processEvents()
 
     def set_module_not_executed(self, moduleId):
@@ -3003,10 +3222,12 @@ class QPipelineScene(QInteractiveGraphicsScene):
         Post an event to the scene (self) for updating the module color
         
         """
-        if self.progress:
-            self.cancel_progress()
-            self.progress.setValue(self.progress.value() + 1)
-            self.progress.setLabelText(self.controller.current_pipeline.get_module_by_id(moduleId).name)
+        p = self.controller.progress
+        if p is not None:
+            self.check_progress_canceled()
+            pipeline = self.controller.current_pipeline
+            module = pipeline.get_module_by_id(moduleId)
+            p.setLabelText(module.name)
         QtGui.QApplication.postEvent(self,
                                      QModuleStatusEvent(moduleId, 4, ''))
         QtCore.QCoreApplication.processEvents()
@@ -3016,16 +3237,17 @@ class QPipelineScene(QInteractiveGraphicsScene):
         Post an event to the scene (self) for updating the module color
         
         """
-        if self.progress:
+        p = self.controller.progress
+        if p is not None:
             try:
-                self.cancel_progress()
+                self.check_progress_canceled()
             except AbortExecution:
-                self.progress._progress_canceled = True
+                p._progress_canceled = True
                 raise
+        status = '%d%% Completed' % int(progress*100)
         QtGui.QApplication.postEvent(self,
                                      QModuleStatusEvent(moduleId, 5,
-                                                        '%d%% Completed' % int(progress*100),
-                                                        progress))
+                                                        status, progress))
         QtCore.QCoreApplication.processEvents()
 
     def set_module_persistent(self, moduleId):
@@ -3034,28 +3256,20 @@ class QPipelineScene(QInteractiveGraphicsScene):
         QtCore.QCoreApplication.processEvents()
 
     def set_module_suspended(self, moduleId, error):
-        """ set_module_suspended(moduleId: int, error: str) -> None
+        """ set_module_suspended(moduleId: int, error: str/instance) -> None
         Post an event to the scene (self) for updating the module color
         
         """
-        msg = error if isinstance(error, str) else error.msg
-        text = "Module is suspended, reason: %s" % msg
+        status = "Module is suspended, reason: %s" % error
         QtGui.QApplication.postEvent(self,
-                                     QModuleStatusEvent(moduleId, 7, text))
+                                     QModuleStatusEvent(moduleId, 7, status))
         QtCore.QCoreApplication.processEvents()
-        # add to suspended modules dialog
-        if isinstance(error, str):
-            return
-        from vistrails.gui.job_monitor import QJobView
-        jobView = QJobView.instance()
-        try:
-            result = jobView.add_job(self.controller, error)
-            if result:
-                jobView.set_visible(True)
-        except Exception, e:
-            import traceback
-            debug.critical("Error Monitoring Job: %s" % str(e), traceback.format_exc())
-            
+
+    def set_execution_progress(self, progress):
+        p = self.controller.progress
+        if p is not None:
+            p.setValue(int(progress * 100))
+
     def reset_module_colors(self):
         for module in self.modules.itervalues():
             module.statusBrush = None
@@ -3094,6 +3308,196 @@ class QPipelineScene(QInteractiveGraphicsScene):
         This will prevent user to add/remove modules and connections."""
         self.read_only_mode = on
 
+class QGraphicsFunctionsWidget(QtGui.QGraphicsWidget):
+    """ GraphicsWidget containing all editable functions
+
+    """
+    
+    function_changed = QtCore.pyqtSignal(str, list)
+
+    def __init__(self, module, parent=None, constant=None):
+        QtGui.QGraphicsWidget.__init__(self, parent)
+        self.function_widgets = []
+        height = 0
+        width = 0
+        for port_spec in module.destinationPorts():
+            if port_spec.name in module.editable_input_ports:
+                # create default dummies
+                params = []
+                for psi in port_spec.items:
+                    param = ModuleParam(type=psi.descriptor.name,
+                                        identifier=psi.descriptor.identifier,
+                                        namespace=psi.descriptor.namespace)
+                    params.append(param)
+                function = ModuleFunction(name=port_spec.name,
+                                          parameters=params)
+                for f in module.functions:
+                    if f.name == port_spec.name:
+                        function = f
+
+                for psi, param in zip(port_spec.port_spec_items, 
+                                                             function.params):
+                    param.port_spec_item = psi
+                function_widget = QGraphicsFunctionWidget(function, self, constant)
+                function_widget.setPos(0, height)
+                function_widget.function_changed.connect(self.function_changed)
+                self.function_widgets.append(function_widget)
+                height += function_widget.boundingRect().height()
+                width = max(width,function_widget.boundingRect().width())
+        # center widgets
+        for function_widget in self.function_widgets:
+            for widget, w in function_widget.widths:
+                widget.moveBy((width-w)/2, 0.0)
+        self.bounds = QtCore.QRectF(0,0,width,height)
+
+    def boundingRect(self):
+        return self.bounds
+
+class QGraphicsFunctionWidget(QtGui.QGraphicsWidget):
+    """ GraphicsWidget containing an editable function
+
+    """
+
+    function_changed = QtCore.pyqtSignal(str, list)
+
+    def __init__(self, function, parent=None, constant=None):
+        QtGui.QGraphicsWidget.__init__(self, parent)
+        self.function = function
+        self.param_widgets = []
+        self.widths = [] # (widget, width)
+        self.bounds = None
+        width = 0
+        height = 0
+        SCALE = 3.0/4 # make QWidgets a bit smaller than normal
+        MAX_WIDTH = 150
+        if not constant:
+            # add name label
+            name = self.function.name
+            bounds = CurrentTheme.MODULE_EDIT_FONT_METRIC.boundingRect
+            editRect = bounds(name)
+            if editRect.width()>MAX_WIDTH:
+                while bounds(name + '...').width() > MAX_WIDTH:
+                    name = name[:-1]
+                name += '...'
+            editRect = bounds(name)
+            width = max(width, editRect.width())
+            fname = QtGui.QGraphicsSimpleTextItem(name, self)
+            fname.setFont(CurrentTheme.MODULE_EDIT_FONT)
+            fname.setPos(-1, -1)
+
+            names = []
+            sigstring = function.sigstring
+            for sig in sigstring[1:-1].split(','):
+                k = sig.split(':', 2)
+                if len(k) < 2:
+                    names.append(k[0])
+                else:
+                    names.append(k[1])
+            short_sigstring = '(' + ','.join(names) + ')'
+            tooltip = function.name + short_sigstring
+            fname.setToolTip(tooltip)
+
+            #height += bounds(name).height()
+            height += 11 # hardcoded because fontmetric can give wrong value
+
+        for i in xrange(len(function.parameters)):
+            param = function.parameters[i]
+            # check
+            psi = param.port_spec_item
+            if psi.entry_type is not None:
+                # !!only pull off the prefix!! options follow in camelcase
+                prefix_end = len(psi.entry_type.lstrip(string.lowercase))
+                if prefix_end == 0:
+                    entry_type = psi.entry_type
+                else:
+                    entry_type = psi.entry_type[:-prefix_end]
+            else:
+                entry_type = None
+
+            Widget = get_widget_class(psi.descriptor, entry_type)
+            if hasattr(Widget, 'GraphicsItem') and Widget.GraphicsItem:
+                param_widget = Widget.GraphicsItem(param, self)
+                # resize to MAX_WIDTH
+                rect = param_widget.boundingRect()
+                param_widget.setZValue(self.zValue()+0.2)
+                scale = max(rect.width(), rect.height())
+                if scale>MAX_WIDTH:
+                    param_widget.setScale(MAX_WIDTH/scale)
+                    rect.setSize(rect.size()*MAX_WIDTH/scale)
+                bg = QtGui.QGraphicsRectItem(rect, self)
+                # TODO COLOR
+                bg.setBrush(QtGui.QBrush(QtGui.QColor('#FFFFFF')))
+                bg.setZValue(-1)
+                bg.setPos(0, height)
+                def get_focusable(widget):
+                    return lambda e:widget.setFocus() or widget.mousePressEvent(e)
+                bg.mousePressEvent = get_focusable(param_widget)
+                param_widget.setPos(0, height)
+                self.widths.append((param_widget,rect.width()))
+            else:
+                param_widget = Widget(param)
+                param_widget.setAutoFillBackground(False)
+                param_widget.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
+                param_widget.setMaximumSize(MAX_WIDTH/SCALE, MAX_WIDTH/SCALE)
+                param_widget.setWindowFlags(QtCore.Qt.BypassGraphicsProxyWidget)
+                proxy = QtGui.QGraphicsProxyWidget(self)
+                proxy.setWidget(param_widget)
+                proxy.setScale(SCALE)
+                rect = param_widget.geometry()
+                rect.setSize(rect.size()*SCALE)# uninitialized bounds need to be scaled
+                rect.moveTo(0.0,0.0)
+                proxy.setPos(0, height)
+                self.widths.append((proxy,rect.width()))
+            width = max(width, rect.width())
+            rect.setHeight(rect.height()+2) # space between parameters
+            height += rect.height()
+            param_widget.contentsChanged.connect(self.param_changed)
+            self.param_widgets.append(param_widget)
+        self.bounds = QtCore.QRectF(0.0, 0.0, width, height)
+
+    def param_changed(self, values):
+        # get values from all parameters
+        values = [p.contents() for p in self.param_widgets]
+        self.function_changed.emit(self.function.name, values)
+
+    def setContents(self, values):
+        for pw, value in zip(self.param_widgets, values):
+            pw.setContents(value, silent=True)
+
+    def getContents(self):
+        return [pw.contents() for pw in self.param_widgets]
+
+    def boundingRect(self):
+        return self.bounds
+
+def set_lod(limit, item, draw=None):
+    """Sets the limit of level of detail used when painting items.
+    """
+    # This function replaces the paint() methods of the given item and its
+    # children. The new version doesn't actually draw any of the items if the
+    # level of detail OF THE TOP ITEM (which is the only one checked) is under
+    # the threshold
+    # Only the top-level item is checked, because children might have different
+    # scales
+
+    paint_orig = item.paint # store reference to original paint method
+    top_item = draw is None
+    if draw is None:
+        draw = [True]
+
+    # Overrides paint() on that item
+    def paint_with_lod_check(painter, option, widget):
+        if top_item:
+            draw[0] = option.levelOfDetailFromTransform(
+                    painter.worldTransform()) > limit
+        if draw[0]:
+            return paint_orig(painter, option, widget)
+    item.paint = paint_with_lod_check
+
+    # Recursively process children
+    for i in item.childItems():
+        set_lod(limit, i, draw)
+
 class QModuleStatusEvent(QtCore.QEvent):
     """
     QModuleStatusEvent is trying to handle thread-safe real-time
@@ -3189,41 +3593,15 @@ class QPipelineView(QInteractiveGraphicsView, BaseView):
         return False
     
     def execute(self, target=None):
-        # view.checkModuleConfigPanel()
         # reset job view
-        from vistrails.gui.job_monitor import QJobView
-        jobView = QJobView.instance()
-        if jobView.updating_now:
-            debug.critical("Execution Aborted: Job Monitor is updating. Please wait a few seconds and try again.")
-            return
-        jobView.delete_job(self.controller)
-        jobView.updating_now = True
-
-        try:
-            modules = len(self.controller.current_pipeline.modules)
-            progress = ExecutionProgressDialog(modules)
-            self.scene().progress = progress
-            progress.show()
-
-            if target is not None:
-                self.controller.execute_current_workflow(
-                        sinks=[target],
-                        reason="Execute specific module")
-            else:
-                self.controller.execute_current_workflow()
-
-            progress.setValue(modules)
-            #progress.hide()
-            self.scene().progress = None
-        except Exception, e:
-            import traceback
-            debug.critical(str(e) or e.__class__.__name__,
-                           traceback.format_exc())
-        finally:
-            self.scene().progress = None
-            jobView.updating_now = False
-            from vistrails.gui.vistrails_window import _app
-            _app.notify('execution_updated')
+        if target is not None:
+            self.controller.execute_user_workflow(
+                    sinks=[target],
+                    reason="Execute specific module")
+        else:
+            self.controller.execute_user_workflow()
+        from vistrails.gui.vistrails_window import _app
+        _app.notify('execution_updated')
         
     def publish_to_web(self):
         from vistrails.gui.publishing import QVersionEmbed
@@ -3252,7 +3630,7 @@ class QPipelineView(QInteractiveGraphicsView, BaseView):
         return module_ids_len > 0
 
     def has_selected_module(self, module):
-        #print 'calling has_selected_module'
+        # 'calling has_selected_module'
         return self.has_selected_modules(module, True)
 
     def has_selected_groups(self, module, only_one=False):
@@ -3306,11 +3684,12 @@ class QPipelineView(QInteractiveGraphicsView, BaseView):
     def set_controller(self, controller):
         oldController = self.controller
         if oldController != controller:
-            if oldController != None:
+            #if oldController is not None:
                 # self.disconnect(oldController,
                 #                 QtCore.SIGNAL('versionWasChanged'),
                 #                 self.version_changed)
-                oldController.current_pipeline_view = None
+                # is this needed. It causes errors in api tests
+                #oldController.current_pipeline_view = None
             self.controller = controller
             self.scene().controller = controller
             # self.connect(controller,
@@ -3368,25 +3747,6 @@ class QPipelineView(QInteractiveGraphicsView, BaseView):
         m = self.matrix()
         return module_item.paintToPixmap(m.m11(), m.m22())
 
-class ExecutionProgressDialog(QtGui.QProgressDialog):
-    def __init__(self, modules):
-        QtGui.QProgressDialog.__init__(self, 'Executing Workflow',
-                                       '&Cancel',
-                                       0, modules)
-        self.setWindowTitle('Executing')
-        self.setWindowModality(QtCore.Qt.WindowModal)
-        self._last_set_value = 0
-        self._progress_canceled = False
-
-    def setValue(self, value):
-        self._last_set_value = value
-        super(ExecutionProgressDialog, self).setValue(value)
-
-    def goOn(self):
-        self.reset()
-        self.show()
-        super(ExecutionProgressDialog, self).setValue(self._last_set_value)
-
 ################################################################################
 # Testing
 
diff --git a/vistrails/gui/pipeline_view_select.py b/vistrails/gui/pipeline_view_select.py
index 732ba69..b72cdde 100644
--- a/vistrails/gui/pipeline_view_select.py
+++ b/vistrails/gui/pipeline_view_select.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 
 QReadOnlyPortSelectPipelineView
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.gui.pipeline_view import QGraphicsConfigureItem, QGraphicsModuleItem, \
     QAbstractGraphicsPortItem, QPipelineScene, QPipelineView
@@ -61,13 +64,17 @@ class QReadOnlyPortSelectPipelineView(QPipelineView):
         # Create custom scene
         scene_copy = QPipelineScene(self)
         scene_copy.controller = scene.controller
-        scene_copy.setupScene(scene.pipeline)
+        scene_copy.setupScene(scene.current_pipeline)
         scene_copy.selectAll()
         if include_module_ids:
             # Remove modules not in the include list and associated connections
             sel_modules, sel_connections = scene_copy.get_selected_item_ids()
-            [scene_copy.remove_module(m_id) for m_id in sel_modules if m_id not in include_module_ids]
-            [scene_copy.remove_connection(c_id) for c_id in sel_connections if c_id not in scene_copy.get_selected_item_ids()[1]]
+            for m_id in sel_modules:
+                if m_id not in include_module_ids:
+                    scene_copy.remove_module(m_id)
+            for c_id in sel_connections:
+                if c_id not in scene_copy.get_selected_item_ids()[1]:
+                    scene_copy.remove_connection(c_id)
         # Hide configure button on modules
         for item in scene_copy.selectedItems():
             if isinstance(item, QGraphicsModuleItem):
diff --git a/vistrails/gui/port_documentation.py b/vistrails/gui/port_documentation.py
index a484fb4..01a5bcc 100644
--- a/vistrails/gui/port_documentation.py
+++ b/vistrails/gui/port_documentation.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,6 +38,8 @@ dialog, which displays the available documentation for a given VisTrails module.
 
 QMethodDocumentation
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.vistrail.port import PortEndPoint
 from vistrails.core.utils import VistrailsInternalError
diff --git a/vistrails/gui/ports_pane.py b/vistrails/gui/ports_pane.py
index 5de8234..3ebf8b5 100644
--- a/vistrails/gui/ports_pane.py
+++ b/vistrails/gui/ports_pane.py
@@ -1,52 +1,74 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from itertools import izip
 import os
+import string
 
 from vistrails.core import debug
+from vistrails.core.configuration import get_vistrails_configuration
 from vistrails.core.modules.basic_modules import identifier as basic_identifier
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.modules.utils import create_port_spec_string
 from vistrails.core.vistrail.port_spec import PortSpec
 from vistrails.core.system import vistrails_root_directory
-from vistrails.gui.modules import get_widget_class
+from vistrails.gui.modules.utils import get_widget_class
 from vistrails.gui.common_widgets import QToolWindowInterface
 from vistrails.gui.port_documentation import QPortDocumentation
 from vistrails.gui.theme import CurrentTheme
 
+def letterIcon(letter, crossed=False):
+    """ Creates icon with a specific letter
+    """
+    pixmap = QtGui.QPixmap(48,48)
+    pixmap.fill(QtCore.Qt.transparent)
+    painter = QtGui.QPainter(pixmap)
+    painter.setPen(QtGui.QColor(0, 0, 0, 255))
+    font = painter.font()
+    font.setPointSize(40)
+    painter.setFont(font)
+    painter.drawText(0, 0, 48, 48, QtCore.Qt.AlignCenter, letter)
+    if crossed:
+        painter.drawLine(0,0,48,48)
+        painter.drawLine(0,48,48,0)
+    painter.end()
+    return QtGui.QIcon(pixmap)
+
 class AliasLabel(QtGui.QLabel):
     """
     AliasLabel is a QLabel that supports hover actions similar
@@ -126,26 +148,37 @@ class AliasLabel(QtGui.QLabel):
                     self.parent().updateMethod()
 
 class Parameter(object):
-    def __init__(self, desc):
+    def __init__(self, desc, psi=None):
         self.type = desc.name
         self.identifier = desc.identifier
         self.namespace = None if not desc.namespace else desc.namespace
         self.strValue = ''
         self.alias = ''
         self.queryMethod = None
-        self.port_spec_item = None
+        self.port_spec_item = psi
         self.param_exists = False
+
+class Function(object):
+    def __init__(self, name, params, port_spec=None):
+        self.name = name
+        self.parameters = params
+        self.port_spec = port_spec
+
+    def get_spec(self, port_type):
+        return self.port_spec
+
         
 class ParameterEntry(QtGui.QTreeWidgetItem):
     plus_icon = QtGui.QIcon(os.path.join(vistrails_root_directory(),
                                          'gui/resources/images/plus.png'))
     minus_icon = QtGui.QIcon(os.path.join(vistrails_root_directory(),
                                           'gui/resources/images/minus.png'))
-    def __init__(self, port_spec, function=None, parent=None):
+    def __init__(self, port_spec, function=None, types_visible=True, parent=None):
         QtGui.QTreeWidgetItem.__init__(self, parent)
         self.setFirstColumnSpanned(True)
         self.port_spec = port_spec
         self.function = function
+        self.types_visible = types_visible
 
     def build_widget(self, widget_accessor, with_alias=True):
         reg = get_module_registry()
@@ -208,21 +241,35 @@ class ParameterEntry(QtGui.QTreeWidgetItem):
 
         for i, (psi, param) in enumerate(izip(self.port_spec.port_spec_items, 
                                               params)):
-            widget_class = widget_accessor(psi.descriptor.module)
+            if psi.entry_type is not None:
+                # !!only pull off the prefix!! options follow in camelcase
+                prefix_end = len(psi.entry_type.lstrip(string.lowercase))
+                if prefix_end == 0:
+                    entry_type = psi.entry_type
+                else:
+                    entry_type = psi.entry_type[:-prefix_end]
+            else:
+                entry_type = None
+            widget_class = widget_accessor(psi.descriptor, entry_type)
             if param is not None:
                 obj = param
             else:
                 obj = Parameter(psi.descriptor)
             obj.port_spec_item = psi
-            if with_alias:
-                label = AliasLabel(obj.alias, obj.type, psi.label)
-                self.my_labels.append(label)
-            else:
-                label = QtGui.QLabel(obj.type)
+
+            if self.types_visible:
+                if with_alias:
+                    label = AliasLabel(obj.alias, obj.type, psi.label)
+                    self.my_labels.append(label)
+                else:
+                    label = QtGui.QLabel(obj.type)
+                layout.addWidget(label, i, 0)
+                layout.setAlignment(label, QtCore.Qt.AlignLeft)
+
             param_widget = widget_class(obj, self.group_box)
             self.my_widgets.append(param_widget)
-            layout.addWidget(label, i, 0)
             layout.addWidget(param_widget, i, 1)
+            layout.addItem(QtGui.QSpacerItem(0,0, QtGui.QSizePolicy.MinimumExpanding), i, 2)
 
         self.group_box.setLayout(layout)
         def updateMethod():
@@ -247,9 +294,16 @@ class ParameterEntry(QtGui.QTreeWidgetItem):
         return self.build_widget(get_widget_class, True)
 
 class PortItem(QtGui.QTreeWidgetItem):
-    null_icon = QtGui.QIcon()
-    eye_icon = QtGui.QIcon(os.path.join(vistrails_root_directory(),
-                                        'gui/resources/images/eye.png'))
+    edit_show =  QtGui.QIcon(os.path.join(vistrails_root_directory(),
+                             'gui/resources/images/pencil.png'))
+    edit_hide = QtGui.QIcon(os.path.join(vistrails_root_directory(),
+                             'gui/resources/images/pencil-disabled.png'))
+    eye_open_icon = \
+        QtGui.QIcon(os.path.join(vistrails_root_directory(),
+                                 'gui/resources/images/eye.png'))
+    eye_closed_icon = \
+        QtGui.QIcon(os.path.join(vistrails_root_directory(),
+                                 'gui/resources/images/eye_closed.png'))
     eye_disabled_icon = \
         QtGui.QIcon(os.path.join(vistrails_root_directory(),
                                  'gui/resources/images/eye_gray.png'))
@@ -258,7 +312,7 @@ class PortItem(QtGui.QTreeWidgetItem):
                                  'gui/resources/images/connection.png'))
 
     def __init__(self, port_spec, is_connected, is_optional, is_visible,
-                 parent=None):
+                 is_editable=False, parent=None):
         QtGui.QTreeWidgetItem.__init__(self, parent)
         # self.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
         self.setFlags(QtCore.Qt.ItemIsEnabled)
@@ -267,7 +321,10 @@ class PortItem(QtGui.QTreeWidgetItem):
         self.is_connected = is_connected
         self.is_optional = is_optional
         self.is_visible = is_visible
-        self.build_item(port_spec, is_connected, is_optional, is_visible)
+        self.is_editable = is_editable
+        self.is_unset = False
+        self.build_item(port_spec, is_connected, is_optional, is_visible,
+                        is_editable)
 
     def visible(self):
         return not self.is_optional or self.is_visible
@@ -275,9 +332,16 @@ class PortItem(QtGui.QTreeWidgetItem):
     def set_visible(self, visible):
         self.is_visible = visible
         if visible:
-            self.setIcon(0, PortItem.eye_icon)
+            self.setIcon(0, PortItem.eye_open_icon)
+        else:
+            self.setIcon(0, PortItem.eye_closed_icon)
+
+    def set_editable(self, edit):
+        self.is_editable = edit
+        if edit:
+            self.setIcon(0, PortItem.edit_show)
         else:
-            self.setIcon(0, PortItem.null_icon)
+            self.setIcon(0, PortItem.edit_hide)
 
     def get_visible(self):
         return self.visible_checkbox
@@ -289,19 +353,37 @@ class PortItem(QtGui.QTreeWidgetItem):
         return (self.port_spec.is_valid and 
                 get_module_registry().is_constant(self.port_spec))
 
-    def build_item(self, port_spec, is_connected, is_optional, is_visible):
+    def calcUnset(self):
+        self.is_unset = self.is_constant() and \
+                        self.port_spec.is_mandatory() and \
+                        not self.is_connected and \
+                        not self.isExpanded()
+        if self.is_unset:
+            font = self.font(3)
+            font.setWeight(QtGui.QFont.Bold)
+            self.setFont(3, font)
+
+    def build_item(self, port_spec, is_connected, is_optional, is_visible, is_editable):
         if not is_optional:
-            self.setIcon(0, PortItem.eye_disabled_icon)
+            self.setIcon(1, PortItem.eye_disabled_icon)
         elif is_visible:
-            self.setIcon(0, PortItem.eye_icon)
-            
+            self.setIcon(1, PortItem.eye_open_icon)
+        else:
+            self.setIcon(1, PortItem.eye_closed_icon)
+
         if is_connected:
-            self.setIcon(1, PortItem.conn_icon)
-        self.setText(2, port_spec.name)
+            self.setIcon(2, PortItem.conn_icon)
+        self.setText(3, port_spec.name)
 
-        # if port_spec is not a method, make it gray
-        if not self.is_constant():
-            self.setForeground(2, 
+        if self.is_constant():
+            if len(self.port_spec.port_spec_items)>0:
+                if is_editable:
+                    self.setIcon(0, PortItem.edit_show)
+                else:
+                    self.setIcon(0, PortItem.edit_hide)
+        else:
+            # if port_spec is not a method, make it gray
+            self.setForeground(3,
                                QtGui.QBrush(QtGui.QColor.fromRgb(128,128,128)))
 
         self.visible_checkbox = QtGui.QCheckBox()
@@ -329,13 +411,24 @@ class PortItem(QtGui.QTreeWidgetItem):
         widget.setAttribute(QtCore.Qt.WA_DeleteOnClose)
         widget.exec_()
 
+    def __lt__(self, other):
+        # put unset mandatory ports first
+        if self.is_unset != other.is_unset:
+            return self.is_unset and not other.is_unset
+        # put set (expanded) functions first
+        if self.isExpanded() != other.isExpanded():
+            return self.isExpanded() and not other.isExpanded()
+        # otherwise use port name
+        return self.port_spec.name < other.port_spec.name
+
 class PortsList(QtGui.QTreeWidget):
     def __init__(self, port_type, parent=None):
         QtGui.QTreeWidget.__init__(self, parent)
         self.port_type = port_type
-        self.setColumnCount(3)
+        self.setColumnCount(4)
         self.setColumnWidth(0,24)
         self.setColumnWidth(1,24)
+        self.setColumnWidth(2,24)
         self.setRootIsDecorated(False)
         self.setIndentation(0)
         self.setHeaderHidden(True)
@@ -344,19 +437,24 @@ class PortsList(QtGui.QTreeWidget):
         self.module = None
         self.port_spec_items = {}
         self.entry_klass = ParameterEntry
+        self.ports_visible = True
+        self.types_visible = True
 
     def setReadOnly(self, read_only):
         self.setEnabled(not read_only)
 
     def set_entry_klass(self, entry_klass):
-        self.entry_klass = entry_klass
-        self.update_module(self.module)
+        if entry_klass != entry_klass:
+            self.entry_klass = entry_klass
+            self.update_module(self.module)
 
     def update_module(self, module):
         """ update_module(module: Module) -> None        
         Setup this tree widget to show functions of module
         
         """
+        self.setColumnHidden(0, True)
+        self.setColumnHidden(1, not self.ports_visible)
         # this is strange but if you try to clear the widget when the focus is 
         # in one of the items (after setting a parameter for example), 
         # VisTrails crashes on a Mac (Emanuele) This is probably a Qt bug
@@ -371,6 +469,8 @@ class PortsList(QtGui.QTreeWidget):
             reg = get_module_registry()
             descriptor = module.module_descriptor
             if self.port_type == 'input':
+                self.setColumnHidden(0,not get_vistrails_configuration(
+                                        ).check('showInlineParameterWidgets'))
                 port_specs = module.destinationPorts()
                 connected_ports = module.connected_input_ports
                 visible_ports = module.visible_input_ports
@@ -384,10 +484,11 @@ class PortsList(QtGui.QTreeWidget):
             for port_spec in sorted(port_specs, key=lambda x: x.name):
                 connected = port_spec.name in connected_ports and \
                     connected_ports[port_spec.name] > 0
-                item = PortItem(port_spec, 
+                item = PortItem(port_spec,
                                 connected,
                                 port_spec.optional,
-                                port_spec.name in visible_ports)
+                                port_spec.name in visible_ports,
+                                port_spec.name in module.editable_input_ports)
                 self.addTopLevelItem(item)
                 self.port_spec_items[port_spec.name] = (port_spec, item)
 
@@ -396,13 +497,14 @@ class PortsList(QtGui.QTreeWidget):
                     if not function.is_valid:
                         continue
                     port_spec, item = self.port_spec_items[function.name]
-                    subitem = self.entry_klass(port_spec, function)
+                    subitem = self.entry_klass(port_spec, function,
+                                               self.types_visible)
                     self.function_map[function.real_id] = subitem
                     item.addChild(subitem)
                     subitem.setFirstColumnSpanned(True)
-                    self.setItemWidget(subitem, 0, subitem.get_widget())
+                    self.setItemWidget(subitem, 2, subitem.get_widget())
                     item.setExpanded(True)
-                
+
                     # self.setItemWidget(item, 0, item.get_visible())
                     # self.setItemWidget(item, 1, item.get_connected())
 
@@ -414,7 +516,12 @@ class PortsList(QtGui.QTreeWidget):
                     # connceted_checkbox = QtGui.QCheckBox()
                     # connected_checkbox.setEnabled(False)
                     # self.setItemWidget(i, 1, connected_checkbox)
-                
+
+                # Highlight unset ports
+                for _, item  in self.port_spec_items.itervalues():
+                    item.calcUnset()
+
+                self.sortItems(0, QtCore.Qt.AscendingOrder)
 
             # base_items = {}
             # # Create the base widget item for each descriptor
@@ -476,7 +583,7 @@ class PortsList(QtGui.QTreeWidget):
                 self.function_map[function.real_id] = subitem
                 item.addChild(subitem)
                 subitem.setFirstColumnSpanned(True)
-                self.setItemWidget(subitem, 0, subitem.get_widget())
+                self.setItemWidget(subitem, 2, subitem.get_widget())
                 item.setExpanded(True)
 
     def item_clicked(self, item, col):
@@ -485,12 +592,26 @@ class PortsList(QtGui.QTreeWidget):
 
         if self.port_type == 'input':
             visible_ports = self.module.visible_input_ports
+            editable_ports = self.module.editable_input_ports
         elif self.port_type == 'output':
             visible_ports = self.module.visible_output_ports
         else:
             raise TypeError("Unknown port type: '%s'" % self.port_type)
 
         if col == 0:
+            if item.is_constant() and len(item.port_spec.port_spec_items)>0:
+                item.set_editable(not item.is_editable)
+                if item.is_editable:
+                    editable_ports.add(item.port_spec.name)
+                else:
+                    editable_ports.discard(item.port_spec.name)
+                self.controller.flush_delayed_actions()
+                self.controller.add_annotation((self.module.INLINE_WIDGET_ANNOTATION,
+                                                ','.join(editable_ports)),
+                                               self.module.id)
+                self.controller.current_pipeline_scene.recreate_module(
+                    self.controller.current_pipeline, self.module.id)
+        if col == 1:
             if item.is_optional:
                 item.set_visible(not item.is_visible)
                 if item.is_visible:
@@ -500,7 +621,7 @@ class PortsList(QtGui.QTreeWidget):
                 self.controller.flush_delayed_actions()
                 self.controller.current_pipeline_scene.recreate_module(
                     self.controller.current_pipeline, self.module.id)
-        if col == 2:
+        if col == 3:
             if item.isExpanded():
                 item.setExpanded(False)
             elif item.childCount() > 0:
@@ -574,7 +695,7 @@ class PortsList(QtGui.QTreeWidget):
         subitem = self.entry_klass(port_spec)
         item.addChild(subitem)
         subitem.setFirstColumnSpanned(True)
-        self.setItemWidget(subitem, 0, subitem.get_widget())
+        self.setItemWidget(subitem, 2, subitem.get_widget())
         item.setExpanded(True)
         if len(port_spec.descriptors()) == 0:
             self.update_method(subitem, port_spec.name, [], [])
diff --git a/vistrails/gui/preferences.py b/vistrails/gui/preferences.py
index 7e7a437..b08dfc7 100644
--- a/vistrails/gui/preferences.py
+++ b/vistrails/gui/preferences.py
@@ -1,50 +1,57 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
 from vistrails.core import get_vistrails_application
 from vistrails.core.packagemanager import get_package_manager
+from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.modules.package import Package
+from vistrails.core.requirements import MissingRequirement
+from vistrails.core.system import get_vistrails_basic_pkg_id
 from vistrails.core.utils import InvalidPipeline
 from vistrails.core.utils.uxml import (named_elements,
                              elements_filter, enter_named_element)
-from vistrails.gui.configuration import (QConfigurationWidget, QGeneralConfiguration,
-                               QThumbnailConfiguration)
+from vistrails.gui.configuration import QConfigurationWidget, \
+    QConfigurationPane
 from vistrails.gui.module_palette import QModulePalette
+from vistrails.gui.modules.output_configuration import OutputModeConfigurationWidget
 from vistrails.gui.pipeline_view import QPipelineView
 from vistrails.core.configuration import get_vistrails_persistent_configuration, \
-    get_vistrails_configuration
+    get_vistrails_configuration, base_config
 from vistrails.core import debug
 import os.path
 
@@ -67,10 +74,8 @@ class QPackageConfigurationDialog(QtGui.QDialog):
 
         layout = QtGui.QVBoxLayout(self)
         self.setLayout(layout)
-        self._status_bar = QtGui.QStatusBar(self)
 
-        self._configuration_widget = QConfigurationWidget(self, c, c,
-                                                          self._status_bar)
+        self._configuration_widget = QConfigurationWidget(self, c, c)
         layout.addWidget(self._configuration_widget)
 
         btns = (QtGui.QDialogButtonBox.Close |
@@ -86,7 +91,6 @@ class QPackageConfigurationDialog(QtGui.QDialog):
                      QtCore.SIGNAL('configuration_changed'),
                      self.configuration_changed)
                      
-        layout.addWidget(self._status_bar)
         layout.addWidget(self._button_box)
 
     def button_clicked(self, button):
@@ -107,14 +111,15 @@ class QPackageConfigurationDialog(QtGui.QDialog):
 
     def reset_configuration(self):
         self._package.reset_configuration()
-        conf = self._package.configuration
-        self._configuration_widget.configuration_changed(conf)
+        self._configuration_widget.configuration_changed(
+                self._package.persistent_configuration,
+                self._package.configuration)
 
     def close_dialog(self):
         self.done(0)
 
     def configuration_changed(self, item, new_value):
-        self._package.set_persistent_configuration()
+        self._package.persist_configuration()
 
 ##############################################################################
 
@@ -126,9 +131,8 @@ class QPackagesWidget(QtGui.QWidget):
     ##########################################################################
     # Initialization
 
-    def __init__(self, parent, status_bar):
+    def __init__(self, parent):
         QtGui.QWidget.__init__(self, parent)
-        self._status_bar = status_bar
 
         base_layout = QtGui.QHBoxLayout(self)
         
@@ -299,8 +303,9 @@ class QPackagesWidget(QtGui.QWidget):
             new_deps = self._current_package.dependencies()
         except Exception, e:
             debug.critical("Failed getting dependencies of package %s, "
-                           "so it will not be enabled" % \
-                            self._current_package.name, str(e))
+                           "so it will not be enabled" %
+                            self._current_package.name,
+                            e)
             return
         from vistrails.core.modules.basic_modules import identifier as basic_modules_identifier
         if self._current_package.identifier != basic_modules_identifier:
@@ -309,7 +314,7 @@ class QPackagesWidget(QtGui.QWidget):
         try:
             pm.check_dependencies(self._current_package, new_deps)
         except Package.MissingDependency, e:
-            debug.critical("Missing dependencies", str(e))
+            debug.critical("Missing dependencies", e)
         else:
             # Deselects available list to prevent another package from getting
             # selected once the current item leaves the list
@@ -319,9 +324,10 @@ class QPackagesWidget(QtGui.QWidget):
             palette.setUpdatesEnabled(False)
             try:
                 pm.late_enable_package(codepath)
-            except Package.InitializationFailed, e:
+            except (Package.InitializationFailed, MissingRequirement), e:
                 debug.critical("Initialization of package '%s' failed" %
-                               codepath, str(e))
+                               codepath,
+                               e)
                 # Loading failed: reselect the item
                 self._available_packages_list.setCurrentItem(item)
                 raise
@@ -356,15 +362,24 @@ class QPackagesWidget(QtGui.QWidget):
         dlg.exec_()
 
     def reload_current_package(self):
-        # DISABLES the current package and all reverse dependencies
-        inst = self._enabled_packages_list
-        item = inst.currentItem()
-        pm = get_package_manager()
-        codepath = str(item.text())
-        
-        palette = QModulePalette.instance()
-        palette.setUpdatesEnabled(False)
-        pm.reload_package_disable(codepath)
+        if self._enabled_packages_list.currentItem() is not None:
+            # Disables the selected package (which was enabled) and all its
+            # reverse dependencies, then enables it all again
+            item = self._enabled_packages_list.currentItem()
+            pm = get_package_manager()
+            codepath = str(item.text())
+
+            palette = QModulePalette.instance()
+            palette.setUpdatesEnabled(False)
+            pm.reload_package_disable(codepath)
+        elif self._available_packages_list.currentItem() is not None:
+            # Reloads the selected package's (which was not enabled) __init__
+            # module
+            item = self._available_packages_list.currentItem()
+            pm = get_package_manager()
+            codepath = str(item.text())
+            pm._available_packages.pop(codepath).unload()
+            self.selected_available_list()
 
     def reload_current_package_finisher(self, codepath, reverse_deps, prefix_dictionary):
         # REENABLES the current package and all reverse dependencies
@@ -373,7 +388,8 @@ class QPackagesWidget(QtGui.QWidget):
             pm.reload_package_enable(reverse_deps, prefix_dictionary)
         except Package.InitializationFailed, e:
             debug.critical("Re-initialization of package '%s' failed" % 
-                            codepath, str(e))
+                            codepath,
+                            e)
             raise
         finally:
             self.populate_lists()
@@ -446,7 +462,7 @@ class QPackagesWidget(QtGui.QWidget):
         self._configure_button.setEnabled(False)
         self._disable_button.setEnabled(False)
         self._enable_button.setEnabled(True)
-        self._reload_button.setEnabled(False)
+        self._reload_button.setEnabled(True)
 
     def set_package_information(self):
         """Looks at current package and sets all labels (name,
@@ -466,15 +482,16 @@ class QPackagesWidget(QtGui.QWidget):
             self._dependencies_label.setText(msg)
             self._description_label.setText(msg)
             self._reverse_dependencies_label.setText(msg)
-            debug.critical('Cannot load package', str(e))
+            debug.critical('Cannot load package', e)
         else:
             self._name_label.setText(p.name)
             try:
                 deps = ', '.join(str(d) for d in p.dependencies()) or \
                     'No package dependencies.'
             except Exception, e:
-                debug.critical("Failed getting dependencies of package %s "
-                               "" % p.name, str(e))
+                debug.critical("Failed getting dependencies of package %s" %
+                               p.name,
+                               e)
                 deps = "ERROR: Failed getting dependencies"
             try:
                 pm = get_package_manager()
@@ -524,12 +541,77 @@ class QPackagesWidget(QtGui.QWidget):
     def invalidate_current_pipeline(self):
         from vistrails.gui.vistrails_window import _app
         _app.invalidate_pipelines()
+
+class QOutputConfigurationPane(QtGui.QWidget):
+    def __init__(self, parent, persistent_config, temp_config):
+        QtGui.QWidget.__init__(self, parent)
+
+        self.persistent_config = persistent_config
+        self.temp_config = temp_config
+
+        scroll_area = QtGui.QScrollArea()
+        inner_widget =  QtGui.QWidget()
+        self.inner_layout = QtGui.QVBoxLayout()
+        inner_widget.setLayout(self.inner_layout)
+        scroll_area.setWidget(inner_widget)
+        scroll_area.setWidgetResizable(True)
+        self.setLayout(QtGui.QVBoxLayout())
+        self.layout().addWidget(scroll_area, 1)
+        self.layout().setContentsMargins(0,0,0,0)
+
+        app = get_vistrails_application()
+        app.register_notification("package_added", self.update_output_modules)
+        app.register_notification("package_removed", self.update_output_modules)
+
+        self.mode_widgets = {}
+
+    def update_output_modules(self, *args, **kwargs):
+        # need to find all currently loaded output modes (need to
+        # check after modules are loaded and spin through registery)
+        # and display them here
+        reg = get_module_registry()
+        output_d = reg.get_descriptor_by_name(get_vistrails_basic_pkg_id(),
+                                              "OutputModule")
+        sublist = reg.get_descriptor_subclasses(output_d)
+        modes = {}
+        for d in sublist:
+            if hasattr(d.module, '_output_modes_dict'):
+                for mode_type, (mode, _) in (d.module._output_modes_dict
+                                                     .iteritems()):
+                    modes[mode_type] = mode
+
+        found_modes = set()
+        for mode_type, mode in modes.iteritems():
+            found_modes.add(mode_type)
+            if mode_type not in self.mode_widgets:
+                mode_config = None
+                output_settings = self.persistent_config.outputDefaultSettings
+                if output_settings.has(mode_type):
+                    mode_config = getattr(output_settings, mode_type)
+                widget = OutputModeConfigurationWidget(mode, mode_config)
+                widget.fieldChanged.connect(self.field_was_changed)
+                self.inner_layout.addWidget(widget)
+                self.mode_widgets[mode_type] = widget
         
+        for mode_type, widget in self.mode_widgets.items():
+            if mode_type not in found_modes:
+                self.inner_layout.removeWidget(self.mode_widgets[mode_type])
+                del self.mode_widgets[mode_type]
+
+    def field_was_changed(self, mode_widget):
+        # FIXME need to use temp_config to show command-line overrides
+        for k1, v_dict in mode_widget._changed_config.iteritems():
+            for k2, v in v_dict.iteritems():
+                k = "%s.%s" % (k1, k2)
+                self.persistent_config.outputDefaultSettings.set_deep_value(
+                    k, v, True)
+                self.temp_config.outputDefaultSettings.set_deep_value(
+                    k, v, True)
+
 class QPreferencesDialog(QtGui.QDialog):
 
     def __init__(self, parent):
         QtGui.QDialog.__init__(self, parent)
-        self._status_bar = QtGui.QStatusBar(self)
         self.setWindowTitle('VisTrails Preferences')
         layout = QtGui.QHBoxLayout(self)
         layout.setMargin(0)
@@ -547,71 +629,47 @@ class QPreferencesDialog(QtGui.QDialog):
         self._tab_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                        QtGui.QSizePolicy.Expanding)
 
-        self._general_tab = self.create_general_tab()
-        self._tab_widget.addTab(self._general_tab, 'General Configuration')
+        tabs = [("General", ["General", "Packages"]),
+                ("Interface", ["Interface", "Startup"]),
+                ("Paths && URLs", ["Paths", "Web Sharing"]),
+                ("Advanced", ["Upgrades", "Thumbnails", "Advanced"]),
+                ]
+        for (tab_name, categories) in tabs:
+            tab = QConfigurationPane(self, 
+                                     get_vistrails_persistent_configuration(),
+                                     get_vistrails_configuration(),
+                                     [(c, base_config[c]) for c in categories])
+            self._tab_widget.addTab(tab, tab_name)
+
+        output_tab = QOutputConfigurationPane(self,
+                                    get_vistrails_persistent_configuration(), 
+                                    get_vistrails_configuration())
+        self._tab_widget.addTab(output_tab, "Output")
 
-        self._thumbs_tab = self.create_thumbs_tab()
-        self._tab_widget.addTab(self._thumbs_tab, 'Thumbnails Configuration')
-        
         self._packages_tab = self.create_packages_tab()
-        self._tab_widget.addTab(self._packages_tab, 'Module Packages')
+        self._tab_widget.addTab(self._packages_tab, 'Packages')
         
         self._configuration_tab = self.create_configuration_tab()
-        self._tab_widget.addTab(self._configuration_tab, 'Expert Configuration')
+        self._tab_widget.addTab(self._configuration_tab, 'Expert')
 
-        self._button_box = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Close,
-                                                  QtCore.Qt.Horizontal,
-                                                  f)
         self.connect(self._tab_widget,
                      QtCore.SIGNAL('currentChanged(int)'),
                      self.tab_changed)
 
-        self.connect(self._button_box,
-                     QtCore.SIGNAL('clicked(QAbstractButton *)'),
-                     self.close_dialog)
-
         self.connect(self._configuration_tab._tree.treeWidget,
                      QtCore.SIGNAL('configuration_changed'),
                      self.configuration_changed)
 
-        self.connect(self._general_tab,
-                     QtCore.SIGNAL('configuration_changed'),
-                     self.configuration_changed)
-        
-        self.connect(self._thumbs_tab,
-                     QtCore.SIGNAL('configuration_changed'),
-                     self.configuration_changed)
-
-        l.addWidget(self._button_box)
-        l.addWidget(self._status_bar)
-
     def close_dialog(self):
         self.done(0)
 
-    def create_general_tab(self):
-        """ create_general_tab() -> QGeneralConfiguration
-        
-        """
-        return QGeneralConfiguration(self,
-                                     get_vistrails_persistent_configuration(),
-                                     get_vistrails_configuration())
-        
-    def create_thumbs_tab(self):
-        """ create_thumbs_tab() -> QThumbnailConfiguration
-        
-        """
-        return QThumbnailConfiguration(self,
-                                       get_vistrails_persistent_configuration(),
-                                       get_vistrails_configuration())
-
     def create_configuration_tab(self):
         return QConfigurationWidget(self,
                                     get_vistrails_persistent_configuration(),
-                                    get_vistrails_configuration(),
-                                    self._status_bar)
+                                    get_vistrails_configuration())
 
     def create_packages_tab(self):
-        return QPackagesWidget(self, self._status_bar)
+        return QPackagesWidget(self)
 
     def sizeHint(self):
         return QtCore.QSize(800, 600)
@@ -621,12 +679,11 @@ class QPreferencesDialog(QtGui.QDialog):
         Keep general and advanced configurations in sync
         
         """
+
+        # FIXME Need to fix this
         self._configuration_tab.configuration_changed(
                                        get_vistrails_persistent_configuration(),
                                        get_vistrails_configuration())
-        self._general_tab.update_state(
-                                       get_vistrails_persistent_configuration(),
-                                       get_vistrails_configuration())
     
     def configuration_changed(self, item, new_value):
         """ configuration_changed(item: QTreeWidgetItem *, 
@@ -637,7 +694,6 @@ class QPreferencesDialog(QtGui.QDialog):
         we guarantee the changes were saved before VisTrails crashes.
         
         """
-        from PyQt4 import QtCore
         from vistrails.gui.application import get_vistrails_application
         get_vistrails_application().save_configuration()
 
@@ -659,24 +715,32 @@ class TestPreferencesDialog(unittest.TestCase):
         prefs = builder.preferencesDialog
         packages = prefs._packages_tab
         prefs._tab_widget.setCurrentWidget(packages)
+        QtGui.QApplication.processEvents()
 
         # check if package is loaded
         av = packages._available_packages_list
-        for item in av.findItems(pkg, QtCore.Qt.MatchExactly):
-            av.setCurrentItem(item)
-            packages.enable_current_package()
-            QtCore.QCoreApplication.processEvents()
+        item, = av.findItems(pkg, QtCore.Qt.MatchExactly)
+        av.setCurrentItem(item)
+        QtGui.QApplication.processEvents()
+        QtGui.QApplication.processEvents()
+        packages.enable_current_package()
+        QtGui.QApplication.processEvents()
+        QtGui.QApplication.processEvents()
 
         inst = packages._enabled_packages_list
-        for item in inst.findItems(pkg, QtCore.Qt.MatchExactly):
-            inst.setCurrentItem(item)
-            packages.disable_current_package()
-            QtCore.QCoreApplication.processEvents()
+        item, = inst.findItems(pkg, QtCore.Qt.MatchExactly)
+        inst.setCurrentItem(item)
+        QtGui.QApplication.processEvents()
+        QtGui.QApplication.processEvents()
+        packages.disable_current_package()
+        QtGui.QApplication.processEvents()
+        QtGui.QApplication.processEvents()
 
         # force delayed calls
         packages.populate_lists()
         packages.select_package_after_update_slot(pkg)
-        QtCore.QCoreApplication.processEvents()
+        QtGui.QApplication.processEvents()
+        QtGui.QApplication.processEvents()
 
         # This does not work because the selection is delayed
         av = packages._available_packages_list
@@ -684,19 +748,8 @@ class TestPreferencesDialog(unittest.TestCase):
         self.assertEqual(len(items), 1, "No available items selected!")
         self.assertEqual(items[0].text(), unicode(pkg),
                          "Wrong available item selected: %s" % items[0].text())
+
         # check if configuration has been written correctly
-        startup = _app.vistrailsStartup
-        doc = startup.startup_dom().documentElement
-        disabledpackages = enter_named_element(doc, 'disabledpackages')
-        dpackage = None
-        for package_node in named_elements(disabledpackages, 'package'):
-            if str(package_node.attributes['name'].value) == pkg:
-                dpackage = package_node
-        self.assertIsNotNone(dpackage, "Removed package '%s' is not in unloaded packages list!" % pkg)
-
-        epackages = enter_named_element(doc, 'packages')
-        apackage = None
-        for package_node in named_elements(epackages, 'package'):
-            if str(package_node.attributes['name'].value) == pkg:
-                apackage = package_node
-        self.assertIsNone(apackage, "Removed package '%s' is still in loaded packages list!" % pkg)
+        startup = _app.startup
+        self.assertIn(pkg, startup.disabled_packages)
+        self.assertNotIn(pkg, startup.enabled_packages)
diff --git a/vistrails/gui/publishing.py b/vistrails/gui/publishing.py
index 0f6edb1..e24794b 100644
--- a/vistrails/gui/publishing.py
+++ b/vistrails/gui/publishing.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 import os
 
@@ -453,13 +456,13 @@ class QVersionEmbed(QtGui.QWidget, QVistrailsPaletteInterface):
         label1 = QtGui.QLabel("Embed:")
         self.cbcontent = QtGui.QComboBox()
         self.cbcontent.setEditable(False)
-        items = ["Workflow Results", "Workflow Graph", "History Tree Graph"];
+        items = ["Workflow Results", "Workflow Graph", "History Tree Graph"]
         self.cbcontent.addItems(items)
         label2 = QtGui.QLabel("In:")
         
         self.cbtype = QtGui.QComboBox()
         self.cbtype.setEditable(False)
-        items = ["Wiki", "Latex", "Shared Memory"];
+        items = ["Wiki", "Latex", "Shared Memory"]
         self.cbtype.addItems(items)
         
         self.controller = None
diff --git a/vistrails/gui/qt.py b/vistrails/gui/qt.py
index 3f8d217..da6b5ff 100644
--- a/vistrails/gui/qt.py
+++ b/vistrails/gui/qt.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -44,6 +45,8 @@ from setting okToCreateQObjects directly.
 
 As the python saying goes, 'we are all consenting adults here'."""
 
+from __future__ import division
+
 import inspect
 from PyQt4 import QtGui, QtCore
 import types
@@ -79,20 +82,26 @@ class qt_super(object):
 
 class DisallowedCaller(Exception):
     """This expection is raised whenever a caller that's not privileged to
-allow QObject construction tries to do so."""
+    allow QObject construction tries to do so.
+
+    """
     def __str__(self):
         return "Caller is not allowed to call this function"
 
 class QApplicationNotYetCreated(Exception):
     """This expection is raised whenever a function asks for permission to
-create a QObject but the QApplication has not granted it yet."""
+    create a QObject but the QApplication has not granted it yet.
+
+    """
     def __str__(self):
         return "QApplication has not been created yet"
 
 def allowQObjects():
     """Allows subsequent QObject creation. The constructor for the
-QApplication-derived class must call this so that we know it's alright
-to start creating other QtCore.QObjects."""
+    QApplication-derived class must call this so that we know it's
+    alright to start creating other QtCore.QObjects.
+
+    """
     
     # tries to check if caller is allowed to call this
     caller = inspect.currentframe().f_back
@@ -104,18 +113,19 @@ to start creating other QtCore.QObjects."""
     okToCreateQObjects = True
 
 def askForQObjectCreation():
-    """This function simply throws an exception if it is not yet ok
-to create QObjects."""
-    global okToCreateQObjects
+    """This function simply throws an exception if it is not yet ok to
+    create QObjects.
+
+    """
     if not okToCreateQObjects:
         raise QApplicationNotYetCreated()
 
-global _appHolder
 _appHolder = None
 
 def createBogusQtGuiApp(argv=["bogus"]):    
-    """createBogusQtGuiApp creates a bogus QtApplication so we can
-    create qobjects during test runs.
+    """createBogusQtGuiApp creates a bogus QtApplication so we can create
+    qobjects during test runs.
+
     """    
     class BogusApplication(QtGui.QApplication):
         def __init__(self):
@@ -130,7 +140,7 @@ def createBogusQtGuiApp(argv=["bogus"]):
 
 def destroyBogusQtApp():
     global _appHolder
-    del _appHolder
+    _appHolder = None
 
 def qt_version():
     return [int(i)
@@ -142,12 +152,13 @@ def qt_version():
 okToCreateQObjects = False
 
 class SignalSet(object):
-    
-    """SignalSet stores a list of (object, signal, method) that can be
-    all connected and disconnected simultaneously. This way, it's
-    harder to forget to disconnect one of many signals. Also, if the
+    """SignalSet stores a list of (object, signal, method) that can be all
+    connected and disconnected simultaneously. This way, it's harder
+    to forget to disconnect one of many signals. Also, if the
     SignalSet has already been plugged, it will signal an exception,
-    to avoid multiple connections."""
+    to avoid multiple connections.
+
+    """
     
     def __init__(self, owner, signalTripleList):
         self.owner = owner
diff --git a/vistrails/gui/query_view.py b/vistrails/gui/query_view.py
index 0b09ef3..b2d1c6b 100644
--- a/vistrails/gui/query_view.py
+++ b/vistrails/gui/query_view.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core.collection import Collection
@@ -46,7 +49,7 @@ from vistrails.core.vistrail.vistrail import Vistrail
 
 from vistrails.gui.base_view import BaseView
 from vistrails.gui.common_widgets import QSearchBox
-from vistrails.gui.modules import get_query_widget_class
+from vistrails.gui.modules.utils import get_query_widget_class
 from vistrails.gui.pipeline_view import QPipelineView
 from vistrails.gui.ports_pane import ParameterEntry
 from vistrails.gui.theme import CurrentTheme
@@ -64,6 +67,7 @@ class QueryController(object):
         self.search_str = None
         self.search_pipeline = None
         self.search_level = 3
+        self.use_regex = False
         self.vt_controller = None
         self.level = QueryController.LEVEL_VISTRAIL
         self.workflow_version = None
@@ -72,6 +76,9 @@ class QueryController(object):
         self.query_view.query_box.setLevel(level)
         self.level_changed(level)
 
+    def set_use_regex(self, use_regex):
+        self.use_regex = use_regex
+
     def level_changed(self, level):
         self.query_view.set_result_level(level)
         if level >= QueryController.LEVEL_VISTRAIL and \
@@ -113,7 +120,6 @@ class QueryController(object):
             # reset changed here
             self.query_view.p_controller.set_changed(False)
             vt_controller = self.query_view.vt_controller
-            current_vistrail = self.vt_controller.vistrail
 
             def do_search(only_current_vistrail=False, 
                           only_current_workflow=False):
@@ -134,7 +140,8 @@ class QueryController(object):
                             versions_to_check = set(graph.vertices.iterkeys())
                         entities_to_check[entity] = versions_to_check
                 self.set_search(MultipleSearch(search_str, search_pipeline,
-                                               entities_to_check))
+                                               entities_to_check,
+                                               self.use_regex))
                 self.search.run()
                 return self.search.getResultEntities()
                 
@@ -146,7 +153,7 @@ class QueryController(object):
                 result_entities = do_search(True)
                 self.update_version_tree()
                 self.show_workflow_matches()
-            elif self.level == QueryController.LEVEL_ALL:
+            else:  # self.level == QueryController.LEVEL_ALL
                 result_entities = do_search()
                 self.show_global_matches()
 
@@ -291,13 +298,14 @@ class QQueryBox(QtGui.QWidget):
         layout.setSpacing(2)
         self.searchBox = QSearchBox(True, False, self)
         layout.addWidget(self.searchBox)
-        radio_layout = QtGui.QHBoxLayout()
-        radio_layout.setSpacing(5)
-        radio_layout.setAlignment(QtCore.Qt.AlignLeft)
-        radio_layout.addWidget(QtGui.QLabel("Search:"))
+        options_layout = QtGui.QHBoxLayout()
+        options_layout.setSpacing(5)
+        options_layout.setAlignment(QtCore.Qt.AlignLeft)
+        options_layout.addWidget(QtGui.QLabel("Search:"))
         searchAll = QtGui.QRadioButton("Open Vistrails")
         searchCurrent = QtGui.QRadioButton("Current Vistrail")
         searchWorkflow = QtGui.QRadioButton("Current Workflow")
+        useRegex = QtGui.QCheckBox("Regular expression")
         self.level_group = QtGui.QButtonGroup()
         self.level_group.addButton(searchAll)
         self.level_group.addButton(searchCurrent)
@@ -306,19 +314,20 @@ class QQueryBox(QtGui.QWidget):
             Bidict([(QueryController.LEVEL_ALL, searchAll),
                     (QueryController.LEVEL_VISTRAIL, searchCurrent),
                     (QueryController.LEVEL_WORKFLOW, searchWorkflow)])
-        radio_layout.addWidget(searchAll)
-        radio_layout.addWidget(searchCurrent)
-        radio_layout.addWidget(searchWorkflow)
+        options_layout.addWidget(searchAll)
+        options_layout.addWidget(searchCurrent)
+        options_layout.addWidget(searchWorkflow)
+        options_layout.addWidget(useRegex)
         searchCurrent.setChecked(True)
         
         self.editButton = QtGui.QPushButton("Edit")
         self.editButton.setEnabled(False)
         self.backButton = QtGui.QPushButton("Back to Search")
         self.backButton.setEnabled(False)
-        radio_layout.addStretch(1)
-        radio_layout.addWidget(self.editButton, 0, QtCore.Qt.AlignRight)
-        radio_layout.addWidget(self.backButton, 0, QtCore.Qt.AlignRight)
-        layout.addLayout(radio_layout)
+        options_layout.addStretch(1)
+        options_layout.addWidget(self.editButton, 0, QtCore.Qt.AlignRight)
+        options_layout.addWidget(self.backButton, 0, QtCore.Qt.AlignRight)
+        layout.addLayout(options_layout)
         self.setLayout(layout)
 
         self.connect(self.searchBox, QtCore.SIGNAL('resetSearch()'),
@@ -334,6 +343,8 @@ class QQueryBox(QtGui.QWidget):
         self.connect(self.level_group, 
                      QtCore.SIGNAL('buttonClicked(QAbstractButton*)'),
                      self.levelChanged)
+        self.connect(useRegex, QtCore.SIGNAL('stateChanged(int)'),
+                     self.useRegexChanged)
 
     def resetSearch(self, emit_signal=True):
         """
@@ -357,6 +368,9 @@ class QQueryBox(QtGui.QWidget):
     def levelChanged(self, button):
         self.controller.set_level(self.level_map.inverse[button])
 
+    def useRegexChanged(self, status):
+        self.controller.set_use_regex(status != QtCore.Qt.Unchecked)
+
     def setLevel(self, level):
         self.level_map[level].setChecked(True)
 
@@ -372,7 +386,7 @@ class QQueryBox(QtGui.QWidget):
             #     search = CombinedSearch(s, 
             #     search = SearchCompiler(s).searchStmt
             # except SearchParseError, e:
-            #     debug.warning("Search Parse Error", str(e))
+            #     debug.warning("Search Parse Error", e)
             #     search = None
             # self.controller.set_search(search, s)
             # self.emit(QtCore.SIGNAL('textQueryChange(bool)'), s!='')
diff --git a/vistrails/gui/repository.py b/vistrails/gui/repository.py
index 0a26544..f05e69c 100644
--- a/vistrails/gui/repository.py
+++ b/vistrails/gui/repository.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 Dialog for web repository options
 Includes login and upload tabs
 """
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
 from vistrails.core.configuration import get_vistrails_configuration, get_vistrails_persistent_configuration
 from vistrails.core.repository.poster.encode import multipart_encode
@@ -228,7 +231,7 @@ class QRepositoryPushWidget(QtGui.QWidget):
                             ("Error checking user projects (server side issues)")
                     debug.critical("Error checking user projects (server side issues)")
                 else:
-                    debug.critical(str(e))
+                    debug.critical("Exception checking user projects", e)
 
                 self._push_button.setEnabled(False)
                 self.update_push_information()
@@ -277,7 +280,7 @@ class QRepositoryPushWidget(QtGui.QWidget):
                             ("Error when checking dependencies (server side issues)")
                     debug.critical("Error when checking dependencies (server side issues)")
                 else:
-                    debug.critical(str(e))
+                    debug.critical("Exception checking dependencies", e)
 
                 self._push_button.setEnabled(False)
                 self.update_push_information()
@@ -305,7 +308,7 @@ class QRepositoryPushWidget(QtGui.QWidget):
                     if module.name[-6:] == 'Reader' or \
                        module.name in self.local_data_modules:
                         for edge in pipeline.graph.edges_to(module.id):
-                            if pipeline.modules[edge[0]].name in ['HTTPFile',
+                            if pipeline.modules[edge[0]].name in ['DownloadFile',
                                                                   'RepoSync']:
                                 on_repo = True
 
@@ -528,7 +531,7 @@ class QRepositoryPushWidget(QtGui.QWidget):
                             "Update to repository was successful"
 
         except Exception, e:
-            debug.critical("An error occurred", str(e))
+            debug.critical("An error occurred", e)
             self._repository_status['details'] = "An error occurred"
         self.update_push_information()
 
@@ -558,8 +561,8 @@ class QRepositoryLoginPopup(QtGui.QDialog):
         l2 = QtGui.QLabel("Username:", self)
         grid_layout.addWidget(l2, 1, 0)
 
-        if self.config.check('webRepositoryLogin'):
-            self.loginUser = QtGui.QLineEdit(self.config.webRepositoryLogin, self)
+        if self.config.check('webRepositoryUser'):
+            self.loginUser = QtGui.QLineEdit(self.config.webRepositoryUser, self)
         else:
             self.loginUser = QtGui.QLineEdit("", self)
 
@@ -579,7 +582,7 @@ class QRepositoryLoginPopup(QtGui.QDialog):
         grid_layout.addWidget(self.loginPassword, 2, 1)
 
         self.saveLogin = QtGui.QCheckBox("Save username", self)
-        if self.config.check('webRepositoryLogin'):
+        if self.config.check('webRepositoryUser'):
             self.saveLogin.setChecked(True)
         grid_layout.addWidget(self.saveLogin, 3, 0)
 
@@ -668,18 +671,18 @@ class QRepositoryLoginPopup(QtGui.QDialog):
 
             # add association between VisTrails user and web repository user
             if self.saveLogin.checkState():
-                if not (self.config.check('webRepositoryLogin') and self.config.webRepositoryLogin == self.loginUser.text()):
-                    self.config.webRepositoryLogin = str(self.loginUser.text())
+                if not (self.config.check('webRepositoryUser') and self.config.webRepositoryUser == self.loginUser.text()):
+                    self.config.webRepositoryUser = str(self.loginUser.text())
                     pers_config = get_vistrails_persistent_configuration()
-                    pers_config.webRepositoryLogin = self.config.webRepositoryLogin
+                    pers_config.webRepositoryUser = self.config.webRepositoryUser
                     get_vistrails_application().save_configuration()
 
             # remove association between VisTrails user and web repository user
             else:
-                if self.config.check('webRepositoryLogin') and self.config.webRepositoryLogin:
-                    self.config.webRepositoryLogin = ""
+                if self.config.check('webRepositoryUser') and self.config.webRepositoryUser:
+                    self.config.webRepositoryUser = ""
                     pers_config = get_vistrails_persistent_configuration()
-                    pers_config.webRepositoryLogin = ""
+                    pers_config.webRepositoryUser = ""
                     get_vistrails_application().save_configuration()
             self.close_dialog(0)
 
diff --git a/vistrails/gui/requirements.py b/vistrails/gui/requirements.py
index 6b7adf8..58777c2 100644
--- a/vistrails/gui/requirements.py
+++ b/vistrails/gui/requirements.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import os
 import sys
 
diff --git a/vistrails/gui/resources/__init__.py b/vistrails/gui/resources/__init__.py
index cfd644b..cce6ceb 100644
--- a/vistrails/gui/resources/__init__.py
+++ b/vistrails/gui/resources/__init__.py
@@ -1,35 +1,38 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 pass
diff --git a/vistrails/gui/resources/images/disclaimer.png b/vistrails/gui/resources/images/disclaimer.png
index 84892ab..100c954 100644
Binary files a/vistrails/gui/resources/images/disclaimer.png and b/vistrails/gui/resources/images/disclaimer.png differ
diff --git a/vistrails/gui/resources/images/eye_closed.png b/vistrails/gui/resources/images/eye_closed.png
new file mode 100644
index 0000000..d12ed2e
Binary files /dev/null and b/vistrails/gui/resources/images/eye_closed.png differ
diff --git a/vistrails/gui/resources/images/pencil-disabled.png b/vistrails/gui/resources/images/pencil-disabled.png
new file mode 100644
index 0000000..6fe7590
Binary files /dev/null and b/vistrails/gui/resources/images/pencil-disabled.png differ
diff --git a/vistrails/gui/resources/images/pencil.png b/vistrails/gui/resources/images/pencil.png
new file mode 100644
index 0000000..c112902
Binary files /dev/null and b/vistrails/gui/resources/images/pencil.png differ
diff --git a/vistrails/gui/resources/images/vistrails_splash.png b/vistrails/gui/resources/images/vistrails_splash.png
index c53e406..54e54ff 100644
Binary files a/vistrails/gui/resources/images/vistrails_splash.png and b/vistrails/gui/resources/images/vistrails_splash.png differ
diff --git a/vistrails/gui/resources/macroicons_rc.py b/vistrails/gui/resources/macroicons_rc.py
index b3a7f29..018101f 100644
--- a/vistrails/gui/resources/macroicons_rc.py
+++ b/vistrails/gui/resources/macroicons_rc.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,6 +40,8 @@
 #
 # WARNING! All changes made in this file will be lost!
 
+from __future__ import division
+
 from PyQt4 import QtCore
 
 qt_resource_data = b"\
diff --git a/vistrails/gui/shell.py b/vistrails/gui/shell.py
index bff7c37..69c5d97 100644
--- a/vistrails/gui/shell.py
+++ b/vistrails/gui/shell.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -42,800 +43,39 @@ More information on PyCute, visit:
 http://gerard.vermeulen.free.fr/html/pycute-intro.html
 
 """
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
-from code import InteractiveInterpreter
-import copy
 import sys
-import time
-import os.path
 
-import vistrails.api
-from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core.bundles import py_import
 from vistrails.core.interpreter.default import get_default_interpreter
-import vistrails.core.modules.module_registry
-from vistrails.core.modules.utils import create_port_spec_string
-import vistrails.core.system
-from vistrails.core.vistrail.port_spec import PortSpec
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
-from vistrails.core.utils import all
 
 ################################################################################
 
-class QShellDialog(QtGui.QWidget, QVistrailsPaletteInterface):
-    """This class incorporates the QShell into a dockable widget for use in the
-    VisTrails environment"""
-    def __init__(self, parent=None):
-        QtGui.QWidget.__init__(self, parent=parent)
-        #locals() returns the original dictionary, not a copy as
-        #the docs say
-        self.firstLocals = copy.copy(locals())
-        self.shell = QShell(self.firstLocals,None)
-        layout = QtGui.QVBoxLayout()
-        layout.setMargin(0)
-        layout.setSpacing(0)
-        layout.addWidget(self.shell)
-        self.setLayout(layout)
-        # self.setWidget(self.shell)
-        self.setWindowTitle(self.shell.windowTitle())
-        # self.setTitleBarWidget(QtGui.QLabel(self.shell.windowTitle()))
-        # self.monitorWindowTitle(self.shell)
-        self.vistrails_interpreter = get_default_interpreter()
-    
-    def createMenu(self):
-        """createMenu() -> None
-        Creates a menu bar and adds it to the main layout.
-
-        """
-        self.newSessionAct = QtGui.QAction(self.tr("&Restart"),self)
-        self.newSessionAct.setShortcut(self.tr("Ctrl+R"))
-        self.connect(self.newSessionAct, QtCore.SIGNAL("triggered()"),
-                     self.newSession)
-
-        self.saveSessionAct = QtGui.QAction(self.tr("&Save"), self)
-        self.saveSessionAct.setShortcut(self.tr("Ctrl+S"))
-        self.connect(self.saveSessionAct, QtCore.SIGNAL("triggered()"),
-                     self.saveSession)
-
-        self.closeSessionAct = QtGui.QAction(self.tr("Close"), self)
-        self.closeSessionAct.setShortcut(self.tr("Ctrl+W"))
-        self.connect(self.closeSessionAct,QtCore.SIGNAL("triggered()"), 
-                     self.closeSession)
-        
-        self.menuBar = QtGui.QMenuBar(self)
-        menu = self.menuBar.addMenu(self.tr("&Session"))
-        menu.addAction(self.newSessionAct)
-        menu.addAction(self.saveSessionAct)
-        menu.addAction(self.closeSessionAct)
-
-        self.layout().setMenuBar(self.menuBar)
-
-    def closeEvent(self, e):
-        """closeEvent(e) -> None
-        Event handler called when the dialog is about to close."""
-        self.closeSession()
-        self.emit(QtCore.SIGNAL("shellHidden()"))
-    
-    def showEvent(self, e):
-        """showEvent(e) -> None
-        Event handler called when the dialog acquires focus 
-
-        """
-        self.shell.show()
-
-    def closeSession(self):
-        """closeSession() -> None.
-        Hides the dialog instead of closing it, so the session continues open.
-
-        """
-        self.hide()
-
-    def newSession(self):
-        """newSession() -> None
-        Tells the shell to start a new session passing a copy of the original
-        locals dictionary.
-
-        """
-        self.shell.restart(copy.copy(self.firstLocals))
-
-    def saveSession(self):
-        """saveSession() -> None
-        Opens a File Save dialog and passes the filename to shell's saveSession.
-
-        """
-        default = 'visTrails' + '-' + time.strftime("%Y%m%d-%H%M.log")
-        default = os.path.join(vistrails.core.system.vistrails_file_directory(),default)
-        fileName = QtGui.QFileDialog.getSaveFileName(self,
-                                                     "Save Session As..",
-                                                     default,
-                                                     "Log files (*.log)")
-        if not fileName:
-            return
-
-        self.shell.saveSession(str(fileName))
-
-    def visibility_changed(self, visible):
-        QVistrailsPaletteInterface.visibility_changed(self, visible)
-        if visible:
-            self.shell.show()
-        else:
-            self.shell.hide()
-
-##############################################################################
-# QShell
-        
-
-class vistrails_port(object):
-    def __init__(self, vistrails_module, port_spec):
-        # print 'calling vistrails_port.__init__'
-        self._vistrails_module = vistrails_module
-        self._port_spec = port_spec
-
-    def __call__(self, *args, **kwargs):
-        if len(args) + len(kwargs) > 0:
-            self._vistrails_module._update_func(self._port_spec,
-                                                *args, **kwargs)
-            return None
-        return self
-
-class vistrails_module(object):
-    def __init__(self, *args, **kwargs):
-        if not hasattr(self, '_module'):
-            self._module = \
-                vistrails.api.add_module_from_descriptor(self._module_desc)
-            # FIXME if constant, we can use args
-            module_desc = self._module_desc
-            for attr_name, value in kwargs.iteritems():
-                self._process_attr_value(attr_name, value)
-
-    def _process_attr_value(self, attr_name, value):
-        if self._module.has_port_spec(attr_name, 'input'):
-            port_spec = self._module.get_port_spec(attr_name, 'input')
-
-            args = None
-            # FIXME want this to be any iterable
-            if isinstance(value, tuple):
-                args = value
-            else:
-                args = (value,)
-            self._update_func(port_spec, *args)
-        else:
-            raise AttributeError("type object '%s' has no "
-                                 "attribute '%s'" % \
-                                     (self.__class__.__name__,
-                                      attr_name))                
-
-    def __getattr__(self, attr_name):
-        def create_port(port_spec):
-            return vistrails_port(self, port_spec)
-        try:
-            return self.__dict__[attr_name]
-        except KeyError:
-            if self._module.has_port_spec(attr_name, 'output'):
-                port_spec = \
-                    self._module.get_port_spec(attr_name, 'output')
-                return create_port(port_spec)
-            elif self._module.has_port_spec(attr_name, 'input'):
-                port_spec = \
-                    self._module.get_port_spec(attr_name, 'input')
-                return create_port(port_spec)
-            else:
-                raise AttributeError("type object '%s' has no "
-                                     "attribute '%s'" % \
-                                         (self.__class__.__name__, 
-                                          attr_name))
-
-    def __setattr__(self, attr_name, value):
-        if attr_name.startswith('_'):
-            self.__dict__[attr_name] = value
-        else:
-            self._process_attr_value(attr_name, value)
-
-    def _update_func(self, port_spec, *args, **kwargs):
-        # print 'running _update_func', port_spec.name
-        # print args
-
-        if port_spec.type != 'input':
-            if self._module.has_port_spec(port_spec.name, 'input'):
-                port_spec = \
-                    self._module.get_port_spec(port_spec.name, 'input')
-            else:
-                raise TypeError("cannot update an output port spec")
-
-        # FIXME deal with kwargs
-        num_ports = 0
-        num_params = 0
-        for value in args:
-            # print 'processing', type(value), value
-            if isinstance(value, vistrails_port):
-                # make connection to specified output port
-                # print 'updating port'
-                num_ports += 1
-            elif isinstance(value, vistrails_module):
-                # make connection to 'self' output port of value
-                # print 'updating module'
-                num_ports += 1
-            else:
-                # print 'update literal', type(value), value
-                num_params += 1
-        if num_ports > 1 or (num_ports == 1 and num_params > 0):
-            reg = vistrails.core.modules.module_registry.get_module_registry()
-            tuple_desc = reg.get_descriptor_by_name(
-                vistrails.core.system.get_vistrails_basic_pkg_id(), 'Tuple')
-
-            d = {'_module_desc': tuple_desc,
-                 '_package': self._package,}
-            tuple = type('module', (vistrails_module,), d)()
-
-            output_port_spec = PortSpec(id=-1,
-                                        name='value',
-                                        type='output',
-                                        sigstring=port_spec.sigstring)
-            vistrails.api.add_port_spec(tuple._module.id, output_port_spec)
-            self._update_func(port_spec, *[tuple.value()])
-            assert len(port_spec.descriptors()) == len(args)
-            for i, descriptor in enumerate(port_spec.descriptors()):
-                arg_name = 'arg%d' % i
-                sigstring = create_port_spec_string([descriptor.spec_tuple])
-                tuple_port_spec = PortSpec(id=-1,
-                                           name=arg_name,
-                                           type='input',
-                                           sigstring=sigstring)
-                vistrails.api.add_port_spec(tuple._module.id, tuple_port_spec)
-                tuple._process_attr_value(arg_name, args[i])
-                
-                
-            # create tuple object
-            pass
-        elif num_ports == 1:
-            other = args[0]
-            if isinstance(other, vistrails_port):
-                if other._port_spec.type != 'output':
-                    other_module = other._vistrails_module._module
-                    if other_module.has_port_spec(port_spec.name, 
-                                                   'output'):
-                        other_port_spec = \
-                            other_module.get_port_spec(port_spec.name, 
-                                                        'output')
-                    else:
-                        raise TypeError("cannot update an input "
-                                        "port spec")
-                else:
-                    other_port_spec = other._port_spec
-
-                vistrails.api.add_connection(other._vistrails_module._module.id,
-                                   other_port_spec,
-                                   self._module.id, 
-                                   port_spec)
-            elif isinstance(other, vistrails_module):
-                other_port_spec = \
-                    other._module.get_port_spec('self', 'output')
-                vistrails.api.add_connection(other._module.id, 
-                                   other_port_spec,
-                                   self._module.id,
-                                   port_spec)
-        else:
-            vistrails.api.change_parameter(self._module.id,
-                                 port_spec.name,
-                                 [str(x) for x in args])
-
-class QShell(QtGui.QTextEdit):
-    """This class embeds a python interperter in a QTextEdit Widget
-    It is based on PyCute developed by Gerard Vermeulen.
-    
-    """
-    def __init__(self, locals=None, parent=None):
-        """Constructor.
-
-        The optional 'locals' argument specifies the dictionary in which code
-        will be executed; it defaults to a newly created dictionary with key 
-        "__name__" set to "__console__" and key "__doc__" set to None.
-
-        The optional 'log' argument specifies the file in which the interpreter
-        session is to be logged.
-        
-        The optional 'parent' argument specifies the parent widget. If no parent
-        widget has been specified, it is possible to exit the interpreter 
-        by Ctrl-D.
-
-        """
-
-        QtGui.QTextEdit.__init__(self, parent)
-        self.setReadOnly(False)
-        self.setWindowTitle("Console")
-        # to exit the main interpreter by a Ctrl-D if QShell has no parent
-        if parent is None:
-            self.eofKey = QtCore.Qt.Key_D
-        else:
-            self.eofKey = None
-
-        # flag for knowing when selecting text
-        self.selectMode = False
-        self.interpreter = None
-        self.controller = None
-        # storing current state
-        #this is not working on mac
-        #self.prev_stdout = sys.stdout
-        #self.prev_stdin = sys.stdin
-        #self.prev_stderr = sys.stderr
-        # capture all interactive input/output
-        #sys.stdout   = self
-        #sys.stderr   = self
-        #sys.stdin    = self
-        
-        # user interface setup
-        
-        self.setAcceptRichText(False)
-        self.setWordWrapMode(QtGui.QTextOption.WrapAnywhere)
-        
-        conf = get_vistrails_configuration()
-        shell_conf = conf.shell
-        # font
-        font = QtGui.QFont(shell_conf.font_face, shell_conf.font_size)
-        font.setFixedPitch(1)
-        self.setFont(font)
-        self.reset(locals)
-
-    def load_package(self, pkg_name):
-        reg = vistrails.core.modules.module_registry.get_module_registry()
-        package = reg.get_package_by_name(pkg_name)
-        
-        def create_dict(modules, ns, m, mdesc):
-            md = {}
-            if len(ns) == 0:
-                d = {'_module_desc': mdesc,
-                     '_package': pkg,}
-                modules[m] = type('module', (vistrails_module,), d)
-            else:
-                if ns[0] in modules:
-                    md = create_dict(modules[ns[0]], ns[1:], m, mdesc)
-                else:
-                    md = create_dict(md, ns[1:], m, mdesc)
-                    modules[ns[0]] = md
-            return modules
-        
-        def create_namespace_path(root, modules):
-            for k,v in modules.iteritems():
-                if isinstance(v, dict):
-                    d = create_namespace_path(k,v)
-                    modules[k] = d
-            
-            if root is not None:
-                modules['_package'] = pkg
-                return type(root, (object,), modules)()
-            else:
-                return modules
-        
-        def get_module_init(module_desc):
-            def init(self, *args, **kwargs):
-                self.__dict__['module'] = \
-                    vistrails.api.add_module_from_descriptor(module_desc)
-            return init
-        
-        def get_module(package):
-            def getter(self, attr_name):
-                desc_tuple = (attr_name, '')
-                if desc_tuple in package.descriptors:
-                    module_desc = package.descriptors[desc_tuple]
-                    d = {'_module_desc': module_desc,
-                         '_package': self,}
-                    return type('module', (vistrails_module,), d)
-                else:
-                    raise AttributeError("type object '%s' has no attribute "
-                                         "'%s'" % (self.__class__.__name__, 
-                                                   attr_name))
-            return getter
-        
-        d = {'__getattr__': get_module(package),}
-        pkg = type(package.name, (object,), d)()
-        
-        modules = {}
-        for (m,ns) in package.descriptors:
-            module_desc = package.descriptors[(m,ns)]
-            modules = create_dict(modules, ns.split('|'), m, module_desc)   
-        
-        modules = create_namespace_path(None, modules)
-        
-        for (k,v) in modules.iteritems():
-            setattr(pkg, k, v)
-        return pkg
-
-    def selected_modules(self):
-        shell_modules = []
-        modules = vistrails.api.get_selected_modules()
-        for module in modules:
-            d = {'_module': module}
-            shell_modules.append(type('module', (vistrails_module,), d)())
-        return shell_modules
-
-    def reset(self, locals):
-        """reset(locals) -> None
-        Reset shell preparing it for a new session.
-        
-        """
-        locals['load_package'] = self.load_package
-        locals['selected_modules'] = self.selected_modules
-        if self.interpreter:
-            del self.interpreter
-        self.interpreter = InteractiveInterpreter(locals)
- 
-        # last line + last incomplete lines
-        self.line    = ''
-        self.lines   = []
-        # the cursor position in the last line
-        self.point   = 0
-        # flag: the interpreter needs more input to run the last lines. 
-        self.more    = 0
-        # flag: readline() is being used for e.g. raw_input() and input()
-        self.reading = 0
-        # history
-        self.history = []
-        self.pointer = 0
-        self.last   = 0
-                # interpreter prompt.
-        if hasattr(sys, "ps1"):
-            sys.ps1
-        else:
-            sys.ps1 = ">>> "
-        if hasattr(sys, "ps2"):
-            sys.ps2
-        else:
-            sys.ps2 = "... "
-        
-        # interpreter banner
-        
-        self.write('VisTrails shell running Python %s on %s.\n' %
-                   (sys.version, sys.platform))
-        self.write('Type "copyright", "credits" or "license"'
-                   ' for more information on Python.\n')
-        self.write(sys.ps1)
-
+_shell_dialog = None
 
-    def flush(self):
-        """flush() -> None. 
-        Simulate stdin, stdout, and stderr.
-        
-        """
-        pass
+def get_shell_dialog():
+    global _shell_dialog
 
-    def isatty(self):
-        """isatty() -> int
-        Simulate stdin, stdout, and stderr.
-        
-        """
-        return 1
+    if _shell_dialog is not None:
+        return _shell_dialog
 
-    def readline(self):
-        """readline() -> str
-        
-        Simulate stdin, stdout, and stderr.
-        
-        """
-        self.reading = 1
-        self.__clearLine()
-        cursor = self.textCursor()
-        cursor.movePosition(QtGui.QTextCursor.End)
-        self.setTextCursor(cursor)
-      
-        while self.reading:
-            qApp.processOneEvent()
-        if len(self.line) == 0:
-            return '\n'
-        else:
-            return self.line 
-    
-    def write(self, text):
-        """write(text: str) -> None
-        Simulate stdin, stdout, and stderr.
-        
-        """
-                
-        cursor = self.textCursor()
-        cursor.movePosition(QtGui.QTextCursor.End)
-        cursor.clearSelection()
-        self.setTextCursor(cursor)
-        self.insertPlainText(text)
-        cursor = self.textCursor()
-        self.last = cursor.position()
-
-    def insertFromMimeData(self, source):
-        if source.hasText():
-            cursor = self.textCursor()
-            cursor.movePosition(QtGui.QTextCursor.End)
-            cursor.clearSelection()
-            self.setTextCursor(cursor)
-            self.__insertText(source.text())
-        
-    def scroll_bar_at_bottom(self):
-        """Returns true if vertical bar exists and is at bottom, or if
-        vertical bar does not exist."""
-        bar = self.verticalScrollBar()
-        if not bar:
-            return True
-        return bar.value() == bar.maximum()
-        
-    def __run(self):
-        """__run() -> None
-        Append the last line to the history list, let the interpreter execute
-        the last line(s), and clean up accounting for the interpreter results:
-        (1) the interpreter succeeds
-        (2) the interpreter fails, finds no errors and wants more line(s)
-        (3) the interpreter fails, finds errors and writes them to sys.stderr
-        
-        """
-        cursor = self.textCursor()
-        cursor.movePosition(QtGui.QTextCursor.End)
-        self.setTextCursor(cursor)
-        # self.set_controller()
-        should_scroll = self.scroll_bar_at_bottom()
-        self.pointer = 0
-        self.history.append(self.line)
-        self.lines.append(self.line)
-        source = '\n'.join(self.lines)
-        self.write('\n')
-        self.more = self.interpreter.runsource(source)
-        if self.more:
-            self.write(sys.ps2)
-        else:
-            self.write(sys.ps1)
-            self.lines = []
-        self.__clearLine()
-        if should_scroll:
-            bar = self.verticalScrollBar()
-            if bar:
-                bar.setValue(bar.maximum())
-
-    def __clearLine(self):
-        """__clearLine() -> None
-        Clear input line buffer.
-        
-        """
-        self.line = ""
-        self.point = 0
-        
-    def __insertText(self, text):
-        """__insertText(text) -> None
-        Insert text at the current cursor position.
-        
-        """
-        self.insertPlainText(text)
-        self.line = self.line[:self.point] + text + self.line[self.point:]
-        self.point += len(text)
-
-    # def add_pipeline(self, p):
-    #     """
-    #     add_pipeline(p) -> None
-    #     Set the active pipeline in the command shell.  This replaces the modules
-    #     variable with the list of current active modules of the selected pipeline.
-    #     """
-    #     if self.controller:
-    #         self.interpreter.active_pipeline = self.controller.current_pipeline
-    #     else:
-    #         self.interpreter.active_pipeline = p
-    #     cmd = 'active_pipeline = self.shell.interpreter.active_pipeline'
-    #     self.interpreter.runcode(cmd)
-    #     cmd = 'modules = self.vistrails_interpreter.find_persistent_entities(active_pipeline)[0]'
-    #     self.interpreter.runcode(cmd)
-
-    def set_controller(self, controller=None):
-        """set_controller(controller: VistrailController) -> None
-        Set the current VistrailController on the shell.
-        """
-        self.controller = controller
-        if controller:
-            self.interpreter.active_pipeline = self.controller.current_pipeline
-            cmd = 'active_pipeline = self.shell.interpreter.active_pipeline'
-            self.interpreter.runcode(cmd)
-            cmd = 'modules = self.vistrails_interpreter.' \
-                'find_persistent_entities(active_pipeline)[0]'
-            self.interpreter.runcode(cmd)
-
-    # def set_pipeline(self):
-    #     """set_active_pipeline() -> None
-    #     Makes sure that the pipeline being displayed is present in the shell for
-    #     direct inspection and manipulation
-    #     """
-    #     self.add_pipeline(None)
-        
-    def keyPressEvent(self, e):
-        """keyPressEvent(e) -> None
-        Handle user input a key at a time.
-
-        Notice that text might come more than one keypress at a time
-        if user is a fast enough typist!
-        
-        """
-        text  = e.text()
-        key   = e.key()
-
-        # NB: Sometimes len(str(text)) > 1!
-        if len(text) and all(ord(x) >= 32 and
-                             ord(x) < 127
-                             for x in str(text)):
-        # exit select mode and jump to end of text
-            cursor = self.textCursor()
-            if self.selectMode or cursor.hasSelection():
-                self.selectMode = False
-                cursor.movePosition(QtGui.QTextCursor.End)
-                cursor.clearSelection()
-                self.setTextCursor(cursor)
-            self.__insertText(text)
-            return
- 
-        if e.modifiers() & QtCore.Qt.MetaModifier and key == self.eofKey:
-            self.parent().closeSession()
-        
-        if e.modifiers() & QtCore.Qt.ControlModifier:
-            if key == QtCore.Qt.Key_C or key == QtCore.Qt.Key_Insert:
-                self.copy()
-            elif key == QtCore.Qt.Key_V:
-                cursor = self.textCursor()
-                cursor.movePosition(QtGui.QTextCursor.End)
-                cursor.clearSelection()
-                self.setTextCursor(cursor)
-                self.paste()
-            elif key == QtCore.Qt.Key_A:
-                self.selectAll()
-                self.selectMode = True
-            else:
-                e.ignore()
-            return
-
-        if e.modifiers() & QtCore.Qt.ShiftModifier:
-            if key == QtCore.Qt.Key_Insert:
-                cursor = self.textCursor()
-                cursor.movePosition(QtGui.QTextCursor.End)
-                cursor.clearSelection()
-                self.setTextCursor(cursor)
-                self.paste()
-            else:
-                e.ignore()
-            return
-
-        # exit select mode and jump to end of text
-        cursor = self.textCursor()
-        if self.selectMode or cursor.hasSelection():
-            self.selectMode = False
-            cursor.movePosition(QtGui.QTextCursor.End)
-            cursor.clearSelection()
-            self.setTextCursor(cursor)
-
-        if key == QtCore.Qt.Key_Backspace:
-            if self.point:
-                QtGui.QTextEdit.keyPressEvent(self, e)
-                self.point -= 1
-                self.line = self.line[:self.point] + self.line[self.point+1:]
-        elif key == QtCore.Qt.Key_Delete:
-            QtGui.QTextEdit.keyPressEvent(self, e)
-            self.line = self.line[:self.point] + self.line[self.point+1:]
-        elif key == QtCore.Qt.Key_Return or key == QtCore.Qt.Key_Enter:
-            if self.reading:
-                self.reading = 0
-            else:
-                self.__run()
-        elif key == QtCore.Qt.Key_Tab:
-            self.__insertText(text)
-        elif key == QtCore.Qt.Key_Left:
-            if self.point:
-                QtGui.QTextEdit.keyPressEvent(self, e)
-                self.point -= 1
-        elif key == QtCore.Qt.Key_Right:
-            if self.point < len(self.line):
-                QtGui.QTextEdit.keyPressEvent(self, e)
-                self.point += 1
-        elif key == QtCore.Qt.Key_Home:
-            cursor = self.textCursor()
-            cursor.movePosition(QtGui.QTextCursor.StartOfLine)
-            cursor.setPosition(cursor.position() + 4)
-            self.setTextCursor(cursor)
-            self.point = 0
-        elif key == QtCore.Qt.Key_End:
-            QtGui.QTextEdit.keyPressEvent(self, e)
-            self.point = len(self.line)
-        elif key == QtCore.Qt.Key_Up:
-            if len(self.history):
-                if self.pointer == 0:
-                    self.pointer = len(self.history)
-                self.pointer -= 1
-                self.__recall()
-        elif key == QtCore.Qt.Key_Down:
-            if len(self.history):
-                self.pointer += 1
-                if self.pointer == len(self.history):
-                    self.pointer = 0
-                self.__recall()
-        else:
-            e.ignore()
-
-    def __recall(self):
-        """__recall() -> None
-        Display the current item from the command history.
-        
-        """
-        cursor = self.textCursor()
-        cursor.setPosition(self.last)
-        
-        cursor.select(QtGui.QTextCursor.LineUnderCursor)
-
-        cursor.removeSelectedText()
-        self.setTextCursor(cursor)
-        self.insertPlainText(sys.ps1)
-        self.__clearLine()
-        self.__insertText(self.history[self.pointer])
-
-        
-    def focusNextPrevChild(self, next):
-        """focusNextPrevChild(next) -> None
-        Suppress tabbing to the next window in multi-line commands. 
-        
-        """
-        if next and self.more:
-            return 0
-        return QtGui.QTextEdit.focusNextPrevChild(self, next)
-
-    def mousePressEvent(self, e):
-        """mousePressEvent(e) -> None
-        Keep the cursor after the last prompt.
-        """
-        if e.button() == QtCore.Qt.LeftButton:
-            self.selectMode = True
-            QtGui.QTextEdit.mousePressEvent(self, e)
-#            cursor = self.textCursor()
-#            cursor.movePosition(QtGui.QTextCursor.End)
-#            self.setTextCursor(cursor)
-        return
-
-    def hide(self):
-        """suspend() -> None
-        Called when hiding the parent window in order to recover the previous
-        state.
-
-        """
-        #recovering the state
-        sys.stdout   = sys.__stdout__
-        sys.stderr   = sys.__stderr__
-        sys.stdin    = sys.__stdin__
-
-    def show(self):
-        """show() -> None
-        Store previous state and starts capturing all interactive input and 
-        output.
-        
-        """
-        # capture all interactive input/output
-        sys.stdout   = self
-        sys.stderr   = self
-        sys.stdin    = self
-        self.setFocus()
-
-    def saveSession(self, fileName):
-        """saveSession(fileName: str) -> None 
-        Write its contents to a file """
-        output = open(str(fileName), 'w')
-        output.write(self.toPlainText())
-        output.close()
-
-    def restart(self, locals=None):
-        """restart(locals=None) -> None 
-        Restart a new session 
-
-        """
-        self.clear()
-        self.reset(locals)
-
-    def contentsContextMenuEvent(self,ev):
-        """
-        contentsContextMenuEvent(ev) -> None
-        Suppress the right button context menu.
-        
-        """
-        return
-
-################################################################################
-
-def getIPythonDialog():
-    from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
-    from IPython.qt.inprocess import QtInProcessKernelManager
-#    from IPython.kernel.inprocess.ipkernel import InProcessKernel
+    try:
+        deps = {'pip': 'ipython>=1.0',
+                'linux-ubuntu': 'ipython-qtconsole',
+                'linux-debian': 'ipython-qtconsole'}
+
+        IPython = py_import('IPython.qt.console.rich_ipython_widget', deps,
+                            True)
+        RichIPythonWidget = \
+                IPython.qt.console.rich_ipython_widget.RichIPythonWidget
+        py_import('IPython.qt.inprocess', deps, True)
+        QtInProcessKernelManager = \
+                IPython.qt.inprocess.QtInProcessKernelManager
+    except ImportError:
+        return None
 
     km = QtInProcessKernelManager()
     km.start_kernel()
@@ -845,32 +85,17 @@ def getIPythonDialog():
     kernel_client = km.client()
     kernel_client.start_channels()
 
-    def stop():
-        kernel_client.stop_channels()
-        km.shutdown_kernel()
-
     class IPythonDialog(RichIPythonWidget, QVistrailsPaletteInterface):
         """This class incorporates an  IPython shell into a dockable widget for use in the
         VisTrails environment"""
         def __init__(self, parent=None):
             RichIPythonWidget.__init__(self, parent)
+            self.old_streams = None
             self.running_workflow = False
             self.kernel_manager = km
             self.kernel_client = kernel_client
-            self.exit_requested.connect(stop)
-            #locals() returns the original dictionary, not a copy as
-            #the docs say
-    #        self.firstLocals = copy.copy(locals())
-    #        self.shell = IPythonXXX(self.firstLocals,None)
-    #        layout = QtGui.QVBoxLayout()
-    #        layout.setMargin(0)
-    #        layout.setSpacing(0)
-    #        layout.addWidget(self.shell)
-    #        self.setLayout(layout)
-            # self.setWidget(self.shell)
+            self.exit_requested.connect(self.stop)
             self.setWindowTitle("Console")
-            # self.setTitleBarWidget(QtGui.QLabel(self.shell.windowTitle()))
-            # self.monitorWindowTitle(self.shell)
             self.vistrails_interpreter = get_default_interpreter()
 
         def visibility_changed(self, visible):
@@ -879,64 +104,69 @@ def getIPythonDialog():
                 self.show()
             else:
                 self.hide()
+        def stop(self):
+            kernel_client.stop_channels()
+            km.shutdown_kernel()
 
         def hide(self):
             """suspend() -> None
             Called when hiding the parent window in order to recover the previous
             state.
-    
+
             """
             #recovering the state
-            sys.stdout   = sys.__stdout__
-            sys.stderr   = sys.__stderr__
-            sys.stdin    = sys.__stdin__
+            if self.old_streams is not None:
+                sys.stdout, sys.stderr, sys.stdin = self.old_streams
+                self.old_streams = None
             RichIPythonWidget.hide(self)
-    
+
         def show(self):
             """show() -> None
-            Store previous state and starts capturing all interactive input and 
+            Store previous state and starts capturing all interactive input and
             output.
-            
+
             """
             # capture all interactive input/output
-            sys.stdout   = self
-            sys.stderr   = self
-            sys.stdin    = self
+            if self.old_streams is None:
+                self.old_streams = sys.stdout, sys.stderr, sys.stdin
+                sys.stdout   = self
+                sys.stderr   = self
+                sys.stdin    = self
             RichIPythonWidget.show(self)
 
         def showEvent(self, e):
             """showEvent(e) -> None
-            Event handler called when the dialog acquires focus 
-    
+            Event handler called when the dialog acquires focus
+
             """
             self.show()
 
         def flush(self):
-            """flush() -> None. 
+            """flush() -> None.
             Simulate stdin, stdout, and stderr.
-            
+
             """
             pass
-    
+
         def isatty(self):
             """isatty() -> int
             Simulate stdin, stdout, and stderr.
-            
+
             """
             return 1
-    
+
         def readline(self):
             """readline() -> str
-            
+
             Simulate stdin, stdout, and stderr.
-            
+
             """
             return ""
-        
+
         def write(self, text):
             """write(text: str) -> None
             Simulate stdin, stdout, and stderr.
-            
+
             """
             self.input_buffer = ''
             if not self.running_workflow:
@@ -948,7 +178,6 @@ def getIPythonDialog():
             self._control.ensureCursorVisible()
             self._control.moveCursor(QtGui.QTextCursor.End)
 
-
         def eventFilter(self, obj, event):
             """ Reimplemented to ensure a console-like behavior in the underlying
                 text widgets.
@@ -958,27 +187,5 @@ def getIPythonDialog():
                 self.running_workflow = False
             return RichIPythonWidget.eventFilter(self, obj, event)
 
+    _shell_dialog = IPythonDialog
     return IPythonDialog
-
-#install_attempted = False
-#installed = vistrails.core.requirements.python_module_exists('IPython.frontend.qt')
-#if not installed and not install_attempted:
-#    print "attempt to install"
-#    install_attempted = True
-#    from vistrails.core.bundles import installbundle
-#    installed = installbundle.install({'linux-ubuntu': 'ipython-qtconsole'})
-#if installed:
-#    print "installed!"
-#    QShellDialog = getIPythonDialog()
-
-# This is tested with IPython 1.0.0 and its beta versions
-# TODO: Once IPython 1.0 is included in the distro we should add auto-install
-try:
-    from IPython.qt.inprocess import QtInProcessKernelManager
-    try:
-        QShellDialog = getIPythonDialog()
-    except Exception, e:
-        import traceback; traceback.print_exc()
-        print str(e)
-except:
-    pass
diff --git a/vistrails/gui/theme.py b/vistrails/gui/theme.py
index b65e0cf..c45b99f 100644
--- a/vistrails/gui/theme.py
+++ b/vistrails/gui/theme.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 This module describes a theme structure for VisTrails GUI. It
 specifies colors, background images and other measurements
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core.utils.color import ColorByName
@@ -307,18 +310,25 @@ class DefaultTheme(DefaultCoreTheme):
     
         #### FONTS ####        
         # Font for module text
-        self.MODULE_FONT = QtGui.QFont("Arial", 14, QtGui.QFont.Bold)
+        # Use fixed dpi to get same font size on all platforms
+        def fixDPI(i):
+            return i*72//QtGui.QApplication.desktop().logicalDpiY()
+        GRAPHICS_FONT = "Arial"
+        self.MODULE_FONT = QtGui.QFont(GRAPHICS_FONT, fixDPI(14), QtGui.QFont.Bold)
         self.MODULE_FONT_METRIC = QtGui.QFontMetrics(self.MODULE_FONT)
-        self.MODULE_DESC_FONT = QtGui.QFont("Arial", 12)
+        self.MODULE_DESC_FONT = QtGui.QFont(GRAPHICS_FONT, fixDPI(12))
         self.MODULE_DESC_FONT_METRIC = QtGui.QFontMetrics(self.MODULE_DESC_FONT)
+        self.MODULE_EDIT_FONT = QtGui.QFont(GRAPHICS_FONT, fixDPI(10))
+        self.MODULE_EDIT_FONT_METRIC = QtGui.QFontMetrics(self.MODULE_EDIT_FONT)
     
         # Font for version text
-        self.VERSION_FONT = QtGui.QFont("Arial", 15, QtGui.QFont.Bold)
+        self.VERSION_FONT = QtGui.QFont(GRAPHICS_FONT, fixDPI(15), QtGui.QFont.Bold)
         self.VERSION_FONT_METRIC = QtGui.QFontMetrics(self.VERSION_FONT)
-        self.VERSION_DESCRIPTION_FONT = QtGui.QFont("Arial", 15, QtGui.QFont.Normal, 
-                                                    True)
+        self.VERSION_DESCRIPTION_FONT = QtGui.QFont(GRAPHICS_FONT, fixDPI(15),
+                                                    QtGui.QFont.Normal, True)
         self.VERSION_DESCRIPTION_FONT_METRIC = \
             QtGui.QFontMetrics(self.VERSION_DESCRIPTION_FONT)
+
         self.VERSION_PROPERTIES_FONT = QtGui.QFont("Arial", 12)
         self.VERSION_PROPERTIES_FONT_METRIC = \
             QtGui.QFontMetrics(self.VERSION_PROPERTIES_FONT)
@@ -627,11 +637,23 @@ class DefaultTheme(DefaultCoreTheme):
                 vistrails.core.system.vistrails_root_directory() +
                 '/gui/resources/images/multiline_string_icon.png'))
 
+        # icons for the port list combination modes
+        self.DOT_PRODUCT_ICON = QtGui.QIcon(QtGui.QPixmap(
+            vistrails.core.system.vistrails_root_directory() +
+            '/gui/resources/images/macro.png'))
+
+        self.CROSS_PRODUCT_ICON = QtGui.QIcon(QtGui.QPixmap(
+            vistrails.core.system.vistrails_root_directory() +
+            '/gui/resources/images/remove_param.png'))
+
         #### COLORS ####
         # Color for the PIP frame
         self.PIP_FRAME_COLOR = QtGui.QColor(
             *(ColorByName.get_int('yellow_light')))
 
+        # Color for invalid parameter frames
+        self.PARAM_INVALID_COLOR = QtGui.QColor('#efef00')
+
         # Color of selected methods in the modules method area
         self.METHOD_SELECT_COLOR = QtGui.QColor(
             *ColorByName.get_int('yellow_light'))
@@ -726,8 +748,6 @@ def initializeCurrentTheme():
     Assign the current theme to the default theme
     
     """
-    global CurrentTheme
-    
     CurrentTheme.setTheme(get_current_theme())
 
 global CurrentTheme
diff --git a/vistrails/gui/utils.py b/vistrails/gui/utils.py
index 86edd6a..51f6a63 100644
--- a/vistrails/gui/utils.py
+++ b/vistrails/gui/utils.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 """ Utilities for creating simple dialogs, notifications in Vistrails
 without exposing Qt codes """
+from __future__ import division
+
 from PyQt4 import QtGui, QtCore
 from vistrails.gui.theme import CurrentTheme
 import vistrails.gui.theme
@@ -203,7 +206,7 @@ def getBuilderWindow():
     """
     try:
         return QtCore.QCoreApplication.instance().builderWindow
-    except:
+    except AttributeError:
         return None
 
 def getCurrentVersion():
diff --git a/vistrails/gui/variable_dropbox.py b/vistrails/gui/variable_dropbox.py
index 748df0d..5a22423 100644
--- a/vistrails/gui/variable_dropbox.py
+++ b/vistrails/gui/variable_dropbox.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -42,6 +43,8 @@ QVariableInputForm
 QDragVariableLabel
 QHoverVariableLabel
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core import debug
 from vistrails.core.vistrail.module_function import ModuleFunction
@@ -50,9 +53,8 @@ from vistrails.core.modules import module_registry
 from vistrails.core.modules.basic_modules import Constant
 from vistrails.core.vistrail.vistrailvariable import VistrailVariable
 from vistrails.gui.common_widgets import QPromptWidget
-from vistrails.gui.modules import get_widget_class
-from vistrails.gui.modules.constant_configuration import StandardConstantWidget, \
-    FileChooserToolButton
+from vistrails.gui.modules.utils import get_widget_class
+from vistrails.gui.modules.constant_configuration import StandardConstantWidget
 from vistrails.gui.module_palette import QModuleTreeWidget
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.utils import show_question, YES_BUTTON, NO_BUTTON
@@ -338,7 +340,7 @@ class QVariableInputForm(QtGui.QGroupBox):
         p = ModuleParam(type=descriptor.name, identifier=descriptor.identifier,
                         namespace=descriptor.namespace)
         p.strValue = var_strValue
-        widget_type = get_widget_class(descriptor.module)
+        widget_type = get_widget_class(descriptor)
         self.widget = widget_type(p, self)
         self.label = QDragVariableLabel(p.type)
         self.layout().addWidget(self.label, 0, 0)
diff --git a/vistrails/gui/version_prop.py b/vistrails/gui/version_prop.py
index 14da589..1244911 100644
--- a/vistrails/gui/version_prop.py
+++ b/vistrails/gui/version_prop.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -44,18 +45,56 @@ QVersionThumbs
 QVersionMashups
 
 """
+from __future__ import division
+
 import re
-import os.path
 from PyQt4 import QtCore, QtGui
-from vistrails.core.query.version import SearchCompiler, SearchParseError, TrueSearch
+from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core import debug
 from vistrails.core.thumbnails import ThumbnailCache
+from vistrails.core.utils import all
+from vistrails.core.vistrail.controller import custom_color_key, \
+    parse_custom_color
 from vistrails.gui.theme import CurrentTheme
-from vistrails.gui.common_widgets import QSearchBox
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
-from vistrails.core.utils import all
-from vistrails.core import debug
 
-################################################################################
+###############################################################################
+
+class ColorChooserButton(QtGui.QPushButton):
+    color_selected = QtCore.pyqtSignal(object)
+
+    def __init__(self, parent=None):
+        QtGui.QToolButton.__init__(self, parent)
+        self.setColor(None)
+
+        self.connect(self, QtCore.SIGNAL('clicked()'), self.changeColor)
+
+    def setColor(self, color, silent=True):
+        self.color = color
+        if color is not None:
+            self.setStyleSheet('ColorChooserButton {'
+                               'border: 1px solid black; '
+                               'background-color: rgb(%d, %d, %d); }' % (
+                               color.red(), color.green(), color.blue()))
+        else:
+            self.setStyleSheet('ColorChooserButton {'
+                               'border: 1px dashed black; }')
+        self.update()
+        if not silent:
+            self.color_selected.emit(self.color)
+
+    def sizeHint(self):
+        return QtCore.QSize(20, 20)
+
+    def changeColor(self):
+        if self.color is not None:
+            self.setColor(None, silent=False)
+        else:
+            color = QtGui.QColorDialog.getColor(QtCore.Qt.white, self)
+            if color.isValid():
+                self.setColor(color, silent=False)
+
+###############################################################################
 
 class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
     """
@@ -69,7 +108,7 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         
         """
         QtGui.QWidget.__init__(self, parent)
-        self.setWindowTitle('Properties')
+        self.setWindowTitle('Workflow Info')
 
         vLayout = QtGui.QVBoxLayout()
         vLayout.setMargin(2)
@@ -83,7 +122,7 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         gLayout.setRowMinimumHeight(0,20)
         gLayout.setRowMinimumHeight(1,20)
         gLayout.setRowMinimumHeight(2,20)
-        gLayout.setRowMinimumHeight(3,20)        
+        gLayout.setRowMinimumHeight(3,20)
         vLayout.addLayout(gLayout)
         
         tagLabel = QtGui.QLabel('Tag:', self)
@@ -97,7 +136,7 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         editLayout.addWidget(self.tagEdit)
         self.tagEdit.setEnabled(False)
         self.tagEdit.setMinimumHeight(22)
-        
+
         self.tagReset = QtGui.QToolButton(self)
         self.tagReset.setIcon(QtGui.QIcon(
                 self.style().standardPixmap(QtGui.QStyle.SP_DialogCloseButton)))
@@ -106,6 +145,14 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         self.tagReset.setEnabled(False)
         editLayout.addWidget(self.tagReset)
 
+        configuration = get_vistrails_configuration()
+        self.use_custom_colors = configuration.check('enableCustomVersionColors')
+
+        if self.use_custom_colors:
+            self.customColor = ColorChooserButton(self)
+            editLayout.addWidget(self.customColor)
+            self.customColor.color_selected.connect(self.custom_color_selected)
+
         gLayout.addLayout(editLayout, 0, 2, 1, 1)
 
         userLabel = QtGui.QLabel('User:', self)
@@ -154,11 +201,16 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         Assign the controller to the property page
         
         """
+        if self.controller == controller:
+            return
         self.controller = controller
         self.versionNotes.controller = controller
         self.versionThumbs.controller = controller
         self.versionMashups.controller = controller
-        self.updateVersion(controller.current_version)
+        if controller is not None:
+            self.updateVersion(controller.current_version)
+        else:
+            self.updateVersion(-1)
 
     def updateVersion(self, versionNumber):
         """ updateVersion(versionNumber: int) -> None
@@ -170,10 +222,33 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         self.versionThumbs.updateVersion(versionNumber)
         self.versionMashups.updateVersion(versionNumber)
         if self.controller:
-            if self.controller.vistrail.actionMap.has_key(versionNumber):
-                action = self.controller.vistrail.actionMap[versionNumber]
-                name = self.controller.vistrail.getVersionName(versionNumber)
-                self.tagEdit.setText(name)
+            vistrail = self.controller.vistrail
+            if self.use_custom_colors:
+                custom_color = vistrail.get_action_annotation(versionNumber,
+                                                              custom_color_key)
+                if custom_color is not None:
+                    try:
+                        custom_color = parse_custom_color(custom_color.value)
+                        custom_color = QtGui.QColor(*custom_color)
+                    except ValueError, e:
+                        debug.warning("Version %r has invalid color "
+                                      "annotation (%s)" % (versionNumber, e))
+                        custom_color = None
+                self.customColor.setColor(custom_color)
+
+            if vistrail.actionMap.has_key(versionNumber):
+                # Follow upgrades forward to find tag
+                tag = vistrail.search_upgrade_versions(
+                        versionNumber,
+                        lambda vt, v, bv: vt.getVersionName(v) or None) or ''
+
+                if getattr(get_vistrails_configuration(), 'hideUpgrades', True):
+                    base_ver = vistrail.get_base_upgrade_version(versionNumber)
+                else:
+                    base_ver = versionNumber
+
+                action = vistrail.actionMap[base_ver]
+                self.tagEdit.setText(tag)
                 self.userEdit.setText(action.user)
                 self.dateEdit.setText(action.date)
                 self.idEdit.setText(unicode(action.id))
@@ -182,12 +257,11 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
             else:
                 self.tagEdit.setEnabled(False)
                 self.tagReset.setEnabled(False)
-                
+
         self.tagEdit.setText('')
         self.userEdit.setText('')
         self.dateEdit.setText('')
         self.idEdit.setText('')
-        
 
     def tagFinished(self):
         """ tagFinished() -> None
@@ -215,6 +289,18 @@ class QVersionProp(QtGui.QWidget, QVistrailsPaletteInterface):
         self.tagEdit.setText('')
         self.tagFinished()
 
+    def custom_color_selected(self, color):
+        if color is not None:
+            self.controller.vistrail.set_action_annotation(
+                    self.controller.current_version, custom_color_key,
+                    '%d,%d,%d' % (color.red(), color.green(), color.blue()))
+        else:
+            self.controller.vistrail.set_action_annotation(
+                    self.controller.current_version, custom_color_key, None)
+        self.controller.set_changed(True)
+        self.controller.recompute_terse_graph()
+        self.controller.invalidate_version_tree()
+
 class QVersionNotes(QtGui.QTextEdit):
     """
     QVersionNotes is text widget that update/change a version notes
@@ -233,18 +319,21 @@ class QVersionNotes(QtGui.QTextEdit):
         # Reset text to black, for some reason it is grey by default on the mac
         self.palette().setBrush(QtGui.QPalette.Text,
                                 QtGui.QBrush(QtGui.QColor(0,0,0,255)))
-        
 
     def updateVersion(self, versionNumber):
         """ updateVersion(versionNumber: int) -> None
         Update the text to be the notes of the vistrail versionNumber
         
         """
+        if self.versionNumber == versionNumber:
+            return
         self.versionNumber = versionNumber
         if self.controller:
             if self.controller.vistrail.actionMap.has_key(versionNumber):
-                action = self.controller.vistrail.actionMap[versionNumber]
-                notes = self.controller.vistrail.get_notes(versionNumber)
+                # Follow upgrades forward to find notes
+                notes = self.controller.vistrail.search_upgrade_versions(
+                        versionNumber,
+                        lambda vt, v, bv: vt.get_notes(v) or None)
                 if notes:
                     self.setHtml(notes)
                     # work around a strange bug where an empty new paragraph gets added every time
@@ -259,7 +348,8 @@ class QVersionNotes(QtGui.QTextEdit):
 
     def commit_changes(self):
         if self.controller and self.document().isModified():
-            self.controller.update_notes(str(self.toHtml()))
+            self.controller.update_notes('' if self.document().isEmpty()
+                                         else str(self.toHtml()))
 
     def reset_changes(self):
         """ reset_changes() -> None
@@ -287,8 +377,8 @@ class QVersionNotes(QtGui.QTextEdit):
             cursor = QtGui.QTextCursor(doc)
             cursor.deleteChar()
 
+###############################################################################
 
-################################################################################
 class QVersionPropOverlay(QtGui.QFrame):
     """
     QVersionPropOverlay is a transparent widget that sits on top of the version
@@ -413,6 +503,8 @@ class QVersionPropOverlay(QtGui.QFrame):
         Assign the controller to the properties
         
         """
+        if self.controller == controller:
+            return
         self.controller = controller
         self.notes_dialog.updateController(controller)
 
@@ -421,17 +513,28 @@ class QVersionPropOverlay(QtGui.QFrame):
         Update the text items
         
         """
+
         self.notes_dialog.updateVersion(versionNumber)
         if self.controller:
             if self.controller.vistrail.actionMap.has_key(versionNumber):
-                action = self.controller.vistrail.actionMap[versionNumber]
-                name = self.controller.vistrail.getVersionName(versionNumber)
-                description = self.controller.vistrail.get_description(versionNumber)
-                self.tag.setText(self.truncate(name))
+                vistrail = self.controller.vistrail
+                # Follow upgrades forward to find tag
+                tag = vistrail.search_upgrade_versions(
+                        versionNumber,
+                        lambda vt, v, bv: vt.getVersionName(v) or None) or ''
+
+                if getattr(get_vistrails_configuration(), 'hideUpgrades', True):
+                    base_ver = vistrail.get_base_upgrade_version(versionNumber)
+                else:
+                    base_ver = versionNumber
+
+                action = vistrail.actionMap[base_ver]
+                description = vistrail.get_description(base_ver)
+                self.tag.setText(self.truncate(tag))
                 self.description.setText(self.truncate(description))
                 self.user.setText(self.truncate(action.user))
                 self.date.setText(self.truncate(action.date))
-                notes = self.controller.vistrail.get_notes(action.id)
+                notes = vistrail.get_notes(action.id)
                 if notes:
                     s = self.convertHtmlToText(notes)
                     self.notes.setText(self.truncate(s))
@@ -484,7 +587,8 @@ class QVersionPropOverlay(QtGui.QFrame):
                 return False
         return QtGui.QFrame.event(self, e)
 
-################################################################################
+###############################################################################
+
 class QExpandButton(QtGui.QLabel):
     """
     A transparent button type with a + draw in 
@@ -545,7 +649,8 @@ class QExpandButton(QtGui.QLabel):
         painter.end()
         self.setPicture(self.picture)
 
-################################################################################
+###############################################################################
+
 class QNotesDialog(QtGui.QDialog):
     """
     A small non-modal dialog with text entry to modify and view notes
@@ -627,8 +732,12 @@ class QNotesDialog(QtGui.QDialog):
         self.notes.updateVersion(versionNumber)
         if self.controller:
             if self.controller.vistrail.actionMap.has_key(versionNumber):
-                name = self.controller.vistrail.getVersionName(versionNumber)
-                title = "Notes: "+name
+                # Follow upgrades forward to find tag
+                tag = self.controller.vistrail.search_upgrade_versions(
+                        versionNumber,
+                        lambda vt, v, bv: vt.getVersionName(v) or None) or ''
+
+                title = "Notes: " + tag
                 self.setWindowTitle(title)
             else:
                 self.setWindowTitle("Notes")
@@ -639,7 +748,7 @@ class QNotesDialog(QtGui.QDialog):
         """
         return QtCore.QSize(250,200)
         
-################################################################################
+###############################################################################
 
 class QVersionThumbs(QtGui.QWidget):
     def __init__(self, parent=None):
@@ -672,22 +781,28 @@ class QVersionThumbs(QtGui.QWidget):
         if self.controller:
             vistrail = self.controller.vistrail
             if versionNumber in vistrail.actionMap.keys():
-                action = vistrail.actionMap[versionNumber]
-                if action and vistrail.has_thumbnail(action.id):
-                    cache = ThumbnailCache.getInstance()
-                    fname = cache.get_abs_name_entry(
-                        vistrail.get_thumbnail(action.id))
-                    if fname is not None:
-                        pixmap = QtGui.QPixmap(fname)
-                        self.thumbs.setPixmap(pixmap)
-                        self.thumbs.adjustSize()
-                    self.thumbs.setFrameShape(QtGui.QFrame.StyledPanel)
-                    return
-                
+                # Follow upgrades forward to find a thumbnail
+                thumb_ver = self.controller.vistrail.search_upgrade_versions(
+                        versionNumber,
+                        lambda vt, v, bv: v if vt.has_thumbnail(v) else None)
+                if thumb_ver is not None:
+                    action = vistrail.actionMap[thumb_ver]
+                    if vistrail.has_thumbnail(action.id):
+                        cache = ThumbnailCache.getInstance()
+                        fname = cache.get_abs_name_entry(
+                            vistrail.get_thumbnail(action.id))
+                        if fname is not None:
+                            pixmap = QtGui.QPixmap(fname)
+                            self.thumbs.setPixmap(pixmap)
+                            self.thumbs.adjustSize()
+                        self.thumbs.setFrameShape(QtGui.QFrame.StyledPanel)
+                        return
+
         self.thumbs.setPixmap(QtGui.QPixmap())
         self.thumbs.setFrameShape(QtGui.QFrame.NoFrame)
 
-################################################################################
+###############################################################################
+
 class QVersionMashups(QtGui.QWidget):
     def __init__(self, parent=None):
         QtGui.QWidget.__init__(self, parent)
diff --git a/vistrails/gui/version_view.py b/vistrails/gui/version_view.py
index 90784f5..eb8c279 100644
--- a/vistrails/gui/version_view.py
+++ b/vistrails/gui/version_view.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -44,21 +45,25 @@ QGraphicsVersionItem
 QVersionTreeScene
 QVersionTreeView
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
+from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core import debug
 from vistrails.core.system import systemType
 from vistrails.core.thumbnails import ThumbnailCache
+from vistrails.core.vistrail.controller import custom_color_key, \
+    parse_custom_color
+from vistrails.core.vistrail.vistrail import Vistrail
 from vistrails.gui.base_view import BaseView
 from vistrails.gui.graphics_view import (QInteractiveGraphicsScene,
                                QInteractiveGraphicsView,
-                               QGraphicsItemInterface,
-                               QGraphicsRubberBandItem)
+                               QGraphicsItemInterface)
 from vistrails.gui.qt import qt_super
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.version_prop import QVersionPropOverlay
-from vistrails.gui.vis_diff import QVisualDiff
 from vistrails.gui.collection.workspace import QParamExplorationEntityItem
 import vistrails.gui.utils
-import math
 
 
 ################################################################################
@@ -130,8 +135,8 @@ class QGraphicsLinkItem(QGraphicsItemInterface, QtGui.QGraphicsPolygonItem):
 
         # check if it is the same geometry 
         # improves performance on updates
-        if self.c1 != None and self.c2 != None and \
-                self.expand != None and self.collapse !=None:
+        if self.c1 is not None and self.c2 is not None and \
+                self.expand is not None and self.collapse !=None:
             isTheSame = self.c1 == c1 and \
                 self.c2 == c2 and \
                 self.expand == expand and \
@@ -477,7 +482,8 @@ class QGraphicsVersionItem(QGraphicsItemInterface, QtGui.QGraphicsEllipseItem):
                 self._versionPen = self._versionPenNormal
             self.updatePainterState()
 
-    def update_color(self, isThisUs, new_rank, new_max_rank, new_ghosted):
+    def update_color(self, isThisUs, new_rank, new_max_rank, new_ghosted,
+                     new_customcolor):
         """ update_color(isThisUs: bool,
                          new_rank, new_max_rank: int) -> None
 
@@ -487,22 +493,35 @@ class QGraphicsVersionItem(QGraphicsItemInterface, QtGui.QGraphicsEllipseItem):
         NOTE: if username changes during execution, this might break.
         """
         if (new_rank == self.rank and new_max_rank == self.max_rank and
-            new_ghosted == self.ghosted):
+            new_ghosted == self.ghosted and
+            new_customcolor == self.custom_color):
             # nothing changed
             return
         self.setGhosted(new_ghosted)
+        self.custom_color = new_customcolor
         self.rank = new_rank
         self.max_rank = new_max_rank
         if not self.ghosted:
-            if isThisUs:
-                brush = CurrentTheme.VERSION_USER_BRUSH
+            if self.custom_color is not None:
+                configuration = get_vistrails_configuration()
+                sat_from_rank = not configuration.check(
+                        'fixedCustomVersionColorSaturation')
+                brush = QtGui.QBrush(QtGui.QColor.fromRgb(*self.custom_color))
             else:
-                brush = CurrentTheme.VERSION_OTHER_BRUSH
-            sat = float(new_rank+1) / new_max_rank
-            (h, s, v, a) = brush.color().getHsvF()
-            newHsv = (h, s*sat, v+(1.0-v)*(1-sat), a)
-            self.versionBrush = QtGui.QBrush(QtGui.QColor.fromHsvF(*newHsv))
-                
+                if isThisUs:
+                    brush = CurrentTheme.VERSION_USER_BRUSH
+                else:
+                    brush = CurrentTheme.VERSION_OTHER_BRUSH
+                sat_from_rank = True
+            if sat_from_rank:
+                sat = float(new_rank+1) / new_max_rank
+                (h, s, v, a) = brush.color().getHsvF()
+                newHsv = (h, s*sat, v+(1.0-v)*(1-sat), a)
+                brush = QtGui.QBrush(brush)
+                brush.setColor(QtGui.QColor.fromHsvF(*newHsv))
+            self.versionBrush = brush
+        self.update()
+
     def setSaturation(self, isThisUser, sat):
         """ setSaturation(isThisUser: bool, sat: float) -> None        
         Set the color of this version depending on whose is the user
@@ -573,7 +592,7 @@ class QGraphicsVersionItem(QGraphicsItemInterface, QtGui.QGraphicsEllipseItem):
             textToDraw=self.label
         else:
             textToDraw=self.descriptionLabel
-        
+
         if (ThumbnailCache.getInstance().conf.mouseHover and
             action and action.thumbnail is not None):
             fname = ThumbnailCache.getInstance().get_abs_name_entry(action.thumbnail)
@@ -768,19 +787,17 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
         self.edges = {}     # (sourceVersion, targetVersion) -> edge gui object
         self.controller = None
         self.fullGraph = None
-        self.timer = QtCore.QBasicTimer()
-        self.animation_step = 1
-        self.num_animation_steps = 1
         self.emit_selection = True
         self.select_by_click = True
         self.connect(self, QtCore.SIGNAL("selectionChanged()"),
                      self.selectionChanged)
-   
+
     def addVersion(self, node, action, tag, description):
-        """ addModule(node, action: DBAction, tag: str, description: str) 
+        """ addModule(node, action: DBAction, tag: str, description: str,
+                custom_color: (int, int, int))
                 -> None
         Add a module to the scene.
-        
+
         """
         versionShape = QGraphicsVersionItem(None)
         versionShape.setupVersion(node, action, tag, description)
@@ -860,9 +877,24 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
             else:
                 max_rank = otherMaxRank
 #             max_rank = ourMaxRank if nodeUser==currentUser else otherMaxRank
+            configuration = get_vistrails_configuration()
+            if configuration.check('enableCustomVersionColors'):
+                custom_color = controller.vistrail.get_action_annotation(
+                    nodeId,
+                    custom_color_key)
+                if custom_color is not None:
+                    try:
+                        custom_color = parse_custom_color(custom_color.value)
+                    except ValueError, e:
+                        debug.warning("Version %r has invalid color annotation "
+                                      "(%s)" % (nodeId, e))
+                        custom_color = None
+            else:
+                custom_color = None
+            ####
             item.update_color(nodeUser==currentUser,
                               ranks[nodeId],
-                              max_rank, ghosted)
+                              max_rank, ghosted, custom_color)
         for (version_from, version_to), link in self.edges.iteritems():
             if self.versions[version_from].ghosted and \
                     self.versions[version_to].ghosted:
@@ -900,21 +932,21 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
 
         # update link items
         dst = controller._current_terse_graph.edges_from(new_version)
-        for eto, _ in dst:
+        for eto, (expand, collapse) in dst:
             edge = self.edges[(old_version, eto)]
             edge.setupLink(self.versions[new_version],
                            self.versions[eto],
-                           self.fullGraph.parent(eto) != new_version,
+                           expand,
                            False) # We shouldn't ever need a collapse here
             self.edges[(new_version, eto)] = edge
             del self.edges[(old_version, eto)]
 
         src = controller._current_terse_graph.edges_to(new_version)
-        for efrom, _ in src:
+        for efrom, (expand, collapse) in src:
             edge = self.edges[(efrom, old_version)]
             edge.setupLink(self.versions[efrom],
                            self.versions[new_version],
-                           self.fullGraph.parent(new_version) != efrom,
+                           expand,
                            False) # We shouldn't ever need a collapse here
             self.edges[(efrom, new_version)] = edge
             del self.edges[(efrom, old_version)]
@@ -924,23 +956,11 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
         Construct the scene to view a version tree
         
         """
-        import time
-        t = time.clock()
-
-        tClearRefine = time.clock()
-
-        # Clean the previous scene
-        # self.clear()
-
         self.select_by_click = False        
         self.controller = controller
 
         # perform graph layout
-        (tree, self.fullGraph, layout) = \
-            controller.refine_graph(float(self.animation_step)/
-                                    float(self.num_animation_steps))
-
-        tClearRefine = time.clock() - tClearRefine
+        (tree, self.fullGraph, layout) = controller.refine_graph()
 
         # compute nodes that should be removed
         # O(n  * (hashmap query key time)) on 
@@ -960,18 +980,16 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
 
         # loop on the nodes of the tree
         vistrail = controller.vistrail
-        tm = vistrail.get_tagMap()
         am = vistrail.actionMap
         last_n = vistrail.getLastActions(controller.num_versions_always_shown)
 
         self.emit_selection = False
         for node in layout.nodes.itervalues():
-
             # version id
             v = node.id
 
             # version tag
-            tag = tm.get(v, None)
+            tag = tree.vertices.get(v, None)
             action = am.get(v, None)
             description = vistrail.get_description(v)
 
@@ -982,12 +1000,11 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
             else:
                 self.addVersion(node, action, tag, description)
             if select_node:
-                self.versions[v].setSelected(v == controller.current_version)
+                self.versions[v].setSelected(v == controller.current_base_version)
 
         self.emit_selection = True
         self.selectionChanged()
 
-
         # remove gui edges from scene
         for (v1, v2) in removeEdgeSet:
             self.removeLink(v1,v2)
@@ -996,73 +1013,28 @@ class QVersionTreeScene(QInteractiveGraphicsScene):
         for v in removeNodeSet:
             self.removeVersion(v)
 
-        tCreate = time.clock()
-
         # adjust the colors
         self.adjust_version_colors(controller)
 
         # Add or update links
-        for source in tree.vertices.iterkeys():
+        for source, source_tag in tree.vertices.iteritems():
             eFrom = tree.edges_from(source)
-            for (target, aux) in eFrom:
+            for target, (expand, collapse) in eFrom:
                 guiSource = self.versions[source]
                 guiTarget = self.versions[target]
-                sourceChildren = [to for (to, _) in 
-                                  self.fullGraph.adjacency_list[source]
-                                  if (to in am) and not vistrail.is_pruned(to)]
-                targetChildren = [to for (to, _) in
-                                  self.fullGraph.adjacency_list[target]
-                                  if (to in am) and not vistrail.is_pruned(to)]
-                expand = self.fullGraph.parent(target)!=source
-                collapse = (self.fullGraph.parent(target)==source and # No in betweens
-                            len(targetChildren) == 1 and # target is not a leaf or branch
-                            target != controller.current_version and # target is not selected
-                            target not in tm and # target has no tag
-                            target not in last_n and # not one of the last n modules
-                            (source in tm or # source has a tag
-                             source == 0 or # source is root node
-                             len(sourceChildren) > 1 or # source is branching node 
-                             source == controller.current_version)) # source is selected
                 if self.edges.has_key((source,target)):
                     linkShape = self.edges[(source,target)]
                     linkShape.setupLink(guiSource, guiTarget,
                                         expand, collapse)
                 else:
-                    #print "add link %d %d" % (source, target)
                     self.addLink(guiSource, guiTarget, 
                                  expand, collapse)
 
-        tCreate = time.clock() - tCreate
-
         # Update bounding rects and fit to all view
-        tUpdate = time.clock()
-        if not self.controller.animate_layout:
-            self.updateSceneBoundingRect()
-        elif not self.timer.isActive():
-            self.timer.start(0, self)
-        tUpdate = time.clock() - tUpdate
+        self.updateSceneBoundingRect()
 
         self.select_by_click = True
 
-        t = time.clock() - t
-        # print "time in msec to setupScene total: %f  refine %f  layout %f  create %f" % (t, tClearRefine, tCreate)
-
-    def timerEvent(self, event):
-        """ timerEvent(event: QTimerEvent) -> None
-        
-        Start up a timer for animating tree drawing events
-        """
-        if event.timerId() == self.timer.timerId():
-            self.animation_step += 1
-            if self.animation_step >= self.num_animation_steps:
-                self.animation_step = 1
-                self.timer.stop()
-                self.controller.animate_layout = False
-            self.setupScene(self.controller)
-            self.update()
-        else:
-            qt_super(QVersionTreeScene, self).timerEvent(event)
-
     def keyPressEvent(self, event):
         """ keyPressEvent(event: QKeyEvent) -> None
         Capture 'Del', 'Backspace' for pruning versions when not editing a tag
@@ -1183,7 +1155,7 @@ class QVersionTreeView(QInteractiveGraphicsView, BaseView):
         return pipeline is not None and len(pipeline.modules) > 0
     
     def execute(self):
-        res = self.controller.execute_current_workflow()
+        res = self.controller.execute_user_workflow()
         from vistrails.gui.vistrails_window import _app
         if len(res[0][0].errors) > 0:
             _app.qactions['pipeline'].trigger()
@@ -1214,7 +1186,7 @@ class QVersionTreeView(QInteractiveGraphicsView, BaseView):
         items = self.scene().items(br)
         if len(items)==0 or items==[self.selectionBox]:
             for item in self.scene().selectedItems():
-                if isinstance(item, vistrails.gui.version_view.QGraphicsVersionItem):
+                if isinstance(item, QGraphicsVersionItem):
                     item.text.clearFocus()
         qt_super(QVersionTreeView, self).selectModules()
                 
@@ -1225,7 +1197,7 @@ class QVersionTreeView(QInteractiveGraphicsView, BaseView):
     def set_controller(self, controller):
         oldController = self.controller
         if oldController != controller:
-            if oldController != None:
+            if oldController is not None:
                 self.disconnect(oldController,
                                 QtCore.SIGNAL('vistrailChanged()'),
                                 self.vistrailChanged)
@@ -1296,4 +1268,3 @@ class QVersionTreeView(QInteractiveGraphicsView, BaseView):
 
     def select_current_version(self):
         self.scene().setupScene(self.controller)
-################################################################################
diff --git a/vistrails/gui/view_manager.py b/vistrails/gui/view_manager.py
deleted file mode 100644
index 55abd54..0000000
--- a/vistrails/gui/view_manager.py
+++ /dev/null
@@ -1,904 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-""" This holds a customized QTabWidget for controlling different
-vistrail views and tools
-
-QViewManager
-"""
-from PyQt4 import QtCore, QtGui
-from vistrails.gui.theme import CurrentTheme
-from vistrails.gui.utils import getBuilderWindow
-from vistrails.gui.vistrail_view import QVistrailView
-from vistrails.core import system, debug
-from vistrails.core.configuration import get_vistrails_configuration
-from vistrails.core.db.locator import FileLocator, XMLFileLocator, untitled_locator
-from vistrails.core.db.io import load_vistrail
-from vistrails.core.thumbnails import ThumbnailCache
-from vistrails.core.log.log import Log
-from vistrails.core.log.opm_graph import OpmGraph
-from vistrails.core.collection import Collection
-import vistrails.core.system
-from vistrails.core.vistrail.pipeline import Pipeline
-from vistrails.core.vistrail.tag import Tag
-from vistrails.core.vistrail.vistrail import Vistrail
-from vistrails.core.modules.module_registry import ModuleRegistry, \
-    ModuleRegistryException
-import copy
-
-################################################################################
-class QDetachedView(QtGui.QStackedWidget):
-    """
-    QDetachedView is a stacked widget holding detached views
-    (e.g. Pipeline, History, etc) from the main view manager.
-    
-    """
-    
-    def __init__(self, title, parent=None):
-        """ QDetachedView(parent: QWidget) -> QDetachedView
-        Create an empty stacked widget
-        
-        """
-        QtGui.QStackedWidget.__init__(self, parent)
-        self.title = title
-        self.setWindowTitle(self.title)
-
-    def sizeHint(self):
-        """ sizeHint() -> QRect
-        Return the recommended size of a detached view
-
-        """
-        return QtCore.QSize(800, 600)
-        
-
-################################################################################
-class QViewManager(QtGui.QTabWidget):
-    """
-    QViewManager is a tabbed widget to containing multiple Vistrail
-    views. It takes care of emiting useful signals to the builder
-    window
-    
-    """
-    def __init__(self, parent=None):
-        """ QViewManager(view: QVistrailView) -> QViewManager
-        Create an empty tab widget
-        
-        """
-        QtGui.QTabWidget.__init__(self, parent)
-        self.closeButton = QtGui.QToolButton(self)
-        self.closeButton.setIcon(CurrentTheme.VIEW_MANAGER_CLOSE_ICON)
-        self.closeButton.setAutoRaise(True)
-        self.setCornerWidget(self.closeButton)
-        self.activeIndex = -1
-        
-        self.connect(self, QtCore.SIGNAL('currentChanged(int)'),
-                     self.currentChanged)
-        self.connect(self.closeButton, QtCore.SIGNAL('clicked()'),
-                     self.closeVistrail)
-        
-        self._views = {}
-        self.single_document_mode = False
-        self.pip_mode = True
-
-        self.createDetachedViews()
-
-    def createDetachedViews(self):
-        """ createDetachedViews() -> None
-        Create a set of QStackedWidget for displaying detached views
-        based on the input configuration
-        
-        """
-        if getattr(get_vistrails_configuration(), 'detachHistoryView'):
-            self.historyView = QDetachedView('History View')
-            self.historyView.show()
-        else:
-            self.historyView = None
-        
-    def set_single_document_mode(self, on):
-        """ set_single_document_mode(on: bool) -> None
-        Toggle single document interface
-        
-        """
-        self.single_document_mode = on
-        if self.single_document_mode:
-            self.tabBar().hide()
-        else:
-            self.tabBar().show()
-
-    def add_vistrail_view(self, view):
-        """ add_vistrail_view(view: QVistrailView) -> None
-        Add a vistrail view to the tab, and connect to the right signals
-        
-        """
-        self._views[view] = view.controller
-        if self.indexOf(view)!=-1:
-            return
-
-        if self.historyView!=None:
-            self.historyView.addWidget(view.versionTab)
-                
-        view.installEventFilter(self)
-        self.connect(view.pipelineTab,
-                     QtCore.SIGNAL('moduleSelectionChange'),
-                     self.moduleSelectionChange)
-        self.connect(view,
-                     QtCore.SIGNAL('versionSelectionChange'),
-                     self.versionSelectionChange)
-        self.connect(view,
-                     QtCore.SIGNAL('execStateChange()'),
-                     self.execStateChange)
-        self.connect(view.versionTab,
-                     QtCore.SIGNAL('vistrailChanged()'),
-                     self.vistrailChanged)
-        self.connect(view.pipelineTab,
-                     QtCore.SIGNAL('resetQuery()'),
-                     self.resetQuery)
-        self.connect(view.versionTab,
-                     QtCore.SIGNAL('resetQuery()'),
-                     self.resetQuery)
-        self.connect(view.queryTab,
-                     QtCore.SIGNAL('resetQuery()'),
-                     self.resetQuery)
-
-        self.emit(QtCore.SIGNAL('vistrailViewAdded'), view)
-        self.addTab(view, view.windowTitle())
-        if self.count()==1:
-            self.emit(QtCore.SIGNAL('currentChanged(int)'), 0)
-
-    def removeVistrailView(self, view):
-        """ removeVistrailView(view: QVistrailView) -> None
-        Remove the current vistrail view and destroy it
-        
-        """
-        if view:
-            del self._views[view]
-            view.removeEventFilter(self)
-            self.disconnect(view.pipelineTab,
-                            QtCore.SIGNAL('moduleSelectionChange'),
-                            self.moduleSelectionChange)
-            self.disconnect(view,
-                            QtCore.SIGNAL('versionSelectionChange'),
-                            self.versionSelectionChange)
-            self.disconnect(view.versionTab,
-                            QtCore.SIGNAL('vistrailChanged()'),
-                            self.vistrailChanged)
-
-            # FIXME move this elsewhere?
-            self.disconnect(view.versionTab.versionView.scene(),
-                            QtCore.SIGNAL('selectionChanged()'),
-                            view.versionTab.versionView.scene().selectionChanged)
-            self.emit(QtCore.SIGNAL('vistrailViewRemoved'), view)
-            index = self.indexOf(view) 
-            if index !=-1:
-                if self.historyView:
-                    self.historyView.removeWidget(self.historyView.widget(self.currentIndex()))
-                self.removeTab(self.currentIndex())
-                self.activeIndex = self.currentIndex()
-            view.controller.cleanup()
-            view.close()
-            view.deleteLater()
-
-    def moduleSelectionChange(self, selection):
-        """ moduleSelectionChange(selection: list[id]) -> None
-        Just echo the signal from the view
-        
-        """
-        self.emit(QtCore.SIGNAL('moduleSelectionChange'), selection)
-
-    def versionSelectionChange(self, versionId):
-        """ versionSelectionChange(versionId: int) -> None
-        Just echo the signal from the view
-        
-        """
-        self.emit(QtCore.SIGNAL('versionSelectionChange'), versionId)
-
-    def execStateChange(self):
-        """ execStateChange() -> None
-        Just echo the signal from the view
-
-        """
-        self.emit(QtCore.SIGNAL('execStateChange()'))
-
-    def vistrailChanged(self):
-        """ vistrailChanged() -> None
-        Just echo the signal from the view
-        
-        """
-        self.emit(QtCore.SIGNAL('vistrailChanged()'))
-
-    def copySelection(self):
-        """ copySelection() -> None
-        Copy the current selected pipeline modules
-        
-        """
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().copySelection()
-
-    def group(self):
-        """group() -> None
-        Creates a group from the selected pipeline modules
-        
-        """
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().group()
-
-    def ungroup(self):
-        """ungroup() -> None
-        Ungroups selected pipeline modules
-        
-        """
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().ungroup()
-
-    def makeAbstraction(self):
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().makeAbstraction()
-    
-    def convertToAbstraction(self):
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().convertToAbstraction()
-
-    def importAbstraction(self):
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().importAbstraction()
-
-    def exportAbstraction(self):
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pipelineTab.pipelineView.scene().exportAbstraction()
-            
-    def currentView(self):
-        """currentView() -> VistrailView. Returns the current vistrail view."""
-        return self.currentWidget()
-
-    def pasteToCurrentPipeline(self):
-        """ pasteToCurrentPipeline() -> None
-        Paste what is on the clipboard to the current pipeline
-        
-        """        
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.pasteToCurrentTab()
-
-    def selectAllModules(self):
-        """ selectAllModules() -> None
-        Select all modules in the current view
-        
-        """
-        vistrailView = self.currentWidget()
-        if vistrailView:
-            vistrailView.selectAll()
-
-    def canSelectAll(self):
-        """ canSelectAll() -> bool        
-        Check to see if there is any module in the pipeline view to be
-        selected
-        
-        """
-        vistrailView = self.currentWidget()
-        if vistrailView and vistrailView.controller.current_pipeline:
-            return len(vistrailView.controller.current_pipeline.modules)>0
-        return False
-
-    def redo(self):
-        """ redo() -> none
-        Performs a redo step.
-
-        """
-        vistrailView = self.currentWidget()
-        if not vistrailView:
-            return
-        new_version = vistrailView.redo()
-        self.emit(QtCore.SIGNAL('versionSelectionChange'), new_version)
-
-    def undo(self):
-        """ undo() -> None
-        Performs an undo step.
-
-        """
-        vistrailView = self.currentWidget()
-        if not vistrailView:
-            return
-        new_version = vistrailView.undo()
-        self.emit(QtCore.SIGNAL('versionSelectionChange'), new_version)
-
-    def newVistrail(self, recover_files=True):
-        """ newVistrail() -> (None or QVistrailView)
-        Create a new vistrail with no name. If user cancels process,
-        returns None.
-
-        FIXME: We should do the interactive parts separately.
-        
-        """
-        if self.single_document_mode and self.currentView():
-            if not self.closeVistrail():
-                return None
-        if recover_files and untitled_locator().has_temporaries():
-            locator = copy.copy(untitled_locator())
-        else:
-            locator = None
-        try:
-            (vistrail, abstraction_files, thumbnail_files, _) = load_vistrail(locator)
-        except ModuleRegistryException, e:
-            debug.critical("Module registry error for %s" %
-                           str(e.__class__.__name__), str(e))
-        except Exception, e:
-            debug.critical('An error has occurred', str(e))
-            raise
-        return self.set_vistrail_view(vistrail, locator, abstraction_files,
-                                      thumbnail_files)
-
-    def close_first_vistrail_if_necessary(self):
-        # Close first vistrail of no change was made
-        if not self._first_view:
-            return
-        vt = self._first_view.controller.vistrail
-        if vt.get_version_count() == 0:
-            self.closeVistrail(self._first_view)
-            self._first_view = None
-        else:
-            # We set it to none, since it's been changed, so
-            # we don't want to ever close it again.
-            self._first_view = None
-
-    def set_vistrail_view(self, vistrail, locator, abstraction_files=None,
-                          thumbnail_files=None, version=None):
-        """set_vistrail_view(vistrail: Vistrail,
-                             locator: VistrailLocator,
-                             abstraction_files: list(str),
-                             thumbnail_files: list(str),
-                             version=None)
-                          -> QVistrailView
-        Sets a new vistrail view for the vistrail object for the given version
-        if version is None, use the latest version
-        """
-
-        if isinstance(version, basestring):
-            try:
-                version = vistrail.get_version_number(version)
-            except:
-                version = None
-
-        vistrailView = QVistrailView()
-        vistrailView.set_vistrail(vistrail, locator, abstraction_files,
-                                  thumbnail_files)
-        self.add_vistrail_view(vistrailView)
-        self.setCurrentWidget(vistrailView)
-        vistrailView.setup_view(version)
-        vistrailView.setPIPMode(self.pip_mode)
-        self.versionSelectionChange(vistrailView.controller.current_version)
-        return vistrailView
-
-    def open_vistrail(self, locator, version=None, is_abstraction=False):
-        """open_vistrail(locator: Locator, version = None: int or str,
-                         is_abstraction: bool)
-
-        opens a new vistrail from the given locator, selecting the
-        given version.
-
-        """
-        self.close_first_vistrail_if_necessary()
-        if self.single_document_mode and self.currentView():
-            self.closeVistrail()
-        view = self.ensureVistrail(locator)
-        if view:
-            if version is not None:
-                if isinstance(version, basestring):
-                    try:
-                        version = view.vistrail.get_version_number(version)
-                    except:
-                        version = None
-                if version is not None:
-                    view.setup_view(version)
-            return view
-        try:
-            (vistrail, abstraction_files, thumbnail_files, _) = \
-                                        load_vistrail(locator, is_abstraction)
-            result = self.set_vistrail_view(vistrail, locator, 
-                                            abstraction_files, thumbnail_files,
-                                            version)
-            # update collection
-            try:
-                vistrail.thumbnails = thumbnail_files
-                vistrail.abstractions = abstraction_files
-                collection = Collection.getInstance()
-                url = locator.to_url()
-                # create index if not exist
-                entity = collection.fromUrl(url)
-                if entity:
-                    # find parent vistrail
-                    while entity.parent:
-                        entity = entity.parent 
-                else:
-                    entity = collection.updateVistrail(url, vistrail)
-                # add to relevant workspace categories
-                collection.add_to_workspace(entity)
-                collection.commit()
-            except Exception, e:
-                import traceback
-                debug.critical('Failed to index vistrail', str(e) + traceback.format_exc())
-            return result
-        except ModuleRegistryException, e:
-            debug.critical("Module registry error for %s" %
-                           str(e.__class__.__name__), str(e))
-        except Exception, e:
-            import traceback
-            debug.critical('An error has occurred', str(e) + traceback.format_exc())
-            raise
-        
-    def save_vistrail(self, locator_class,
-                      vistrailView=None,
-                      force_choose_locator=False):
-        """
-
-        force_choose_locator=True triggers 'save as' behavior
-        """
-        global bobo
-
-        if not vistrailView:
-            vistrailView = self.currentWidget()
-        vistrailView.flush_changes()
-        if vistrailView:
-            gui_get = locator_class.save_from_gui
-            # get a locator to write to
-            if force_choose_locator:
-                locator = gui_get(self, Vistrail.vtType,
-                                  vistrailView.controller.locator)
-            else:
-                locator = (vistrailView.controller.locator or
-                           gui_get(self, Vistrail.vtType,
-                                   vistrailView.controller.locator))
-            if locator == untitled_locator():
-                locator = gui_get(self, Vistrail.vtType,
-                                  vistrailView.controller.locator)
-            # if couldn't get one, ignore the request
-            if not locator:
-                return False
-            # update collection
-            vistrailView.controller.flush_delayed_actions()
-            try:
-                vistrailView.controller.write_vistrail(locator)
-            except Exception, e:
-                debug.critical('An error has occurred', str(e))
-                raise
-                return False
-            try:
-                thumb_cache = ThumbnailCache.getInstance()
-                vistrailView.controller.vistrail.thumbnails = \
-                    vistrailView.controller.find_thumbnails(
-                        tags_only=thumb_cache.conf.tagsOnly)
-                vistrailView.controller.vistrail.abstractions = \
-                    vistrailView.controller.find_abstractions(
-                        vistrailView.controller.vistrail, True)
-
-                collection = Collection.getInstance()
-                url = locator.to_url()
-                # create index if not exist
-                entity = collection.fromUrl(url)
-                if entity:
-                    # find parent vistrail
-                    while entity.parent:
-                        entity = entity.parent 
-                else:
-                    entity = collection.updateVistrail(url, vistrailView.controller.vistrail)
-                # add to relevant workspace categories
-                collection.add_to_workspace(entity)
-                collection.commit()
-            except Exception, e:
-                debug.critical('Failed to index vistrail', str(e))
-            return locator
-        return False
-   
-    def open_workflow(self, locator, version=None):
-        self.close_first_vistrail_if_necessary()
-        if self.single_document_mode and self.currentView():
-            self.closeVistrail()
-
-        vistrail = Vistrail()
-        try:
-            if locator is not None:
-                workflow = locator.load(Pipeline)
-                action_list = []
-                for module in workflow.module_list:
-                    action_list.append(('add', module))
-                for connection in workflow.connection_list:
-                    action_list.append(('add', connection))
-                action = vistrails.core.db.action.create_action(action_list)
-                vistrail.add_action(action, 0L)
-                vistrail.update_id_scope()
-                vistrail.addTag("Imported workflow", action.id)
-                # FIXME might need different locator?
-        except ModuleRegistryException, e:
-            msg = ('Cannot find module "%s" in package "%s". '
-                    'Make sure package is ' 
-                   'enabled in the Preferences dialog.' % \
-                       (e._name, e._identifier))
-            debug.critical(msg)
-        except Exception, e:
-            debug.critical('An error has occurred', str(e))
-            raise
-
-        return self.set_vistrail_view(vistrail, None)
-
-    # FIXME normalize workflow/log/registry!!!
-    def save_workflow(self, locator_class, force_choose_locator=True):
-        vistrailView = self.currentWidget()
-
-        if vistrailView:
-            vistrailView.flush_changes()
-            gui_get = locator_class.save_from_gui
-            if force_choose_locator:
-                locator = gui_get(self, Pipeline.vtType,
-                                  vistrailView.controller.locator)
-            else:
-                locator = (vistrailView.controller.locator or
-                           gui_get(self, Pipeline.vtType,
-                                   vistrailView.controller.locator))
-            if locator == untitled_locator():
-                locator = gui_get(self, Pipeline.vtType,
-                                  vistrailView.controller.locator)
-            if not locator:
-                return False
-            vistrailView.controller.write_workflow(locator)
-            return True
-        return False
-
-    def save_log(self, locator_class, force_choose_locator=True):
-        vistrailView = self.currentWidget()
-
-        if vistrailView:
-            vistrailView.flush_changes()
-            gui_get = locator_class.save_from_gui
-            if force_choose_locator:
-                locator = gui_get(self, Log.vtType,
-                                  vistrailView.controller.locator)
-            else:
-                locator = (vistrailView.controller.locator or
-                           gui_get(self, Log.vtType,
-                                   vistrailView.controller.locator))
-            if locator == untitled_locator():
-                locator = gui_get(self, Log.vtType,
-                                  vistrailView.controller.locator)
-            if not locator:
-                return False
-            vistrailView.controller.write_log(locator)
-            return True
-        return False
-
-    def save_registry(self, locator_class, force_choose_locator=True):
-        vistrailView = self.currentWidget()
-
-        if vistrailView:
-            vistrailView.flush_changes()
-            gui_get = locator_class.save_from_gui
-            if force_choose_locator:
-                locator = gui_get(self, ModuleRegistry.vtType,
-                                  vistrailView.controller.locator)
-            else:
-                locator = (vistrailView.controller.locator or
-                           gui_get(self, ModuleRegistry.vtType,
-                                   vistrailView.controller.locator))
-            if locator == untitled_locator():
-                locator = gui_get(self, ModuleRegistry.vtType,
-                                  vistrailView.controller.locator)
-            if not locator:
-                return False
-            vistrailView.controller.write_registry(locator)
-            return True
-        return False
-
-    def save_opm(self, locator_class=XMLFileLocator, 
-                 force_choose_locator=True):
-        vistrailView = self.currentWidget()
-
-        if vistrailView:
-            vistrailView.flush_changes()
-            gui_get = locator_class.save_from_gui
-            if force_choose_locator:
-                locator = gui_get(self, OpmGraph.vtType,
-                                  vistrailView.controller.locator)
-            else:
-                locator = (vistrailView.controller.locator or
-                           gui_get(self, OpmGraph.vtType,
-                                   vistrailView.controller.locator))
-            if locator == untitled_locator():
-                locator = gui_get(self, OpmGraph.vtType,
-                                  vistrailView.controller.locator)
-            if not locator:
-                return False
-            vistrailView.controller.write_opm(locator)
-            return True
-        return False
-             
-    def export_stable(self, locator_class=XMLFileLocator,
-                      force_choose_locator=True):
-        vistrailView = self.currentWidget()
-        vistrailView.flush_changes()
-
-        if vistrailView:
-            vistrailView.flush_changes()
-            gui_get = locator_class.save_from_gui
-            if force_choose_locator:
-                locator = gui_get(self, Vistrail.vtType,
-                                  vistrailView.controller.locator)
-            else:
-                locator = (vistrailView.controller.locator or
-                           gui_get(self, Vistrail.vtType,
-                                   vistrailView.controller.locator))
-            if locator == untitled_locator():
-                locator = gui_get(self, Vistrail.vtType,
-                                  vistrailView.controller.locator)
-            if not locator:
-                return False
-            vistrailView.controller.write_vistrail(locator, '1.0.1')
-            return True
-        return False
-
-    def closeVistrail(self, vistrailView=None, quiet=False):
-        """ closeVistrail(vistrailView: QVistrailView, quiet: bool) -> bool
-        Close the current active vistrail
-        
-        """
-        if not vistrailView:
-            vistrailView = self.currentWidget()
-        vistrailView.flush_changes()
-
-        if vistrailView:
-            if not quiet and vistrailView.controller.changed:
-                text = vistrailView.controller.name
-                if text=='':
-                    text = 'Untitled%s'%vistrails.core.system.vistrails_default_file_type()
-                text = ('Vistrail ' +
-                        QtCore.Qt.escape(text) +
-                        ' contains unsaved changes.\n Do you want to '
-                        'save changes before closing it?')
-                res = QtGui.QMessageBox.information(getBuilderWindow(),
-                                                    'Vistrails',
-                                                    text, 
-                                                    '&Save', 
-                                                    '&Discard',
-                                                    'Cancel',
-                                                    0,
-                                                    2)
-            else:
-                res = 1
-            locator = vistrailView.controller.locator
-            if res == 0:
-                if locator is None:
-                    class_ = FileLocator()
-                else:
-                    class_ = type(locator)
-                locator = self.save_vistrail(class_)
-                if not locator:
-                    return False
-            elif res == 2:
-                return False
- 
-            vistrailView.controller.close_vistrail(locator)
-            self.removeVistrailView(vistrailView)
-            if self.count()==0:
-                self.emit(QtCore.SIGNAL('currentVistrailChanged'), None)
-                self.emit(QtCore.SIGNAL('versionSelectionChange'), -1)
-        if vistrailView == self._first_view:
-            self._first_view = None
-        return True
-    
-    def closeAllVistrails(self):
-        """ closeAllVistrails() -> bool        
-        Attemps to close every single vistrail, return True if
-        everything is closed correctly
-        
-        """
-        while self.count()>0:
-            if not self.closeVistrail():
-                return False
-        return True
-
-    def currentChanged(self, index):
-        """ currentChanged(index: int):        
-        Emit signal saying a different vistrail has been chosen to the
-        builder
-        
-        """
-        self.activeIndex = index
-        self.emit(QtCore.SIGNAL('currentVistrailChanged'),
-                  self.currentWidget())
-        if index >= 0:
-            self.emit(QtCore.SIGNAL('versionSelectionChange'), 
-                      self.currentWidget().controller.current_version)
-        else:
-            self.emit(QtCore.SIGNAL('versionSelectionChange'), 
-                      -1)
-        if self.historyView:
-            self.historyView.setCurrentIndex(index)
-            if self.currentView()!=None:
-                self.historyView.setWindowTitle('History View - ' +
-                                                self.currentView().windowTitle())
-        
-    def eventFilter(self, object, event):
-        """ eventFilter(object: QVistrailView, event: QEvent) -> None
-        Filter the window title change event for the view widget
-        
-        """
-        if event.type()==QtCore.QEvent.WindowTitleChange:
-            if object==self.currentWidget():
-                self.setTabText(self.currentIndex(), object.windowTitle())
-                self.currentChanged(self.currentIndex())
-        return QtGui.QTabWidget.eventFilter(self, object, event)
-
-    def getCurrentVistrailFileName(self):
-        """ getCurrentVistrailFileName() -> str        
-        Return the filename of the current vistrail or None if it
-        doesn't have one
-        
-        """        
-        vistrailView = self.currentWidget()
-        if vistrailView and vistrailView.controller.name!='':
-            return vistrailView.controller.name
-        else:
-            return None
-
-    def setPIPMode(self, on):
-        """ setPIPMode(on: Bool) -> None
-        Set the picture-in-picture mode for all views
-        
-        """
-        self.pip_mode = on
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setPIPMode(on)
-
-    def setMethodsMode(self, on):
-        """ setMethodsMode(on: Bool) -> None
-        Turn the methods panel on/off for all views
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setMethodsMode(on)
-
-
-    def setSetMethodsMode(self, on):
-        """ setSetMethodsMode(on: Bool) -> None
-        Turn the set methods panel on/off for all views
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setSetMethodsMode(on)
-
-    def setPropertiesMode(self, on):
-        """ setPropertiesMode(on: Bool) -> None
-        Turn the properties panel on/off for all views
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setPropertiesMode(on)
-
-    def setPropertiesOverlayMode(self, on):
-        """ setPropertiesOverlayMode(on: Bool) -> None
-        Turn the properties overlay panel on/off for all views
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setPropertiesOverlayMode(on)
-            
-    def setModuleConfigMode(self, on):
-        """ setModuleConfigMode(on: Bool) -> None
-        Turn the module configuration panel on/off for all views
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setModuleConfigMode(on)
-            
-    def setVistrailVarsMode(self, on):
-        """ setVistrailVarsMode(on: Bool) -> None
-        Turn the vistrail variables panel on/off for all views
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            vistrailView.setVistrailVarsMode(on)
-            
-    def ensureVistrail(self, locator):
-        """ ensureVistrail(locator: VistrailLocator) -> QVistrailView        
-        This will first find among the opened vistrails to see if
-        vistrails from locator has been opened. If not, it will return None.
-        
-        """
-        for i in xrange(self.count()):
-            view = self.widget(i)
-            if view.controller.vistrail.locator == locator:
-                self.setCurrentWidget(view)
-                return view
-        return None
-    
-    def set_first_view(self, view):
-        self._first_view = view
-
-    def viewModeChanged(self, mode):
-        """ viewModeChanged(mode: int) -> None
-        
-        """
-        for viewIndex in xrange(self.count()):
-            vistrailView = self.widget(viewIndex)
-            if self.historyView!=None and mode>1:
-                vistrailView.viewModeChanged(mode-1)
-            else:
-                vistrailView.viewModeChanged(mode)
-    
-    def changeCursor(self, mode):
-        """ changeCursor(mode: Int) -> None
-        
-        """
-        for viewIndex in xrange(self.count()):            
-            vistrailView = self.widget(viewIndex)
-            vistrailView.updateCursorState(mode)            
-        
-    def resetQuery(self):
-        """ resetQwuery() -> None
-        
-        """
-        self.queryVistrail(False)
-
-    def queryVistrail(self, on=True):
-        """ queryVistrail(on: bool) -> None
-        
-        """
-        self.currentView().setFocus(QtCore.Qt.MouseFocusReason)
-        self.currentView().queryVistrail(on)
-
-    def executeCurrentPipeline(self):
-        """ executeCurrentPipeline() -> None
-        
-        """
-        self.currentView().setFocus(QtCore.Qt.MouseFocusReason)
-        self.currentView().checkModuleConfigPanel()
-        self.currentView().controller.execute_current_workflow()
-
-    def executeCurrentExploration(self):
-        """ executeCurrentExploration() -> None
-        
-        """
-        self.currentView().setFocus(QtCore.Qt.MouseFocusReason)
-        self.currentView().executeParameterExploration()
diff --git a/vistrails/gui/vis_diff.py b/vistrails/gui/vis_diff.py
index c89c548..637d5f7 100644
--- a/vistrails/gui/vis_diff.py
+++ b/vistrails/gui/vis_diff.py
@@ -1,41 +1,45 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This modules builds a widget to interact with vistrail diff
 operation """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.system import get_vistrails_basic_pkg_id
+from vistrails.core.utils import VistrailsInternalError
 from vistrails.core.utils.color import ColorByName
 from vistrails.core.vistrail.abstraction import Abstraction
 from vistrails.core.vistrail.pipeline import Pipeline
@@ -291,7 +295,8 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
         g_layout.addWidget(self.legend)
         legend_group.setLayout(g_layout)
         layout.addWidget(legend_group)
-
+        layout.setStretch(0,0)
+        layout.addStretch(1)
         self.params = QParamTable()
         params_group = QtGui.QGroupBox("Parameter Changes")
         g_layout = QtGui.QVBoxLayout()
@@ -300,6 +305,28 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
         g_layout.addWidget(self.params)
         params_group.setLayout(g_layout)
         layout.addWidget(params_group)
+        layout.setStretch(2,1000)
+
+        self.cparams = QParamTable()
+        params_group = QtGui.QGroupBox("Control Parameter Changes")
+        g_layout = QtGui.QVBoxLayout()
+        g_layout.setMargin(0)
+        g_layout.setSpacing(0)
+        g_layout.addWidget(self.cparams)
+        params_group.setLayout(g_layout)
+        layout.addWidget(params_group)
+        layout.setStretch(3,1000)
+        
+        self.annotations = QParamTable()
+        params_group = QtGui.QGroupBox("Annotation Changes")
+        g_layout = QtGui.QVBoxLayout()
+        g_layout.setMargin(0)
+        g_layout.setSpacing(0)
+        g_layout.addWidget(self.annotations)
+        params_group.setLayout(g_layout)
+        layout.addWidget(params_group)
+        layout.setStretch(3,1000)
+        
         self.setLayout(layout)
         self.addButtonsToToolbar()
 
@@ -332,7 +359,7 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
         result = str(result)
         try:
             self.controller.add_analogy(result, version_a, version_b)
-        except:
+        except VistrailsInternalError:
             debug.critical("Analogy name already exists")
 
     def set_diff(self):
@@ -340,8 +367,6 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
             return
         ((vistrail_a, version_a), (vistrail_b, version_b)) = \
             self.controller.current_diff_versions
-        (p1, p2, v1Andv2, heuristicMatch, v1Only, v2Only, paramChanged) = \
-            self.controller.current_diff
 
         # Set up the version name correctly
         v1_name = vistrail_a.getVersionName(version_a)
@@ -366,10 +391,14 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
         
         self.legend.set_names(v1_name, v2_name)
         self.params.set_names(v1_name, v2_name)
+        self.cparams.set_names(v1_name, v2_name)
+        self.annotations.set_names(v1_name, v2_name)
+        self.update_module()
 
     def set_controller(self, controller=None):
         self.controller = controller
-        self.set_diff()
+        if self.controller is not None:
+            self.set_diff()
         
     def update_module(self, module=None):
         """ moduleSelected(id: int, selectedItems: [QGraphicsItem]) -> None
@@ -379,11 +408,16 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
         """
         if module is None or not hasattr(self.controller, 'current_diff'):
             self.params.model().clearList()
+            self.params.parent().setVisible(False)
+            self.cparams.model().clearList()
+            self.cparams.parent().setVisible(False)
+            self.annotations.model().clearList()
+            self.annotations.parent().setVisible(False)
             return
         
-        # Interprete the diff result and setup item models
-        (p1, p2, v1Andv2, heuristicMatch, v1Only, v2Only, paramChanged) = \
-            self.controller.current_diff
+        # Interpret the diff result and setup item models
+        (p1, p2, v1Andv2, heuristicMatch, v1Only, v2Only, paramChanged,
+         cparamChanged, annotChanged) = self.controller.current_diff
 
         # # Set the window title
         # if id>self.maxId1:
@@ -395,15 +429,18 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
 
         # FIXME set the module name/package info?
             
-        # Clear the old inspector
-        param_model = self.params.model()
-        # annotations = self.inspector.annotationsTab.model()
-        param_model.clearList()
-        # annotations.clearList()
+        to_text = lambda x:'%s(%s)' % (x[0], ','.join(v[1] for v in x[1]))
+        self.setTable(module, paramChanged, self.params, to_text)
+        to_text = lambda x:'%s(%s)' % (x[0], x[1])
+        self.setTable(module, cparamChanged, self.cparams, to_text)
+        self.setTable(module, annotChanged, self.annotations, to_text)
 
+    def setTable(self, module, changed, table, to_text):
         # Find the parameter changed module
+        model = table.model()
+        model.clearList()
         matching = None
-        for ((m1id, m2id), paramMatching) in paramChanged:
+        for ((m1id, m2id), paramMatching) in changed:
             if m1id == module.id:
                 #print "found match"
                 matching = paramMatching
@@ -412,26 +449,24 @@ class QDiffProperties(QtGui.QWidget, QVistrailsPaletteInterface):
         #print "matching:", matching
         # If the module has no parameter changed, just display nothing
         if not matching:          
+            table.parent().setVisible(False)
             return
         
+        table.parent().setVisible(True)
+
         # Else just layout the diff on a table
-        param_model.insertRows(0,len(matching))
+        model.insertRows(0,len(matching))
         currentRow = 0
         for (f1, f2) in matching:
             if f1[0]!=None:
-                param_model.setData(
-                    param_model.index(currentRow, 0),
-                    '%s(%s)' % (f1[0], ','.join(v[1] for v in f1[1])))
+                model.setData(model.index(currentRow, 0), to_text(f1))
             if f2[0]!=None:
-                param_model.setData(
-                    param_model.index(currentRow, 1),
-                    '%s(%s)' % (f2[0], ','.join(v[1] for v in f2[1])))
+                model.setData(model.index(currentRow, 1), to_text(f2))
             if f1==f2:
-                param_model.disableRow(currentRow)
+                model.disableRow(currentRow)
             currentRow += 1
 
-        self.params.resizeRowsToContents()
-        # self.inspector.annotationsTab.resizeRowsToContents()
+        table.resizeRowsToContents()
 
 class QDiffView(QPipelineView):
     def __init__(self, parent=None):
@@ -521,8 +556,8 @@ class QDiffView(QPipelineView):
         self.set_diff_version_names()
         self.diff = vistrails.core.db.io.get_workflow_diff(*self.diff_versions)
             # self.controller.vistrail.get_pipeline_diff(version_a, version_b)
-        (p1, p2, v1Andv2, heuristicMatch, v1Only, v2Only, paramChanged) = \
-            self.diff
+        (p1, p2, v1Andv2, heuristicMatch, v1Only, v2Only, paramChanged,
+         cparamChanged, annotChanged) = self.diff
         # print "  $$$ v1Andv2:", v1Andv2
         # print "  $$$ heuristicMatch:", heuristicMatch
         # print "  $$$ v1Only", v1Only
@@ -635,10 +670,11 @@ class QDiffView(QPipelineView):
             p_both.add_module(copy.copy(p1.modules[m1id]))
 
         # Then add parameter changed version
-        for ((m1id, m2id), matching) in paramChanged:
+        inChanged = set(m for (m, matching)
+                        in chain(paramChanged, cparamChanged, annotChanged))
+        for (m1id, m2id) in inChanged:
             m1 = p1.modules[m1id]
             m2 = p2.modules[m2id]
-            
             sum1_x += p1.modules[m1id].location.x
             sum1_y += p1.modules[m1id].location.y
             sum2_x += p2.modules[m2id].location.x
@@ -721,7 +757,7 @@ class QDiffView(QPipelineView):
         for (m1id, m2id) in heuristicMatch:
             v1Tov2[m1id] = m2id
             v2Tov1[m2id] = m1id
-        for ((m1id, m2id), matching) in paramChanged:
+        for (m1id, m2id) in inChanged:
             v1Tov2[m1id] = m2id
             v2Tov1[m2id] = m1id
 
@@ -900,7 +936,7 @@ class QVisualDiff(QtGui.QMainWindow):
         result = str(result)
         try:
             self.controller.add_analogy(result, self.v1, self.v2)
-        except:
+        except VistrailsInternalError:
             debug.critical("Analogy name already exists")
         
     def createToolWindows(self, v1Name, v2Name):
diff --git a/vistrails/gui/vistrail_controller.py b/vistrails/gui/vistrail_controller.py
index c670e3d..0fa629f 100644
--- a/vistrails/gui/vistrail_controller.py
+++ b/vistrails/gui/vistrail_controller.py
@@ -1,86 +1,101 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
+from __future__ import division
+
+import copy
+import math
+import os
+import uuid
+
 from PyQt4 import QtCore, QtGui
-from vistrails.core.common import *
+
+import vistrails.core.analogy
 from vistrails.core.configuration import get_vistrails_configuration
+from vistrails.core.data_structures.graph import Graph
 from vistrails.core import debug
 import vistrails.core.db.action
-import vistrails.core.db.locator
-import vistrails.core.modules.vistrails_module
-from vistrails.core.utils import VistrailsInternalError, InvalidPipeline
+from vistrails.core.interpreter.default import get_default_interpreter
+from vistrails.core.vistrail.job import Workflow as JobWorkflow
 from vistrails.core.layout.version_tree_layout import VistrailsTreeLayoutLW
 from vistrails.core.log.opm_graph import OpmGraph
 from vistrails.core.log.prov_document import ProvDocument
 from vistrails.core.modules.abstraction import identifier as abstraction_pkg
-from vistrails.core.modules.module_registry import get_module_registry, MissingPort
-from vistrails.core.modules.package import Package
-from vistrails.core.packagemanager import PackageManager
+from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.param_explore import ActionBasedParameterExploration
 from vistrails.core.query.version import TrueSearch
 from vistrails.core.query.visual import VisualQuery
-from vistrails.core.param_explore import ActionBasedParameterExploration
+from vistrails.core.utils import DummyView, VistrailsInternalError, InvalidPipeline
 import vistrails.core.system
-
-from vistrails.core.vistrail.annotation import Annotation
-from vistrails.core.vistrail.controller import VistrailController as BaseController, \
-    vt_action
-from vistrails.core.vistrail.location import Location
-from vistrails.core.vistrail.module import Module
-from vistrails.core.vistrail.module_function import ModuleFunction
-from vistrails.core.vistrail.module_param import ModuleParam
+from vistrails.core.vistrail.controller import VistrailController as BaseController
 from vistrails.core.vistrail.pipeline import Pipeline
-from vistrails.core.vistrail.port_spec import PortSpec
 from vistrails.core.vistrail.vistrail import Vistrail, TagExists
-from vistrails.core.interpreter.default import get_default_interpreter
 from vistrails.gui.pipeline_view import QPipelineView
 from vistrails.gui.theme import CurrentTheme
+import vistrails.gui.utils
 from vistrails.gui.utils import show_warning, show_question, YES_BUTTON, NO_BUTTON
 from vistrails.gui.version_prop import QVersionProp
 
-import vistrails.core.analogy
-import copy
-import os.path
-import math
 
-import unittest
-import vistrails.gui.utils
-import vistrails.api
-import os
-from vistrails.core.utils import DummyView
 
 ################################################################################
 
+class ExecutionProgressDialog(QtGui.QProgressDialog):
+    def __init__(self, parent=None):
+        QtGui.QProgressDialog.__init__(self, 'Executing Workflow',
+                                       '&Cancel',
+                                       0, 100,
+                                       parent, QtCore.Qt.Dialog)
+        self.setWindowTitle('Executing')
+        self.setWindowModality(QtCore.Qt.WindowModal)
+        self._last_set_value = 0
+        self._progress_canceled = False
+        # if suspended is true we should not wait for a job to complete
+        self.suspended = False
+
+    def setValue(self, value):
+        self._last_set_value = value
+        super(ExecutionProgressDialog, self).setValue(value)
+
+    def goOn(self):
+        self.reset()
+        self.show()
+        super(ExecutionProgressDialog, self).setValue(self._last_set_value)
+
+
 class VistrailController(QtCore.QObject, BaseController):
     """
     VistrailController is the class handling all action control in
@@ -135,6 +150,8 @@ class VistrailController(QtCore.QObject, BaseController):
         self.reset_pipeline_view = False
         self.reset_version_view = True
         self.quiet = False
+        self.progress = None
+        self.create_job = False
         
         self.analogy = {}
         # if self._auto_save is True, an auto_saving timer will save a temporary
@@ -143,8 +160,6 @@ class VistrailController(QtCore.QObject, BaseController):
         self.timer = None
         if self._auto_save:
             self.setup_timer()
-        
-        self._previous_graph_layout = None
 
         def width_f(text):
             return CurrentTheme.VERSION_FONT_METRIC.width(text)
@@ -153,7 +168,6 @@ class VistrailController(QtCore.QObject, BaseController):
                                   CurrentTheme.VERSION_FONT_METRIC.height(), 
                                   CurrentTheme.VERSION_LABEL_MARGIN[0], 
                                   CurrentTheme.VERSION_LABEL_MARGIN[1])
-        self.animate_layout = False
         #this was moved to BaseController
         #self.num_versions_always_shown = 1
         BaseController.__init__(self, vistrail, locator, abstractions, 
@@ -221,7 +235,6 @@ class VistrailController(QtCore.QObject, BaseController):
         
         """
         self.reset_version_view = reset_version_view
-        self.animate_layout = animate_layout
         #FIXME: in the future, rename the signal
         try:
             self.emit(QtCore.SIGNAL('vistrailChanged()'))
@@ -252,7 +265,7 @@ class VistrailController(QtCore.QObject, BaseController):
     def get_locator(self):
         from vistrails.gui.application import get_vistrails_application
         if (self._auto_save and 
-            get_vistrails_application().configuration.check('autosave')):
+            get_vistrails_application().configuration.check('autoSave')):
             if self.locator is None:
                 raise ValueError("locator is None")
             return self.locator
@@ -330,16 +343,18 @@ class VistrailController(QtCore.QObject, BaseController):
         return self.create_abstraction(module_ids, connection_ids, name)
 
     def update_notes(self, notes):
-        """
-        Parameters
-        ----------
+        # Find current location of notes
+        notes_version = self.vistrail.search_upgrade_versions(
+                self.current_version,
+                lambda vt, v, bv: v if vt.get_notes(v) else None)
 
-        - notes : 'string'
-        
-        """
-        self.flush_delayed_actions()
-        
-        if self.vistrail.set_notes(self.current_version, str(notes)):
+        # Remove notes
+        if notes_version is not None:
+            self.vistrail.set_notes(notes_version, None)
+
+        # Add notes
+        if self.vistrail.set_notes(self.current_base_version, str(notes)):
+            self.set_changed(True)
             self.emit(QtCore.SIGNAL('notesChanged()'))
 
     ##########################################################################
@@ -358,28 +373,87 @@ class VistrailController(QtCore.QObject, BaseController):
         return (results, changed)
 
     def execute_current_workflow(self, custom_aliases=None, custom_params=None,
-                                 reason='Pipeline Execution', sinks=None):
+                                 extra_info=None, reason='Pipeline Execution',
+                                 sinks=None):
         """ execute_current_workflow() -> None
         Execute the current workflow (if exists)
         
         """
         self.flush_delayed_actions()
+
+        if self.create_job:
+            version_id = self.current_version
+            # check if a job exist for this workflow
+            current_workflow = None
+            for wf in self.jobMonitor.workflows.itervalues():
+                try:
+                    wf_version = int(wf.version)
+                except ValueError:
+                    wf_version = self.vistrail.get_version_number(wf.version)
+                if version_id == wf_version:
+                    current_workflow = wf
+                    self.jobMonitor.startWorkflow(wf)
+            if not current_workflow:
+                current_workflow = JobWorkflow(version_id)
+                self.jobMonitor.startWorkflow(current_workflow)
+            self.create_job = False
+
         if self.current_pipeline:
             locator = self.get_locator()
             if locator:
                 locator.clean_temporaries()
                 locator.save_temporary(self.vistrail)
-            return self.execute_workflow_list([(self.locator,
-                                         self.current_version,
-                                         self.current_pipeline,
-                                         self.current_pipeline_scene,
-                                         custom_aliases,
-                                         custom_params,
-                                         reason,
-                                         sinks,
-                                         None)])
+            try:
+                return self.execute_workflow_list([(self.locator,
+                                             self.current_version,
+                                             self.current_pipeline,
+                                             self.current_pipeline_scene,
+                                             custom_aliases,
+                                             custom_params,
+                                             reason,
+                                             sinks,
+                                             extra_info)])
+            except Exception, e:
+                debug.unexpected_exception(e)
+                raise
         return ([], False)
-    
+
+
+    def execute_user_workflow(self, reason='Pipeline Execution', sinks=None):
+        """ execute_user_workflow() -> None
+        Execute the current workflow (if exists) and monitors it if it contains jobs
+        
+        """
+
+        # reset job view
+        from vistrails.gui.job_monitor import QJobView
+        jobView = QJobView.instance()
+        if jobView.updating_now:
+            debug.critical("Execution Aborted: Job Monitor is updating. "
+                           "Please wait a few seconds and try again.")
+            return
+        jobView.updating_now = True
+
+        try:
+            self.progress = ExecutionProgressDialog(self.vistrail_view)
+            self.progress.show()
+
+            if not self.jobMonitor.currentWorkflow():
+                self.create_job = True
+
+            result =  self.execute_current_workflow(reason=reason, sinks=sinks)
+
+            self.progress.setValue(100)
+        finally:
+            self.progress.hide()
+            self.progress.deleteLater()
+            self.progress = None
+            self.create_job = False
+            self.jobMonitor.finishWorkflow()
+            jobView.updating_now = False
+
+        return result
+
     def enable_missing_package(self, identifier, deps):
         configuration = get_vistrails_configuration()
         if getattr(configuration, 'enablePackagesSilently', False):
@@ -388,7 +462,8 @@ class VistrailController(QtCore.QObject, BaseController):
         msg = "VisTrails needs to enable package '%s'." % identifier
         if len(deps) > 0:
             msg += (" This will also enable the dependencies: %s." 
-                    " Do you want to enable these packages?") % str(deps)
+                    " Do you want to enable these packages?" % (
+                    ", ".join(deps),))
         else:
             msg += " Do you want to enable this package?"
         res = show_question('Enable package?',
@@ -396,9 +471,6 @@ class VistrailController(QtCore.QObject, BaseController):
                             [YES_BUTTON, NO_BUTTON], 
                             YES_BUTTON)
         if res == NO_BUTTON:
-#             QtGui.QMessageBox.warning(get_vistrails_application().builderWindow,
-#                                       'Missing modules',
-#                                       'Some necessary modules will be missing.')
             return False
         return True
 
@@ -441,9 +513,8 @@ class VistrailController(QtCore.QObject, BaseController):
             self.do_version_switch(new_version, report_all_errors,
                                    do_validate, from_root)
         except InvalidPipeline, e:
-            from vistrails.gui.application import get_vistrails_application
-
-
+#            from vistrails.gui.application import get_vistrails_application
+#
 #             def process_err(err):
 #                 if isinstance(err, Package.InitializationFailed):
 #                     QtGui.QMessageBox.critical(
@@ -486,11 +557,11 @@ class VistrailController(QtCore.QObject, BaseController):
 #                                           "construct this workflow.")
 #                msg_box.setStandardButtons(QtGui.QMessageBox.Ok)
 #                msg_box.setDefaultButton(QtGui.QMessageBox.Ok)
-#                msg_box.setDetailedText(str(e))
+#                msg_box.setDetailedText(debug.format_exception(e))
 #                msg_box.exec_()
                 # text = "The current workflow could not be validated."
-                # debug.critical('%s\n%s' % (text, str(e)))
-                debug.critical(str(e))
+                # debug.critical(text, e)
+                debug.critical("Error changing version", e)
 
 #                 print 'got to exception set'
 #                 # Process all errors as usual
@@ -501,10 +572,9 @@ class VistrailController(QtCore.QObject, BaseController):
 #                 else:
 #                     process_err(exception_set.__iter__().next())
 
-        except Exception, e:
-            import traceback
-            debug.critical('Unexpected Exception\n%s' % str(e), 
-                           traceback.format_exc())
+        except Exception:
+            debug.critical('Unexpected Exception',
+                           debug.format_exc())
         
         # FIXME: this code breaks undo/redo, and seems to be ok with normal
         # pipeline manipulations so I am leaving it commented out for now
@@ -560,7 +630,6 @@ class VistrailController(QtCore.QObject, BaseController):
 
     def recompute_terse_graph(self):
         BaseController.recompute_terse_graph(self)
-        self._previous_graph_layout = copy.deepcopy(self._current_graph_layout)
         self._current_graph_layout.layout_from(self.vistrail,
                                                self._current_terse_graph)
 
@@ -574,83 +643,8 @@ class VistrailController(QtCore.QObject, BaseController):
         if self._current_full_graph is None:
             self.recompute_terse_graph()
 
-        if not self.animate_layout:
-            return (self._current_terse_graph, self._current_full_graph,
-                    self._current_graph_layout)
-
-        graph_layout = copy.deepcopy(self._current_graph_layout)
-        terse_graph = copy.deepcopy(self._current_terse_graph)
-        am = self.vistrail.actionMap
-        step = 1.0/(1.0+math.exp(-(step*12-6))) # use a logistic sigmoid function
-        
-        # Adding nodes to tree
-        for (c_id, c_node) in self._current_graph_layout.nodes.iteritems():
-            if self._previous_graph_layout.nodes.has_key(c_id):
-                p_node = self._previous_graph_layout.nodes[c_id]
-            else: 
-                p_id = c_id
-                # Find closest child of contained in both graphs
-                while not self._previous_graph_layout.nodes.has_key(p_id):
-                    # Should always have exactly one child
-                    p_id = [to for (to, _) in \
-                                self._current_full_graph.adjacency_list[p_id]
-                            if (to in am) and \
-                                not self.vistrail.is_pruned(to)][0]
-                p_node = self._previous_graph_layout.nodes[p_id]
-
-            # Interpolate position
-            x = p_node.p.x - c_node.p.x
-            y = p_node.p.y - c_node.p.y
-            graph_layout.move_node(c_id, x*(1.0-step), y*(1.0-step))
-            
-        # Removing nodes from tree
-        for (p_id, p_node) in self._previous_graph_layout.nodes.iteritems():
-            if not self._current_graph_layout.nodes.has_key(p_id):
-                # Find closest parent contained in both graphs
-                shared_parent = p_id
-                while (shared_parent > 0 and 
-                       shared_parent not in self._current_graph_layout.nodes):
-                    shared_parent = \
-                        self._current_full_graph.parent(shared_parent)
-
-                # Find closest child contained in both graphs
-                c_id = p_id
-                while not self._current_graph_layout.nodes.has_key(c_id):
-                    # Should always have exactly one child
-                    c_id = [to for (to, _) in \
-                                self._current_full_graph.adjacency_list[c_id]
-                            if (to in am) and \
-                                not self.vistrail.is_pruned(to)][0]
-                    
-                # Don't show edge that skips the disappearing nodes
-                if terse_graph.has_edge(shared_parent, c_id):
-                    terse_graph.delete_edge(shared_parent, c_id)
-
-                # Add the disappearing node to the graph and layout
-                c_node = copy.deepcopy(self._current_graph_layout.nodes[c_id])
-                c_node.id = p_id
-                graph_layout.add_node(p_id, c_node)
-                terse_graph.add_vertex(p_id)
-                p_parent = self._current_full_graph.parent(p_id)
-                if not terse_graph.has_edge(p_id, p_parent):
-                    terse_graph.add_edge(p_parent, p_id)
-                p_child = p_id
-                while p_child not in self._current_graph_layout.nodes:
-                    # Should always have exactly one child
-                    p_child = [to for (to, _) in \
-                                   self._current_full_graph.adjacency_list[p_child]
-                               if (to in am) and \
-                                   not self.vistrail.is_pruned(to)][0]
-                if not terse_graph.has_edge(p_id, p_child):
-                    terse_graph.add_edge(p_id, p_child)
-
-                # Interpolate position
-                x = p_node.p.x - c_node.p.x
-                y = p_node.p.y - c_node.p.y
-                graph_layout.move_node(p_id, x*(1.0-step), y*(1.0-step))
-
-        return (terse_graph, self._current_full_graph,
-                graph_layout)
+        return (self._current_terse_graph, self._current_full_graph,
+                self._current_graph_layout)
 
     ##########################################################################
     # undo/redo navigation
@@ -722,207 +716,6 @@ class VistrailController(QtCore.QObject, BaseController):
 
         """
         self._change_version_short_hop(which_child)
-        
-
-    def prune_versions(self, versions):
-        """ prune_versions(versions: list of version numbers) -> None
-        Prune all versions in 'versions' out of the view
-        
-        """
-        # We need to go up-stream to the highest invisible node
-        current = self._current_terse_graph
-        if not current:
-            (current, full, layout) = self.refine_graph()
-        else:
-            full = self._current_full_graph
-        changed = False
-        new_current_version = None
-        for v in versions:
-            if v!=0: # not root
-                highest = v
-                while True:
-                    p = full.parent(highest)
-                    if p==-1:
-                        break
-                    if p in current.vertices:
-                        break
-                    highest = p
-                if highest!=0:
-                    changed = True
-                    if highest == self.current_version:
-                        new_current_version = full.parent(highest)
-                self.vistrail.pruneVersion(highest)
-        if changed:
-            self.set_changed(True)
-        if new_current_version is not None:
-            self.change_selected_version(new_current_version)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False)
-
-    def hide_versions_below(self, v=None):
-        """ hide_versions_below(v: int) -> None
-        Hide all versions including and below v
-        
-        """
-        if v is None:
-            v = self.current_version
-        full = self.vistrail.getVersionGraph()
-        x = [v]
-
-        am = self.vistrail.actionMap
-
-        changed = False
-
-        while 1:
-            try:
-                current=x.pop()
-            except IndexError:
-                break
-
-            children = [to for (to, _) in full.adjacency_list[current]
-                        if (to in am) and \
-                            not self.vistrail.is_pruned(to)]
-            self.vistrail.hideVersion(current)
-            changed = True
-
-            for child in children:
-                x.append(child)
-
-        if changed:
-            self.set_changed(True)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False, False) 
-
-    def show_all_versions(self):
-        """ show_all_versions() -> None
-        Unprune (graft?) all pruned versions
-
-        """
-        full = self.vistrail.getVersionGraph()
-        am = self.vistrail.actionMap
-        for a in am.iterkeys():
-            self.vistrail.showVersion(a)
-        self.set_changed(True)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False, False)
-
-    def expand_versions(self, v1, v2):
-        """ expand_versions(v1: int, v2: int) -> None
-        Expand all versions between v1 and v2
-        
-        """
-        full = self.vistrail.getVersionGraph()
-        changed = False
-        p = full.parent(v2)
-        while p>v1:
-            self.vistrail.expandVersion(p)
-            changed = True
-            p = full.parent(p)
-        if changed:
-            self.set_changed(True)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False, True)
-
-    def collapse_versions(self, v):
-        """ collapse_versions(v: int) -> None
-        Collapse all versions including and under version v until the next tag or branch
-        
-        """
-        full = self.vistrail.getVersionGraph()
-        x = [v]
-
-        am = self.vistrail.actionMap
-        tm = self.vistrail.get_tagMap()
-
-        changed = False
-
-        while 1:
-            try:
-                current=x.pop()
-            except IndexError:
-                break
-
-            children = [to for (to, _) in full.adjacency_list[current]
-                        if (to in am) and not self.vistrail.is_pruned(to)]
-            if len(children) > 1:
-                break;
-            self.vistrail.collapseVersion(current)
-            changed = True
-
-            for child in children:
-                if (not child in tm and  # has no Tag
-                    child != self.current_version): # not selected
-                    x.append(child)
-
-        if changed:
-            self.set_changed(True)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False, True) 
-
-    def expand_or_collapse_all_versions_below(self, v=None, expand=True):
-        """ expand_or_collapse_all_versions_below(v: int) -> None
-        Expand/Collapse all versions including and under version v
-        
-        """
-        if v is None:
-            v = self.current_version
-
-        full = self.vistrail.getVersionGraph()
-        x = [v]
-        
-        am = self.vistrail.actionMap
-
-        changed = False
-
-        while 1:
-            try:
-                current=x.pop()
-            except IndexError:
-                break
-
-            children = [to for (to, _) in full.adjacency_list[current]
-                        if (to in am) and not self.vistrail.is_pruned(to)]
-            if expand:
-                self.vistrail.expandVersion(current)
-            else:
-                self.vistrail.collapseVersion(current)
-            changed = True
-
-            for child in children:
-                x.append(child)
-
-        if changed:
-            self.set_changed(True)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False, True) 
-
-    def expand_all_versions_below(self, v=None):
-        self.expand_or_collapse_all_versions_below(v, True)
-
-    def collapse_all_versions_below(self, v=None):
-        self.expand_or_collapse_all_versions_below(v, False)
-
-    def collapse_all_versions(self):
-        """ collapse_all_versions() -> None
-        Collapse all expanded versions
-
-        """
-        am = self.vistrail.actionMap
-        for a in am.iterkeys():
-            self.vistrail.collapseVersion(a)
-        self.set_changed(True)
-        self.recompute_terse_graph()
-        self.invalidate_version_tree(False, True)
-
-    def set_num_versions_always_shown(self, num):
-        """ set_num_versions_always_shown(num: int) -> None
-
-        """
-        if num <> self.num_versions_always_shown:
-            self.num_versions_always_shown = num
-            self.set_changed(True)
-            self.recompute_terse_graph()
-            self.invalidate_version_tree(False)
 
     def setSavedQueries(self, queries):
         """ setSavedQueries(queries: list of (str, str, str)) -> None
@@ -932,22 +725,38 @@ class VistrailController(QtCore.QObject, BaseController):
         self.vistrail.setSavedQueries(queries)
         self.set_changed(True)
         
-    def update_current_tag(self,tag):
+    def update_current_tag(self, tag):
         """ update_current_tag(tag: str) -> Bool
         Update the current vistrail tag and return success predicate
         
         """
         self.flush_delayed_actions()
-        try:
-            if self.vistrail.hasTag(self.current_version):
-                self.vistrail.changeTag(tag, self.current_version)
-            else:
-                self.vistrail.addTag(tag, self.current_version)
-        except TagExists:
-            show_warning('Name Exists',
-                         "There is already another version named '%s'.\n"
-                         "Please enter a different one." % tag)
+
+        # Find current location of tag
+        tag_version = self.vistrail.search_upgrade_versions(
+                self.current_version,
+                lambda vt, v, bv: v if vt.has_tag(v) else None)
+
+        # No change in tag: return
+        if (tag_version is not None and
+                self.vistrail.getVersionName(tag_version) == tag):
+            return True
+
+        # This tag already exists elsewhere: error
+        if self.vistrail.has_tag_str(tag):
+            show_warning("Name Exists",
+                         "There is another version named '%s'.\n"
+                         "Please enter a different name." % tag)
             return False
+
+        # Remove current tag
+        self.vistrail.set_tag(tag_version, None)
+
+        if self.vistrail.hasTag(self.current_version):
+            self.vistrail.changeTag(tag, self.current_base_version)
+        else:
+            self.vistrail.addTag(tag, self.current_base_version)
+
         self.set_changed(True)
         self.recompute_terse_graph()
         self.invalidate_version_tree(False)
@@ -977,7 +786,7 @@ class VistrailController(QtCore.QObject, BaseController):
         self.invalidate_version_tree(False)
 
     def get_pipeline_name(self, version=None):
-        if version == None:
+        if version is None:
             version = self.current_version
         return self.vistrail.get_pipeline_name(version)
 
@@ -1049,7 +858,6 @@ class VistrailController(QtCore.QObject, BaseController):
         remove_duplicate_aliases(pipeline)
 
         modules = []
-        connections = []
         if pipeline:
             def process_group(group):
                 # reset pipeline id for db
@@ -1075,10 +883,7 @@ class VistrailController(QtCore.QObject, BaseController):
                        if (op.what == 'module' or 
                            op.what == 'abstraction' or
                            op.what == 'group')]
-            connections = [op.objectId
-                           for op in action.operations
-                           if op.what == 'connection']
-                
+
             self.add_new_action(action)
             self.vistrail.change_description("Paste", action.id)
             self.perform_action(action)
@@ -1141,10 +946,34 @@ class VistrailController(QtCore.QObject, BaseController):
         if dir_name:
             return None
         dir_name = os.path.abspath(str(dir_name))
-        setattr(get_vistrails_configuration(), 'fileDirectory', dir_name)
+        setattr(get_vistrails_configuration(), 'fileDir', dir_name)
         vistrails.core.system.set_vistrails_file_directory(dir_name)
         return dir_name
-    
+
+    def create_abstractions_from_groups(self, group_ids):
+        for group_id in group_ids:
+            self.create_abstraction_from_group(group_id)
+
+    def create_abstraction_from_group(self, group_id, name=""):
+        self.flush_delayed_actions()
+        name = self.get_abstraction_name(name)
+
+        (abstraction, connections) = \
+            self.build_abstraction_from_group(self.current_pipeline,
+                                              group_id, name)
+
+        op_list = []
+        getter = self.get_connections_to_and_from
+        op_list.extend(('delete', c)
+                       for c in getter(self.current_pipeline, [group_id]))
+        op_list.append(('delete', self.current_pipeline.modules[group_id]))
+        op_list.append(('add', abstraction))
+        op_list.extend(('add', c) for c in connections)
+        action = vistrails.core.db.action.create_action(op_list)
+        self.add_new_action(action)
+        result = self.perform_action(action)
+        return abstraction
+
     def export_abstractions(self, abstraction_ids):
         save_dir = self.do_save_dir_prompt()
         if not save_dir:
@@ -1223,7 +1052,8 @@ class VistrailController(QtCore.QObject, BaseController):
             if abstraction.is_abstraction() and \
                     abstraction.package == abstraction_pkg:
                 abstractions.append(abstraction)
-                [abstractions.extend(v) for v in self.find_abstractions(abstraction.vistrail).itervalues()]
+                for v in self.find_abstractions(abstraction.vistrail).itervalues():
+                    abstractions.extend(v)
         pkg_subworkflows = []
         pkg_dependencies = set()
         for abstraction in abstractions:
@@ -1385,9 +1215,8 @@ class VistrailController(QtCore.QObject, BaseController):
         corresponding to each dimension
         
         """
-        reg = vistrails.core.modules.module_registry.get_module_registry()
-        spreadsheet_pkg = '%s.spreadsheet' % \
-                vistrails.core.system.get_vistrails_default_pkg_prefix()
+        reg = get_module_registry()
+        spreadsheet_pkg = 'org.vistrails.vistrails.spreadsheet'
         use_spreadsheet = reg.has_module(spreadsheet_pkg, 'CellLocation') and\
                           reg.has_module(spreadsheet_pkg, 'SheetReference')
 
@@ -1397,6 +1226,7 @@ class VistrailController(QtCore.QObject, BaseController):
                         pe.collectParameterActions(self.current_pipeline)
 
         if self.current_pipeline and actions:
+            pe_log_id = uuid.uuid1()
             explorer = ActionBasedParameterExploration()
             (pipelines, performedActions) = explorer.explore(
                 self.current_pipeline, actions, pre_actions)
@@ -1410,7 +1240,10 @@ class VistrailController(QtCore.QObject, BaseController):
                     dim[2], dim[1], dim[0], pipelines, pe.layout, self)
                 QParamExploreView.explorationId += 1
             else:
+                from vistrails.core.param_explore import _pipelinePositions
                 modifiedPipelines = pipelines
+                pipelinePositions = _pipelinePositions(
+                    dim[2], dim[1], dim[0], pipelines)
 
             mCount = []
             for p in modifiedPipelines:
@@ -1451,9 +1284,11 @@ class VistrailController(QtCore.QObject, BaseController):
                     if 'pathDumpCells' in extra_info:
                         images[pipelinePositions[pi]] = \
                                    os.path.join(extra_info['pathDumpCells'], name)
+                pe_cell_id = (pe_log_id,) + pipelinePositions[pi]
                 kwargs = {'locator': self.locator,
                           'current_version': self.current_version,
-                          'reason': 'Parameter Exploration',
+                          'reason': 'Parameter Exploration %s %s_%s_%s' % pe_cell_id,
+                          'logger': self.get_logger(),
                           'actions': performedActions[pi],
                           'extra_info': extra_info
                           }
@@ -1480,6 +1315,8 @@ class VistrailController(QtCore.QObject, BaseController):
                 filename = os.path.join(extra_info['pathDumpCells'],
                                         os.path.splitext(self.name)[0])
                 assembleThumbnails(images, filename)
+            from vistrails.gui.vistrails_window import _app
+            _app.notify('execution_updated')
             return errors
 
 ################################################################################
@@ -1492,12 +1329,10 @@ class TestVistrailController(vistrails.gui.utils.TestVisTrailsGUI):
     #     v = api.new_vistrail()
        
     def tearDown(self):
-        from vistrails.core.configuration import get_vistrails_configuration
         vistrails.gui.utils.TestVisTrailsGUI.tearDown(self)
 
-        config = get_vistrails_configuration()
-        filename = os.path.join(config.abstractionsDirectory,
-                                '__TestFloatList.xml')
+        d = vistrails.core.system.get_vistrails_directory('subworkflowsDir')
+        filename = os.path.join(d, '__TestFloatList.xml')
         if os.path.exists(filename):
             os.remove(filename)
 
@@ -1530,11 +1365,8 @@ class TestVistrailController(vistrails.gui.utils.TestVisTrailsGUI):
 
     def test_abstraction_create(self):
         from vistrails.core.db.locator import XMLFileLocator
-        import vistrails.core.db.io
-        from vistrails.core.configuration import get_vistrails_configuration
-        config = get_vistrails_configuration()
-        filename = os.path.join(config.abstractionsDirectory,
-                                '__TestFloatList.xml')
+        d = vistrails.core.system.get_vistrails_directory('subworkflowsDir')
+        filename = os.path.join(d, '__TestFloatList.xml')
         locator = XMLFileLocator(vistrails.core.system.vistrails_root_directory() +
                            '/tests/resources/test_abstraction.xml')
         v = locator.load()
@@ -1544,15 +1376,16 @@ class TestVistrailController(vistrails.gui.utils.TestVisTrailsGUI):
         # controller.change_selected_version(9L)
         controller.select_latest_version()
         self.assertNotEqual(controller.current_pipeline, None)
-        
-        # DAK: changed these because of upgrades...
-        # module_ids = [1, 2, 3]
-        # connection_ids = [1, 2, 3]
-        module_ids = [8, 10, 11]
-        #connection_ids = [6, 8, 9]
-        # TE: changed again because upgrades produced different id:s
-        # also saved upgrade in test_abstraction.xml
-        connection_ids = [13,14,15]
+
+        # If getting a KeyError here, run the upgrade on the vistrail and
+        # update the ids
+        # TODO : rewrite test so we don't have to update this unrelated code
+        # each time new upgrades are introduced
+        # Original ids:
+        #     module_ids = [1, 2, 3]
+        #     connection_ids = [1, 2, 3]
+        module_ids = [15, 13, 14]
+        connection_ids = [21, 18, 20]
         controller.create_abstraction(module_ids, connection_ids,
                                       '__TestFloatList')
         self.assert_(os.path.exists(filename))
diff --git a/vistrails/gui/vistrail_variables.py b/vistrails/gui/vistrail_variables.py
index ad59c76..3434d9b 100644
--- a/vistrails/gui/vistrail_variables.py
+++ b/vistrails/gui/vistrail_variables.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,9 +37,10 @@
 drop constants from the module palette
 
 """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.gui.variable_dropbox import QVariableDropBox
-from vistrails.gui.common_widgets import QToolWindowInterface
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
 
 ################################################################################
diff --git a/vistrails/gui/vistrail_view.py b/vistrails/gui/vistrail_view.py
index 0f6fcfb..7f9315c 100644
--- a/vistrails/gui/vistrail_view.py
+++ b/vistrails/gui/vistrail_view.py
@@ -1,53 +1,55 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ The file describes a container widget consisting of a pipeline
 view and a version tree for each opened Vistrail """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core import debug
 from vistrails.core.collection import Collection
-from vistrails.core.debug import critical
-from vistrails.core.data_structures.bijectivedict import Bidict
-from vistrails.core.system import vistrails_default_file_type
+from vistrails.core.system import vistrails_default_file_type, \
+    vistrails_file_directory
 from vistrails.core.thumbnails import ThumbnailCache
 from vistrails.core.vistrail.vistrail import Vistrail
 from vistrails.core.vistrail.pipeline import Pipeline
 from vistrails.core.log.log import Log
 from vistrails.core.log.opm_graph import OpmGraph
 from vistrails.core.log.prov_document import ProvDocument
-from vistrails.core.db.locator import FileLocator, XMLFileLocator
+from vistrails.core.db.locator import XMLFileLocator
 from vistrails.core.modules.module_registry import ModuleRegistry
 from vistrails.core.configuration import get_vistrails_configuration
 
@@ -58,7 +60,6 @@ from vistrails.gui.version_view import QVersionTreeView
 from vistrails.gui.query_view import QQueryView
 from vistrails.gui.paramexplore.pe_view import QParamExploreView
 from vistrails.gui.vis_diff import QDiffView
-from vistrails.gui.paramexplore.param_view import QParameterView
 from vistrails.gui.vistrail_controller import VistrailController
 from vistrails.gui.mashups.mashup_view import QMashupView
 from vistrails.gui.ports_pane import ParameterEntry
@@ -231,8 +232,8 @@ class QVistrailView(QtGui.QWidget):
         try:
             qaction = self.tab_state[self.tabs.currentIndex()]
             qaction.trigger()
-        except:
-            pass
+        except Exception, e:
+            debug.unexpected_exception(e)
         
     def reset_tab_view_to_current(self):
         index = self.tabs.currentIndex()
@@ -356,7 +357,8 @@ class QVistrailView(QtGui.QWidget):
             self.mashup_view.updateView()
             self.tab_to_view[self.tabs.currentIndex()] = self.get_current_tab()
         except Exception, e:
-            print "EXCEPTION: ", str(e)
+            debug.unexpected_exception(e)
+            print "EXCEPTION: ", debug.format_exception(e)
     def mashup_unselected(self):
         #print "MASHUP UN"
         self.stack.setCurrentIndex(
@@ -423,7 +425,6 @@ class QVistrailView(QtGui.QWidget):
                         newPipelineView
                     module.pipeline.ensure_connection_specs()
                     newPipelineView.scene().setupScene(module.pipeline)
-                    newPipelineView.scene().current_pipeline = module.pipeline
 
     def create_view(self, klass, add_tab=True):
         view = klass(self)
@@ -689,7 +690,7 @@ class QVistrailView(QtGui.QWidget):
         self.set_to_current(view)
         
     def set_to_current(self, view):
-        from vistrails.gui.vistrails_window import _app, QVistrailViewWindow
+        from vistrails.gui.vistrails_window import _app
         if isinstance(view, QDiffView):
             view.set_to_current()
             #print "view changed!", self.controller, \
@@ -902,12 +903,9 @@ class QVistrailView(QtGui.QWidget):
             return False
         try:
             self.controller.write_vistrail(locator, export=export)
-        except Exception, e:
-            import traceback
-            debug.critical('Failed to save vistrail: %s' % str(e),
-                           traceback.format_exc())
+        except Exception:
+            debug.critical('Failed to save vistrail', debug.format_exc())
             raise
-            return False
         if export:
             return self.controller.locator
         
@@ -933,9 +931,8 @@ class QVistrailView(QtGui.QWidget):
             # add to relevant workspace categories
             collection.add_to_workspace(entity)
             collection.commit()
-        except Exception, e:
-            import traceback
-            debug.critical('Failed to index vistrail', traceback.format_exc())
+        except Exception:
+            debug.critical('Failed to index vistrail', debug.format_exc())
 
         from vistrails.gui.vistrails_window import _app
         # update recent files menu items
@@ -956,27 +953,16 @@ class QVistrailView(QtGui.QWidget):
         """ Exports vistrail without updating the current vistrail """
         self.save_vistrail(locator_class, force_choose_locator=True, export=True)
 
-    def export_stable(self, locator_class=XMLFileLocator,
-                      force_choose_locator=True):
-        """ save vistrail to previous stable version """
+    def export_stable(self, locator_class=XMLFileLocator):
+        """ save workflow to previous stable version """
         self.flush_changes()
         gui_get = locator_class.save_from_gui
-        if force_choose_locator:
-            locator = gui_get(self, Vistrail.vtType,
-                              self.controller.locator)
-        else:
-            locator = (self.controller.locator or
-                      gui_get(self, Vistrail.vtType, self.controller.locator))
-        if locator is not None and locator.is_untitled():
-            locator = gui_get(self, Vistrail.vtType,
-                              self.controller.locator)
+        locator = gui_get(self, Pipeline.vtType)
         if not locator:
             return False
-        self.controller.write_vistrail(locator, '1.0.2', True)
+        self.controller.write_workflow(locator, '1.0.3')
         return True
 
-
-
     # FIXME normalize workflow/log/registry!!!
     def save_workflow(self, locator_class, force_choose_locator=True):
         self.flush_changes()
@@ -1027,6 +1013,16 @@ class QVistrailView(QtGui.QWidget):
             return False
         self.controller.write_registry(locator)
 
+    def save_version_graph(self):
+        filename = QtGui.QFileDialog.getSaveFileName(
+            self.window(),
+            "Save DOT...",
+            vistrails_file_directory(),
+            "Graphviz DOT files (*.dot)")
+        if not filename:
+            return
+        self.controller.save_version_graph(filename)
+
 
     def save_opm(self, locator_class=XMLFileLocator, 
              force_choose_locator=True):
diff --git a/vistrails/gui/vistrails_palette.py b/vistrails/gui/vistrails_palette.py
index abb47a6..98d5c87 100644
--- a/vistrails/gui/vistrails_palette.py
+++ b/vistrails/gui/vistrails_palette.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.gui.common_widgets import QToolWindowInterface
 
diff --git a/vistrails/gui/vistrails_window.py b/vistrails/gui/vistrails_window.py
index 4cf8e4b..57aa25b 100644
--- a/vistrails/gui/vistrails_window.py
+++ b/vistrails/gui/vistrails_window.py
@@ -1,77 +1,70 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ The file describes a container widget consisting of a pipeline
 view and a version tree for each opened Vistrail """
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 import copy
-from itertools import izip
-import operator
 
-from vistrails.core import get_vistrails_application
 from vistrails.core.configuration import (get_vistrails_configuration,
                                 get_vistrails_persistent_configuration)
 from vistrails.core.db.locator import FileLocator, XMLFileLocator, DBLocator, \
     UntitledLocator
-from vistrails.core.db.io import load_vistrail
 from vistrails.core.interpreter.cached import CachedInterpreter
-from vistrails.core.modules.module_registry import ModuleRegistry, \
-                                         ModuleRegistryException
 from vistrails.core.recent_vistrails import RecentVistrailList
 import vistrails.core.system
 import vistrails.core.db.action
-from vistrails.core.packagemanager import get_package_manager
 from vistrails.core.system import vistrails_default_file_type
 from vistrails.core.vistrail.vistrail import Vistrail
 from vistrails.core.vistrail.pipeline import Pipeline
 from vistrails.core.thumbnails import ThumbnailCache
-from vistrails.core.collection import Collection
 from vistrails.core import debug
 
 from vistrails.gui.application import get_vistrails_application
 from vistrails.gui.preferences import QPreferencesDialog
 from vistrails.gui.base_view import BaseView
 from vistrails.gui.common_widgets import QToolWindow
-from vistrails.gui.pipeline_view import QPipelineView
 from vistrails.gui.repository import QRepositoryDialog
-from vistrails.gui.theme import initializeCurrentTheme, CurrentTheme
+from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.utils import build_custom_window
 from vistrails.gui.vistrail_view import QVistrailView
 from vistrails.gui import merge_gui
 from vistrails.gui.vistrail_variables import QVistrailVariables
 from vistrails.gui.vistrails_palette import QVistrailsPaletteInterface
-from vistrails.gui.mashups.mashup_app import QMashupAppMainWindow
 from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin
 from vistrails.gui.paramexplore.pe_view import QParamExploreView
 from vistrails.gui.mashups.alias_inspector import QAliasInspector
@@ -156,10 +149,8 @@ class QBaseViewWindow(QtGui.QMainWindow):
                     else:
                         self.connect(qaction, QtCore.SIGNAL("triggered()"),
                                      callback)
-        
+
     def init_action_list(self):
-        global _app
-        
         self._actions = [("file", "&File",
                    [("export", "Export",
                       [('savePDF', "PDF...",
@@ -167,6 +158,12 @@ class QBaseViewWindow(QtGui.QMainWindow):
                          'enabled': True,
                          'callback': _app.pass_through(self.get_current_tab,
                                                        'save_pdf')}),
+                       ('saveDOT', "Version tree to Graphviz DOT...",
+                        {'statusTip': "Save the version view to a Graphviz "
+                             "DOT file",
+                         'enabled': True,
+                         'callback': _app.pass_through(self.get_current_view,
+                                                       'save_version_graph')}),
                        "---",
                        ('saveWorkflow', "Workflow To XML...",
                         {'statusTip': "Save the current workflow to a file",
@@ -371,7 +368,6 @@ class QVistrailViewWindow(QBaseViewWindow):
             self.setWindowTitle('%s - VisTrails' % self.view.get_name())
 
     def close_vistrail(self):
-        global _app
         return _app.close_vistrail(self.view)
         
     def closeEvent(self, event):
@@ -450,7 +446,6 @@ class QVistrailViewWindow(QBaseViewWindow):
             self.set_title('(empty)')
 
     def build_packages_menu_from_main_app(self):
-        global _app
         if len(self._package_menu_items) == 0:
             self.qmenus['packages'].menuAction().setEnabled(True)
             
@@ -467,7 +462,6 @@ class QVistrailViewWindow(QBaseViewWindow):
                     pkg_menu.addAction(action)
 
     def init_action_list(self):
-        global _app
         # This keeps track of the menu items for each package
         self._package_menu_items = {}
         
@@ -554,19 +548,18 @@ class QVistrailViewWindow(QBaseViewWindow):
                              _app.pass_through_locator(self.get_current_view,
                                                        'export_vistrail', 
                                                        reverse=True)}),
-                       ('exportStable', "To Stable Version...",
-                        {'statusTip': "Save vistrail as XML according to " \
-                             "the older (stable) schema",
-                         'enabled': True,
-                         'callback': \
-                             _app.pass_through_locator(self.get_current_view,
-                                                       'export_stable')}),
                        "---",
                        ('savePDF', "PDF...",
                         {'statusTip': "Save the current view to a PDF file",
                          'enabled': True,
                          'callback': _app.pass_through(self.get_current_tab,
                                                        'save_pdf')}),
+                       ('saveDOT', "Version tree to Graphviz DOT...",
+                        {'statusTip': "Save the version view to a Graphviz "
+                             "DOT file",
+                         'enabled': True,
+                         'callback': _app.pass_through(self.get_current_view,
+                                                       'save_version_graph')}),
                        "---",
                        ('saveWorkflow', "Workflow To XML...",
                         {'statusTip': "Save the current workflow to a file",
@@ -582,6 +575,13 @@ class QVistrailViewWindow(QBaseViewWindow):
                              _app.pass_through_locator(self.get_current_view,
                                                        'save_workflow',
                                                        DBLocator)}),
+                       ('exportStable', "Workflow to VisTrails 2.1 XML...",
+                        {'statusTip': "Save workflow as XML according to " \
+                             "the previous schema",
+                         'enabled': True,
+                         'callback': \
+                             _app.pass_through_locator(self.get_current_view,
+                                                       'export_stable')}),
                        "---",
                        ('saveOpm', "OPM XML...",
                         {'statusTip': "Save provenance according to the " \
@@ -715,7 +715,7 @@ class QVistrailViewWindow(QBaseViewWindow):
                            _app.pass_through(self.get_current_controller,
                                              'collapse_all_versions')}),
                      ("hideBranch", "Hide Branch",
-                      {'statusTip': "Hide all versions in the tre including " \
+                      {'statusTip': "Hide all versions in the tree including " \
                            "and below the current version",
                        'enabled': True,
                        'callback': \
@@ -819,7 +819,6 @@ class QVistrailViewWindow(QBaseViewWindow):
         Construct all menu/toolbar actions for window.
 
         """
-        global _app
 
         # format of each item in the list is:
         # item: reference, title, options
@@ -884,7 +883,7 @@ class QVistrailsWindow(QVistrailViewWindow):
         self.connect(QtGui.QApplication.clipboard(),
                      QtCore.SIGNAL('dataChanged()'),
                      self.clipboard_changed)
-        self.connect(QtGui.QApplication.instance(), 
+        self.connect(QtGui.QApplication.instance(),
                      QtCore.SIGNAL("focusChanged(QWidget*,QWidget*)"),
                      self.applicationFocusChanged)
 
@@ -959,7 +958,12 @@ class QVistrailsWindow(QVistrailViewWindow):
             window = self.windows[view]
             window.close()
         QWorkspaceWindow.instance().remove_vt_window(view)
-        self.current_view = None
+
+        # DK: **Do not** set current_view here because remove_vistrail
+        # calls change_view which sends notifications that there is
+        # not current controller
+        #
+        # self.current_view = None
 
     def view_triggered(self, action):
         #print "VIEW_TRIGGERED", action
@@ -1005,11 +1009,12 @@ class QVistrailsWindow(QVistrailViewWindow):
         from vistrails.gui.debugger import QDebugger
         from vistrails.gui.module_configuration import QModuleConfiguration
         from vistrails.gui.module_documentation import QModuleDocumentation
+        from vistrails.gui.module_options import QModuleOptions
         from vistrails.gui.module_palette import QModulePalette
         from vistrails.gui.module_info import QModuleInfo
         from vistrails.gui.paramexplore.param_view import QParameterView
         from vistrails.gui.paramexplore.pe_inspector import QParamExploreInspector
-        from vistrails.gui.shell import QShellDialog
+        from vistrails.gui.shell import get_shell_dialog
         from vistrails.gui.version_prop import QVersionProp
         from vistrails.gui.vis_diff import QDiffProperties
         from vistrails.gui.collection.explorer import QExplorerWindow
@@ -1017,10 +1022,10 @@ class QVistrailsWindow(QVistrailViewWindow):
         from vistrails.gui.collection.vis_log import QLogDetails
         from vistrails.gui.mashups.mashups_inspector import QMashupsInspector
         from vistrails.gui.mashups.alias_parameter_view import QAliasParameterView
-        from vistrails.gui.publishing import QLatexAssistant, QVersionEmbed
+        from vistrails.gui.publishing import QVersionEmbed
         self.palettes = []
         self.palette_window = None
-        
+
         self.palette_layout = \
             [(self.UPPER_LEFT_DOCK_AREA,
               [((QWorkspaceWindow,True),
@@ -1030,9 +1035,7 @@ class QVistrailsWindow(QVistrailViewWindow):
              (self.LOWER_LEFT_DOCK_AREA,
               [(QModulePalette, True),
                ((QParamExploreInspector, False),
-                (('pipeline_changed', 'set_pipeline'),
-                 ('exploration_changed', 'set_exploration'),
-                 ('controller_changed', 'set_controller'))),
+                (('controller_changed', 'set_controller'),)),
                ((QMashupsInspector, False),
                 (('controller_changed', 'updateVistrailController'),
                  ('mshpcontroller_changed', 'updateMshpController'),
@@ -1050,8 +1053,8 @@ class QVistrailsWindow(QVistrailViewWindow):
                 (('controller_changed', 'set_controller'),
                  ('module_changed', 'update_module'))),
                ((QParameterView, False),
-                (('controller_changed', 'set_controller'),
-                 ('pipeline_changed', 'set_pipeline'))),
+                (('pipeline_changed', 'set_pipeline'),
+                 ('controller_changed', 'set_controller'))),
                ((QLogDetails, False),
                 (('controller_changed', 'set_controller'),
                  ('execution_updated', 'execution_updated'),
@@ -1069,12 +1072,17 @@ class QVistrailsWindow(QVistrailViewWindow):
                 (('controller_changed', 'set_controller'),
                  ('module_changed', 'update_module'),
                  ('descriptor_changed', 'update_descriptor'))),
-               ((QShellDialog, True),
-                (('controller_changed', 'set_controller'),)),
-               ((QDebugger, True),
+               ((QModuleOptions, True),
+                (('controller_changed', 'set_controller'),
+                 ('module_changed', 'update_module')))] +
+              ([] if not get_shell_dialog() else [
+               ((get_shell_dialog(), True),
+                (('controller_changed', 'set_controller'),))]) +
+              [((QDebugger, True),
                 (('controller_changed', 'set_controller'),)),
                (DebugView, True),
-               (QJobView, True),
+               ((QJobView, True),
+                (('controller_changed', 'set_controller'),)),
                (QExplorerWindow, True),
 #               ((QLatexAssistant, True),
 #                (('controller_changed', 'set_controller'),)),
@@ -1165,11 +1173,11 @@ class QVistrailsWindow(QVistrailViewWindow):
             for dock_area, p_group in self.palette_layout:
                 for p_klass in p_group:
                 
+                    assert isinstance(p_klass, tuple)
+                    p_klass, visible = p_klass
                     if isinstance(p_klass, tuple):
+                        notifications = visible
                         p_klass, visible = p_klass
-                        if isinstance(p_klass, tuple):
-                            notifications = visible
-                            p_klass, visible = p_klass      
                     palette = p_klass.instance()
                     if dock_area == QtCore.Qt.RightDockWidgetArea:
                         pin_status = palette.get_pin_status()
@@ -1253,31 +1261,6 @@ class QVistrailsWindow(QVistrailViewWindow):
         vt_app = get_vistrails_application()
         vt_app.send_notification(notification_id, *args)
 
-        # # do global notifications
-        # if notification_id in self.notifications:
-        #     print 'global notification ', notification_id
-        #     for m in self.notifications[notification_id]:
-        #         try:
-        #             #print "  m: ", m
-        #             m(*args)
-        #         except Exception, e:
-        #             import traceback
-        #             traceback.print_exc()
-        # notifications = {}
-        # # do local notifications
-        # if self.current_view in self.view_notifications:
-        #     notifications = self.view_notifications[self.current_view]
-        #     print 'local notification ', notification_id, self.current_view
-                
-        # if notification_id in notifications:
-        #     for m in notifications[notification_id]:
-        #         try:
-        #             #print "  m: ", m
-        #             m(*args)
-        #         except Exception, e:
-        #             import traceback
-        #             traceback.print_exc()
-
     def clipboard_changed(self):
         self.notify("clipboard_changed")
 
@@ -1374,7 +1357,6 @@ class QVistrailsWindow(QVistrailViewWindow):
         self._first_view = self.get_current_view()
 
     def change_view(self, view):
-        #print 'changing view', id(view), view
         if isinstance(view, QVistrailView) or view is None:
             self.view_changed(view)
             if view and view not in self.windows:
@@ -1433,6 +1415,8 @@ class QVistrailsWindow(QVistrailViewWindow):
                 self.notify('controller_changed', new_view.get_controller())
                 if new_view.current_tab:
                     self.set_action_defaults(new_view.current_tab)
+            else:
+                self.notify('controller_changed', None)
         
         if new_view is not None:
             window = None
@@ -1495,17 +1479,6 @@ class QVistrailsWindow(QVistrailViewWindow):
                 # FIXME how do we choose which one? -- really should open all
                 locator = untitled_temps[0]
 
-        # try:
-        #     (vistrail, abstraction_files, thumbnail_files) = load_vistrail(locator)
-        # except ModuleRegistryException, e:
-        #     debug.critical("Module registry error for %s" %
-        #                    str(e.__class__.__name__), str(e))
-        # except Exception, e:
-        #     debug.critical('An error has occurred', str(e))
-        #     raise
-        # return self.set_vistrail_view(vistrail, locator, abstraction_files,
-        #                               thumbnail_files)
-        
         self.open_vistrail(locator)
         self.qactions['pipeline'].trigger()
 
@@ -1530,7 +1503,7 @@ class QVistrailsWindow(QVistrailViewWindow):
             self._first_view = None
 
     def ensureController(self, controller):
-        """ ensureController(locator: VistrailController) -> QVistrailView        
+        """ ensureController(controller: VistrailController) -> QVistrailView        
         This will first find among the opened vistrails to see if
         controller is open. If not, it will try to open it if a locator exist.
 
@@ -1555,10 +1528,10 @@ class QVistrailsWindow(QVistrailViewWindow):
         return None
 
     def getViewFromLocator(self, locator):
-        """ getViewFromLocator(locator: VistrailLocator) -> QVistrailView        
+        """ getViewFromLocator(locator: VistrailLocator) -> QVistrailView
         This will find the view associated with the locator. If not, it will
         return None.
-        
+
         """
         if locator is None:
             return None
@@ -1571,6 +1544,17 @@ class QVistrailsWindow(QVistrailViewWindow):
                 return view
         return None
 
+    def getAllViews(self):
+        """ getAllViews() ->[QVistrailView]
+        Returns all open views.
+
+        """
+        views = []
+        for i in xrange(self.stack.count()):
+            views.append(self.stack.widget(i))
+        views.extend(self.windows)
+        return views
+
     def ensureVistrail(self, locator):
         """ ensureVistrail(locator: VistrailLocator) -> QVistrailView        
         This will first find among the opened vistrails to see if
@@ -1603,10 +1587,6 @@ class QVistrailsWindow(QVistrailViewWindow):
     def remove_vistrail(self, locator):
         for view in copy.copy(self.vistrail_widgets):
             if view.controller.locator == locator:
-                from vistrails.gui.job_monitor import QJobView
-                jobView = QJobView.instance()
-                jobView.delete_job(view.controller, all=True)
-
                 view.closeDetachedViews()
                 self.remove_view(view)
                 self.vistrail_widgets.remove(view)
@@ -1634,10 +1614,11 @@ class QVistrailsWindow(QVistrailViewWindow):
 
         """
         old_view = self.getViewFromLocator(locator)
-        self.close_first_vistrail_if_necessary()
         
-        get_vistrails_application().open_vistrail(locator, version, 
-                                                  is_abstraction)
+        if not get_vistrails_application().open_vistrail(locator, version, 
+                                                         is_abstraction):
+            return None
+        self.close_first_vistrail_if_necessary()
         view = self.get_current_view()
         view.is_abstraction = view.controller.is_abstraction
         if not old_view:
@@ -1653,17 +1634,18 @@ class QVistrailsWindow(QVistrailViewWindow):
         """
         locator = locator_class.load_from_gui(self, Vistrail.vtType)
         if locator:
+            version = None
             if not self.getViewFromLocator(locator):
                 if locator.has_temporaries():
                     if not locator_class.prompt_autosave(self):
                         locator.clean_temporaries()
-            if hasattr(locator, '_vnode'):
+            if hasattr(locator,'_vtag'):
+                # if a tag is set, it should be used instead of the
+                # version number
+                if locator._vtag != '':
+                    version = locator._vtag
+            elif hasattr(locator, '_vnode'):
                 version = locator._vnode
-                if hasattr(locator,'_vtag'):
-                    # if a tag is set, it should be used instead of the
-                    # version number
-                    if locator._vtag != '':
-                        version = locator._vtag
             mashuptrail = None
             mashupversion = None
             execute = False
@@ -1673,7 +1655,7 @@ class QVistrailsWindow(QVistrailViewWindow):
                 mashupversion = locator._mshpversion
                 if mashupversion:
                     execute = True
-            self.open_vistrail_without_prompt(locator, version, 
+            self.open_vistrail_without_prompt(locator, version,
                                               mashuptrail=mashuptrail,
                                               mashupVersion=mashupversion,
                                               execute_workflow=execute)
@@ -1686,7 +1668,8 @@ class QVistrailsWindow(QVistrailViewWindow):
             pe = vistrail.get_paramexp(pe_id)
         except ValueError:
             pe= vistrail.get_named_paramexp(pe_id)
-        except Exception:
+        except Exception, e:
+            debug.unexpected_exception(e)
             return
         self.current_view.open_parameter_exploration(pe.id)
         self.qactions['execute'].trigger()
@@ -1745,19 +1728,31 @@ class QVistrailsWindow(QVistrailViewWindow):
                     if not locator.prompt_autosave(self):
                         locator.clean_temporaries()
             view = self.open_vistrail(locator, version, is_abstraction)
+            if view is None:
+                return
             view.version_view.select_current_version()
             conf = get_vistrails_configuration()
-            has_tag = len(view.controller.vistrail.get_tagMap()) > 0
-            if (not conf.check('showPipelineViewOnLoad')) and \
-               (conf.check('showHistoryViewOnLoad') or has_tag):
-                self.qactions['history'].trigger()
-
             if version:
                 self.qactions['pipeline'].trigger()
-                
+            elif conf.check('viewOnLoad') and conf.viewOnLoad == 'history':
+                self.qactions['history'].trigger()
+            elif conf.check('viewOnLoad') and conf.viewOnLoad == 'pipeline':
+                self.qactions['pipeline'].trigger()
+            else:
+                # appropriate
+                has_tag = len(view.controller.vistrail.get_tagMap()) > 0
+                if has_tag:
+                    self.qactions['history'].trigger()
+                else:
+                    self.qactions['pipeline'].trigger()
+                            
             if mashuptrail is not None and mashupVersion is not None:
                 mashup = view.get_mashup_from_mashuptrail_id(mashuptrail,
                                                              mashupVersion)
+                if mashup is None:
+                    debug.critical("Mashup not found. If workflow has been "
+                                   "upgraded, try executing it first.")
+                    return
                 if execute_workflow:
                     view.open_mashup(mashup)
                 else:
@@ -1824,9 +1819,12 @@ class QVistrailsWindow(QVistrailViewWindow):
 
     def open_workflow(self, locator):
         self.close_first_vistrail_if_necessary()
-
         get_vistrails_application().open_workflow(locator)
-
+        view = self.get_current_view()
+        view.controller.recompute_terse_graph()
+        view.controller.invalidate_version_tree()
+        from vistrails.gui.collection.workspace import QWorkspaceWindow
+        QWorkspaceWindow.instance().add_vt_window(view)
         self.qactions['pipeline'].trigger()
     
     def close_vistrail(self, current_view=None, quiet=False):
@@ -1836,6 +1834,8 @@ class QVistrailsWindow(QVistrailViewWindow):
         if current_view:
             locator = current_view.controller.locator
 
+        SAVE_BUTTON, DISCARD_BUTTON, CANCEL_BUTTON = 0, 1, 2
+
         if not quiet and current_view and current_view.has_changes():
             window = current_view.window()
             name = current_view.controller.name
@@ -1853,54 +1853,10 @@ class QVistrailsWindow(QVistrailViewWindow):
                                                 'Cancel',
                                                 0,
                                                 2)
-            # Check if any unsaved workflow contains jobs
-            if res == 1:
-                vistrail = current_view.controller.vistrail
-                conf = get_vistrails_configuration()
-                if not conf.has('runningJobsList') or not conf.runningJobsList:
-                    conf_jobs = []
-                else:
-                    conf_jobs = conf.runningJobsList.split(';')
-                    res2 = 0
-                for url in conf_jobs:
-                    loc, version = url.split('?')
-                    version = int(version.split('=')[1])
-                    if loc != locator.to_url():
-                        continue
-                    action = vistrail.db_get_action_by_id(version)
-                    if not action.is_dirty:
-                        continue
-                    if res2 == 1:
-                        # already discarded
-                        from vistrails.gui.job_monitor import QJobView
-                        QJobView.instance().delete_job(
-                                             current_view.controller, version)
-                        continue
-                    text = ('Vistrail ' +
-                            QtCore.Qt.escape(name) +
-                            ' contains unsaved jobs.\n Do you want to '
-                            'save changes or discard the job(s)?')
-                    res2 = QtGui.QMessageBox.information(window,
-                                                        'Vistrails',
-                                                        text, 
-                                                        '&Save', 
-                                                        '&Discard',
-                                                        'Cancel',
-                                                        0,
-                                                        2)
-                    if res2 == 0:
-                        res = 0
-                        break
-                    elif res2 == 1:
-                        from vistrails.gui.job_monitor import QJobView
-                        QJobView.instance().delete_job(
-                                             current_view.controller, version)
-                    elif res2 == 2:
-                        return False
         else:
-            res = 1
+            res = DISCARD_BUTTON
         
-        if res == 0:
+        if res == SAVE_BUTTON:
             if locator is None or locator.is_untitled():
                 class_ = FileLocator()
             else:
@@ -1908,7 +1864,7 @@ class QVistrailsWindow(QVistrailViewWindow):
             locator = current_view.save_vistrail(class_)
             if not locator:
                 return False
-        elif res == 2:
+        elif res == CANCEL_BUTTON:
             return False
         
         if locator is not None:
@@ -1961,7 +1917,7 @@ class QVistrailsWindow(QVistrailViewWindow):
             return self.stack.currentWidget()
         else:
             if len(self.windows) > 0:
-                return self.windows.iterkeys().next()
+                return next(self.windows.iterkeys())
         return None
         
     def get_current_controller(self):
@@ -2261,10 +2217,6 @@ class QVistrailsWindow(QVistrailViewWindow):
         conf.subscribe('maxRecentVistrails', self.max_recent_vistrails_changed)
         self.update_recent_vistrail_actions()
 
-    def check_running_jobs(self):
-        from vistrails.gui.job_monitor import QJobView
-        QJobView.instance().load_running_jobs()
-
     def open_recent_vistrail(self):
         """ open_recent_vistrail() -> None
         Opens a vistrail from Open Recent menu list
@@ -2299,7 +2251,7 @@ class QVistrailsWindow(QVistrailViewWindow):
             action.setCheckable(True)
             
             base_view_windows = {}
-            if current_view == None or \
+            if current_view is None or \
                QtGui.QApplication.activeWindow() == self:
                 action.setChecked(True)
             actions.append(action)
@@ -2442,6 +2394,13 @@ class QVistrailsWindow(QVistrailViewWindow):
         self.qactions[action_name].setChecked(False)
         self.qactions[action_name].setChecked(True)
 
+    def show_looping_options(self):
+        from vistrails.gui.module_options import QModuleOptions
+        action_name = QModuleOptions.instance().get_title()
+        # easy way to make sure that looping options window is raised
+        self.qactions[action_name].setChecked(False)
+        self.qactions[action_name].setChecked(True)
+
 #    def show_group(self):
 #        class DummyController(object):
 #            def __init__(self, pip):
@@ -2520,13 +2479,15 @@ class QVistrailsWindow(QVistrailViewWindow):
 
         vistrails.db.services.vistrail.merge(s1, s2, "", merge_gui, l1, l2)
         vistrail = s1.vistrail
-        vistrail.locator = None
+        vistrail.locator = UntitledLocator()
         vistrail.set_defaults()
         view = self.create_view(vistrail, None)
         # FIXME need to figure out what to do with this !!!
         view.controller.set_vistrail(vistrail, None, thumbnails=s1.thumbnails)
         view.controller.set_changed(True)
         self.view_changed(view)
+        from vistrails.gui.collection.workspace import QWorkspaceWindow
+        QWorkspaceWindow.instance().add_vt_window(view)
         self.reset_toolbar_for_view(view)
         self.qactions['history'].trigger()
         view.version_view.scene().fitToView(view.version_view, True)
@@ -2680,8 +2641,8 @@ class QPaletteMainWindow(QtGui.QMainWindow):
     def closeDockedPalettes(self):
         for p in self.palettes:
             if (p.toolWindow().isVisible() and 
-                not p.toolWindow().isFloating()):
-                        p.toolWindow().close()
+                    not p.toolWindow().isFloating()):
+                p.toolWindow().close()
             
     def closeEvent(self, event):
         if not QtCore.QCoreApplication.closingDown():
diff --git a/vistrails/packages/CLTools/README b/vistrails/packages/CLTools/README
deleted file mode 100644
index 79b82cc..0000000
--- a/vistrails/packages/CLTools/README
+++ /dev/null
@@ -1,73 +0,0 @@
-CLTools provide a way to wrap command line tools so that they can be used as modules in VisTrails.
-
-
-== Using the Wizard ==
-
-To launch the wizard run:
-python vistrails/package/CLTools/wizard.py
-
-The wizard enables you to create and edit a wrapper for a command line tool. You can create input/output ports or constant arguments and ports for stdin/stdout/stderr pipes. You can view and import flags from man and help pages.
-
-Files should be saved as {modulename}.clt in the directory .vistrails/CLTools/
-
-Supported flags:
--c    Import a command with arguments automatically
-example:
-create a wrapper for ls with two flags
-"python wizard.py -c ls -l -A"
-
-
-== Creating a standalone package ==
-
-1. Create a new directory in ".vistrails/userpackages/"
-2. Copy "__init__.py" and "init.py" from "vistrails/packages/CLTools" to the new directory.
-3. Update "name", "identifier", and "version" in "__init__.py" to the desired values
-4. Move all desired tools (*.clt files) to the new directory
-5. Test the new package
-
-
-== File Format ==
-
-The wrapper is stored as a JSON file with the following syntax:
-
-ROOT is a dict with the following possible keys:
-* command (required) - value is the command to execute like "cat" or "/home/tommy/cat"
-* stdin - handle stdin - value is a 3-list ["port name", CLASS, OPTIONDICT]
-* stdout - handle stdout - value is a 3-list ["port name", CLASS, OPTIONDICT]
-* stderr - handle stdout - value is a 3-list ["port name", CLASS, OPTIONDICT]
-* args - list of ordered arguments that can either be constants, inputs, or outputs. See ARG.
-* options - a dict of module options - see OPTIONDICT
-OPTIONDICT is a dict with module specific options
-recognized options are:
-std_using_files - connect files to pipes so that they need not be stored in memory. This is useful for large files but may be unsafe since it does not use subprocess.communicate
-ARG is a 4-list containing [TYPE, "name", KLASS, ARGOPTIONDICT]
-TYPE is one of:
-* input - create input port for this arg
-* output - create output port for this arg
-* constant - use "port name" directly as a constant string
-CLASS can either be "File", "String", "Flag", or "List". Unknown types are handled as "String". "Flag" is a boolean with the value specified by option "value". "List" is a list with subtype specified by option "type"
-ARGOPTIONDICT is a dict containing argument options. recognized options are:
-"type": "CLASS" - used by List-types to specify subtype.
-"flag": "name" - Append name as a constant before the specified argument. If type is "List" it is appended before each item
-"prefix": "name" - Append name as a prefix to the final argument. If it is also a list it is appended to each item.
-"required": "" - Makes the port always visible in VisTrails.
-
-
-== EXAMPLE ==
-
-wrap the command "cat" that takes 2 files as input named "first" and "second". Also take a list of files as input named "rest".
-Catch stdout as file, name it "combined".
-Catch stderr as string, name it "stderr".
-Show only "first" and "conbined" by default.
-
-{"command": "cat",
-"args": [["input", "first", "File", {"required":""}],
-         ["input", "second", "File", {}],
-         ["input", "rest", "List", {"type":"File"}]],
-"stdout": ["combined", "File", {"required":""}],
-"stderr": ["stderr", "String", {}]
-}
-
-Save as /home/{username}/.vistrails/CLTools/cat.clt
-Reload CLTools package in VisTrails. Test the new module.
-
diff --git a/vistrails/packages/CLTools/README.md b/vistrails/packages/CLTools/README.md
new file mode 100644
index 0000000..a0bc02a
--- /dev/null
+++ b/vistrails/packages/CLTools/README.md
@@ -0,0 +1,87 @@
+CLTools provide a way to wrap command line tools so that they can be used as modules in VisTrails.
+
+
+Using the Wizard
+================
+
+To launch the wizard run:
+
+    python vistrails/package/CLTools/wizard.py
+
+The wizard enables you to create and edit a wrapper for a command line tool. You can create input/output ports or constant arguments and ports for stdin/stdout/stderr pipes. You can view and import flags from man and help pages.
+
+Files should be saved as `{modulename}.clt` in the directory `.vistrails/CLTools/`
+
+Supported flags:
+
+    -c    Import a command with arguments automatically
+
+For example, create a wrapper for ls with two flags:
+
+    python wizard.py -c ls -l -A
+
+
+Creating a standalone package
+=============================
+
+1. Create a new directory in `.vistrails/userpackages/`
+2. Copy `__init__.py` and `init.py` from `vistrails/packages/CLTools` to the new directory.
+3. Update `name`, `identifier`, and `version` in `__init__.py` to the desired values
+4. Move all desired tools (`*.clt` files) to the new directory
+5. Test the new package
+
+
+File Format
+===========
+
+The wrapper is stored as a JSON file with the following syntax:
+
+* **ROOT** is a dict with the following possible keys:
+  * `command` (required) - value is the command to execute like "cat" or "/home/tommy/cat"
+  * `stdin` - handle stdin - value is a 3-list ["port name", **CLASS**, **STREAMOPTIONS**]
+  * `stdout` - handle stdout - value is a 3-list ["port name", **CLASS**, **STREAMOPTIONS**]
+  * `stderr` - handle stdout - value is a 3-list ["port name", **CLASS**, **STREAMOPTIONS**]
+  * `args` - list of ordered arguments that can either be constants, inputs, or outputs. See **ARG**.
+  * `options` - a dict of module options - see **OPTIONDICT**
+* **OPTIONDICT** is a dict with module specific options  
+  recognized options are:
+  * `std_using_files` - connect files to pipes so that they need not be stored in memory. This is useful for large files but may be unsafe since it does not use `subprocess.communicate`
+* **ARG** is a 4-list containing [**TYPE**, "name", **KLASS**, **ARGOPTIONDICT**]
+* **TYPE** is one of:
+  * `input` - create input port for this arg
+  * `output` - create output port for this arg
+  * `constant` - use "port name" directly as a constant string
+* **CLASS** can either be `File`, `String`, `Flag`, or `List`. Unknown types are handled as `String`. `Flag` is a boolean with the value specified by option "value". `List` is a list with subtype specified by option "type"
+* **ARGOPTIONDICT** is a dict containing argument options. recognized options are:
+  * `"type": "CLASS"` - used by List-types to specify subtype.
+  * `"flag": "name"` - Append name as a constant before the specified argument. If type is "List" it is appended before each item
+  * `"prefix": "name"` - Append name as a prefix to the final argument. If it is also a list it is appended to each item.
+  * `"required": ""` - Makes the port always visible in VisTrails.
+
+
+EXAMPLE
+=======
+
+* Wraps the command `cat` that takes 2 files as input named `first` and `second`.
+* Also takes a list of files as input named `rest`.  
+* Catches stdout as file, name it "combined".  
+* Catches stderr as string, name it "stderr".  
+* Shows only `first` and `combined` by default.
+
+    {
+        "command": "cat",
+        "args": [
+            ["input", "first", "File", {"required":""}],
+            ["input", "second", "File", {}],
+            ["input", "rest", "List", {"type":"File"}]
+        ],
+        "stdout": [
+            "combined", "File", {"required":""}
+        ],
+        "stderr": [
+            "stderr", "String", {}
+        ]
+    }
+
+Save as `/home/{username}/.vistrails/CLTools/cat.clt`  
+Reload CLTools package in VisTrails. Test the new module.
diff --git a/vistrails/packages/CLTools/__init__.py b/vistrails/packages/CLTools/__init__.py
index cf437f7..7859fad 100644
--- a/vistrails/packages/CLTools/__init__.py
+++ b/vistrails/packages/CLTools/__init__.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """ This package provides a way to wrap command line tools into VisTrails modules
 """
+from __future__ import division
+
 from vistrails.core.configuration import ConfigurationObject
 
 from identifiers import *
diff --git a/vistrails/packages/CLTools/identifiers.py b/vistrails/packages/CLTools/identifiers.py
index 4b61931..d64fe19 100644
--- a/vistrails/packages/CLTools/identifiers.py
+++ b/vistrails/packages/CLTools/identifiers.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 name = 'CLTools'
 identifier = "org.vistrails.vistrails.cltools"
 version = "0.1.2"
diff --git a/vistrails/packages/CLTools/init.py b/vistrails/packages/CLTools/init.py
index 5c66aa2..d42bc65 100644
--- a/vistrails/packages/CLTools/init.py
+++ b/vistrails/packages/CLTools/init.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED B Y THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED B Y THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import errno
 import json
 import os
@@ -60,7 +63,7 @@ class CLTools(Module):
 
     """
     def compute(self):
-        raise IncompleteImplementation
+        raise IncompleteImplementation # pragma: no cover
 
 
 SUFFIX = '.clt'
@@ -76,24 +79,26 @@ def _eintr_retry_call(func, *args):
     while True:
         try:
             return func(*args)
-        except (OSError, IOError), e:
+        except (OSError, IOError), e: # pragma: no cover
             if e.errno == errno.EINTR:
                 continue
             raise
 
 
-def add_tool(path):
+def _add_tool(path):
     # first create classes
     tool_name = os.path.basename(path)
-    if not tool_name.endswith(SUFFIX):
+    if isinstance(tool_name, unicode):
+        tool_name = tool_name.encode('utf-8')
+    if not tool_name.endswith(SUFFIX): # pragma: no cover
         return
     (tool_name, _) = os.path.splitext(tool_name)
 
-    if tool_name in cl_tools:
+    if tool_name in cl_tools: # pragma: no cover
         debug.critical("Package CLTools already added: '%s'" % tool_name)
     try:
         conf = json.load(open(path))
-    except ValueError as exc:
+    except ValueError as exc: # pragma: no cover
         debug.critical("Package CLTools could not parse '%s'" % path, exc)
         return
 
@@ -105,6 +110,7 @@ def add_tool(path):
         # add all arguments as an unordered list
         args = [self.conf['command']]
         file_std = 'options' in self.conf and 'std_using_files' in self.conf['options']
+        fail_with_cmd = 'options' in self.conf and 'fail_with_cmd' in self.conf['options']
         setOutput = [] # (name, File) - set File contents as output for name
         open_files = []
         stdin = None
@@ -122,7 +128,7 @@ def add_tool(path):
                         args.append('%s%s' % (options.get('prefix', ''), name))
             elif "input" == type:
                 # handle multiple inputs
-                values = self.forceGetInputListFromPort(name)
+                values = self.force_get_input_list(name)
                 if values and 'list' == klass:
                     values = values[0]
                     klass = options['type'].lower() \
@@ -136,7 +142,7 @@ def add_tool(path):
                         else:
                             # use name as flag
                             value = name
-                    elif 'file' == klass:
+                    elif klass in ('file', 'directory', 'path'):
                         value = value.name
                     # check for flag and append file name
                     if not 'flag' == klass and 'flag' in options:
@@ -156,34 +162,35 @@ def add_tool(path):
                     args.append(options['flag'])
                 args.append(fname)
                 if "file" == klass:
-                    self.setResult(name, file)
+                    self.set_output(name, file)
                 elif "string" == klass:
                     setOutput.append((name, file))
                 else:
                     raise ValueError
             elif "inputoutput" == type:
                 # handle single file that is both input and output
-                value = self.getInputFromPort(name)
+                value = self.get_input(name)
 
                 # create copy of infile to operate on
                 outfile = self.interpreter.filePool.create_file(
                         suffix=options.get('suffix', DEFAULTFILESUFFIX))
                 try:
                     shutil.copyfile(value.name, outfile.name)
-                except IOError, e:
-                    raise ModuleError(self, "Error copying file '%s': %s" % (
-                                      value.name, e))
+                except IOError, e: # pragma: no cover
+                    raise ModuleError(self,
+                                      "Error copying file '%s': %s" %
+                                      (value.name, debug.format_exception(e)))
                 value = '%s%s' % (options.get('prefix', ''), outfile.name)
                 # check for flag and append file name
                 if 'flag' in options:
                     args.append(options['flag'])
                 args.append(value)
-                self.setResult(name, outfile)
+                self.set_output(name, outfile)
         if "stdin" in self.conf:
             name, type, options = self.conf["stdin"]
             type = type.lower()
-            if self.hasInputFromPort(name):
-                value = self.getInputFromPort(name)
+            if self.has_input(name):
+                value = self.get_input(name)
                 if "file" == type:
                     if file_std:
                         f = open(value.name, 'rb')
@@ -200,7 +207,7 @@ def add_tool(path):
                         f = open(file.name, 'rb')
                     else:
                         stdin = value
-                else:
+                else: # pragma: no cover
                     raise ValueError
                 if file_std:
                     open_files.append(f)
@@ -214,10 +221,10 @@ def add_tool(path):
                 file = self.interpreter.filePool.create_file(
                         suffix=DEFAULTFILESUFFIX)
                 if "file" == type:
-                    self.setResult(name, file)
+                    self.set_output(name, file)
                 elif "string" == type:
                     setOutput.append((name, file))
-                else:
+                else: # pragma: no cover
                     raise ValueError
                 f = open(file.name, 'wb')
                 open_files.append(f)
@@ -231,10 +238,10 @@ def add_tool(path):
                 file = self.interpreter.filePool.create_file(
                         suffix=DEFAULTFILESUFFIX)
                 if "file" == type:
-                    self.setResult(name, file)
+                    self.set_output(name, file)
                 elif "string" == type:
                     setOutput.append((name, file))
-                else:
+                else: # pragma: no cover
                     raise ValueError
                 f = open(file.name, 'wb')
                 open_files.append(f)
@@ -242,7 +249,10 @@ def add_tool(path):
             else:
                 kwargs['stderr'] = subprocess.PIPE
 
-        return_code = self.conf.get('return_code', None)
+        if fail_with_cmd:
+            return_code = 0
+        else:
+            return_code = self.conf.get('return_code', None)
 
         env = {}
         # 0. add defaults
@@ -257,9 +267,10 @@ def add_tool(path):
                     value = value.strip()
                     if key:
                         env[key] = value
-            except Exception, e:
+            except Exception, e: # pragma: no cover
                 raise ModuleError(self,
-                                  "Error parsing configuration env: %s" % e)
+                                  "Error parsing configuration env: %s" % (
+                                  debug.format_exception(e)))
 
         if 'options' in self.conf and 'env' in self.conf['options']:
             try:
@@ -269,12 +280,13 @@ def add_tool(path):
                     value = value.strip()
                     if key:
                         env[key] = value
-            except Exception, e:
+            except Exception, e: # pragma: no cover
                 raise ModuleError(self,
-                                  "Error parsing module env: %s" % e)
+                                  "Error parsing module env: %s" % (
+                                  debug.format_exception(e)))
             
         if 'options' in self.conf and 'env_port' in self.conf['options']:
-            for e in self.forceGetInputListFromPort('env'):
+            for e in self.force_get_input_list('env'):
                 try:
                     for var in e.split(';'):
                         if not var:
@@ -284,9 +296,10 @@ def add_tool(path):
                         value = value.strip()
                         if key:
                             env[key] = value
-                except Exception, e:
+                except Exception, e: # pragma: no cover
                     raise ModuleError(self,
-                                      "Error parsing env port: %s" % e)
+                                      "Error parsing env port: %s" % (
+                                      debug.format_exception(e)))
 
         if env:
             kwargs['env'] = dict(os.environ)
@@ -315,18 +328,18 @@ def add_tool(path):
             if process.returncode != return_code:
                 raise ModuleError(self, "Command returned %d (!= %d)" % (
                                   process.returncode, return_code))
-        self.setResult('return_code', process.returncode)
+        self.set_output('return_code', process.returncode)
 
         for f in open_files:
             f.close()
 
         for name, file in setOutput:
             f = open(file.name, 'rb')
-            self.setResult(name, f.read())
+            self.set_output(name, f.read())
             f.close()
 
         if not file_std:
-            if stdout and "stdout" in self.conf:
+            if "stdout" in self.conf:
                 name, type, options = self.conf["stdout"]
                 type = type.lower()
                 if "file" == type:
@@ -335,12 +348,12 @@ def add_tool(path):
                     f = open(file.name, 'wb')
                     f.write(stdout)
                     f.close()
-                    self.setResult(name, file)
+                    self.set_output(name, file)
                 elif "string" == type:
-                    self.setResult(name, stdout)
-                else:
+                    self.set_output(name, stdout)
+                else: # pragma: no cover
                     raise ValueError
-            if stderr and "stderr" in self.conf:
+            if "stderr" in self.conf:
                 name, type, options = self.conf["stderr"]
                 type = type.lower()
                 if "file" == type:
@@ -349,10 +362,10 @@ def add_tool(path):
                     f = open(file.name, 'wb')
                     f.write(stderr)
                     f.close()
-                    self.setResult(name, file)
+                    self.set_output(name, file)
                 elif "string" == type:
-                    self.setResult(name, stderr)
-                else:
+                    self.set_output(name, stderr)
+                else: # pragma: no cover
                     raise ValueError
 
 
@@ -360,10 +373,10 @@ def add_tool(path):
     d = """This module is a wrapper for the command line tool '%s'""" % \
         conf['command']
     # create module
-    M = new_module(CLTools, tool_name,{"compute": compute,
-                                           "conf": conf,
-                                           "tool_name": tool_name,
-                                           "__doc__": d})
+    M = new_module(CLTools, tool_name, {"compute": compute,
+                                        "conf": conf,
+                                        "tool_name": tool_name,
+                                        "__doc__": d})
     reg = vistrails.core.modules.module_registry.get_module_registry()
     reg.add_module(M, package=identifiers.identifier,
                    package_version=identifiers.version)
@@ -371,7 +384,8 @@ def add_tool(path):
     def to_vt_type(s):
         # add recognized types here - default is String
         return '(basic:%s)' % \
-          {'file':'File', 'flag':'Boolean', 'list':'List',
+          {'file':'File', 'path':'Path', 'directory': 'Directory',
+           'flag':'Boolean', 'list':'List',
            'float':'Float','integer':'Integer'
           }.get(s.lower(), 'String')
     # add module ports
@@ -402,36 +416,18 @@ def add_tool(path):
     cl_tools[tool_name] = M
 
 
-def initialize(*args, **keywords):
-    if "CLTools" == identifiers.name:
-        # this is the original package 
-        location = os.path.join(vistrails.core.system.current_dot_vistrails(),
-                                "CLTools")
-        # make sure dir exist
-        if not os.path.isdir(location):
-            try:
-                debug.log("Creating CLTools directory...")
-                os.mkdir(location)
-            except:
-                debug.critical("""Could not create CLTools directory. Make
- sure '%s' does not exist and parent directory is writable""" % location)
-                sys.exit(1)
-    else:
-        # this is a standalone package so modules are placed in this directory
-        location = os.path.dirname(__file__)
-    
+def add_tool(path):
+    try:
+        _add_tool(path)
+    except Exception as exc:  # pragma: no cover
+        import traceback
+        debug.critical("Package CLTools failed to create module "
+           "from '%s': %s" % (path, exc),
+           traceback.format_exc())
 
-    reg = vistrails.core.modules.module_registry.get_module_registry()
-    reg.add_module(CLTools, abstract=True)
-    for path in os.listdir(location):
-        if path.endswith(SUFFIX):
-            try:
-                add_tool(os.path.join(location, path))
-            except Exception as exc:
-                import traceback
-                debug.critical("Package CLTools failed to create module "
-                   "from '%s': %s" % (os.path.join(location, path), exc),
-                   traceback.format_exc())
+
+def initialize(*args, **keywords):
+    reload_scripts(initial=True)
 
 
 def remove_all_scripts():
@@ -440,40 +436,51 @@ def remove_all_scripts():
         del cl_tools[tool_name]
         reg.delete_module(identifiers.identifier, tool_name)
 
-def reload_scripts():
-    remove_all_scripts()
+def reload_scripts(initial=False, name=None):
+    reg = vistrails.core.modules.module_registry.get_module_registry()
+    if not initial:
+        if name is None:
+            remove_all_scripts()
+        else:
+            del cl_tools[name]
+            reg.delete_module(identifiers.identifier, name)
+
     if "CLTools" == identifiers.name:
         # this is the original package
         location = os.path.join(vistrails.core.system.current_dot_vistrails(),
                                 "CLTools")
         # make sure dir exist
-        if not os.path.isdir(location):
+        if not os.path.isdir(location): # pragma: no cover # pragma: no branch
             try:
                 debug.log("Creating CLTools directory...")
                 os.mkdir(location)
-            except:
-                debug.critical("""Could not create CLTools directory. Make
- sure '%s' does not exist and parent directory is writable""" % location)
+            except Exception, e:
+                debug.critical("Could not create CLTools directory. Make "
+                               "sure '%s' does not exist and parent directory "
+                               "is writable" % location,
+                               e)
                 sys.exit(1)
-    else:
+    else:  # pragma: no cover
         # this is a standalone package so modules are placed in this directory
         location = os.path.dirname(__file__)
-    
-    for path in os.listdir(location):
-        if path.endswith(SUFFIX):
-            try:
+
+    if initial:
+        reg.add_module(CLTools, abstract=True)
+    if name is None:
+        for path in os.listdir(location):
+            if path.endswith(SUFFIX):  # pragma: no branch
                 add_tool(os.path.join(location, path))
-            except Exception as exc:
-                import traceback
-                debug.critical("Package CLTools failed to create module "
-                   "from '%s': %s" % (os.path.join(location, path), exc),
-                   traceback.format_exc())
+    else:
+        path = os.path.join(location, name + SUFFIX)
+        if os.path.exists(path):
+            add_tool(path)
 
-    from vistrails.core.interpreter.cached import CachedInterpreter
-    CachedInterpreter.clear_package(identifiers.identifier)
+    if not initial:
+        from vistrails.core.interpreter.cached import CachedInterpreter
+        CachedInterpreter.clear_package(identifiers.identifier)
 
-    from vistrails.gui.vistrails_window import _app
-    _app.invalidate_pipelines()
+        from vistrails.gui.vistrails_window import _app
+        _app.invalidate_pipelines()
 
 
 wizards_list = []
@@ -484,13 +491,16 @@ def menu_items():
     callback function that will be executed when that menu item is selected.
     
     """
-    # if wizard.py does not exist, assume it is a standalone package and abort
     try:
         from wizard import QCLToolsWizardWindow
-    except:
-        return
+    except Exception, e: # pragma: no cover
+        if "CLTools" == identifiers.name:
+            debug.unexpected_exception(e)
+            raise
+        else:
+            return
     lst = []
-    if "CLTools" == identifiers.name:
+    if "CLTools" == identifiers.name: # pragma: no branch
         def open_wizard():
             window = QCLToolsWizardWindow(reload_scripts=reload_scripts)
             wizards_list.append(window)
@@ -504,6 +514,20 @@ def finalize():
     pass
 
 
+def contextMenuName(name):
+    if "CLTools" == name:
+        return "Reload All Scripts"
+    else:
+        return "Reload Script"
+
+
+def callContextMenu(name):
+    if "CLTools" == name:
+        reload_scripts()
+    else:
+        reload_scripts(name=name)
+
+
 ###############################################################################
 
 import unittest
@@ -515,7 +539,7 @@ class TestCLTools(unittest.TestCase):
     def setUpClass(cls):
         # first make sure CLTools is loaded
         pm = get_package_manager()
-        if 'CLTools' not in pm._package_list:
+        if 'CLTools' not in pm._package_list: # pragma: no cover # pragma: no branch
             pm.late_enable_package('CLTools')
         remove_all_scripts()
         cls.testdir = os.path.join(packages_directory(), 'CLTools', 'test_files')
@@ -523,7 +547,7 @@ class TestCLTools(unittest.TestCase):
         for name in os.listdir(cls.testdir):
             if not name.endswith(SUFFIX):
                 continue
-            add_tool(os.path.join(cls.testdir, name))
+            _add_tool(os.path.join(cls.testdir, name))
             toolname = os.path.splitext(name)[0]
             cls._tools[toolname] = cl_tools[toolname]
         cls._old_dir = os.getcwd()
@@ -535,11 +559,12 @@ class TestCLTools(unittest.TestCase):
         reload_scripts()
 
     def do_the_test(self, toolname):
-        with intercept_results(self._tools['intern_cltools_1'],
+        with intercept_results(
+                self._tools[toolname],
                 'return_code', 'f_out', 'stdout') as (
                 return_code, f_out, stdout):
             self.assertFalse(execute([
-                    ('intern_cltools_1', 'org.vistrails.vistrails.cltools', [
+                    (toolname, 'org.vistrails.vistrails.cltools', [
                         ('f_in', [('File', self.testdir + '/test_1.cltest')]),
                         ('chars', [('List', '["a", "b", "c"]')]),
                         ('false', [('Boolean', 'False')]),
diff --git a/vistrails/packages/CLTools/test_files/test_script_1.py b/vistrails/packages/CLTools/test_files/test_script_1.py
index 31a76c6..dca9989 100644
--- a/vistrails/packages/CLTools/test_files/test_script_1.py
+++ b/vistrails/packages/CLTools/test_files/test_script_1.py
@@ -1,3 +1,7 @@
+# pragma: no testimport
+
+from __future__ import division
+
 import sys
 
 
diff --git a/vistrails/packages/CLTools/wizard.py b/vistrails/packages/CLTools/wizard.py
index 51a0895..ad17e14 100644
--- a/vistrails/packages/CLTools/wizard.py
+++ b/vistrails/packages/CLTools/wizard.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 if __name__ == '__main__':
     import sip
     sip.setapi('QString', 2)
@@ -97,7 +100,7 @@ class Command(object):
                 self.process = subprocess.Popen(self.command, **kwargs)
                 self.output, self.error = self.process.communicate()
                 self.status = self.process.returncode
-            except:
+            except Exception:
                 import traceback
                 self.error = traceback.format_exc()
                 self.status = -1
@@ -216,6 +219,12 @@ class QCLToolsWizard(QtGui.QWidget):
         self.stdAsFiles.setCheckable(True)
         self.toolBar.addAction(self.stdAsFiles)
 
+        self.failWithCmd = QtGui.QAction('fail execution if return != 0', self)
+        self.failWithCmd.setToolTip('If selected, VisTrails will check the exitcode, and abort the execution if not 0')
+        self.failWithCmd.setCheckable(True)
+        self.failWithCmd.setChecked(True)
+        self.toolBar.addAction(self.failWithCmd)
+
         self.toolBar.addSeparator()
 
         self.previewPorts = QtGui.QAction('preview', self)
@@ -360,6 +369,7 @@ class QCLToolsWizard(QtGui.QWidget):
         self.argList = QtGui.QListWidget()
         self.layout().addWidget(self.argList)
         self.stdAsFiles.setChecked(False)
+        self.failWithCmd.setChecked(True)
         self.setTitle()
         self.generate_preview()
     
@@ -403,6 +413,8 @@ class QCLToolsWizard(QtGui.QWidget):
                                 'env_port' in conf['options'])
         self.stdAsFiles.setChecked('options' in conf and
                                    'std_using_files' in conf['options'])
+        self.failWithCmd.setChecked('options' in conf and
+                                    'fail_with_cmd' in conf['options'])
         self.envOption = conf['options']['env'] \
                  if ('options' in conf and 'env' in conf['options']) else None
         self.conf = conf
@@ -430,6 +442,8 @@ class QCLToolsWizard(QtGui.QWidget):
         options = {}
         if self.stdAsFiles.isChecked():
             options['std_using_files'] = ''
+        if self.failWithCmd.isChecked():
+            options['fail_with_cmd'] = ''
         if self.envPort.isChecked():
             options['env_port'] = ''
         if self.envOption:
@@ -683,7 +697,7 @@ class QCLToolsWizard(QtGui.QWidget):
             for a, b in encode_list:
                 text = text.replace(a, b)
             return text
-        except:
+        except Exception:
             return None
     
     def generateFromManPage(self):
@@ -788,7 +802,8 @@ class QCLToolsWizard(QtGui.QWidget):
 class QArgWidget(QtGui.QWidget):
     """ Widget for configuring an argument """
     KLASSES = {
-            'input': ['flag', 'file', 'string', 'integer', 'float', 'list'],
+            'input': ['flag', 'file', 'path', 'directory',
+                      'string', 'integer', 'float', 'list'],
             'output': ['file', 'string'],
             'inputoutput': ['file'],
             'stdin': ['file', 'string'],
@@ -801,6 +816,8 @@ class QArgWidget(QtGui.QWidget):
             'integer': 'Integer',
             'float': 'Float',
             'file': 'File',
+            'path': 'Path',
+            'directory': 'Directory',
             'list': 'List',
         }
 
@@ -866,7 +883,7 @@ class QArgWidget(QtGui.QWidget):
             self.klassDict[n] = i
         self.klassList.setCurrentIndex(self.klassDict.get(self.klass, 0))
         #label = QtGui.QLabel('Class:')
-        tt = 'Port Type. Can be String, Integer, Float, File or Boolean Flag. List means an input list of one of the other types. Only File and String should be used for output ports.'
+        tt = 'Port Type. Can be String, Integer, Float, File/Directory/Path or Boolean Flag. List means an input list of one of the other types. Only File and String should be used for output ports.'
         self.klassList.setToolTip(tt)
         #label.setToolTip(tt)
         #layout1.addWidget(label)
@@ -911,7 +928,7 @@ class QArgWidget(QtGui.QWidget):
         layout2.addWidget(self.required)
         
         # subtype
-        self.subList = ['String', 'Integer', 'Float', 'File']
+        self.subList = ['String', 'Integer', 'Float', 'File', 'Directory', 'Path']
         self.subDict = dict(zip(self.subList, xrange(len(self.subList))))
         self.subDict.update(dict(zip([s.lower() for s in self.subList], xrange(len(self.subList)))))
         self.subtype = QtGui.QComboBox()
@@ -998,14 +1015,14 @@ class QArgWidget(QtGui.QWidget):
             self.suffix.setText(self.options.get('suffix', ''))
         self.typeChanged()
         self.klassChanged()
-            
+
     def toList(self):
         self.getValues()
         if self.argtype not in self.stdTypes:
-            return [self.argtype, self.name, self.klass, self.options]
+            return [self.argtype, self.name, self.klass, dict(self.options)]
         else:
-            return [self.name, self.klass, self.options]
-            
+            return [self.name, self.klass, dict(self.options)]
+
     def fromList(self, arg):
         if self.argtype not in self.stdTypes:
             self.argtype, self.name, klass, self.options = arg
@@ -1045,9 +1062,15 @@ class QArgWidget(QtGui.QWidget):
 
     def guess(self, name, count=0):
         """ add argument by guessing what the arg might be """
-        if '.' in name or '/' in name or '\\' in name: # guess file
-            self.fromList(['Input', 'file%s' % count, 'File',
-                           {'desc':'"%s" guessed to be an Input file' % name}])
+        if '.' in name or '/' in name or '\\' in name: # guess path
+            if os.path.isfile(name):
+                guessed, type_ = 'file', 'File'
+            elif os.path.isdir(name):
+                guessed, type_ = 'directory', 'Directory'
+            else:
+                guessed, type_ = 'path', 'Path'
+            self.fromList(['Input', '%s%d' % (guessed, count), type_,
+                           {'desc':'"%s" guessed to be an Input %s' % (name, guessed)}])
         elif name.startswith('-'): # guess flag
             self.fromList(['Input', 'flag%s' % name, 'Flag',
                            {'desc':'"%s" guessed to be a flag' % name,
diff --git a/vistrails/packages/HTTP/__init__.py b/vistrails/packages/HTTP/__init__.py
deleted file mode 100644
index c4046f3..0000000
--- a/vistrails/packages/HTTP/__init__.py
+++ /dev/null
@@ -1,46 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-"""HTTP provides packages for HTTP-based file fetching. This provides
-a location-independent way of referring to files. This package uses a
-local cache of the files, inside the per-user VisTrails
-directory. This way, files that haven't been changed do not need
-downloading. The check is performed efficiently using the HTTP GET
-headers.
-"""
-
-identifier = 'org.vistrails.vistrails.http'
-name = 'HTTP'
-version = '0.9.1'
-old_identifiers = ['edu.utah.sci.vistrails.http']
diff --git a/vistrails/packages/HTTP/http_directory.py b/vistrails/packages/HTTP/http_directory.py
deleted file mode 100644
index d24d492..0000000
--- a/vistrails/packages/HTTP/http_directory.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# https://gist.github.com/remram44/6540454
-
-from HTMLParser import HTMLParser
-import urllib2
-import os
-import re
-
-
-re_url = re.compile(r'^(([a-zA-Z_-]+)://([^/]+))(/.*)?$')
-
-def resolve_link(link, url):
-    m = re_url.match(link)
-    if m is not None:
-        if not m.group(4):
-            # http://domain -> http://domain/
-            return link + '/'
-        else:
-            return link
-    elif link[0] == '/':
-        # /some/path
-        murl = re_url.match(url)
-        return murl.group(1) + link
-    else:
-        # relative/path
-        if url[-1] == '/':
-            return url + link
-        else:
-            return url + '/' + link
-
-
-class ListingParser(HTMLParser):
-    """Parses an HTML file and build a list of links.
-
-    Links are stored into the 'links' set. They are resolved into absolute
-    links.
-    """
-    def __init__(self, url):
-        HTMLParser.__init__(self)
-
-        if url[-1] != '/':
-            url += '/'
-        self.__url = url
-        self.links = set()
-
-    def handle_starttag(self, tag, attrs):
-        if tag == 'a':
-            for key, value in attrs:
-                if key == 'href':
-                    if not value:
-                        continue
-                    value = resolve_link(value, self.__url)
-                    self.links.add(value)
-                    break
-
-
-def download_directory(url, target):
-    def mkdir():
-        if not mkdir.done:
-            try:
-                os.mkdir(target)
-            except OSError:
-                pass
-            mkdir.done = True
-    mkdir.done = False
-
-    response = urllib2.urlopen(url)
-
-    if response.info().type == 'text/html':
-        contents = response.read()
-
-        parser = ListingParser(url)
-        parser.feed(contents)
-        for link in parser.links:
-            link = resolve_link(link, url)
-            if link[-1] == '/':
-                link = link[:-1]
-            if not link.startswith(url):
-                continue
-            name = link.rsplit('/', 1)[1]
-            if '?' in name:
-                continue
-            mkdir()
-            download_directory(link, os.path.join(target, name))
-        if not mkdir.done:
-            # We didn't find anything to write inside this directory
-            # Maybe it's a HTML file?
-            if url[-1] != '/':
-                end = target[-5:].lower()
-                if not (end.endswith('.htm') or end.endswith('.html')):
-                    target = target + '.html'
-                with open(target, 'wb') as fp:
-                    fp.write(contents)
-    else:
-        buffer_size = 4096
-        with open(target, 'wb') as fp:
-            chunk = response.read(buffer_size)
-            while chunk:
-                fp.write(chunk)
-                chunk = response.read(buffer_size)
-
-
-###############################################################################
-
-import unittest
-
-
-class TestLinkResolution(unittest.TestCase):
-    def test_absolute_link(self):
-        self.assertEqual(
-                resolve_link('http://website.org/p/test.txt',
-                             'http://some/other/url'),
-                'http://website.org/p/test.txt')
-        self.assertEqual(
-                resolve_link('http://website.org',
-                             'http://some/other/url'),
-                'http://website.org/')
-
-    def test_absolute_path(self):
-        self.assertEqual(
-                resolve_link('/p/test.txt', 'http://some/url'),
-                'http://some/p/test.txt')
-        self.assertEqual(
-                resolve_link('/p/test.txt', 'http://some/url/'),
-                'http://some/p/test.txt')
-        self.assertEqual(
-                resolve_link('/p/test.txt', 'http://site'),
-                'http://site/p/test.txt')
-        self.assertEqual(
-                resolve_link('/p/test.txt', 'http://site/'),
-                'http://site/p/test.txt')
-
-    def test_relative_path(self):
-        self.assertEqual(
-                resolve_link('some/file', 'http://site/folder'),
-                'http://site/folder/some/file')
-        self.assertEqual(
-                resolve_link('some/file', 'http://site/folder/'),
-                'http://site/folder/some/file')
-        self.assertEqual(
-                resolve_link('some/dir/', 'http://site/folder'),
-                'http://site/folder/some/dir/')
-
-
-class TestParser(unittest.TestCase):
-    def test_parse(self):
-        parser = ListingParser('http://a.remram.fr/test')
-        parser.feed("""
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html><head><title>
-Index of /test</title></head><body><h1>Index of /test</h1><table><tr><th>
-<img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a>
-</th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size
-</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5">
-<hr></th></tr><tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td>
-<td><a href="/">Parent Directory</a></td><td> </td><td align="right">  - 
-</td><td> </td></tr><tr><td valign="top">
-<img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="a">a</a></td>
-<td align="right">11-Sep-2013 15:46  </td><td align="right">  3 </td><td> 
-</td></tr><tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td>
-<td><a href="/bb">bb</a></td><td align="right">11-Sep-2013 15:46  </td>
-<td align="right">  3 </td><td> </td></tr><tr><td valign="top">
-<img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="/cc/">cc/</a></td>
-<td align="right">11-Sep-2013 15:46  </td><td align="right">  - </td><td> 
-</td></tr><tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td>
-<td><a href="http://a.remram.fr/dd">dd/</a></td><td align="right">
-11-Sep-2013 15:46  </td><td align="right">  - </td><td> </td></tr><tr>
-<th colspan="5"><hr></th></tr></table></body></html>
-        """)
-        links = set(l for l in parser.links if '?' not in l)
-        self.assertEqual(links, set([
-                'http://a.remram.fr/',
-                'http://a.remram.fr/test/a',
-                'http://a.remram.fr/bb',
-                'http://a.remram.fr/cc/',
-                'http://a.remram.fr/dd',
-        ]))
diff --git a/vistrails/packages/HTTP/init.py b/vistrails/packages/HTTP/init.py
deleted file mode 100644
index 41279b4..0000000
--- a/vistrails/packages/HTTP/init.py
+++ /dev/null
@@ -1,539 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-"""HTTP provides packages for HTTP-based file fetching. This provides
-a location-independent way of referring to files. This package uses a
-local cache of the files, inside the per-user VisTrails
-directory. This way, files that haven't been changed do not need
-downloading. The check is performed efficiently using the HTTP GET
-headers.
-"""
-from vistrails.core.modules.vistrails_module import ModuleError
-from vistrails.core.configuration import get_vistrails_persistent_configuration
-from vistrails.gui.utils import show_warning
-from vistrails.core.modules.vistrails_module import Module
-import vistrails.core.modules.basic_modules
-import vistrails.core.modules.module_registry
-from vistrails.core import debug
-from vistrails.core.system import current_dot_vistrails
-import vistrails.gui.repository
-
-import datetime
-import email.utils
-import hashlib
-import os.path
-import sys
-import unittest
-import urllib
-import urllib2
-
-from vistrails.core.repository.poster.encode import multipart_encode
-from vistrails.core.repository.poster.streaminghttp import register_openers
-
-from vistrails.core.utils import DummyView
-
-from http_directory import download_directory
-
-# special file uploaders used to push files to repository
-
-package_directory = None
-
-###############################################################################
-
-class HTTPFile(Module):
-    """ Downloads file from URL """
-
-    def compute(self):
-        self.checkInputPort('url')
-        url = self.getInputFromPort("url")
-        (result, downloaded_file, local_filename) = self.download(url)
-        self.setResult("local_filename", local_filename)
-        if result == 2:
-            raise ModuleError(self, downloaded_file)
-        else:
-            self.setResult("file", downloaded_file)
-
-    def download(self, url):
-        """download(url:string) -> (result: int, downloaded_file: File,
-                                    local_filename:string)
-        Tries to download a file from url. It returns a tuple with:
-        result: 0 -> success
-                1 -> couldn't download the file, but found a cached version
-                2 -> failed (in this case downloaded_file will contain the 
-                             error message)
-        downloaded_file: The downloaded file or the error message in case it
-                         failed
-                         
-        local_filename: the path to the local_filename
-        
-        """
-        
-        self._parse_url(url)
-
-        opener = urllib2.build_opener()
-
-        local_filename = self._local_filename(url)
-
-        # Get ETag from disk
-        try:
-            with open(local_filename + '.etag') as etag_file:
-                etag = etag_file.read()
-        except IOError:
-            etag = None
-
-        try:
-            request = urllib2.Request(url)
-            if etag is not None:
-                request.add_header(
-                    'If-None-Match',
-                    etag)
-            try:
-                mtime = email.utils.formatdate(os.path.getmtime(local_filename),
-                                               usegmt=True)
-                request.add_header(
-                    'If-Modified-Since',
-                    mtime)
-            except OSError:
-                pass
-            f1 = opener.open(request)
-        except urllib2.URLError, e:
-            if isinstance(e, urllib2.HTTPError) and e.code == 304:
-                # Not modified
-                result = vistrails.core.modules.basic_modules.File()
-                result.name = local_filename
-                return (0, result, local_filename)
-            if self._file_is_in_local_cache(local_filename):
-                debug.warning('A network error occurred. HTTPFile will use a '
-                              'cached version of the file')
-                result = vistrails.core.modules.basic_modules.File()
-                result.name = local_filename
-                return (1, result, local_filename)
-            else:
-                return (2, (str(e)), local_filename)
-        else:
-            try:
-                mod_header = f1.headers['last-modified']
-            except KeyError:
-                mod_header = None
-            try:
-                size_header = f1.headers['content-length']
-                if not size_header:
-                    raise ValueError
-                size_header = int(size_header)
-            except (KeyError, ValueError):
-                size_header = None
-
-            result = vistrails.core.modules.basic_modules.File()
-            result.name = local_filename
-
-            if (not self._file_is_in_local_cache(local_filename) or
-                    not mod_header or
-                    self._is_outdated(mod_header, local_filename)):
-                try:
-                    dl_size = 0
-                    CHUNKSIZE = 4096
-                    f2 = open(local_filename, 'wb')
-                    while True:
-                        if size_header is not None:
-                            self.logging.update_progress(
-                                    self,
-                                    dl_size*1.0/size_header)
-                        chunk = f1.read(CHUNKSIZE)
-                        if not chunk:
-                            break
-                        dl_size += len(chunk)
-                        f2.write(chunk)
-                    f2.close()
-                    f1.close()
-
-                except Exception, e:
-                    try:
-                        os.unlink(local_filename)
-                    except OSError:
-                        pass
-                    return (2, ("Error retrieving URL: %s" % e), local_filename)
-            result.name = local_filename
-
-            # Save ETag
-            try:
-                etag = f1.headers['ETag']
-            except KeyError:
-                pass
-            else:
-                with open(local_filename + '.etag', 'w') as etag_file:
-                    etag = etag_file.write(etag)
-
-            return (0, result, local_filename)
-        
-    ##########################################################################
-
-    def _parse_url(self, url):
-        s = url.split('/')
-        try:
-            self.host = s[2]
-            self.filename = '/' + '/'.join(s[3:])
-        except:
-            raise ModuleError(self, "Malformed URL: %s" % url)
-
-    def _is_outdated(self, remoteHeader, localFile):
-        """Checks whether local file is outdated."""
-        local_time = \
-                datetime.datetime.utcfromtimestamp(os.path.getmtime(localFile))
-        try:
-            remote_time = datetime.datetime.strptime(remoteHeader,
-                                                     "%a, %d %b %Y %H:%M:%S %Z")
-        except ValueError:
-            try:
-                remote_time = datetime.datetime.strptime(remoteHeader,
-                                                         "%a, %d %B %Y %H:%M:%S %Z")
-            except ValueError:
-                # unable to parse last-modified header, download file again
-                debug.warning("Unable to parse Last-Modified header"
-                              ", downloading file")
-                return True
-        return remote_time > local_time
-
-    def _file_is_in_local_cache(self, local_filename):
-        return os.path.isfile(local_filename)
-
-    def _local_filename(self, url):
-        return package_directory + '/' + urllib.quote_plus(url)
-
-
-class HTTPDirectory(Module):
-    """Downloads a whole directory recursively from a URL
-    """
-
-    def compute(self):
-        self.checkInputPort('url')
-        url = self.getInputFromPort('url')
-        local_path = self.download(url)
-        self.setResult('local_path', local_path)
-        local_dir = vistrails.core.modules.basic_modules.Directory()
-        local_dir.name = local_path
-        self.setResult('directory', local_dir)
-
-    def download(self, url):
-        local_path = self.interpreter.filePool.create_directory(
-                prefix='vt_http').name
-        download_directory(url, local_path)
-        return local_path
-
-
-class RepoSync(Module):
-    """ VisTrails Server version of RepoSync modules. Customized to play 
-    nicely with crowdlabs. Needs refactoring.
-
-    RepoSync enables data to be synced with a online repository. The designated file
-    parameter will be uploaded to the repository on execution,
-    creating a new pipeline version that links to online repository data.
-    If the local file isn't available, then the online repository data is used.
-    """
-
-    def __init__(self):
-        Module.__init__(self)
-
-        config = get_vistrails_persistent_configuration()
-        if config.check('webRepositoryURL'):
-            self.base_url = config.webRepositoryURL
-        else:
-            raise ModuleError(self,
-                              ("No webRepositoryURL value defined"
-                               " in the Expert Configuration"))
-
-        # check if we are running in server mode
-        # this effects how the compute method functions
-        if config.check('isInServerMode'):
-            self.is_server = bool(config.isInServerMode)
-        else:
-            self.is_server = False
-
-        # TODO: this '/' check should probably be done in core/configuration.py
-        if self.base_url[-1] == '/':
-            self.base_url = self.base_url[:-1]
-
-    # used for invaliding cache when user isn't logged in to crowdLabs
-    # but wants to upload data
-    def invalidate_cache(self):
-        return False
-
-    def validate_cache(self):
-        return True
-
-    def _file_is_in_local_cache(self, local_filename):
-        return os.path.isfile(local_filename)
-
-    def checksum_lookup(self):
-        """ checks if the repository has the wanted data """
-
-        checksum_url = "%s/datasets/exists/%s/" % (self.base_url, self.checksum)
-        self.on_server = False
-        try:
-            check_dataset_on_repo = urllib2.urlopen(url=checksum_url)
-            self.up_to_date = True if \
-                    check_dataset_on_repo.read() == 'uptodate' else False
-            self.on_server = True
-        except urllib2.HTTPError:
-            self.up_to_date = True
-
-    def data_sync(self):
-        """ downloads/uploads/uses the local file depending on availability """
-        self.checksum_lookup()
-
-        # local file not on repository, so upload
-        if not self.on_server and os.path.isfile(self.in_file.name):
-            cookiejar = vistrails.gui.repository.QRepositoryDialog.cookiejar
-            if cookiejar:
-                register_openers(cookiejar=cookiejar)
-
-                params = {'dataset_file': open(self.in_file.name, 'rb'),
-                          'name': self.in_file.name.split('/')[-1],
-                          'origin': 'vistrails',
-                          'checksum': self.checksum}
-
-                upload_url = "%s/datasets/upload/" % self.base_url
-
-                datagen, headers = multipart_encode(params)
-                request = urllib2.Request(upload_url, datagen, headers)
-                try:
-                    result = urllib2.urlopen(request)
-                    if result.code != 200:
-                        show_warning("Upload Failure",
-                                     "Data failed to upload to repository")
-                        # make temporarily uncachable
-                        self.is_cacheable = self.invalidate_cache
-                    else:
-                        debug.warning("Push to repository was successful")
-                        # make sure module caches
-                        self.is_cacheable = self.validate_cache
-                except Exception, e:
-                    show_warning("Upload Failure",
-                                 "Data failed to upload to repository")
-                    # make temporarily uncachable
-                    self.is_cacheable = self.invalidate_cache
-                debug.warning('RepoSync uploaded %s to the repository' % \
-                              self.in_file.name)
-            else:
-                show_warning("Please login", ("You must be logged into the web"
-                                              " repository in order to upload "
-                                              "data. No data was synced"))
-                # make temporarily uncachable
-                self.is_cacheable = self.invalidate_cache
-
-            # use local data
-            self.setResult("file", self.in_file)
-        else:
-            # file on repository mirrors local file, so use local file
-            if self.up_to_date and os.path.isfile(self.in_file.name):
-                self.setResult("file", self.in_file)
-            else:
-                # local file not present or out of date, download or used cached
-                self.url = "%s/datasets/download/%s" % (self.base_url,
-                                                       self.checksum)
-                local_filename = package_directory + '/' + \
-                        urllib.quote_plus(self.url)
-                if not self._file_is_in_local_cache(local_filename):
-                    # file not in cache, download.
-                    try:
-                        urllib.urlretrieve(self.url, local_filename)
-                    except IOError, e:
-                        raise ModuleError(self, ("Invalid URL: %s" % e))
-                out_file = vistrails.core.modules.basic_modules.File()
-                out_file.name = local_filename
-                debug.warning('RepoSync is using repository data')
-                self.setResult("file", out_file)
-
-
-    def compute(self):
-        # if server, grab local file using checksum id
-        if self.is_server:
-            self.checkInputPort('checksum')
-            self.checksum = self.getInputFromPort("checksum")
-            # get file path
-            path_url = "%s/datasets/path/%s/"%(self.base_url, self.checksum)
-            try:
-                dataset_path_request = urllib2.urlopen(url=path_url)
-                dataset_path = dataset_path_request.read()
-            except urllib2.HTTPError:
-                pass
-
-            if os.path.isfile(dataset_path):
-                out_file = vistrails.core.modules.basic_modules.File()
-                out_file.name = dataset_path
-                self.setResult("file", out_file)
-        else: # is client
-            self.checkInputPort('file')
-            self.in_file = self.getInputFromPort("file")
-            if os.path.isfile(self.in_file.name):
-                # do size check
-                size = os.path.getsize(self.in_file.name)
-                if size > 26214400:
-                    show_warning("File is too large", ("file is larger than 25MB, "
-                                 "unable to sync with web repository"))
-                    self.setResult("file", self.in_file)
-                else:
-                    # compute checksum
-                    f = open(self.in_file.name, 'r')
-                    self.checksum = hashlib.sha1()
-                    block = 1
-                    while block:
-                        block = f.read(128)
-                        self.checksum.update(block)
-                    f.close()
-                    self.checksum = self.checksum.hexdigest()
-
-                    # upload/download file
-                    self.data_sync()
-
-                    # set checksum param in module
-                    if not self.hasInputFromPort('checksum'):
-                        self.change_parameter('checksum', [self.checksum])
-
-            else:
-                # local file not present
-                if self.hasInputFromPort('checksum'):
-                    self.checksum = self.getInputFromPort("checksum")
-
-                    # download file
-                    self.data_sync()
-
-def initialize(*args, **keywords):
-    reg = vistrails.core.modules.module_registry.get_module_registry()
-    basic = vistrails.core.modules.basic_modules
-
-    reg.add_module(HTTPFile)
-    reg.add_input_port(HTTPFile, "url", (basic.String, 'URL'))
-    reg.add_output_port(HTTPFile, "file", (basic.File, 'local File object'))
-    reg.add_output_port(HTTPFile, "local_filename",
-                        (basic.String, 'local filename'), optional=True)
-
-    reg.add_module(HTTPDirectory)
-    reg.add_input_port(HTTPDirectory, 'url', (basic.String, "URL"))
-    reg.add_output_port(HTTPDirectory, 'directory',
-                        (basic.Directory, "local Directory object"))
-    reg.add_output_port(HTTPDirectory, 'local_path',
-                        (basic.String, "local path"), optional=True)
-
-    reg.add_module(RepoSync)
-    reg.add_input_port(RepoSync, "file", (basic.File, 'File'))
-    reg.add_input_port(RepoSync, "checksum",
-                       (basic.String, 'Checksum'), optional=True)
-    reg.add_output_port(RepoSync, "file", (basic.File,
-                                           'Repository Synced File object'))
-    reg.add_output_port(RepoSync, "checksum",
-                        (basic.String, 'Checksum'), optional=True)
-
-    global package_directory
-    dotVistrails = current_dot_vistrails()
-    package_directory = os.path.join(dotVistrails, "HTTP")
-
-    if not os.path.isdir(package_directory):
-        try:
-            debug.log("Creating HTTP package directory: %s" % package_directory)
-            os.mkdir(package_directory)
-        except:
-            debug.critical(("Create directory failed. Make sure '%s' does not"
-                           " exist and parent directory is writable") %
-                            package_directory)
-            sys.exit(1)
-
-##############################################################################
-
-
-class TestHTTPFile(unittest.TestCase):
-    @classmethod
-    def setUpClass(cls):
-        from vistrails.core.packagemanager import get_package_manager
-        from vistrails.core.modules.module_registry import MissingPackage
-        pm = get_package_manager()
-        try:
-            pm.get_package('org.vistrails.vistrails.http')
-        except MissingPackage:
-            pm.late_enable_package('HTTP')
-
-    def testParseURL(self):
-        foo = HTTPFile()
-        foo._parse_url('http://www.sci.utah.edu/~cscheid/stuff/vtkdata-5.0.2.zip')
-        self.assertEquals(foo.host, 'www.sci.utah.edu')
-        self.assertEquals(foo.filename, '/~cscheid/stuff/vtkdata-5.0.2.zip')
-
-    def testIncorrectURL(self):
-        from vistrails.tests.utils import execute
-        self.assertTrue(execute([
-                ('HTTPFile', identifier, [
-                    ('url', [('String', 'http://idbetthisdoesnotexistohrly')]),
-                ]),
-            ]))
-
-    def testIncorrectURL_2(self):
-        from vistrails.tests.utils import execute
-        self.assertTrue(execute([
-                ('HTTPFile', identifier, [
-                    ('url', [('String', 'http://neitherodesthisohrly')]),
-                ]),
-            ]))
-
-class TestHTTPDirectory(unittest.TestCase):
-    def test_download(self):
-        url = 'http://www.vistrails.org/testing/httpdirectory/test/'
-
-        import shutil
-        import tempfile
-        testdir = tempfile.mkdtemp(prefix='vt_test_http_')
-        try:
-            download_directory(url, testdir)
-            files = {}
-            def addfiles(dirpath):
-                td = os.path.join(testdir, dirpath)
-                for name in os.listdir(td):
-                    filename = os.path.join(testdir, dirpath, name)
-                    dn = os.path.join(dirpath, name)
-                    if os.path.isdir(filename):
-                        addfiles(os.path.join(dirpath, name))
-                    else:
-                        with open(filename, 'rb') as f:
-                            files[dn.replace(os.sep, '/')] = f.read()
-            addfiles('')
-            self.assertEqual(len(files), 4)
-            del files['f.html']
-            self.assertEqual(files, {
-                    'a': 'aa\n',
-                    'bb': 'bb\n',
-                    'cc/d': 'dd\n',
-                })
-        finally:
-            shutil.rmtree(testdir)
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/vistrails/packages/ImageMagick/__init__.py b/vistrails/packages/ImageMagick/__init__.py
index 651420e..38ff0d2 100644
--- a/vistrails/packages/ImageMagick/__init__.py
+++ b/vistrails/packages/ImageMagick/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -38,6 +39,8 @@ This package defines a set of modules that perform some of the
 operations exposed by the ImageMagick package.
 
 """
+from __future__ import division
+
 from vistrails.core.configuration import ConfigurationObject
 
 identifier = 'org.vistrails.vistrails.imagemagick'
diff --git a/vistrails/packages/ImageMagick/init.py b/vistrails/packages/ImageMagick/init.py
index c3393bd..eb174f9 100644
--- a/vistrails/packages/ImageMagick/init.py
+++ b/vistrails/packages/ImageMagick/init.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -51,6 +52,8 @@
 #    Moved quiet to configuration
 #    Fixed bug with GaussianBlur
 
+from __future__ import division
+
 from vistrails.core import debug
 import vistrails.core.modules.basic_modules as basic
 import vistrails.core.modules.module_registry
@@ -64,7 +67,9 @@ import os
 
 class ImageMagick(Module):
     """ImageMagick is the base Module for all Modules in the ImageMagick
-package. It simply defines some helper methods for subclasses."""
+    package. It simply defines some helper methods for subclasses.
+
+    """
 
     def compute(self):
         raise IncompleteImplementation
@@ -73,28 +78,34 @@ package. It simply defines some helper methods for subclasses."""
         """Returns a fully described name in the ImageMagick format.
 
         For example, a file stored in PNG format may be described by:
-        - 'graphic.png' indicates the filename 'graphic.png', using the PNG
-        file format.
-        - 'png:graphic' indicates the filename 'graphic', still using the PNG
-        file format."""
-        i = self.getInputFromPort("input")
-        if self.hasInputFromPort('inputFormat'):
-            return self.getInputFromPort('inputFormat') + ':' + i.name
+        - 'graphic.png' indicates the filename 'graphic.png', using
+        the PNG file format.
+        - 'png:graphic' indicates the filename 'graphic', still using
+        the PNG file format.
+
+        """
+        i = self.get_input("input")
+        if self.has_input('inputFormat'):
+            return self.get_input('inputFormat') + ':' + i.name
         else:
             return i.name
 
     def create_output_file(self):
-        """Creates a File with the output format given by the
-outputFormat port."""
-        if self.hasInputFromPort('outputFormat'):
-            s = '.' + self.getInputFromPort('outputFormat')
+        """Creates a File with the output format given by the outputFormat
+        port.
+
+        """
+        if self.has_input('outputFormat'):
+            s = '.' + self.get_input('outputFormat')
             return self.interpreter.filePool.create_file(suffix=s)
         else:
             return self.interpreter.filePool.create_file(suffix='.png')
 
     def run(self, *args):
         """run(*args), runs ImageMagick's 'convert' on a shell, passing all
-arguments to the program."""
+        arguments to the program.
+
+        """
         path = None
         if configuration.check('path'):
             path = configuration.path
@@ -120,7 +131,7 @@ a descriptive name of the operation it implements."""
         o = self.create_output_file()
         i = self.input_file_description()
         self.run(i, o.name)
-        self.setResult("output", o)
+        self.set_output("output", o)
 
 
 class CombineRGBA(ImageMagick):
@@ -128,10 +139,10 @@ class CombineRGBA(ImageMagick):
 
     def compute(self):
         o = self.create_output_file()
-        r = self.getInputFromPort("r")
-        g = self.getInputFromPort("g")
-        b = self.getInputFromPort("b")
-        a = self.forceGetInputFromPort("a")
+        r = self.get_input("r")
+        g = self.get_input("g")
+        b = self.get_input("b")
+        a = self.force_get_input("a")
 
         if a is not None:
             self.run(r.name, g.name, b.name, a.name,
@@ -142,21 +153,24 @@ class CombineRGBA(ImageMagick):
                      '-channel', 'RGB',
                      '-combine', o.name)
 
-        self.setResult("output", o)
+        self.set_output("output", o)
 
 
 class Scale(Convert):
-    """Scale rescales the input image to the given geometry description."""
+    """Scale rescales the input image to the given geometry
+    description.
+
+    """
 
     def geometry_description(self):
         """returns a string with the description of the geometry as
 indicated by the appropriate ports (geometry or width and height)"""
         # if complete geometry is available, ignore rest
-        if self.hasInputFromPort("geometry"):
-            return self.getInputFromPort("geometry")
-        elif self.hasInputFromPort("width"):
-            w = self.getInputFromPort("width")
-            h = self.getInputFromPort("height")
+        if self.has_input("geometry"):
+            return self.get_input("geometry")
+        elif self.has_input("width"):
+            w = self.get_input("width")
+            h = self.get_input("height")
             return "'%sx%s'" % (w, h)
         else:
             raise ModuleError(self, "Needs geometry or width/height")
@@ -167,21 +181,23 @@ indicated by the appropriate ports (geometry or width and height)"""
                  "-scale",
                  self.geometry_description(),
                  o.name)
-        self.setResult("output", o)
+        self.set_output("output", o)
 
 
 class GaussianBlur(Convert):
-    """GaussianBlur convolves the image with a Gaussian filter of given radius
-and standard deviation."""
+    """GaussianBlur convolves the image with a Gaussian filter of given
+    radius and standard deviation.
+
+    """
 
     def compute(self):
-        (radius, sigma) = self.getInputFromPort('radiusSigma')
+        (radius, sigma) = self.get_input('radiusSigma')
         o = self.create_output_file()
         self.run(self.input_file_description(),
                  "-blur",
                  "%sx%s" % (radius, sigma),
                  o.name)
-        self.setResult("output", o)
+        self.set_output("output", o)
 
 
 no_param_options = [("Negate", "-negate",
@@ -199,14 +215,16 @@ no_param_options = [("Negate", "-negate",
 
 def no_param_options_method_dict(optionName):
     """Creates a method dictionary for a module that takes no extra
-parameters. This dictionary will be used to dynamically create a
-VisTrails module."""
+    parameters. This dictionary will be used to dynamically create a
+    VisTrails module.
+
+    """
    
     def compute(self):
         o = self.create_output_file()
         i = self.input_file_description()
         self.run(i, optionName, o.name)
-        self.setResult("output", o)
+        self.set_output("output", o)
 
     return {'compute': compute}
 
@@ -217,16 +235,18 @@ float_param_options = [("DetectEdges", "-edge", "radius", "filter radius"),
                        ("MedianFilter", "-median", "radius", "filter radius")]
 
 def float_param_options_method_dict(optionName, portName):
-    """Creates a method dictionary for a module that has one port
-taking a floating-point value. This dictionary will be used to
-dynamically create a VisTrails module."""
+    """Creates a method dictionary for a module that has one port taking a
+    floating-point value. This dictionary will be used to dynamically
+    create a VisTrails module.
+
+    """
 
     def compute(self):
         o = self.create_output_file()
-        optionValue = self.getInputFromPort(portName)
+        optionValue = self.get_input(portName)
         i = self.input_file_description()
         self.run(i, optionName, str(optionValue), o.name)
-        self.setResult("output", o)
+        self.set_output("output", o)
 
     return {'compute': compute}
 
diff --git a/vistrails/packages/JobSubmission/__init__.py b/vistrails/packages/JobSubmission/__init__.py
deleted file mode 100644
index 1f1fefb..0000000
--- a/vistrails/packages/JobSubmission/__init__.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import sys
-import vistrails.core
-##
-# TODO list:
-# (V) 1) Write the JobInfo module
-# (V) 2) Make implement generator functionality
-# (V) 4) write generator and exporter functions 
-# (V) 9) Move generators.py, exporters.py -> containers.py
-# (V) 10) auto_generated_types -> generator_definitions 
-# (V) 11) Local file transfer fails when no visible files are present
-# 12) Qprint -> annotate
-# 13) Disconnect and kill process if queue exist
-# 14) Write the clean up and add it to run job
-# 15) There is an error with terminal selection
-
-
-## TODO:
-# 1) Fix the last things whatever they are
-# 9) Pull the git repository
-# 10) Add the package and update
-
-
-### TESTING
-# 1) Test collective operations
-# 2) check wether it uploads anything
-# 3) Try to see what happens when things are connected different from what you are supposed to do
-# 4) Test queue reusing - something tells me that this might fail
-version = '0.2'
-identifier = 'org.comp-phys.batchq'
-name = 'Job Submission'
-
-def package_requirements():
-    from vistrails.core.requirements import require_python_module
-    require_python_module('batchq')
diff --git a/vistrails/packages/JobSubmission/common_definitions.py b/vistrails/packages/JobSubmission/common_definitions.py
deleted file mode 100644
index b1ede6d..0000000
--- a/vistrails/packages/JobSubmission/common_definitions.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from batchq import queues
-from batchq.core.batch import BatchQ
-from batchq.queues import containers
-
-from vistrails.core.modules.basic_modules import File, Directory
-from vistrails.core.system import get_vistrails_basic_pkg_id
-
-###
-# Categories
-categories = {
-'basic_submission': 'Basic Submission',
-'job_collective_operations': "Collective operations",
-'low_level': "Low-level operations"
-}
-##
-# Helper functions
-name_formatter = lambda x: x
-capitalise = lambda x: x[0].upper() + x[1:].lower()
-remove_underscore = lambda j, name: j.join([capitalise(a) for a in name.split("_")])
-
-basic_pkg = get_vistrails_basic_pkg_id()
-type_conversion = {str:'(%s:String)' % basic_pkg, bool:'(%s:Boolean)' % basic_pkg, int:'(%s:Integer)' % basic_pkg, float:'(%s:Float)' % basic_pkg}
-
-batch_queue_list = [(a, getattr(queues,a)) for a in dir(queues) if isinstance(getattr(queues,a),type) and issubclass(getattr(queues,a),BatchQ) ]
-
-
-def create_directory(self, generator = None):
-    x = self.interpreter.filePool.create_directory()
-    return x.name
-
-def create_file(self, contents, generator = None):
-    ext=''
-    if not generator is None:
-        ext = generator.extension
-    f = self.interpreter.filePool.create_file(suffix=ext)
-    h = open(f.name,'w')
-    h.write(contents)
-    h.close()
-    return f, f.name
-
-def directory_wrapper(self, path, generator = None):
-    ret = Directory.translate_to_python(path)
-    return ret
-
-
-generator_definitions = { containers.DirectoryName:create_directory }
-
-exporter_definitions = { containers.TextFile: ('(%s:File)' % basic_pkg, 
-                                               create_file),
-                        containers.DirectoryName: ('(%s:Directory)' % basic_pkg,
-                                                   directory_wrapper)}
diff --git a/vistrails/packages/JobSubmission/init.py b/vistrails/packages/JobSubmission/init.py
deleted file mode 100644
index f2eb931..0000000
--- a/vistrails/packages/JobSubmission/init.py
+++ /dev/null
@@ -1,315 +0,0 @@
-from common_definitions import categories, capitalise, \
-    type_conversion, batch_queue_list, remove_underscore, name_formatter, \
-    generator_definitions, exporter_definitions
-from vistrails.core.modules.vistrails_module import Module, ModuleError, \
-    NotCacheable, InvalidOutput, ModuleSuspended
-from batchq.core.batch import BatchQ, Function, Property, FunctionMessage, \
-    Collection, Exportable
-from batchq.queues import NoHUP
-import copy
-from machine import module_definitions, Machine
-_modules = module_definitions
-
-
-
-#######################################
-## Creating queues/"machines"
-#######################################
-
-## Stores exportable properties 
-## (property_name, vistrails_type, port visibility) for
-## each key = property_name
-exp_job_properties = {}
-
-## Stores all non-auto-generated 
-## properties (property_name, vistrails type, port visibility) 
-## for each key = property_name
-in_job_properties = {}
-
-## Stores property for each key = property_name
-job_properties = {}
-
-## Stores (property_name, vistrails type, generator)
-## for each key = property_name
-auto_job_properties = {}  
-
-operations = {}
-operations_types = {}
-operations_highlevel = {}
-for queue_name, queue in batch_queue_list:
-
-    ## Generating queue classes
-    properties = []
-    for prop_name in dir(queue):
-        if isinstance(getattr(queue,prop_name), Property):
-            attr = getattr(queue,prop_name)
-
-            ## Properties which are machine dependent
-            if attr.verbose and attr.invariant:
-                properties.append( (prop_name,type_conversion[attr.type])  )
-
-            ## Properties which are job dependent
-            if not attr.password and not attr.invariant:
-                job_properties[prop_name] = attr
-
-                # Sorting auto generated fields
-                if attr.generator is None:
-                    in_job_properties[prop_name] = (prop_name, 
-                                                    type_conversion[attr.type], 
-                                                    not attr.verbose)
-                elif attr.generator.type in generator_definitions:
-
-                    auto_job_properties[prop_name] = (prop_name,
-                                                      type_conversion[attr.type],
-                                                      generator_definitions[attr.generator.type])
-
-                # Sorting exportable fields
-                if attr.exporter is None:
-                    exp_job_properties[prop_name] = (prop_name,type_conversion[attr.type], 
-                                                     not attr.verbose)
-                else:
-                    t, _ = exporter_definitions[attr.exporter.type]
-                    exp_job_properties[prop_name] = (prop_name, t, not attr.verbose)
-
-    ## Definiting machines/queuing systems
-    members = { '_input_ports' : [('inherits',
-                                   '(org.comp-phys.batchq:Machine)',
-                                   True)] + properties, 
-                'queue_cls'    : queue,
-                '_output_ports': [('machine', 
-                                   '(org.comp-phys.batchq:Machine)')],
-                'queue'        : None
-                }
-
-    if hasattr(queue, "__descriptive_name__"):
-        descriptive_name =  queue.__descriptive_name__
-    else:
-        descriptive_name = capitalise(queue_name)
-
-    cls = type(name_formatter(descriptive_name), (Machine,), members)
-
-    ## Extracing all functions from the queues - these will be used later 
-    ## for module generation
-    functions = [(a,getattr(queue,a)) for a in dir(queue) 
-                 if isinstance(getattr(queue,a), Function) and 
-                 not a.startswith("_") and getattr(queue,a).enduser ]
-
-    for f, fnc in functions:
-        t = fnc.type
-        if not f in operations:
-            operations[f] = []
-            operations_types[f] = []
-            operations_highlevel[f] = False
-
-        operations[f].append(queue_name)
-        operations_highlevel[f] = operations_highlevel[f] or fnc.highlevel
-
-        if not t in operations_types[f]: operations_types[f].append(t)
-
-    _modules.append((cls,{'namespace':categories['basic_submission']}))
-
-functions = dict(functions)
-
-#######################################
-## Basic Job and Job creation module
-#######################################
-class Job(Machine):
-    pass
-_modules.append((Job, {'abstract':True}))
-
-
-def compute_jobpreparation(self):  
-    mac = self.getInputFromPort("machine")
-    queue, cls = mac.queue, mac.queue_cls
-    kwargs = self.get_kwargs(cls)
-
-    for f, t, generator in auto_job_properties.itervalues():
-        kwargs[f] = generator(self)
-
-    self.queue = cls(queue, **kwargs) 
-
-    self.setResult("job", self)
-
-dct = {'_input_ports'   : [b for b in in_job_properties.itervalues()] \
-           + [('machine', '(org.comp-phys.batchq:Machine)'),],
-       '_output_ports'  : [('job', '(org.comp-phys.batchq:Job)'),],
-       'compute'        : compute_jobpreparation
-       }
-
-PrepareJob = type(name_formatter("Prepare Job"), (Job,), dct)
-
-_modules += [(PrepareJob, {'namespace':categories['basic_submission']})] 
-
-#######################################
-## Creating functions 
-#######################################
-class JobOperation(NotCacheable,Module):
-    pass
-
-def joboperation_compute(self):
-    if self.hasInputFromPort("job"):
-        job = self.getInputFromPort('job')
-        queue = job.queue
-#    print "TERMINAL ID", id(queue.terminal), id(queue.local_terminal)
-        self.anno_counter = 1
-        self.anno_dict = {}
-        def annotate(fncself, *args, **kwargs):
-            if len(args) == 1:
-                self.anno_dict.update( {"note%d"%self.anno_counter: args[0]} )
-            elif len(kwargs) == 0:
-                self.anno_dict.update( {"note%d"%self.anno_counter:" ".join(args)} )
-            else:
-                self.anno_dict.updateself.annotate( kwargs )
-            self.anno_counter +=1
-            return None
-        function = getattr(queue, self.function_name)
-        pnt = function.Qprint
-        function.Qprint = annotate
-        ret = function().val()
-        function.Qprint = pnt 
-        
-        ## TODO: annotate does not seem to work
-        self.annotate(self.anno_dict)
-
-        if isinstance(ret, FunctionMessage) and ret.code != 0:
-            raise ModuleSuspended(self, ret.message, queue) if ret.code > 0 \
-                else ModuleError(self,ret.message)
-
-        self.setResult("job", job)
-        self.setResult("result", ret)
-        self.setResult("string", str(ret))
-    self.setResult("operation", self)
-
-_modules+=[(JobOperation,{'abstract':True})]
-
-members = [ ('_input_ports', [('job', '(org.comp-phys.batchq:Job)'),] ),
-            ('_output_ports', [('job', '(org.comp-phys.batchq:Job)')] ),
-            ('compute', joboperation_compute)]
-
-low_level_functions = {}
-high_level_functions = {}
-high_level_modules = []
-for name in operations.iterkeys():
-    for t in operations_types[name]:
-        dct = dict(copy.deepcopy(members)+[('function_name',name)])
-        if not t is None and not t in [FunctionMessage]:
-            dct['_output_ports'].append( ('result', type_conversion[t]) )
-
-        #  TODO: Multiple types yet to be implemented
-        ## append = "" if len(operations_types[name]) == 1 else capiltalise(str(t))
-        namespace = categories['low_level']
-
-        descriptive_name = remove_underscore(" ",name)
-        if t in [str,int, float, bool]: 
-            if functions[name].exporter is None:
-                low_level_functions[name] = (name,type_conversion[t])
-            else:
-                tt, _ = exporter_definitions[functions[name].exporter.type]
-                low_level_functions[name] = (name,tt)
-
-            if t in [bool]: 
-                descriptive_name = "Is" + remove_underscore("",name)
-            else:
-                descriptive_name = "Get" + remove_underscore("",name)
-
-        if not operations_highlevel[name]:
-            dct['_output_ports'].append( ('operation', '(org.comp-phys.batchq:JobOperation)') )
-            cls = ( type(name_formatter(descriptive_name), 
-                         (JobOperation,),dct), 
-                    {'namespace': namespace} )
-            _modules.append(cls)
-        else:
-            namespace = categories['basic_submission']
-            if t in type_conversion:
-                high_level_functions[name] = (name,type_conversion[t]) 
-            else: 
-                high_level_functions[name] = (name,None)
-            high_level_modules.append((descriptive_name, dct, namespace))
-#        namespace = categories['basic_submission']
-
-
-def jobinfo_compute(self):
-    job = self.getInputFromPort("job")
-    queue = job.queue
-    for function in self.queue_functions:
-        name = function[0]
-        function =getattr(queue, name)
-        ret =function().val()
-        if function.exporter is None:
-            self.setResult(name, ret)
-        else:
-            ## If the field is exported to a vistrails 
-            ## type the conversion is done here
-            exporter = function.exporter
-            _, exp = exporter_definitions[exporter.type]
-            ret = function.exporter.as_str()
-            self.setResult(name, exp(self,ret))
-
-    for prop in self.queue_properties:
-        name = prop[0]
-        field = queue.fields[name]
-        ret = field.get()
-        if field.exporter is None:
-            self.setResult(name, ret)
-        else:
-            exporter = field.exporter
-            _, exp = exporter_definitions[exporter.type]
-
-            ret = exporter.as_str()
-            self.setResult(name, exp(self,ret))
-
-    self.setResult("job", job)
-
-
-queue_properties = [b for b in exp_job_properties.itervalues()]
-queue_functions = [b for b in low_level_functions.itervalues()]
-dct = {'_input_ports': [('job', '(org.comp-phys.batchq:Job)'),],
-       '_output_ports': queue_properties  + queue_functions,
-       'compute': jobinfo_compute,
-       'queue_properties': queue_properties,
-       'queue_functions':  queue_functions}
-JobInfo = type(name_formatter("Job Info"), (NotCacheable,Job,), dct)
-
-_modules += [(JobInfo, {'namespace':categories['basic_submission']})] 
-
-####
-# High-level function
-def highlevel_compute(self):
-    joboperation_compute(self)
-    jobinfo_compute(self)
-
-for descriptive_name, dct, namespace in high_level_modules:
-    dct['compute'] = highlevel_compute
-    dct['is_cacheable'] = lambda self: True
-    _modules.append((type(name_formatter(descriptive_name), (JobInfo,),dct), {'namespace': namespace} ))
-
-######
-## Creating collective operations
-class CollectiveOperation(NotCacheable,Module):
-    pass
-_modules.append((CollectiveOperation, {'abstract':True}))
-
-def collective_compute(self):
-    job = self.getInputFromPort('job')
-    operation = self.getInputFromPort('operation')
-    col = Collection() 
-    col += job.queue
-
-    col2 = getattr(col, self.collection_name)()
-    rets = getattr(col2, operation.function_name)().as_list()
-    ## TODO: ad results
-    self.setResult('job', job)
-
-collective = dict([(name,getattr(Collection, name)) for name in dir(Collection) if isinstance(getattr(Collection, name),Exportable)])
-members = [ ('_input_ports', [('operation', '(org.comp-phys.batchq:JobOperation)'),('job', '(org.comp-phys.batchq:Job)')] ),
-            ('_output_ports', [('job', '(org.comp-phys.batchq:Job)')] ),
-            ('compute', collective_compute ),
-            ('collection_name', name)]
-namespace = categories['job_collective_operations']
-for name, func in collective.iteritems():
-    dct = dict(members)
-    _modules.append((type( "".join([capitalise(a) for a in name.split("_")]) , (CollectiveOperation,),dct),{'namespace':namespace} ))
-
-
-
-_modules = _modules
diff --git a/vistrails/packages/JobSubmission/machine.py b/vistrails/packages/JobSubmission/machine.py
deleted file mode 100644
index b991a99..0000000
--- a/vistrails/packages/JobSubmission/machine.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from vistrails.core.modules.vistrails_module import Module
-from batchq.core.batch import Property
-QUEUE_REGISTER = {}
-####
-# Machine definition
-class Machine(Module):
-    def get_kwargs(self, cls):
-        
-        ret = dict([(a[0],self.getInputFromPort(a[0])) for a in self._input_ports if self.hasInputFromPort(a[0]) and a[0] in cls.__new_fields__ and isinstance(cls.__new_fields__[a[0]],Property)])
-        ret.update({'q_interact': False})
-        return ret
-
-    def compute(self):
-        global QUEUE_REGISTER
-        kwargs = self.get_kwargs(self.queue_cls)
-        inherits = self.getInputFromPort('inherits').queue if self.hasInputFromPort('inherits') else None
-
-# never disconnect because we want to check jobs later
-#        if self.signature in QUEUE_REGISTER:
-#            q = QUEUE_REGISTER[self.signature]
-#            if hasattr(q, "disconnect"):
-#                q.disconnect()
-
-
-        self.queue = self.queue_cls(**kwargs) if inherits is None else self.queue_cls(inherits, **kwargs) 
-
-        QUEUE_REGISTER[str(self.signature)] = self.queue
-
-        self.setResult("machine", self)
-
-module_definitions = [(Machine,{'abstract':True})]
diff --git a/vistrails/packages/RemoteQ/README b/vistrails/packages/RemoteQ/README
new file mode 100644
index 0000000..7f2efb7
--- /dev/null
+++ b/vistrails/packages/RemoteQ/README
@@ -0,0 +1,2 @@
+This package is being developed at https://github.com/rexissimus/BatchQ-PBS/tree/remoteq
+This is commit ff11709b2c694035a577dd6bcb4cc616cf255853
\ No newline at end of file
diff --git a/vistrails/packages/RemoteQ/__init__.py b/vistrails/packages/RemoteQ/__init__.py
new file mode 100644
index 0000000..9aeece6
--- /dev/null
+++ b/vistrails/packages/RemoteQ/__init__.py
@@ -0,0 +1,56 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from vistrails.core.configuration import ConfigurationObject
+
+version = '0.3.1'
+identifier = 'org.vistrails.vistrails.remoteq'
+name = 'RemoteQ'
+
+old_identifiers = ['org.vistrails.pbs', 'edu.utah.sci.vistrails.hadoop']
+
+configuration = ConfigurationObject(server=(None, str), 
+                                    port=(None, int),
+                                    password=True,
+                                    username=(None, str),
+                                    uris=(None, str),
+                                    defaultFS=(None, str))
+
+def package_requirements():
+    import vistrails.core.requirements
+    if not vistrails.core.requirements.python_module_exists('remoteq'):
+        raise vistrails.core.requirements.MissingRequirement('remoteq')
diff --git a/vistrails/packages/RemoteQ/base.py b/vistrails/packages/RemoteQ/base.py
new file mode 100644
index 0000000..5084787
--- /dev/null
+++ b/vistrails/packages/RemoteQ/base.py
@@ -0,0 +1,249 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+""" Base classes for all Hadoop Modules """
+
+from __future__ import division
+
+from init import configuration
+from vistrails.core.modules.basic_modules import File, String
+from vistrails.gui.modules.python_source_configure import \
+                                                PythonSourceConfigurationWidget
+from vistrails.core.modules.config import ModuleSettings, IPort, OPort
+from vistrails.core.modules.vistrails_module import Module, NotCacheable, \
+                                                   ModuleError, ModuleSuspended
+from remoteq.core.stack import select_machine, end_machine, use_machine, \
+                                                                current_machine
+from remoteq.batch.commandline import Subshell
+from remoteq.batch.directories import CreateDirectory
+import urllib
+import xml.etree.cElementTree as ET
+
+from init import RQModule
+
+################################################################################
+class HadoopBaseModule(RQModule):
+    """
+    The base class for all modules in the Hadoop package. We would
+    like to implement a few basic functionality such as looking for
+    Hadoop installation directory, execute Hadoop commands, etc. for
+    subclasses to use
+    
+    """
+    _settings = ModuleSettings(abstract=True)
+
+    hadoop_configuration = None
+    def __init__(self):
+        Module.__init__(self)
+    
+    def get_hadoop_home(self, machine):
+        HADOOP_HOME = machine.remote.send_command("echo $HADOOP_HOME").strip()
+        if HADOOP_HOME == '':
+            # raise ModuleError(self, 'HADOOP_HOME has to be defined')
+            # it does not actually. This means it is part of the system.
+            pass
+        return HADOOP_HOME
+
+    def read_site_config(self, machine):
+        config = HadoopBaseModule.hadoop_configuration
+        # For AWS
+        core_site = config['home']+'/conf/core-site.xml'
+        # for NYU/CUSP
+        #core_site = config['home']+'/etc/hadoop/conf/core-site.xml'
+        site_string = machine.remote.cat(core_site)
+        root = ET.fromstring(site_string)
+        for node in root:
+            name = node.find('name').text
+            value = node.find('value').text
+            config[name] = value
+
+    def get_hadoop_config(self, machine):
+        if HadoopBaseModule.hadoop_configuration==None:
+            hadoop_home = self.get_hadoop_home(machine)
+            # paths to try in order
+            streaming_paths = ['/share/hadoop/tools/lib/',   # AWS
+                               '/usr/lib/hadoop-mapreduce/', # NYU/CUSP
+                               '/contrib/streaming/']
+            for path in streaming_paths:
+                hs = hadoop_home + path
+                command = ("python -c \"import os, os.path; print '' if not "
+                           "os.path.exists('{0}') else ''.join([i for i in "
+                           "os.listdir('{0}') if 'streaming' in i][-1:])\""
+                           ).format(hs)
+                streamingjar = machine.remote.send_command(command).strip()
+                if streamingjar:
+                    break
+            if not streamingjar:
+                raise ModuleError(self,
+                                  'hadoop-streaming.jar not found. Please add '
+                                  'its directory to list of supported paths.')
+            hadoop = (hadoop_home + '/bin/hadoop') if hadoop_home else 'hadoop'
+            hdfs = (hadoop_home + '/bin/hdfs') if hadoop_home else 'hdfs'
+            if not machine.remote.command_exists(hdfs):
+                hdfs = hadoop
+            config = {'home': hadoop_home,
+                      'hadoop': hadoop,
+                      'hdfs': hdfs,
+                      'streaming.jar': hs + streamingjar}
+            HadoopBaseModule.hadoop_configuration = config
+            # reading configuration files are error-prone
+            #self.read_site_config(machine)
+            config['fs.defaultFS'] = ''
+            # can access config only if hdfs command exists
+            if hadoop != hdfs:
+                config['fs.defaultFS'] = \
+                    self.call_hdfs('getconf -confKey fs.defaultFS', machine)
+        return HadoopBaseModule.hadoop_configuration
+
+    def add_prefix(self, path, machine): 
+        aliases = []
+        if configuration.check('uris') and configuration.uris:
+            aliases = dict([(uri.split('#')[1], uri.split('#')[0])
+                            for uri in configuration.uris.split(';')])
+        if path in aliases:
+            return aliases[path]
+        if configuration.check('defaultFS'):
+            prefix = configuration.defaultFS
+            return prefix + path
+        else:
+            prefix = self.get_hadoop_config(machine)['fs.defaultFS']
+            return prefix + '/' + path
+
+
+    def call_hadoop(self, arguments, workdir, identifier, machine):
+        self.is_cacheable = lambda *args, **kwargs: False
+        config = self.get_hadoop_config(machine)
+        argList = [config['hadoop']]
+        if type(arguments) in [str, unicode]:
+            argList += arguments.split(' ')
+        elif type(arguments)==list:
+            argList += arguments
+        else:
+            raise ModuleError(self, 'Invalid argument types to hadoop')
+
+        # 1. this version returns when finished
+        #return subprocess.call(argList)
+        # 2. this version reads the results incrementally
+#         expect = machine.remote._expect_token
+#         machine.remote.push_expect(None) # Do not wait for call to finish
+#         result =  machine.remote.send_command(" ".join(argList)).strip()
+#         machine.remote.pop_expect() # restore expect
+#         # We could show the output in a gui
+#         print "**** hadoop streaming running ****"
+#         print result,
+#         while not expect in result:
+#             output = machine.remote.consume_output()
+#             if output:
+#                 print output,
+#             result += output
+        # 3. The final version should detach the process on the server
+        use_machine(machine)
+        cdir = CreateDirectory("remote", workdir)
+        job = Subshell("remote", command=" ".join(argList),
+                       working_directory=workdir, identifier=identifier,
+                       dependencies=[cdir])
+        job.run()
+        finished = job.finished()
+        if not finished:
+            status = job.status()
+            # The Subshell class provides the JobHandle interface, i.e.
+            # finished()
+            raise ModuleSuspended(self, '%s' % status, handle=job)
+        self.is_cacheable = lambda *args, **kwargs: True
+        return job.standard_error()
+
+    def call_hdfs(self, arguments, machine):
+        config = self.get_hadoop_config(machine)
+        argList = [config['hdfs']]
+        if type(arguments) in [str, unicode]:
+            argList += arguments.split(' ')
+        elif type(arguments)==list:
+            argList += arguments
+        else:
+            raise ModuleError(self, 'Invalid argument types to hdfs: %s'%type(arguments))
+
+        result =  machine.remote.send_command(" ".join(argList)).strip()
+        return result
+        #return subprocess.call(argList)
+
+################################################################################
+class PythonSourceToFileConfigurationWidget(PythonSourceConfigurationWidget):
+    """
+    A simple python source configuration widget, i.e. hiding all of
+    the input/output port table
+    
+    """
+    def __init__(self, module, controller, parent=None):
+        PythonSourceConfigurationWidget.__init__(self, module,
+                                                 controller, parent)
+        self.inputPortTable.hide()
+        self.outputPortTable.hide()
+        self.setWindowTitle('Python Source Editor')
+
+################################################################################
+class PythonSourceToFile(Module):
+    """
+    This is the class for specifying a python code snippet for running
+    with Hadoop Streaming, it will take its contents and output to a
+    temporary Python file. The code will not be passed around.
+    
+    """
+    _settings = ModuleSettings(namespace='hadoop',
+                        configure_widget=PythonSourceToFileConfigurationWidget)
+
+    _input_ports = [IPort('Input File', File),
+                    IPort('source', String, optional=True)]
+
+    _output_ports = [OPort('Temporary File', File)]
+
+    def compute(self):
+        inputFile = self.force_get_input('Input File')
+
+        if inputFile!=None:
+#            tempFile = file_pool.make_local_copy(inputFile.name)
+            tempFile = inputFile
+        else:
+            source = urllib.unquote(self.force_get_input('source', ''))
+            tempFile = self.interpreter.filePool.create_file()
+            f = open(tempFile.name, 'w')
+            f.write(source)
+            f.close()
+        self.set_output('Temporary File', tempFile)
+            
+
+################################################################################
+def register():
+    return [HadoopBaseModule, PythonSourceToFile]
+    
diff --git a/vistrails/packages/RemoteQ/hdfs.py b/vistrails/packages/RemoteQ/hdfs.py
new file mode 100644
index 0000000..bfd7bbf
--- /dev/null
+++ b/vistrails/packages/RemoteQ/hdfs.py
@@ -0,0 +1,193 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+""" Wrapper for Hadoop DFS operations """
+
+from __future__ import division
+
+import os
+import shutil
+
+from vistrails.core.modules.basic_modules import File, Boolean, String, \
+                                                 PathObject, Path
+from vistrails.core.modules.config import IPort, OPort, ModuleSettings
+from vistrails.core.modules.vistrails_module import ModuleError
+from base import HadoopBaseModule
+
+
+################################################################################
+class HDFSPut(HadoopBaseModule):
+    """
+    Putting a local file to the Hadoop DFS
+    First copying it to the server
+    """
+    _settings = ModuleSettings(namespace='hadoop')
+    _input_ports = [IPort('Local File', File),
+                    IPort('Remote Location', String),
+                    IPort('Override', Boolean),
+                    IPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)')]
+
+    _output_ports = [OPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)'),
+                     OPort('Remote Location', String)]
+
+    def __init__(self):
+        HadoopBaseModule.__init__(self)
+
+    def compute(self):
+        machine = self.get_machine()
+        jm = self.job_monitor()
+        id = self.signature
+        job = jm.getCache(id)
+        if not job:
+            remote = self.get_input('Remote Location')
+            local = self.get_input('Local File')
+            override = self.force_get_input('Override', False)
+            if '://' not in remote:
+                remote = self.add_prefix(remote, machine)
+            if not int(self.call_hdfs('dfs -test -e ' + remote +
+                                      '; echo $?', machine)):
+                if override:
+                    self.call_hdfs('dfs -rm -r ' + remote, machine)
+                else:
+                    raise ModuleError(self, 'Remote entry already exists')
+            tempfile = machine.remote.send_command('mktemp -u').strip()
+            result = machine.sendfile(local.name, tempfile)
+            self.call_hdfs('dfs -put %s %s' % (tempfile, remote), machine)
+            result = machine.remote.rm(tempfile,force=True,recursively=True)
+            d = {'remote':remote,'local':local.name}
+            self.set_job_machine(d, machine)
+            jm.setCache(id, d, self.job_name())
+            job = jm.getJob(id)
+        self.set_output('Remote Location', job.parameters['remote'])
+        self.set_output('Machine', machine)
+
+################################################################################
+class HDFSGet(HadoopBaseModule):
+    """
+    Getting a file from the Hadoop DFS
+    Then getting it from the server
+    
+    """
+    _settings = ModuleSettings(namespace='hadoop')
+    _input_ports = [IPort('Local File', Path),
+                    IPort('Remote Location', String),
+                    IPort('Override', Boolean),
+                    IPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)')]
+
+    _output_ports = [OPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)'),
+                     OPort('Local File', File)]
+
+
+    def __init__(self):
+        HadoopBaseModule.__init__(self)
+
+    def compute(self):
+        machine = self.get_machine()
+        jm = self.job_monitor()
+        id = self.signature
+        job = jm.getCache(id)
+        if not job:
+            remote = self.get_input('Remote Location')
+            local = self.get_input('Local File')
+            override = self.force_get_input('Override', False)
+            if '://' not in remote:
+                remote = self.add_prefix(remote, machine)
+            if os.path.exists(local.name):
+                if override==False:
+                    raise ModuleError(self, 'Output already exists')
+                else:
+                    if os.path.isdir(local.name):
+                        shutil.rmtree(local.name)
+                    else:
+                        os.unlink(local.name)
+
+            tempfile = machine.remote.send_command('mktemp -d -u').strip()
+            result = self.call_hdfs('dfs -get %s %s' % (remote, tempfile), machine)
+            # too slow with many files
+            #res = machine.send_command("get -r %s %s" % (tempfile, local.name) )
+            # tar files to increase speed
+            result = machine.local.send_command('mkdir %s'%local.name)
+            result = machine.sync(local.name,
+                                  tempfile,
+                                  mode=machine.MODE_REMOTE_LOCAL,
+                                  use_tar=True)
+            result = machine.remote.rm(tempfile,force=True,recursively=True)
+            d = {'remote':remote,'local':local.name}
+            self.set_job_machine(d, machine)
+            jm.setCache(id, d, self.job_name())
+            job = jm.getCache(id)
+        self.set_output('Local File', PathObject(job.parameters['local']))
+        self.set_output('Machine', machine)
+
+################################################################################
+class HDFSEnsureNew(HadoopBaseModule):
+    """
+    Make sure the file is removed
+    
+    """
+    _settings = ModuleSettings(namespace='hadoop')
+    _input_ports = [IPort('Name', String),
+                    IPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)')]
+
+    _output_ports = [OPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)'),
+                     OPort('Name', String)]
+
+    def __init__(self):
+        HadoopBaseModule.__init__(self)
+
+    def compute(self):
+        machine = self.get_machine()
+        jm = self.job_monitor()
+        id = self.signature
+        job = jm.getCache(id)
+        if not job:
+            entry_name = self.get_input('Name')
+            if '://' not in entry_name:
+                entry_name = self.add_prefix(entry_name, machine)
+            if not int(self.call_hdfs('dfs -test -e ' + entry_name +
+                                      '; echo $?', machine)):
+                #self.call_hdfs('dfs -rm -r ' + entry_name, machine)
+                # we are using -rmr but it is deprecated
+                self.call_hdfs('dfs -rmr ' + entry_name, machine)
+            d = {'entry_name':entry_name}
+            self.set_job_machine(d, machine)
+            jm.setCache(id, d, self.job_name())
+            job = jm.getCache(id)
+        self.set_output('Name', job.parameters['entry_name'])
+        self.set_output('Machine', machine)
+
+################################################################################
+def register():
+    return [HDFSPut, HDFSGet, HDFSEnsureNew]
diff --git a/vistrails/packages/RemoteQ/init.py b/vistrails/packages/RemoteQ/init.py
new file mode 100644
index 0000000..7d068ea
--- /dev/null
+++ b/vistrails/packages/RemoteQ/init.py
@@ -0,0 +1,549 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from vistrails.core.modules.config import ModuleSettings
+from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.modules.vistrails_module import Module, ModuleError, \
+                                                               ModuleSuspended
+from vistrails.core.system import current_user
+from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
+from vistrails.core.vistrail.job import JobMixin
+
+from remoteq.pipelines.shell import FileCommander as BQMachine
+from remoteq.core.stack import select_machine, end_machine, use_machine, \
+                                                               current_machine
+from remoteq.batch.commandline import PBS, PBSScript, Subshell
+from remoteq.batch.directories import CreateDirectory
+from remoteq.batch.files import TransferFiles
+
+
+class Machine(Module):
+    _input_ports = [('server', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('port', '(edu.utah.sci.vistrails.basic:Integer)', True),
+                    ('username', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('password', '(edu.utah.sci.vistrails.basic:String)', True),
+                   ]
+
+    _output_ports = [('value', 'org.vistrails.vistrails.remoteq:Machine')]
+    
+    def compute(self):
+        server = self.get_input('server') \
+              if self.has_input('server') else 'localhost'
+        port = self.get_input('port') \
+            if self.has_input('port') else 22
+        username = self.get_input('username') \
+                if self.has_input('username') else current_user()
+        password = self.get_input('password') \
+                if self.has_input('password') else ''
+        self.machine = Machine.create_machine(server, username, password, port)
+        self.set_output("value", self.machine)
+
+    @staticmethod
+    def validate(v):
+        return isinstance(v, BQMachine)
+
+    @staticmethod
+    def create_machine(server, username, password, port):
+        machine = BQMachine(server, username, password, port,
+                            accept_fingerprint=True)
+        machine.params = {}
+        machine.params['server'] = server
+        machine.params['port'] = port
+        machine.params['username'] = username
+        machine.params['password'] = bool(password)
+        # force creation of server-side help files
+        select_machine(machine)
+        end_machine()
+        return machine
+
+class RQModule(JobMixin, Module):
+    """ This is the base class of all RemoteQ modules and handles the
+        connections to servers
+    
+    """
+
+    _settings = ModuleSettings(abstract=True)
+    # a tuple (server, port, username, machine)
+    default_machine = None
+    machine = None
+
+    def get_machine(self):
+        if self.has_input('machine'):
+            return self.get_input('machine')
+        default = False
+        # check if machine is specified in a job
+        machine = self.get_job_machine()
+        if not machine:
+            machine = self.get_default_machine()
+            default = True
+        if not machine:
+            raise ModuleError(self, 'No Machine specified. Either add a '
+                                    'default machine, or a Machine module.')
+        server, port, username, password = machine
+        if RQModule.default_machine and \
+           (server, port, username) == RQModule.default_machine[:3]:
+            return RQModule.default_machine[3]
+        if password:
+            text = 'Enter password for %s@%s' % (username, server)
+            from PyQt4 import QtGui
+            (password, ok) = QtGui.QInputDialog.getText(None, text, text,
+                                                     QtGui.QLineEdit.Password)
+            if not ok:
+                raise ModuleError(self, "Canceled password")
+        machine = Machine.create_machine(server, username, password, port)
+        if default:
+            RQModule.default_machine = (server, port, username, machine)
+        return machine
+
+    def get_job_machine(self):
+        """ Get machine info from job
+        """
+        jm = self.job_monitor()
+        if jm.hasJob(self.signature):
+            params = jm.getJob(self.signature).parameters
+            if 'server' in params:
+                return (params['server'],
+                        params['port'],
+                        params['username'],
+                        params['password'])
+
+    def set_job_machine(self, params, machine):
+        """ Call this when the machine is set to make the job resumeable
+        """
+        params['server'] = machine.params['server']
+        params['port'] = machine.params['port']
+        params['username'] = machine.params['username']
+        params['password'] = machine.params['password']
+
+    def get_default_machine(self):
+        """ Reads the default machine from the package configuration
+        
+        """
+        server = username = port = password = ''
+        if configuration.check('server'):
+            server = configuration.server
+        if not server:
+            return None
+        if configuration.check('username'):
+            username = configuration.username
+        if not username:
+            username = current_user()
+        if configuration.check('port') is not None:
+            port = configuration.port
+        if configuration.check('password'):
+            password = configuration.password
+        self.annotate({'RemoteQ-server':server,
+                       'RemoteQ-username':username,
+                       'RemoteQ-port':port})
+        return server, port, username, password
+
+class RunCommand(RQModule):
+    """ Runs a command over SSH and waits until it finishes
+
+    """
+
+    _input_ports = [('machine', Machine),
+                    ('command', '(edu.utah.sci.vistrails.basic:String)',True),
+                   ]
+    
+    _output_ports = [('machine', Machine),
+                     ('output', '(edu.utah.sci.vistrails.basic:String)'),
+                    ]
+    
+    def compute(self):
+        machine = self.get_machine()
+
+        jm = self.job_monitor()
+        cache = jm.getCache(self.signature)
+        if cache:
+            result = cache.parameters['result']
+        else:
+            if not self.has_input('command'):
+                raise ModuleError(self, "No command specified")
+            command = self.get_input('command').strip()
+            ## This indicates that the coming commands submitted on the machine
+            # trick to select machine without initializing every time
+            use_machine(machine)
+            m = current_machine()
+            result = m.remote.send_command(command)
+            exitcode = m.remote.last_exitcode()
+            end_machine()
+            if exitcode != 0:
+                raise ModuleError(self,
+                                  "Command failed with exit code %s: %s" %
+                                   (exitcode, result))
+        d = {'result':result}
+        self.set_job_machine(d, machine)
+        jm.setCache(self.signature, d, self.job_name())
+        self.set_output("output", result)
+        self.set_output("machine", machine)
+
+class RunJob(RQModule):
+    """ Run an asynchronous command that can be detached and polled.
+        This is preferable over RunCommand for long-running operations
+    """
+
+    _input_ports = [('machine', Machine),
+                    ('command', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('working_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                   ]
+
+    _output_ports = [('stdout', '(edu.utah.sci.vistrails.basic:String)'),
+                     ('stderr', '(edu.utah.sci.vistrails.basic:String)'),
+                    ]
+
+    job = None
+    def job_read_inputs(self):
+        d = {}
+        if not self.has_input('command'):
+            raise ModuleError(self, "No command specified")
+        d['command'] = self.get_input('command').strip()
+        d['working_directory'] = self.get_input('working_directory') \
+              if self.has_input('working_directory') else '.'
+        return d
+
+    def job_start(self, params):
+        work_dir = params['working_directory']
+        self.machine = self.get_machine()
+        use_machine(self.machine)
+        self.job = Subshell("remote", params['command'], work_dir)
+        self.job.run()
+        ret = self.job._ret
+        if ret:
+            try:
+                job_id = int(ret.split('\n')[0])
+            except ValueError:
+                end_machine()
+                raise ModuleError(self, "Error submitting job: %s" % ret)
+        self.set_job_machine(params, self.machine)
+        return params
+
+    def job_get_handle(self, params):
+        if not self.job:
+            self.job_start(params)
+        return self.job
+
+    def job_finish(self, params):
+        params['stdout'] = self.job.standard_output()
+        params['stderr'] = self.job.standard_error()
+        if self.job.failed():
+            self.job._pushw()
+            code = self.job.terminal.cat("%s.failed" %
+                                         self.job._identifier_filename)
+            self.job._popw()
+            end_machine()
+            raise ModuleError(self,
+                              "Command failed with exit code %s: %s" %
+                               (code.strip(), params['stderr'].strip()))
+        end_machine()
+        return params
+
+    def job_set_results(self, params):
+        self.set_output('stdout', params['stdout'])
+        self.set_output('stderr', params['stderr'])
+
+class PBSJob(RQModule):
+    _input_ports = [('machine', Machine),
+                    ('command', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('working_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('input_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('processes', '(edu.utah.sci.vistrails.basic:Integer)', True),
+                    ('time', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('mpi', '(edu.utah.sci.vistrails.basic:Boolean)', True),
+                    ('threads', '(edu.utah.sci.vistrails.basic:Integer)', True),
+                    ('memory', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('diskspace', '(edu.utah.sci.vistrails.basic:String)', True),
+                   ]
+    
+    _output_ports = [('stdout', '(edu.utah.sci.vistrails.basic:String)'),
+                     ('stderr', '(edu.utah.sci.vistrails.basic:String)'),
+                     ('file_list', '(edu.utah.sci.vistrails.basic:List)'),
+                    ]
+    
+    def compute(self):
+        machine = self.get_machine()
+        if not self.has_input('command'):
+            raise ModuleError(self, "No command specified")
+        command = self.get_input('command').strip()
+        working_directory = self.get_input('working_directory') \
+              if self.has_input('working_directory') else '.'
+        if not self.has_input('input_directory'):
+            raise ModuleError(self, "No input directory specified")
+        input_directory = self.get_input('input_directory').strip()
+        additional_arguments = {'processes': 1, 'time': -1, 'mpi': False,
+                                'threads': 1, 'memory':-1, 'diskspace': -1}
+        for k in additional_arguments:
+            if self.has_input(k):
+                additional_arguments[k] = self.get_input(k)
+        ## This indicates that the coming commands submitted on the machine
+        # trick to select machine without initializing every time
+
+        use_machine(machine)
+        cdir = CreateDirectory("remote", working_directory)
+        trans = TransferFiles("remote", input_directory, working_directory,
+                              dependencies = [cdir])
+        job = PBS("remote", command, working_directory, dependencies = [trans],
+                  **additional_arguments)
+        job.run()
+        ret = job._ret
+        if ret:
+            try:
+                job_id = int(ret)
+            except ValueError:
+                end_machine()
+                raise ModuleError(self, "Error submitting job: %s" % ret)
+        finished = job.finished()
+        job_info = job.get_job_info()
+        if job_info:
+            self.annotate({'job_info': job.get_job_info()})
+        if not finished:
+            status = job.status()
+            # try to get more detailed information about the job
+            # this only seems to work on some versions of torque
+            if job_info:
+                comment = [line for line in job_info.split('\n') if line.startswith('comment =')]
+                if comment:
+                    status += ': ' + comment[10:]
+            end_machine()
+            # The PBS class provides the JobHandle interface, i.e. finished()
+            raise ModuleSuspended(self, '%s' % status, handle=job)
+        # copies the created files to the client
+        get_result = TransferFiles("local", input_directory, working_directory,
+                              dependencies = [cdir])
+        get_result.run()
+        ## Popping from the machine stack                                                                                                                                     
+        end_machine()
+        self.set_output("stdout", job.standard_output())
+        self.set_output("stderr", job.standard_error())
+        files = machine.local.send_command("ls -l %s" % input_directory)
+        self.set_output("file_list",
+                       [f.split(' ')[-1] for f in files.split('\n')[1:]])
+
+class RunPBSScript(RQModule):
+    """ Run a pbs script by submitting it to a PBS scheduler
+
+    """
+
+    _input_ports = [('machine', Machine),
+                    ('command', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('working_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('input_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('processes', '(edu.utah.sci.vistrails.basic:Integer)', True),
+                    ('time', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('mpi', '(edu.utah.sci.vistrails.basic:Boolean)', True),
+                    ('threads', '(edu.utah.sci.vistrails.basic:Integer)', True),
+                    ('memory', '(edu.utah.sci.vistrails.basic:String)', True),
+                    ('diskspace', '(edu.utah.sci.vistrails.basic:String)', True),
+                   ]
+    
+    _output_ports = [('stdout', '(edu.utah.sci.vistrails.basic:String)'),
+                     ('stderr', '(edu.utah.sci.vistrails.basic:String)'),
+                    ]
+    
+    job = None
+    def job_read_inputs(self):
+        d = {}
+        if not self.has_input('command'):
+            raise ModuleError(self, "No command specified")
+        d['command'] = self.get_input('command').strip()
+        d['working_directory'] = self.get_input('working_directory') \
+              if self.has_input('working_directory') else '.'
+        if not self.has_input('input_directory'):
+            raise ModuleError(self, "No input directory specified")
+        d['input_directory'] = self.get_input('input_directory').strip()
+        d['additional_arguments'] = {'processes': 1, 'time': -1, 'mpi': False,
+                                'threads': 1, 'memory':-1, 'diskspace': -1}
+        for k in d['additional_arguments']:
+            if self.has_input(k):
+                d['additional_arguments'][k] = self.get_input(k)
+        return d
+
+    def job_start(self, params):
+        work_dir = params['working_directory']
+        self.machine = self.get_machine()
+        use_machine(self.machine)
+        self.cdir = CreateDirectory("remote", work_dir)
+        trans = TransferFiles("remote", params['input_directory'], work_dir,
+                              dependencies = [self.cdir])
+        self.job = PBSScript("remote", params['command'], work_dir,
+                      dependencies = [trans], **params['additional_arguments'])
+        self.job.run()
+        ret = self.job._ret
+        if ret:
+            try:
+                job_id = int(ret.split('\n')[0])
+            except ValueError:
+                end_machine()
+                raise ModuleError(self, "Error submitting job: %s" % ret)
+        self.set_job_machine(params, self.machine)
+        return params
+        
+    def job_get_handle(self, params):
+        if not self.job:
+            self.job_start(params)
+        return self.job
+
+    def job_finish(self, params):
+        job_info = self.job.get_job_info()
+        if job_info:
+            self.annotate({'job_info': job_info})
+        # copies the created files to the client
+        get_result = TransferFiles("local", params['input_directory'],
+                                   params['working_directory'],
+                                   dependencies = [self.cdir])
+        get_result.run()
+        end_machine()
+        params['stdout'] = self.job.standard_output()
+        params['stderr'] = self.job.standard_error()
+        return params
+
+    def job_set_results(self, params):
+        self.set_output('stdout', params['stdout'])
+        self.set_output('stderr', params['stderr'])
+
+class SyncDirectories(RQModule):
+    """ Copy all files in a directory to/from a remote server using SFTP
+
+    """
+
+    _input_ports = [('machine', Machine),
+                    ('local_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('remote_directory', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('to_local', '(edu.utah.sci.vistrails.basic:Boolean)'),
+                   ]
+    
+    _output_ports = [('machine', Machine),
+                    ]
+    
+    def compute(self):
+        machine = self.get_machine()
+        jm = self.job_monitor()
+        cache = jm.getCache(self.signature)
+        if not cache:
+            if not self.has_input('local_directory'):
+                raise ModuleError(self, "No local directory specified")
+            local_directory = self.get_input('local_directory').strip()
+            if not self.has_input('remote_directory'):
+                raise ModuleError(self, "No remote directory specified")
+            remote_directory = self.get_input('remote_directory').strip()
+            whereto = 'remote'
+            if self.has_input('to_local') and self.get_input('to_local'):
+                whereto = 'local'
+            use_machine(machine)
+            to_dir = local_directory if whereto=='local' else remote_directory
+            cdir = CreateDirectory(whereto, to_dir)
+            job = TransferFiles(whereto, local_directory, remote_directory,
+                              dependencies = [cdir])
+            job.run()
+            end_machine()
+            d = {}
+            self.set_job_machine(d, machine)
+            cache = jm.setCache(self.signature, d, self.job_name())
+
+        self.set_output("machine", machine)
+
+class CopyFile(RQModule):
+    """ Copy a single file to/from a remote server using SFTP
+
+    """
+
+    _input_ports = [('machine', Machine),
+                    ('local_file', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('remote_file', '(edu.utah.sci.vistrails.basic:String)'),
+                    ('to_local', '(edu.utah.sci.vistrails.basic:Boolean)'),
+                   ]
+    
+    _output_ports = [('machine', Machine),
+                    ('output', '(edu.utah.sci.vistrails.basic:String)'),
+                    ]
+    
+    def compute(self):
+        machine = self.get_machine()
+        jm = self.job_monitor()
+        cache = jm.getCache(self.signature)
+        if cache:
+            result = cache.parameters['result']
+        else:
+            if not self.has_input('local_file'):
+                raise ModuleError(self, "No local file specified")
+            local_file = self.get_input('local_file').strip()
+            if not self.has_input('remote_file'):
+                raise ModuleError(self, "No remote file specified")
+            remote_file = self.get_input('remote_file').strip()
+            whereto = 'remote'
+            if self.has_input('to_local') and self.get_input('to_local'):
+                whereto = 'local'
+            ## This indicates that the coming commands submitted on the machine
+            # trick to select machine without initializing every time
+            command = machine.getfile if whereto=='local' else machine.sendfile
+            result = command(local_file, remote_file)
+            d = {'result':result}
+            self.set_job_machine(d, machine)
+            jm.setCache(self.signature, d, self.job_name())
+
+        self.set_output("machine", machine)
+        self.set_output("output", result)
+
+
+def handle_module_upgrade_request(controller, module_id, pipeline):
+    # prepend 'hadoop|' to hadoop modules < 0.3.1
+    reg = get_module_registry()
+
+    hadoop_remaps = ['PythonSourceToFile', 'HDFSPut', 'HDFSGet',
+                     'HDFSEnsureNew', 'URICreator', 'HadoopStreaming']
+
+    module_remap = {}
+    for name in hadoop_remaps:
+        module_remap[name] = [(None, '0.3.0', "hadoop|%s" % name, {})]
+    return UpgradeWorkflowHandler.remap_module(controller,
+                                               module_id,
+                                               pipeline,
+                                               module_remap)
+
+
+def initialize():
+    global _modules
+    _modules = [Machine, RQModule, RunPBSScript, RunCommand, RunJob,
+                SyncDirectories, CopyFile]
+    import base
+    import hdfs
+    import streaming
+    _modules.extend(base.register())
+    _modules.extend(hdfs.register())
+    _modules.extend(streaming.register())
+
+_modules = []
diff --git a/vistrails/packages/RemoteQ/streaming.py b/vistrails/packages/RemoteQ/streaming.py
new file mode 100644
index 0000000..358c66d
--- /dev/null
+++ b/vistrails/packages/RemoteQ/streaming.py
@@ -0,0 +1,244 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+""" Wrapper for Hadoop Streaming to use with Python mapper/reducer,
+cache files, etc...  """
+
+from __future__ import division
+
+import os.path
+
+from vistrails.core.modules.basic_modules import File, String
+from vistrails.core.modules.config import IPort, OPort, ModuleSettings
+from vistrails.core.modules.vistrails_module import ModuleError
+from base import HadoopBaseModule
+from remoteq.core.stack import use_machine
+from remoteq.batch.commandline import Subshell
+
+################################################################################
+class HadoopStreaming(HadoopBaseModule):
+    """
+    The class for executing MapReduce using Hadoop Streaming with
+    customized Python Mapper/Reducer/Combiner
+    
+    """
+    _settings = ModuleSettings(namespace='hadoop')
+    _input_ports = [IPort('Mapper',       File),
+                    IPort('Reducer',      File),
+                    IPort('Combiner',     File),
+                    IPort('Workdir',      String),
+                    IPort('Identifier',   String),
+                    IPort('Input',        String),
+                    IPort('Output',       String),
+                    IPort('CacheFile',    String),
+                    IPort('CacheArchive', String),
+                    IPort('Environment',  String),
+                    IPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)')]
+
+    _output_ports = [OPort('Machine', '(org.vistrails.vistrails.remoteq:Machine)'),
+                     OPort('Output', String)]
+
+    def __init__(self):
+        HadoopBaseModule.__init__(self)
+        self.job = None
+        self.job_machine = None
+
+    def job_read_inputs(self):
+        p = {}
+        self.localMapper = self.force_get_input('Mapper')
+        self.localReducer = self.force_get_input('Reducer')
+        self.localCombiner = self.force_get_input('Combiner')
+        p['workdir'] = self.force_get_input('Workdir')
+        if p['workdir']==None:
+            p['workdir'] = ".vistrails-hadoop"
+        p['job_identifier'] = self.force_get_input('Identifier')
+        if p['job_identifier'] is None:
+            raise ModuleError(self, 'Job Identifier is required')
+        p['input'] = self.force_get_input('Input')
+        p['output'] = self.force_get_input('Output')
+        if p['input']==None or p['output']==None:
+            raise ModuleError(self, 'Input and Output are required')
+        p['files'] = self.force_get_input_list('CacheFile')
+        p['cacheArchives'] = self.force_get_input_list('CacheArchive')
+        p['envVars'] = self.force_get_input_list('Environment') 
+        return p
+
+    def createJob(self, p):
+        self.job_machine = self.get_machine()
+        use_machine(self.job_machine)
+        self.job = Subshell("remote", command="%s",
+                            working_directory=p['workdir'],
+                            identifier=p['job_identifier'])
+
+    def job_start(self, p):
+        self.createJob(p)
+        if not self.job_machine.remote.isdir(p['workdir']):
+            self.job_machine.remote.mkdir(p['workdir'])
+        self.set_job_machine(p, self.job_machine)
+        self.job.reset()
+
+        # Now generate the command line
+        config = self.get_hadoop_config(self.job_machine)
+        command = 'jar %s' % config['streaming.jar']
+        generics = ''
+        arguments = ''
+
+        if '://' not in p['input']:
+            p['input'] = self.add_prefix(p['input'], self.job_machine)
+        if '://' not in p['output']:
+            p['output'] = self.add_prefix(p['output'], self.job_machine)
+        arguments += ' -input %s -output %s' % (p['input'], p['output'])
+        
+        if self.localMapper!=None:
+            tempfile = self.job_machine.remote.send_command('mktemp').strip()
+            result = self.job_machine.sendfile(self.localMapper.name,tempfile)
+            mapperFileName = os.path.split(tempfile)[1]
+            p['files'].append(tempfile)
+            arguments += ' -mapper %s' % mapperFileName
+        else:
+            arguments += ' -mapper org.apache.hadoop.mapred.lib.IdentityMapper'
+
+        if self.localCombiner!=None:
+            tempfile = self.job_machine.remote.send_command('mktemp').strip()
+            result = self.job_machine.sendfile(self.localCombiner.name,
+                                               tempfile)
+            combinerFileName = os.path.split(tempfile)[1]
+            p['files'].append(tempfile)
+            arguments += ' -combiner %s' % combinerFileName
+
+        if self.localReducer!=None:
+            tempfile = self.job_machine.remote.send_command('mktemp').strip()
+            result = self.job_machine.sendfile(self.localReducer.name,
+                                                       tempfile)
+            reducerFileName = os.path.split(tempfile)[1]
+            p['files'].append(tempfile)
+            arguments += ' -reducer %s' % reducerFileName
+        else:
+            arguments += ' -numReduceTasks 0'
+
+        for var in p['envVars']:
+            arguments += ' -cmdenv ' + var
+
+        for cacheArchive in p['cacheArchives']:
+            arguments += ' -cacheArchive %s' % cacheArchive
+
+        #from init import configuration
+        #if configuration.check('uris') and configuration.uris:
+        #    for uri in configuration.uris.split(';'):
+        #        p['files'].append(uri)
+        # files is a generic command and needs to be first
+        if p['files']:
+            generics += ' -files ' + ','.join(p['files'])
+
+        arguments = command + generics + arguments
+        result = self.call_hadoop(arguments, p['workdir'],
+                                  p['job_identifier'], self.job_machine)
+        return p
+
+    def job_get_handle(self, p):
+        if not self.job:
+            self.createJob(p)
+        return self.job
+
+    def job_finish(self, p):
+        r = {}
+        r['output'] = p['output']
+        r['workdir'] = p['workdir']
+        r['job_identifier'] = p['job_identifier']
+        
+        self.annotate({'hadoop_log':self.job.standard_error()})
+        if self.job.failed():
+            error = self.job.standard_error()
+            raise ModuleError(self, error)
+        return r
+
+    def job_set_results(self, p):
+        self.set_output('Output', p['output'])
+        self.set_output('Machine', self.job_machine)
+
+    def call_hadoop(self, arguments, workdir, identifier, machine):
+        config = self.get_hadoop_config(machine)
+        argList = [config['hadoop']]
+        if type(arguments) in [str, unicode]:
+            argList += arguments.split(' ')
+        elif type(arguments)==list:
+            argList += arguments
+        else:
+            raise ModuleError(self, 'Invalid argument types to hadoop')
+        self.annotate({'hadoop_command':" ".join(argList)})
+        self.job.command = self.job.command % " ".join(argList)
+        self.job.run()
+
+################################################################################
+class URICreator(HadoopBaseModule):
+    """
+    The class for caching HDFS file onto the TaskNode local drive
+    
+    """
+    _settings = ModuleSettings(namespace='hadoop')
+    _input_ports = [IPort('HDFS File/URI', String),
+                    IPort('Symlink',       String),
+                    IPort('Machine',        
+                          '(org.vistrails.vistrails.remoteq:Machine)')]
+
+    _output_ports = [OPort('Machine',
+                           '(org.vistrails.vistrails.remoteq:Machine)'),
+                     OPort('URI', String)]
+
+    def compute(self):
+        machine = self.get_machine()
+        jm = self.job_monitor()
+        id = self.signature
+        job = jm.getCache(id)
+        if not job:
+            uri = self.force_get_input('HDFS File/URI')
+            symlink = self.force_get_input('Symlink')
+            if uri==None or symlink==None:
+                raise ModuleError(self,
+                                "Missing 'HDFS File/URI' or 'Symlink' values")
+            if '://' not in uri:
+                uri = self.add_prefix(uri, machine)
+            uri += '#' + symlink
+            d = {'uri':uri}
+            self.set_job_machine(d, machine)
+            jm.setCache(id, d, self.job_name())
+            job = jm.getCache(id)
+        self.set_output('URI', job.parameters['uri'])
+        self.set_output('Machine', machine)
+       
+
+################################################################################
+def register():
+    return [URICreator, HadoopStreaming]
diff --git a/vistrails/packages/SUDSWebServices/__init__.py b/vistrails/packages/SUDSWebServices/__init__.py
index 4e37825..d8441a0 100644
--- a/vistrails/packages/SUDSWebServices/__init__.py
+++ b/vistrails/packages/SUDSWebServices/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 It requires suds library to be installed. Click on configure to add wsdl
 urls to the package (use a ; to separate the urls).
 """
+from __future__ import division
+
 from vistrails.core.configuration import ConfigurationObject
 import vistrails.core
 
diff --git a/vistrails/packages/SUDSWebServices/init.py b/vistrails/packages/SUDSWebServices/init.py
index 90e7e7c..3411256 100644
--- a/vistrails/packages/SUDSWebServices/init.py
+++ b/vistrails/packages/SUDSWebServices/init.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import sys
 import os.path
 import shutil
@@ -136,10 +139,10 @@ def initialize(*args, **keywords):
         try:
             debug.log("Creating SUDS cache directory...")
             os.mkdir(location)
-        except:
+        except OSError, e:
             debug.critical(
 """Could not create SUDS cache directory. Make sure
-'%s' does not exist and parent directory is writable""" % location)
+'%s' does not exist and parent directory is writable""" % location, e)
             sys.exit(1)
     # the number of days to cache wsdl files
     days = 1
@@ -175,7 +178,7 @@ def finalize():
         if s.package:
             reg.remove_package(s.package)
 
-class WSMethod:
+class WSMethod(object):
     """ A WSDL method
     """
     def __init__(self, qname=('','')):
@@ -184,7 +187,7 @@ class WSMethod:
         self.inputs = {}
         self.outputs = {}
 
-class WSElement:
+class WSElement(object):
     """ A part of a WSDL type
     """
     def __init__(self, name='', type=('',''), optional=False, min=0,
@@ -196,7 +199,7 @@ class WSElement:
         self.max = max
         self.enum = enum
 
-class WSType:
+class WSType(object):
     """ A WSDL type definition
     """
     def __init__(self, qname=('',''), enum=False):
@@ -205,7 +208,7 @@ class WSType:
         "name: WSElement"
         self.parts = {}
  
-class Service:
+class Service(object):
     def __init__(self, address):
         """ Process WSDL and add all Types and Methods
         """
@@ -229,20 +232,20 @@ class Service:
         try:
             self.service = suds.client.Client(address, **options)
             self.backUpCache()
-        except Exception, e:
+        except Exception:
             self.service = None
             # We may be offline and the cache may have expired,
             # try to use backup
             if self.restoreFromBackup():
                 try:
                     self.service = suds.client.Client(address, **options)
-                except Exception, e:
+                except Exception:
                     self.service = None
                     debug.critical("Could not load WSDL: %s" % address,
-                           str(e) + '\n' + str(traceback.format_exc()))
+                                   traceback.format_exc())
             else:
                 debug.critical("Could not load WSDL: %s" % address,
-                       str(e) + '\n' + str(traceback.format_exc()))
+                               traceback.format_exc())
         if self.service:
             try:
                 self.createPackage()
@@ -250,9 +253,9 @@ class Service:
                 self.setMethods()
                 self.createTypeClasses()
                 self.createMethodClasses()
-            except Exception, e:
+            except Exception:
                 debug.critical("Could not create Web Service: %s" % address,
-                               str(e) + '\n' + str(traceback.format_exc()))
+                               traceback.format_exc())
                 self.service = None
         if self.wsdlHash == '-1':
             # create empty package so that it can be reloaded/deleted
@@ -478,21 +481,21 @@ class Service:
                 if self.wstype.enum:
                     # only makes sure the enum is one of the valid values
                     p = self.wstype.parts['value']
-                    if self.hasInputFromPort(p.name):
-                        obj = self.getInputFromPort(p.name)
+                    if self.has_input(p.name):
+                        obj = self.get_input(p.name)
                     else:
                         obj = p.enum[0] if len(p.enum) else ''
-                    if self.hasInputFromPort('value'):
-                        obj = self.getInputFromPort('value')
+                    if self.has_input('value'):
+                        obj = self.get_input('value')
                     if obj not in p.enum:
                         raise ModuleError(self,
                                  "'%s' is not one of the valid enums: %s" %
                                  (obj, str(p.enum)) )
-                    self.setResult(self.wstype.qname[0], obj)
-                    self.setResult('value', obj)
+                    self.set_output(self.wstype.qname[0], obj)
+                    self.set_output('value', obj)
                     return
-                if self.hasInputFromPort(self.wstype.qname[0]):
-                    obj = self.getInputFromPort(self.wstype.qname[0])
+                if self.has_input(self.wstype.qname[0]):
+                    obj = self.get_input(self.wstype.qname[0])
                 else:
                     obj = {}
                     s = "{%s}%s"%(self.wstype.qname[1],self.wstype.qname[0])
@@ -511,8 +514,8 @@ class Service:
                             # update each attribute
                             if hasattr(obj.value, part.name):
                                 setattr(obj, part.name, getattr(obj.value, part.name))
-                    if self.hasInputFromPort(part.name):
-                        p = self.getInputFromPort(part.name)
+                    if self.has_input(part.name):
+                        p = self.get_input(part.name)
                         if hasattr(obj, part.name):
                             setattr(obj, part.name, p)
                         else:
@@ -521,8 +524,8 @@ class Service:
                     if hasattr(obj, part.name):
                         # 
                         res = getattr(obj, part.name)
-                        self.setResult(part.name, res)
-                self.setResult(self.wstype.qname[0], obj)
+                        self.set_output(part.name, res)
+                self.set_output(self.wstype.qname[0], obj)
 
             # create docstring
             parts = ", ".join([i.type[0]+' '+i.name for i in t.parts.itervalues()])
@@ -582,15 +585,15 @@ It is a WSDL type with signature:
             def compute(self):
                 # create dict of inputs
                 cacheable = False
-                if self.hasInputFromPort('cacheable'):
-                    cacheable = self.getInputFromPort('cacheable')
+                if self.has_input('cacheable'):
+                    cacheable = self.get_input('cacheable')
                 self.is_cacheable = lambda *args, **kwargs: cacheable            
                 params = {}
                 mname = self.wsmethod.qname[0]
                 for name in self.wsmethod.inputs:
                     name = str(name)
-                    if self.hasInputFromPort(name):
-                        params[name] = self.getInputFromPort(name)
+                    if self.has_input(name):
+                        params[name] = self.get_input(name)
                         if params[name].__class__.__name__ == 'UberClass':
                             params[name] = params[name].value
                         params[name] = self.service.makeDictType(params[name])
@@ -605,31 +608,33 @@ It is a WSDL type with signature:
                     #self.service.service.set_options(retxml = False)
                     result = getattr(self.service.service.service, mname)(**params)
                 except Exception, e:
-                    raise ModuleError(self, "Error invoking method %s: %s"%(name, str(e)))
+                    debug.unexpected_exception(e)
+                    raise ModuleError(self, "Error invoking method %s: %s" % (
+                            mname, debug.format_exception(e)))
                 for name, qtype in self.wsmethod.outputs.iteritems():
                     if isinstance(result, list):
                         # if result is a list just set the output
-                        self.setResult(name, result)
+                        self.set_output(name, result)
                     elif qtype[0] == 'Array':
                         # if result is a type but type is a list try to extract the correct element
                         if len(result.__keylist__):
-                            self.setResult(name, getattr(result, result.__keylist__[0]))
+                            self.set_output(name, getattr(result, result.__keylist__[0]))
                         else:
-                            self.setResult(name, result)
+                            self.set_output(name, result)
                     elif result.__class__.__name__ == 'Text':
                         # only text returned so we assume each output wants all of it
-                        self.setResult(name, str(result.trim()))
+                        self.set_output(name, str(result.trim()))
                     elif result.__class__.__name__ == qtype[0]:
                         # the return value is this type
-                        self.setResult(name, result)
+                        self.set_output(name, result)
                     elif hasattr(result, name):
-                        self.setResult(name, getattr(result, name))
+                        self.set_output(name, getattr(result, name))
                     else:
                         # nothing matches - assume it is an attribute of the correct class
-                        class UberClass:
+                        class UberClass(object):
                             def __init__(self, value):
                                 self.value = value
-                        self.setResult(name, UberClass(result))
+                        self.set_output(name, UberClass(result))
 
             # create docstring
             inputs = ", ".join([t[0]+' '+i for i,t in m.inputs.iteritems()])
@@ -683,7 +688,8 @@ def load_from_signature(signature):
     if not wsdl in wsdlList:
         try:
             service = Service(wsdl)
-        except:
+        except Exception, e:
+            debug.unexpected_exception(e)
             return False
         if not service.service:
             return False
@@ -741,7 +747,8 @@ def handle_missing_module(controller, module_id, pipeline):
         try:
             wsdl = m_namespace.split("|")
             return wsdl[0]
-        except:
+        except Exception, e:
+            debug.unexpected_exception(e)
             return None
     
     m = pipeline.modules[module_id]
diff --git a/vistrails/packages/URL/__init__.py b/vistrails/packages/URL/__init__.py
new file mode 100644
index 0000000..787a697
--- /dev/null
+++ b/vistrails/packages/URL/__init__.py
@@ -0,0 +1,49 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""URL provides modules to download files via the network.
+
+It can refer to HTTP and FTP files, which enables workflows to be distributed
+without its associated data.
+
+This package uses a local cache, inside the per-user VisTrails directory. This
+way, files that haven't been changed do not need to be downloaded again. The
+check is performed efficiently using HTTP headers.
+"""
+
+from __future__ import division
+
+from identifiers import *
diff --git a/vistrails/packages/URL/http_directory.py b/vistrails/packages/URL/http_directory.py
new file mode 100644
index 0000000..a4e68f2
--- /dev/null
+++ b/vistrails/packages/URL/http_directory.py
@@ -0,0 +1,215 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+# https://gist.github.com/remram44/6540454
+
+from __future__ import division
+
+from HTMLParser import HTMLParser
+import os
+import re
+
+from .https_if_available import build_opener
+
+
+re_url = re.compile(r'^(([a-zA-Z_-]+)://([^/]+))(/.*)?$')
+
+def resolve_link(link, url):
+    m = re_url.match(link)
+    if m is not None:
+        if not m.group(4):
+            # http://domain -> http://domain/
+            return link + '/'
+        else:
+            return link
+    elif link[0] == '/':
+        # /some/path
+        murl = re_url.match(url)
+        return murl.group(1) + link
+    else:
+        # relative/path
+        if url[-1] == '/':
+            return url + link
+        else:
+            return url + '/' + link
+
+
+class ListingParser(HTMLParser):
+    """Parses an HTML file and build a list of links.
+
+    Links are stored into the 'links' set. They are resolved into absolute
+    links.
+    """
+    def __init__(self, url):
+        HTMLParser.__init__(self)
+
+        if url[-1] != '/':
+            url += '/'
+        self.__url = url
+        self.links = set()
+
+    def handle_starttag(self, tag, attrs):
+        if tag == 'a':
+            for key, value in attrs:
+                if key == 'href':
+                    if not value:
+                        continue
+                    value = resolve_link(value, self.__url)
+                    self.links.add(value)
+                    break
+
+
+def download_directory(url, target, insecure=False):
+    def mkdir():
+        if not mkdir.done:
+            try:
+                os.mkdir(target)
+            except OSError:
+                pass
+            mkdir.done = True
+    mkdir.done = False
+
+    opener = build_opener(insecure=insecure)
+    response = opener.open(url)
+
+    if response.info().type == 'text/html':
+        contents = response.read()
+
+        parser = ListingParser(url)
+        parser.feed(contents)
+        for link in parser.links:
+            link = resolve_link(link, url)
+            if link[-1] == '/':
+                link = link[:-1]
+            if not link.startswith(url):
+                continue
+            name = link.rsplit('/', 1)[1]
+            if '?' in name:
+                continue
+            mkdir()
+            download_directory(link, os.path.join(target, name), insecure)
+        if not mkdir.done:
+            # We didn't find anything to write inside this directory
+            # Maybe it's a HTML file?
+            if url[-1] != '/':
+                end = target[-5:].lower()
+                if not (end.endswith('.htm') or end.endswith('.html')):
+                    target = target + '.html'
+                with open(target, 'wb') as fp:
+                    fp.write(contents)
+    else:
+        buffer_size = 4096
+        with open(target, 'wb') as fp:
+            chunk = response.read(buffer_size)
+            while chunk:
+                fp.write(chunk)
+                chunk = response.read(buffer_size)
+
+
+###############################################################################
+
+import unittest
+
+
+class TestLinkResolution(unittest.TestCase):
+    def test_absolute_link(self):
+        self.assertEqual(
+                resolve_link('http://website.org/p/test.txt',
+                             'http://some/other/url'),
+                'http://website.org/p/test.txt')
+        self.assertEqual(
+                resolve_link('http://website.org',
+                             'http://some/other/url'),
+                'http://website.org/')
+
+    def test_absolute_path(self):
+        self.assertEqual(
+                resolve_link('/p/test.txt', 'http://some/url'),
+                'http://some/p/test.txt')
+        self.assertEqual(
+                resolve_link('/p/test.txt', 'http://some/url/'),
+                'http://some/p/test.txt')
+        self.assertEqual(
+                resolve_link('/p/test.txt', 'http://site'),
+                'http://site/p/test.txt')
+        self.assertEqual(
+                resolve_link('/p/test.txt', 'http://site/'),
+                'http://site/p/test.txt')
+
+    def test_relative_path(self):
+        self.assertEqual(
+                resolve_link('some/file', 'http://site/folder'),
+                'http://site/folder/some/file')
+        self.assertEqual(
+                resolve_link('some/file', 'http://site/folder/'),
+                'http://site/folder/some/file')
+        self.assertEqual(
+                resolve_link('some/dir/', 'http://site/folder'),
+                'http://site/folder/some/dir/')
+
+
+class TestParser(unittest.TestCase):
+    def test_parse(self):
+        parser = ListingParser('http://a.remram.fr/test')
+        parser.feed("""
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html><head><title>
+Index of /test</title></head><body><h1>Index of /test</h1><table><tr><th>
+<img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a>
+</th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size
+</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5">
+<hr></th></tr><tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td>
+<td><a href="/">Parent Directory</a></td><td> </td><td align="right">  - 
+</td><td> </td></tr><tr><td valign="top">
+<img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="a">a</a></td>
+<td align="right">11-Sep-2013 15:46  </td><td align="right">  3 </td><td> 
+</td></tr><tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td>
+<td><a href="/bb">bb</a></td><td align="right">11-Sep-2013 15:46  </td>
+<td align="right">  3 </td><td> </td></tr><tr><td valign="top">
+<img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="/cc/">cc/</a></td>
+<td align="right">11-Sep-2013 15:46  </td><td align="right">  - </td><td> 
+</td></tr><tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td>
+<td><a href="http://a.remram.fr/dd">dd/</a></td><td align="right">
+11-Sep-2013 15:46  </td><td align="right">  - </td><td> </td></tr><tr>
+<th colspan="5"><hr></th></tr></table></body></html>
+        """)
+        links = set(l for l in parser.links if '?' not in l)
+        self.assertEqual(links, set([
+                'http://a.remram.fr/',
+                'http://a.remram.fr/test/a',
+                'http://a.remram.fr/bb',
+                'http://a.remram.fr/cc/',
+                'http://a.remram.fr/dd',
+        ]))
diff --git a/vistrails/packages/URL/https.py b/vistrails/packages/URL/https.py
new file mode 100644
index 0000000..ce53bcf
--- /dev/null
+++ b/vistrails/packages/URL/https.py
@@ -0,0 +1,109 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+# Python's handling of certificate verification is irresponsible and wrong.
+# Having to include the code below to get what should be the only acceptable
+# default behavior is a shame
+
+# Code from https://gist.github.com/schlamar/2993700
+
+from __future__ import division
+
+import httplib
+import urllib2
+import ssl
+
+import certifi
+from backports.ssl_match_hostname import match_hostname
+
+
+__all__ = ['VerifiedHTTPSHandler', 'https_handler', 'build_opener']
+
+
+class CertValidatingHTTPSConnection(httplib.HTTPConnection):
+    default_port = httplib.HTTPS_PORT
+
+    def __init__(self, host, port=None, key_file=None, cert_file=None,
+                             ca_certs=None, strict=None, **kwargs):
+        httplib.HTTPConnection.__init__(self, host, port, strict, **kwargs)
+        self.key_file = key_file
+        self.cert_file = cert_file
+        self.ca_certs = ca_certs
+        if self.ca_certs:
+            self.cert_reqs = ssl.CERT_REQUIRED
+        else:
+            self.cert_reqs = ssl.CERT_NONE
+
+    def connect(self):
+        httplib.HTTPConnection.connect(self)
+        self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file,
+                                    certfile=self.cert_file,
+                                    cert_reqs=self.cert_reqs,
+                                    ca_certs=self.ca_certs)
+        if self.cert_reqs & ssl.CERT_REQUIRED:
+            cert = self.sock.getpeercert()
+            hostname = self.host.split(':', 0)[0]
+            match_hostname(cert, hostname)
+
+
+class VerifiedHTTPSHandler(urllib2.HTTPSHandler):
+    def __init__(self, **kwargs):
+        urllib2.HTTPSHandler.__init__(self)
+        self._connection_args = kwargs
+
+    def https_open(self, req):
+        def http_class_wrapper(host, **kwargs):
+            full_kwargs = dict(self._connection_args)
+            full_kwargs.update(kwargs)
+            return CertValidatingHTTPSConnection(host, **full_kwargs)
+
+        return self.do_open(http_class_wrapper, req)
+
+
+https_handler = VerifiedHTTPSHandler(ca_certs=certifi.where())
+
+
+def build_opener(*handlers, **kwargs):
+    # Keyword-only argument 'insecure'
+    insecure = kwargs.pop('insecure', False)
+    if kwargs:
+        raise TypeError("build_opener() got unexpected keyword argument %r" %
+                        next(iter(kwargs)))
+
+    if not insecure:
+        handlers = handlers + (https_handler,)
+    handlers = handlers + (urllib2.ProxyHandler(),)
+    return urllib2.build_opener(*handlers)
diff --git a/vistrails/packages/URL/https_if_available.py b/vistrails/packages/URL/https_if_available.py
new file mode 100644
index 0000000..81b0e2f
--- /dev/null
+++ b/vistrails/packages/URL/https_if_available.py
@@ -0,0 +1,61 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import urllib2
+
+from vistrails.core.bundles.pyimport import py_import
+from vistrails.core import debug
+
+
+try:
+    py_import('certifi', {
+                  'pip': 'certifi'},
+              True)
+    py_import('backports.ssl_match_hostname', {
+                  'pip': 'backports.ssl_match_hostname',
+                  'linux-fedora': 'python-backports-ssl_match_hostname'},
+              True)
+except ImportError:
+    def build_opener(*args, **kwargs):
+        insecure = kwargs.pop('insecure', False)
+        if not insecure:
+            debug.warning("Unable to use secure SSL requests -- please "
+                          "install certifi and ssl_match_hostname")
+        return urllib2.build_opener(*args, **kwargs)
+else:
+    from .https import *
diff --git a/vistrails/packages/URL/identifiers.py b/vistrails/packages/URL/identifiers.py
new file mode 100644
index 0000000..c11e44e
--- /dev/null
+++ b/vistrails/packages/URL/identifiers.py
@@ -0,0 +1,53 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""URL provides modules to download files via the network.
+
+It can refer to HTTP and FTP files, which enables workflows to be distributed
+without its associated data.
+
+This package uses a local cache, inside the per-user VisTrails directory. This
+way, files that haven't been changed do not need to be downloaded again. The
+check is performed efficiently using HTTP headers.
+"""
+
+from __future__ import division
+
+identifier = 'org.vistrails.vistrails.url'
+name = 'URL'
+version = '1.0.0'
+old_identifiers = ['org.vistrails.vistrails.http',
+                   'edu.utah.sci.vistrails.http']
diff --git a/vistrails/packages/URL/init.py b/vistrails/packages/URL/init.py
new file mode 100644
index 0000000..3a581e8
--- /dev/null
+++ b/vistrails/packages/URL/init.py
@@ -0,0 +1,735 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""URL provides modules to download files via the network.
+
+It can refer to HTTP and FTP files, which enables workflows to be distributed
+without its associated data.
+
+This package uses a local cache, inside the per-user VisTrails directory. This
+way, files that haven't been changed do not need to be downloaded again. The
+check is performed efficiently using HTTP headers.
+"""
+
+from __future__ import division
+
+from datetime import datetime
+import email.utils
+import hashlib
+import os
+import re
+import urllib
+import urllib2
+
+from vistrails.core.bundles.pyimport import py_import
+from vistrails.core.configuration import get_vistrails_persistent_configuration
+from vistrails.core import debug
+import vistrails.core.modules.basic_modules
+from vistrails.core.modules.basic_modules import PathObject
+import vistrails.core.modules.module_registry
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+from vistrails.core.system import current_dot_vistrails, strptime
+from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
+import vistrails.gui.repository
+from vistrails.gui.utils import show_warning
+
+from vistrails.core.repository.poster.encode import multipart_encode
+from vistrails.core.repository.poster.streaminghttp import register_openers
+
+from .identifiers import identifier
+from .http_directory import download_directory
+from .https_if_available import build_opener
+
+
+package_directory = None
+
+
+###############################################################################
+
+class Downloader(object):
+    def __init__(self, url, module, insecure):
+        self.url = url
+        self.module = module
+        self.opener = build_opener(insecure=insecure)
+
+    def execute(self):
+        """ Tries to download a file from url.
+
+        Returns the path to the local file.
+        """
+        self.local_filename = os.path.join(package_directory,
+                                           urllib.quote_plus(self.url))
+
+        # Before download
+        self.pre_download()
+
+        # Send request
+        try:
+            response = self.send_request()
+        except urllib2.URLError, e:
+            if self.is_in_local_cache:
+                debug.warning("A network error occurred. DownloadFile will "
+                              "use a cached version of the file")
+                return self.local_filename
+            else:
+                raise ModuleError(
+                        self.module,
+                        "Network error: %s" % debug.format_exception(e))
+        if response is None:
+            return self.local_filename
+
+        # Read response headers
+        self.size_header = None
+        if not self.read_headers(response):
+            return self.local_filename
+
+        # Download
+        self.download(response)
+
+        # Post download
+        self.post_download(response)
+
+        return self.local_filename
+
+    def pre_download(self):
+        pass
+
+    def send_request(self):
+        return self.opener.open(self.url)
+
+    def read_headers(self, response):
+        return True
+
+    def download(self, response):
+        try:
+            dl_size = 0
+            CHUNKSIZE = 4096
+            f2 = open(self.local_filename, 'wb')
+            while True:
+                if self.size_header is not None:
+                    self.module.logging.update_progress(
+                            self.module,
+                            dl_size * 1.0/self.size_header)
+                chunk = response.read(CHUNKSIZE)
+                if not chunk:
+                    break
+                dl_size += len(chunk)
+                f2.write(chunk)
+            f2.close()
+            response.close()
+
+        except Exception, e:
+            try:
+                os.unlink(self.local_filename)
+            except OSError:
+                pass
+            raise ModuleError(
+                    self.module,
+                    "Error retrieving URL: %s" % debug.format_exception(e))
+
+    def post_download(self, response):
+        pass
+
+    @property
+    def is_in_local_cache(self):
+        return os.path.isfile(self.local_filename)
+
+
+class HTTPDownloader(Downloader):
+    def pre_download(self):
+        # Get ETag from disk
+        try:
+            with open(self.local_filename + '.etag') as etag_file:
+                self.etag = etag_file.read()
+        except IOError:
+            self.etag = None
+
+    def send_request(self):
+        try:
+            request = urllib2.Request(self.url)
+            if self.etag is not None:
+                request.add_header(
+                    'If-None-Match',
+                    self.etag)
+            try:
+                mtime = email.utils.formatdate(
+                        os.path.getmtime(self.local_filename),
+                        usegmt=True)
+                request.add_header(
+                    'If-Modified-Since',
+                    mtime)
+            except OSError:
+                pass
+            return self.opener.open(request)
+        except urllib2.HTTPError, e:
+            if e.code == 304:
+                # Not modified
+                return None
+            raise
+
+    def read_headers(self, response):
+        try:
+            self.mod_header = response.headers['last-modified']
+        except KeyError:
+            self.mod_header = None
+        try:
+            size_header = response.headers['content-length']
+            if not size_header:
+                raise ValueError
+            self.size_header = int(size_header)
+        except (KeyError, ValueError):
+            self.size_header = None
+        return True
+
+    def _is_outdated(self):
+        local_time = datetime.utcfromtimestamp(
+                os.path.getmtime(self.local_filename))
+        try:
+            remote_time = strptime(self.mod_header,
+                                   "%a, %d %b %Y %H:%M:%S %Z")
+        except ValueError:
+            try:
+                remote_time = strptime(self.mod_header,
+                                       "%a, %d %B %Y %H:%M:%S %Z")
+            except ValueError:
+                # unable to parse last-modified header, download file again
+                debug.warning("Unable to parse Last-Modified header, "
+                              "downloading file")
+                return True
+        return remote_time > local_time
+
+    def download(self, response):
+        if (not self.is_in_local_cache or
+                not self.mod_header or self._is_outdated()):
+            Downloader.download(self, response)
+
+    def post_download(self, response):
+        try:
+            etag = response.headers['ETag']
+        except KeyError:
+            pass
+        else:
+            with open(self.local_filename + '.etag', 'w') as etag_file:
+                etag = etag_file.write(etag)
+
+
+class SSHDownloader(object):
+    """ SSH downloader: downloads files via SCP, using paramiko and scp.
+
+    Recognized URL schemes are:
+        ssh://user[:password]@host[:port]/absolute/path
+            Examples:
+                ssh://john@vistrails.nyu.edu/home/john/example.txt
+                ssh://eve:my%20secret@google.com/tmp/test%20file.bin
+            Note that both password and path are url-encoded, that the path
+            is absolute, and that the username must be specified
+        scp://[user@]host:path
+            Examples:
+                scp://john@vistrails.nyu.edu:files/test.txt
+                scp://poly.edu:/tmp/test.bin
+            Note that nothing is url encoded, that the path can be relative
+            (to the user's home directory) and that no username or port can
+            be specified
+    """
+
+    SSH_FORMAT = re.compile(
+            r'^'
+            'ssh://'                    # Protocol
+            '([A-Za-z0-9_/+.-]+)'       # 1 Username
+            '(?::([^@]+))?'             # 2 Password
+            '@([A-Za-z0-9_.-]+)'        # 3 Hostname
+            '(?::([0-9]+))?'            # 4 Port number
+            '(/.+)'                     # 5 Path (url-encoded!)
+            '$'
+            )
+    SCP_FORMAT = re.compile(
+            r'^'
+            '(?:scp://)?'               # Protocol
+            '(?:([A-Za-z0-9_/+.-]+)@)?' # 1 Username
+            '([A-Za-z0-9_.-]+)'         # 2 Hostname
+            ':(.+)'                     # 3 Path (not url-encoded)
+            '$'
+            )
+
+    def __init__(self, url, module, insecure):
+        self.url = url
+        self.module = module
+
+    def execute(self):
+        # Parse URL
+        password = None
+        portnum = None
+        if self.url.startswith('ssh:'):
+            m = self.SSH_FORMAT.match(self.url)
+            if m is None:
+                raise ModuleError(self.module,
+                                  "SSH error: invalid URL %r" % self.url)
+            username, password, hostname, portnum, path = m.groups()
+            password = urllib.unquote_plus(password)
+            path = urllib.unquote_plus(path)
+        elif self.url.startswith('scp:'):
+            m = self.SCP_FORMAT.match(self.url)
+            if m is None:
+                raise ModuleError(self.module,
+                                  "SSH error: invalid URL %r" % self.url)
+            username, hostname, path = m.groups()
+        else:
+            raise ModuleError(self.module, "SSHDownloader: Invalid URL")
+
+        if portnum is None:
+            portnum = 22
+        else:
+            portnum = int(portnum)
+        return self._open_ssh(username, password, hostname, portnum, path)
+
+    def _open_ssh(self, username, password, hostname, portnum, path):
+        paramiko = py_import('paramiko', {
+                'pip': 'paramiko',
+                'linux-debian': 'python-paramiko',
+                'linux-ubuntu': 'python-paramiko',
+                'linux-fedora': 'python-paramiko'})
+        scp = py_import('scp', {
+                'pip': 'scp'})
+
+        local_filename = os.path.join(package_directory,
+                                      urllib.quote_plus(self.url))
+
+        ssh = paramiko.SSHClient()
+        ssh.load_system_host_keys()
+        try:
+            ssh.connect(hostname, port=portnum,
+                        username=username, password=password)
+        except paramiko.SSHException, e:
+            raise ModuleError(self.module, debug.format_exception(e))
+        client = scp.SCPClient(ssh.get_transport())
+
+        client.get(path, local_filename)
+        return local_filename
+
+
+downloaders = {
+    'http': HTTPDownloader,
+    'https': HTTPDownloader,
+    'ssh': SSHDownloader,
+    'scp': SSHDownloader}
+
+
+class DownloadFile(Module):
+    """ Downloads file from URL.
+
+    This modules downloads a remote file. It tries to cache files on the local
+    filesystem so as to not re-download unchanged files.
+
+    Recognized URL schemes are:
+        http://...
+        https://...
+        ftp://...
+        ssh://user[:password]@host[:port]/absolute/path
+            Examples:
+                ssh://john@vistrails.nyu.edu/home/john/example.txt
+                ssh://eve:my%20secret@google.com/tmp/test%20file.bin
+            Note that both password and path are url-encoded, that the path
+            is absolute, and that the username must be specified
+        scp://[user@]host:path
+            Examples:
+                scp://john@vistrails.nyu.edu:files/test.txt
+                scp://poly.edu:/tmp/test.bin
+            Note that nothing is url encoded, that the path can be relative
+            (to the user's home directory) and that no username or port can
+            be specified
+    """
+
+    def compute(self):
+        self.check_input('url')
+        url = self.get_input('url')
+        insecure = self.get_input('insecure')
+        local_filename = self.download(url, insecure)
+        self.set_output('local_filename', local_filename)
+        result = PathObject(local_filename)
+        self.set_output('file', result)
+
+    def download(self, url, insecure):
+        """ Tries to download a file from url.
+
+        Returns the path to the local file.
+        """
+        scheme = urllib2.splittype(url)[0]
+        DL = downloaders.get(scheme, Downloader)
+        return DL(url, self, insecure).execute()
+
+
+class HTTPDirectory(Module):
+    """Downloads a whole directory recursively from a URL
+    """
+
+    def compute(self):
+        self.check_input('url')
+        url = self.get_input('url')
+        insecure = self.get_input('insecure')
+        local_path = self.download(url, insecure)
+        self.set_output('local_path', local_path)
+        local_dir = PathObject(local_path)
+        self.set_output('directory', local_dir)
+
+    def download(self, url, insecure):
+        local_path = self.interpreter.filePool.create_directory(
+                prefix='vt_http').name
+        download_directory(url, local_path, insecure)
+        return local_path
+
+
+class RepoSync(Module):
+    """ VisTrails Server version of RepoSync modules. Customized to play
+    nicely with crowdlabs. Needs refactoring.
+
+    RepoSync enables data to be synced with a online repository. The designated file
+    parameter will be uploaded to the repository on execution,
+    creating a new pipeline version that links to online repository data.
+    If the local file isn't available, then the online repository data is used.
+    """
+
+    def __init__(self):
+        Module.__init__(self)
+
+        config = get_vistrails_persistent_configuration()
+        if config.check('webRepositoryURL'):
+            self.base_url = config.webRepositoryURL
+        else:
+            raise ModuleError(self,
+                              ("No webRepositoryURL value defined"
+                               " in the Expert Configuration"))
+
+        # check if we are running in server mode
+        # this effects how the compute method functions
+        if config.check('isInServerMode'):
+            self.is_server = bool(config.isInServerMode)
+        else:
+            self.is_server = False
+
+        # TODO: this '/' check should probably be done in core/configuration.py
+        if self.base_url[-1] == '/':
+            self.base_url = self.base_url[:-1]
+
+    # used for invaliding cache when user isn't logged in to crowdLabs
+    # but wants to upload data
+    def invalidate_cache(self):
+        return False
+
+    def validate_cache(self):
+        return True
+
+    def _file_is_in_local_cache(self, local_filename):
+        return os.path.isfile(local_filename)
+
+    def checksum_lookup(self):
+        """ checks if the repository has the wanted data """
+
+        checksum_url = "%s/datasets/exists/%s/" % (self.base_url,
+                                                   self.checksum)
+        self.on_server = False
+        try:
+            check_dataset_on_repo = urllib2.urlopen(url=checksum_url)
+            self.up_to_date = True if \
+                    check_dataset_on_repo.read() == 'uptodate' else False
+            self.on_server = True
+        except urllib2.HTTPError:
+            self.up_to_date = True
+
+    def data_sync(self):
+        """ downloads/uploads/uses the local file depending on availability """
+        self.checksum_lookup()
+
+        # local file not on repository, so upload
+        if not self.on_server and os.path.isfile(self.in_file.name):
+            cookiejar = vistrails.gui.repository.QRepositoryDialog.cookiejar
+            if cookiejar:
+                register_openers(cookiejar=cookiejar)
+
+                params = {'dataset_file': open(self.in_file.name, 'rb'),
+                          'name': self.in_file.name.split('/')[-1],
+                          'origin': 'vistrails',
+                          'checksum': self.checksum}
+
+                upload_url = "%s/datasets/upload/" % self.base_url
+
+                datagen, headers = multipart_encode(params)
+                request = urllib2.Request(upload_url, datagen, headers)
+                try:
+                    result = urllib2.urlopen(request)
+                    if result.code != 200:
+                        show_warning("Upload Failure",
+                                     "Data failed to upload to repository")
+                        # make temporarily uncachable
+                        self.is_cacheable = self.invalidate_cache
+                    else:
+                        debug.warning("Push to repository was successful")
+                        # make sure module caches
+                        self.is_cacheable = self.validate_cache
+                except Exception, e:
+                    show_warning("Upload Failure",
+                                 "Data failed to upload to repository")
+                    # make temporarily uncachable
+                    self.is_cacheable = self.invalidate_cache
+                debug.warning('RepoSync uploaded %s to the repository' % \
+                              self.in_file.name)
+            else:
+                show_warning("Please login", ("You must be logged into the web"
+                                              " repository in order to upload "
+                                              "data. No data was synced"))
+                # make temporarily uncachable
+                self.is_cacheable = self.invalidate_cache
+
+            # use local data
+            self.set_output("file", self.in_file)
+        else:
+            # file on repository mirrors local file, so use local file
+            if self.up_to_date and os.path.isfile(self.in_file.name):
+                self.set_output("file", self.in_file)
+            else:
+                # local file not present or out of date, download or use cache
+                self.url = "%s/datasets/download/%s" % (self.base_url,
+                                                       self.checksum)
+                local_filename = package_directory + '/' + \
+                        urllib.quote_plus(self.url)
+                if not self._file_is_in_local_cache(local_filename):
+                    # file not in cache, download.
+                    try:
+                        urllib.urlretrieve(self.url, local_filename)
+                    except IOError, e:
+                        raise ModuleError(self, ("Invalid URL: %s" % e))
+                out_file = PathObject(local_filename)
+                debug.warning('RepoSync is using repository data')
+                self.set_output("file", out_file)
+
+
+    def compute(self):
+        # if server, grab local file using checksum id
+        if self.is_server:
+            self.check_input('checksum')
+            self.checksum = self.get_input("checksum")
+            # get file path
+            path_url = "%s/datasets/path/%s/"%(self.base_url, self.checksum)
+            dataset_path_request = urllib2.urlopen(url=path_url)
+            dataset_path = dataset_path_request.read()
+
+            if os.path.isfile(dataset_path):
+                out_file = PathObject(dataset_path)
+                self.set_output("file", out_file)
+        else: # is client
+            self.check_input('file')
+            self.in_file = self.get_input("file")
+            if os.path.isfile(self.in_file.name):
+                # do size check
+                size = os.path.getsize(self.in_file.name)
+                if size > 26214400:
+                    show_warning("File is too large",
+                                 "file is larger than 25MB, "
+                                 "unable to sync with web repository")
+                    self.set_output("file", self.in_file)
+                else:
+                    # compute checksum
+                    f = open(self.in_file.name, 'r')
+                    self.checksum = hashlib.sha1()
+                    block = 1
+                    while block:
+                        block = f.read(128)
+                        self.checksum.update(block)
+                    f.close()
+                    self.checksum = self.checksum.hexdigest()
+
+                    # upload/download file
+                    self.data_sync()
+
+                    # set checksum param in module
+                    if not self.has_input('checksum'):
+                        self.change_parameter('checksum', [self.checksum])
+
+            else:
+                # local file not present
+                if self.has_input('checksum'):
+                    self.checksum = self.get_input("checksum")
+
+                    # download file
+                    self.data_sync()
+
+
+class URLEncode(Module):
+    def compute(self):
+        value = self.get_input('string')
+        self.set_output('encoded', urllib.quote_plus(value))
+
+
+class URLDecode(Module):
+    def compute(self):
+        encoded = self.get_input('encoded')
+        self.set_output('string', urllib.unquote_plus(encoded))
+
+
+def initialize(*args, **keywords):
+    reg = vistrails.core.modules.module_registry.get_module_registry()
+    basic = vistrails.core.modules.basic_modules
+
+    reg.add_module(DownloadFile)
+    reg.add_input_port(DownloadFile, "url", (basic.String, 'URL'))
+    reg.add_input_port(DownloadFile, 'insecure',
+                       (basic.Boolean, "Allow invalid SSL certificates"),
+                       optional=True, defaults="['False']")
+    reg.add_output_port(DownloadFile, "file",
+                        (basic.File, 'local File object'))
+    reg.add_output_port(DownloadFile, "local_filename",
+                        (basic.String, 'local filename'), optional=True)
+
+    reg.add_module(HTTPDirectory)
+    reg.add_input_port(HTTPDirectory, 'url', (basic.String, "URL"))
+    reg.add_input_port(HTTPDirectory, 'insecure',
+                       (basic.Boolean, "Allow invalid SSL certificates"),
+                       optional=True, defaults="['False']")
+    reg.add_output_port(HTTPDirectory, 'directory',
+                        (basic.Directory, "local Directory object"))
+    reg.add_output_port(HTTPDirectory, 'local_path',
+                        (basic.String, "local path"), optional=True)
+
+    reg.add_module(RepoSync)
+    reg.add_input_port(RepoSync, "file", (basic.File, 'File'))
+    reg.add_input_port(RepoSync, "checksum",
+                       (basic.String, 'Checksum'), optional=True)
+    reg.add_output_port(RepoSync, "file", (basic.File,
+                                           'Repository Synced File object'))
+    reg.add_output_port(RepoSync, "checksum",
+                        (basic.String, 'Checksum'), optional=True)
+
+    reg.add_module(URLEncode)
+    reg.add_input_port(URLEncode, "string", basic.String)
+    reg.add_output_port(URLEncode, "encoded", basic.String)
+
+    reg.add_module(URLDecode)
+    reg.add_input_port(URLDecode, "encoded", basic.String)
+    reg.add_output_port(URLDecode, "string", basic.String)
+
+    global package_directory
+    dotVistrails = current_dot_vistrails()
+    package_directory = os.path.join(dotVistrails, "HTTP")
+
+    if not os.path.isdir(package_directory):
+        try:
+            debug.log("Creating HTTP package directory: %s" % package_directory)
+            os.mkdir(package_directory)
+        except Exception, e:
+            raise RuntimeError("Failed to create cache directory: %s" %
+                               package_directory, e)
+
+
+def handle_module_upgrade_request(controller, module_id, pipeline):
+    module_remap = {
+            # HTTPFile was renamed DownloadFile
+            'HTTPFile': [
+                (None, '1.0.0', 'DownloadFile', {})
+            ],
+        }
+
+    return UpgradeWorkflowHandler.remap_module(controller,
+                                               module_id,
+                                               pipeline,
+                                               module_remap)
+
+
+###############################################################################
+
+import unittest
+
+
+class TestDownloadFile(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        from vistrails.core.packagemanager import get_package_manager
+        from vistrails.core.modules.module_registry import MissingPackage
+        pm = get_package_manager()
+        try:
+            pm.get_package('org.vistrails.vistrails.http')
+        except MissingPackage:
+            pm.late_enable_package('URL')
+
+    def testIncorrectURL(self):
+        from vistrails.tests.utils import execute
+        self.assertTrue(execute([
+                ('DownloadFile', identifier, [
+                    ('url', [('String', 'http://idbetthisdoesnotexistohrly')]),
+                ]),
+            ]))
+
+    def testIncorrectURL_2(self):
+        from vistrails.tests.utils import execute
+        self.assertTrue(execute([
+                ('DownloadFile', identifier, [
+                    ('url', [('String', 'http://neitherodesthisohrly')]),
+                ]),
+            ]))
+
+
+class TestHTTPDirectory(unittest.TestCase):
+    def test_download(self):
+        url = 'http://www.vistrails.org/testing/httpdirectory/test/'
+
+        import shutil
+        import tempfile
+        testdir = tempfile.mkdtemp(prefix='vt_test_http_')
+        try:
+            download_directory(url, testdir)
+            files = {}
+            def addfiles(dirpath):
+                td = os.path.join(testdir, dirpath)
+                for name in os.listdir(td):
+                    filename = os.path.join(testdir, dirpath, name)
+                    dn = os.path.join(dirpath, name)
+                    if os.path.isdir(filename):
+                        addfiles(os.path.join(dirpath, name))
+                    else:
+                        with open(filename, 'rb') as f:
+                            files[dn.replace(os.sep, '/')] = f.read()
+            addfiles('')
+            self.assertEqual(len(files), 4)
+            del files['f.html']
+            self.assertEqual(files, {
+                    'a': 'aa\n',
+                    'bb': 'bb\n',
+                    'cc/d': 'dd\n',
+                })
+        finally:
+            shutil.rmtree(testdir)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/vistrails/packages/__init__.py b/vistrails/packages/__init__.py
index cdc9214..d1486d2 100644
--- a/vistrails/packages/__init__.py
+++ b/vistrails/packages/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # Nothing here on purpose
+from __future__ import division
+
 pass
diff --git a/vistrails/packages/analytics/__init__.py b/vistrails/packages/analytics/__init__.py
index e132e51..45a18fb 100644
--- a/vistrails/packages/analytics/__init__.py
+++ b/vistrails/packages/analytics/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 name = "VisTrails Analytics"
 identifier = "org.vistrails.vistrails.analytics"
 version = "0.0.2"
diff --git a/vistrails/packages/analytics/init.py b/vistrails/packages/analytics/init.py
index 520290e..bc23e77 100644
--- a/vistrails/packages/analytics/init.py
+++ b/vistrails/packages/analytics/init.py
@@ -1,39 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.core.modules.basic_modules import new_constant
-from vistrails.core.modules.vistrails_module import Module, ModuleError, ModuleConnector
+from __future__ import division
+
+from vistrails.core.modules.vistrails_module import Module, ModuleError
 import vistrails.core.vistrail.vistrail
 import vistrails.core.log.log 
 import vistrails.db.services.io
@@ -83,12 +85,12 @@ class ReadVistrail(Module):
         return None
 
     def compute(self):
-        fname = self.getInputFromPort('file').name
+        fname = self.get_input('file').name
         vistrail = self.read_vistrail(fname)
-        self.setResult('vistrail', vistrail)
-        fname = self.getInputFromPort('file').name
+        self.set_output('vistrail', vistrail)
+        fname = self.get_input('file').name
         log = self.read_log(fname)
-        self.setResult('log', log)
+        self.set_output('log', log)
 
 class CountActions(Module):
     _input_ports = [('vistrail', '(Vistrail)')]
@@ -114,14 +116,14 @@ class CountActions(Module):
                         Tally[action.what] = {action.vtType : 1}
 
                 # if is there, if subdictionary does not have vtType key, create entry
-                elif Tally.has_key(action.what) == none:
+                elif Tally.has_key(action.what) is None:
                     Tally[action.what] = {action.vtType : 1}
         return Tally
 
     def compute(self):
-        vistrail = self.getInputFromPort('vistrail')
+        vistrail = self.get_input('vistrail')
         Tally = self.count_actions(vistrail)
-        self.setResult('counts', Tally)
+        self.set_output('counts', Tally)
 
 class CountExecutedWorkflows(Module):
     _input_ports = [('log', '(Log)')]
@@ -137,9 +139,9 @@ class CountExecutedWorkflows(Module):
         return users
 
     def compute(self):
-        log = self.getInputFromPort('log')
+        log = self.get_input('log')
         users = self.count_executed_workflows(log)
-        self.setResult('completed', users)
+        self.set_output('completed', users)
 
 class TotalDays(Module):
     _input_ports = [('vistrail','(Vistrail)')]
@@ -169,9 +171,9 @@ class TotalDays(Module):
         return totals
                 
     def compute(self):
-        vistrail = self.getInputFromPort('vistrail')
+        vistrail = self.get_input('vistrail')
         totals = self.calc_time(vistrail)
-        self.setResult('completed', totals)
+        self.set_output('completed', totals)
 
 #class TimevsTags(Module):
     #Compare a few workflows to see how long the project took vs. how many tags were made
diff --git a/vistrails/packages/controlflow/__init__.py b/vistrails/packages/controlflow/__init__.py
index 5121f7e..95b5362 100644
--- a/vistrails/packages/controlflow/__init__.py
+++ b/vistrails/packages/controlflow/__init__.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 identifier="org.vistrails.vistrails.control_flow"
 name="Control Flow"
 version="0.2.4"
diff --git a/vistrails/packages/controlflow/conditional.py b/vistrails/packages/controlflow/conditional.py
index 4494406..37f54f2 100644
--- a/vistrails/packages/controlflow/conditional.py
+++ b/vistrails/packages/controlflow/conditional.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module, InvalidOutput, \
     ModuleError
 import copy
@@ -45,8 +48,8 @@ class If(Module):
     executed through the use of a condition.
     """
 
-    def updateUpstream(self):
-        """A modified version of the updateUpstream method."""
+    def update_upstream(self):
+        """A modified version of the update_upstream method."""
 
         # everything is the same except that we don't update anything
         # upstream of TruePort or FalsePort
@@ -61,14 +64,14 @@ class If(Module):
                 for connector in connectorList:
                     if connector.obj.get_output(connector.port) is \
                             InvalidOutput:
-                        self.removeInputConnector(port_name, connector)
+                        self.remove_input_connector(port_name, connector)
 
     def compute(self):
         """ The compute method for the If module."""
 
-        if not self.hasInputFromPort('Condition'):
+        if not self.has_input('Condition'):
             raise ModuleError(self, 'Must set condition')
-        cond = self.getInputFromPort('Condition')
+        cond = self.get_input('Condition')
 
         if cond:
             port_name = 'TruePort'
@@ -77,27 +80,27 @@ class If(Module):
             port_name = 'FalsePort'
             output_ports_name = 'FalseOutputPorts'
 
-        if self.hasInputFromPort(output_ports_name):
+        if self.has_input(output_ports_name):
             for connector in self.inputPorts.get(output_ports_name):
                 connector.obj.update()
 
-        if not self.hasInputFromPort(port_name):
+        if not self.has_input(port_name):
             raise ModuleError(self, 'Must set ' + port_name)
 
         for connector in self.inputPorts.get(port_name):
             connector.obj.update()
 
-            if self.hasInputFromPort(output_ports_name):
-                output_ports = self.getInputFromPort(output_ports_name)
+            if self.has_input(output_ports_name):
+                output_ports = self.get_input(output_ports_name)
                 result = []
                 for output_port in output_ports:
                     result.append(connector.obj.get_output(output_port))
 
                 # FIXME can we just make this a list?
                 if len(output_ports) == 1:
-                    self.setResult('Result', result[0])
+                    self.set_output('Result', result[0])
                 else:
-                    self.setResult('Result', result)
+                    self.set_output('Result', result)
 
 #################################################################################
 ## Default module
@@ -113,7 +116,86 @@ class Default(Module):
     """
 
     def compute(self):
-        if self.hasInputFromPort('Input'):
-            self.setResult('Result', self.getInputFromPort('Input'))
+        if self.has_input('Input'):
+            self.set_output('Result', self.get_input('Input'))
+        else:
+            self.set_output('Result', self.get_input('Default'))
+
+
+###############################################################################
+
+import unittest
+import urllib2
+
+from vistrails.tests.utils import intercept_result, execute
+
+class TestIf(unittest.TestCase):
+    def do_if(self, val):
+        with intercept_result(If, 'Result') as results:
+            interp_dict = execute([
+                    ('If', 'org.vistrails.vistrails.control_flow', [
+                        ('FalseOutputPorts', [('List', "['value']")]),
+                        ('TrueOutputPorts', [('List', "['value']")]),
+                        ('Condition', [('Boolean', str(val))]),
+                    ]),
+                    ('Integer', 'org.vistrails.vistrails.basic', [
+                        ('value', [('Integer', '42')]),
+                    ]),
+                    ('Integer', 'org.vistrails.vistrails.basic', [
+                        ('value', [('Integer', '28')]),
+                    ]),
+                ],
+                [
+                    (1, 'self', 0, 'TruePort'),
+                    (2, 'self', 0, 'FalsePort'),
+                ],
+                full_results=True)
+            self.assertFalse(interp_dict.errors)
+        if val:
+            self.assertEqual(results, [42])
+        else:
+            self.assertEqual(results, [28])
+        self.assertEqual(interp_dict.executed, {0: True, 1: val, 2: not val})
+
+    def test_if_true(self):
+        self.do_if(True)
+
+    def test_if_false(self):
+        self.do_if(False)
+
+
+class TestDefault(unittest.TestCase):
+    def do_default(self, val):
+        if val:
+            src = 'o = 42'
         else:
-            self.setResult('Result', self.getInputFromPort('Default'))
+            src = ('from vistrails.core.modules.vistrails_module import '
+                   'InvalidOutput\n'
+                   'o = InvalidOutput')
+        src = urllib2.quote(src)
+        with intercept_result(Default, 'Result') as results:
+            self.assertFalse(execute([
+                    ('Default', 'org.vistrails.vistrails.control_flow', [
+                        ('Default', [('Integer', '28')]),
+                    ]),
+                    ('PythonSource', 'org.vistrails.vistrails.basic', [
+                        ('source', [('String', src)]),
+                    ]),
+                ],
+                [
+                    (1, 'o', 0, 'Input'),
+                ],
+                add_port_specs=[
+                    (1, 'output', 'o',
+                     'org.vistrails.vistrails.basic:Integer'),
+                ]))
+        if val:
+            self.assertEqual(results, [42])
+        else:
+            self.assertEqual(results, [28])
+
+    def test_default_set(self):
+        self.do_default(True)
+
+    def test_default_unset(self):
+        self.do_default(False)
diff --git a/vistrails/packages/controlflow/fold.py b/vistrails/packages/controlflow/fold.py
index 1886011..b72f210 100644
--- a/vistrails/packages/controlflow/fold.py
+++ b/vistrails/packages/controlflow/fold.py
@@ -1,40 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core import debug
+from vistrails.core.modules.basic_modules import create_constant, get_module
 from vistrails.core.modules.vistrails_module import Module, ModuleError, \
-    ModuleConnector, InvalidOutput, ModuleSuspended
+    ModuleConnector, InvalidOutput, ModuleSuspended, ModuleWasSuspended
 from vistrails.core.modules.basic_modules import Boolean, String, Integer, \
     Float, Constant, List
 from vistrails.core.modules.module_registry import get_module_registry
@@ -66,24 +70,19 @@ class Fold(Module):
         self.partialResult = self.initialValue
         self.elementResult = None
 
-        for element in self.getInputFromPort('InputList'):
+        for element in self.get_input('InputList'):
             self.element = element
             self.operation()
 
-        if self.suspended:
-            raise ModuleSuspended(
-                    self,
-                    self.suspended,
-                    children=self._module_suspended)
-        self.setResult('Result', self.partialResult)
+        self.set_output('Result', self.partialResult)
 
-    def setInitialValue(self):
+    def setInitialValue(self): # pragma: no cover
         """This method defines the initial value of the Fold structure. It must
         be defined before the operation() method."""
 
         pass
 
-    def operation(self):
+    def operation(self): # pragma: no cover
         """This method defines the interaction between the current element of
         the list and the previous iterations' result."""
 
@@ -99,28 +98,45 @@ class FoldWithModule(Fold):
     that this module will use.
     """
 
-    def __init__(self):
-        Fold.__init__(self)
-        self.is_looping_module = True
-
-    def updateUpstream(self):
-        """A modified version of the updateUpstream method."""
+    def update_upstream(self):
+        """A modified version of the update_upstream method."""
 
-        # everything is the same except that we don't update anything
-        # upstream of FunctionPort
+        # everything is the same except that we don't update the module on
+        # FunctionPort
+        suspended = []
+        was_suspended = None
         for port_name, connector_list in self.inputPorts.iteritems():
             if port_name == 'FunctionPort':
                 for connector in connector_list:
-                    connector.obj.updateUpstream()
+                    try:
+                        connector.obj.update_upstream()
+                    except ModuleWasSuspended, e:
+                        was_suspended = e
+                    except ModuleSuspended, e:
+                        suspended.append(e)
             else:
                 for connector in connector_list:
-                    connector.obj.update()
+                    try:
+                        connector.obj.update()
+                    except ModuleWasSuspended, e:
+                        was_suspended = e
+                    except ModuleSuspended, e:
+                        suspended.append(e)
+        if len(suspended) == 1:
+            raise suspended[0]
+        elif suspended:
+            raise ModuleSuspended(
+                    self,
+                    "multiple suspended upstream modules",
+                    children=suspended)
+        elif was_suspended is not None:
+            raise was_suspended
         for port_name, connectorList in list(self.inputPorts.items()):
             if port_name != 'FunctionPort':
                 for connector in connectorList:
                     if connector.obj.get_output(connector.port) is \
-                            InvalidOutput:
-                        self.removeInputConnector(port_name, connector)
+                            InvalidOutput: # pragma: no cover
+                        self.remove_input_connector(port_name, connector)
 
     def updateFunctionPort(self):
         """
@@ -128,9 +144,9 @@ class FoldWithModule(Fold):
         FoldWithModule module. It updates the modules connected to the
         FunctionPort port.
         """
-        nameInput = self.getInputFromPort('InputPort')
-        nameOutput = self.getInputFromPort('OutputPort')
-        rawInputList = self.getInputFromPort('InputList')
+        nameInput = self.get_input('InputPort')
+        nameOutput = self.get_input('OutputPort')
+        rawInputList = self.get_input('InputList')
 
         # Create inputList to always have iterable elements
         # to simplify code
@@ -141,6 +157,7 @@ class FoldWithModule(Fold):
             element_is_iter = True
             inputList = rawInputList
         suspended = []
+        loop = self.logging.begin_loop_execution(self, len(inputList))
         ## Update everything for each value inside the list
         for i, element in enumerate(inputList):
             self.logging.update_progress(self, float(i)/len(inputList))
@@ -148,10 +165,11 @@ class FoldWithModule(Fold):
                 self.element = element
             else:
                 self.element = element[0]
+            do_operation = True
             for connector in self.inputPorts.get('FunctionPort'):
                 module = copy.copy(connector.obj)
 
-                if not self.upToDate:
+                if not self.upToDate: # pragma: no branch
                     ## Type checking
                     if i == 0:
                         self.typeChecking(module, nameInput, inputList)
@@ -159,92 +177,37 @@ class FoldWithModule(Fold):
                     module.upToDate = False
                     module.computed = False
 
-                    ## Setting information for logging stuff
-                    module.is_looping = True
-                    module.first_iteration = i == 0
-                    module.last_iteration = i == len(inputList) - 1
-                    module.loop_iteration = i
+                    self.setInputValues(module, nameInput, element, i)
 
-                    self.setInputValues(module, nameInput, element)
+                loop.begin_iteration(module, i)
 
-                module.update()
-                if hasattr(module, 'suspended') and module.suspended:
-                    suspended.append(module._module_suspended)
-                    module.suspended = False
+                try:
+                    module.update()
+                except ModuleSuspended, e:
+                    suspended.append(e)
+                    do_operation = False
+                    loop.end_iteration(module)
                     continue
+
+                loop.end_iteration(module)
+
                 ## Getting the result from the output port
                 if nameOutput not in module.outputPorts:
                     raise ModuleError(module,
                                       'Invalid output port: %s' % nameOutput)
                 self.elementResult = module.get_output(nameOutput)
-            self.operation()
-        if suspended:
-            self.suspended = "%d module(s) suspended: %s" % (
-                    len(suspended), suspended[0].msg)
-            self._module_suspended = suspended
-
-    def setInputValues(self, module, inputPorts, elementList):
-        """
-        Function used to set a value inside 'module', given the input port(s).
-        """
-        for element, inputPort in izip(elementList, inputPorts):
-            ## Cleaning the previous connector...
-            if inputPort in module.inputPorts:
-                del module.inputPorts[inputPort]
-            new_connector = ModuleConnector(create_constant(element), 'value')
-            module.set_input_port(inputPort, new_connector)
-
-    def typeChecking(self, module, inputPorts, inputList):
-        """
-        Function used to check if the types of the input list element and of the
-        inputPort of 'module' match.
-        """
-        for elementList in inputList:
-            if len(elementList) != len(inputPorts):
-                raise ModuleError(self,
-                                  'The number of input values and input ports '
-                                  'are not the same.')
-            for element, inputPort in izip(elementList, inputPorts):
-                p_modules = module.moduleInfo['pipeline'].modules
-                p_module = p_modules[module.moduleInfo['moduleId']]
-                port_spec = p_module.get_port_spec(inputPort, 'input')
-                v_module = get_module(element, port_spec.signature)
-                if v_module is not None:
-                    if not self.compare(port_spec, v_module, inputPort):
-                        raise ModuleError(self,
-                                          'The type of a list element does '
-                                          'not match with the type of the '
-                                          'port %s.' % inputPort)
-
-                    del v_module
-                else:
-                    break
-
-    def createSignature(self, v_module):
-        """
-    `   Function used to create a signature, given v_module, for a port spec.
-        """
-        if isinstance(v_module, tuple):
-            v_module_class = []
-            for module_ in v_module:
-                v_module_class.append(self.createSignature(module_))
-            return v_module_class
-        else:
-            return v_module
+            if do_operation:
+                self.operation()
 
-    def compare(self, port_spec, v_module, port):
-        """
-        Function used to compare two port specs.
-        """
-        port_spec1 = port_spec
-
-        reg = get_module_registry()
+            self.logging.update_progress(self, i * 1.0 / len(inputList))
 
-        v_module = self.createSignature(v_module)
-        port_spec2 = PortSpec(**{'signature': v_module})
-        matched = reg.are_specs_matched(port_spec2, port_spec1)
-
-        return matched
+        if suspended:
+            raise ModuleSuspended(
+                    self,
+                    "function module suspended in %d/%d iterations" % (
+                            len(suspended), len(inputList)),
+                    children=suspended)
+        loop.end_loop_execution()
 
     def compute(self):
         """The compute method for the Fold."""
@@ -255,54 +218,4 @@ class FoldWithModule(Fold):
 
         self.updateFunctionPort()
 
-        if self.suspended:
-            raise ModuleSuspended(
-                    self,
-                    self.suspended,
-                    children=self._module_suspended)
-        self.setResult('Result', self.partialResult)
-
-###############################################################################
-
-class NewConstant(Constant):
-    """
-    A new Constant module to be used inside the FoldWithModule module.
-    """
-    def setValue(self, v):
-        self.setResult("value", v)
-        self.upToDate = True
-
-def create_constant(value):
-    """
-    Creates a NewConstant module, to be used for the ModuleConnector.
-    """
-    constant = NewConstant()
-    constant.setValue(value)
-    return constant
-
-def get_module(value, signature):
-    """
-    Creates a module for value, in order to do the type checking.
-    """
-    if isinstance(value, Constant):
-        return type(value)
-    elif isinstance(value, bool):
-        return Boolean
-    elif isinstance(value, str):
-        return String
-    elif isinstance(value, int):
-        return Integer
-    elif isinstance(value, float):
-        return Float
-    elif isinstance(value, list):
-        return List
-    elif isinstance(value, tuple):
-        v_modules = ()
-        for element in xrange(len(value)):
-            v_modules += (get_module(value[element], signature[element]),)
-        return v_modules
-    else:
-        debug.warning("Could not identify the type of the list element.")
-        debug.warning("Type checking is not going to be done inside"
-                      "FoldWithModule module.")
-        return None
+        self.set_output('Result', self.partialResult)
diff --git a/vistrails/packages/controlflow/init.py b/vistrails/packages/controlflow/init.py
index 20a22ef..06b318a 100644
--- a/vistrails/packages/controlflow/init.py
+++ b/vistrails/packages/controlflow/init.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.modules.basic_modules import Boolean, String, Variant, \
@@ -210,6 +213,16 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
                     },
                 }),
             ],
+            'Map': [
+                (None, '0.2.4', None, {
+                    'src_port_remap': {'Result': 'Result'}
+                }),
+            ],
+            'Filter': [
+                (None, '0.2.4', None, {
+                    'src_port_remap': {'Result': 'Result'}
+                }),
+            ],
         }
 
     return UpgradeWorkflowHandler.remap_module(controller,
diff --git a/vistrails/packages/controlflow/looping.py b/vistrails/packages/controlflow/looping.py
index 8b945df..27b7b2e 100644
--- a/vistrails/packages/controlflow/looping.py
+++ b/vistrails/packages/controlflow/looping.py
@@ -1,12 +1,58 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from base64 import b16encode, b16decode
 import copy
 from itertools import izip
 import time
 
 from vistrails.core.modules.vistrails_module import Module, InvalidOutput, \
-    ModuleSuspended, ModuleError, ModuleConnector
+    ModuleError, ModuleConnector, ModuleSuspended, ModuleWasSuspended
+from vistrails.core.utils import xor, long2bytes
 
 from fold import create_constant
 
+try:
+    import hashlib
+    sha1_hash = hashlib.sha1
+except ImportError:
+    import sha
+    sha1_hash = sha.new
+
 
 class While(Module):
     """
@@ -14,39 +60,56 @@ class While(Module):
     is false. Then, it returns the result.
     """
 
-    def __init__(self):
-        Module.__init__(self)
-        self.is_looping_module = True
-
-    def updateUpstream(self):
-        """A modified version of the updateUpstream method."""
+    def update_upstream(self):
+        """A modified version of the update_upstream method."""
 
         # everything is the same except that we don't update the module on
         # FunctionPort
+        suspended = []
+        was_suspended = None
         for port_name, connector_list in self.inputPorts.iteritems():
             if port_name == 'FunctionPort':
                 for connector in connector_list:
-                    connector.obj.updateUpstream()
+                    try:
+                        connector.obj.update_upstream()
+                    except ModuleWasSuspended, e:
+                        was_suspended = e
+                    except ModuleSuspended, e:
+                        suspended.append(e)
             else:
                 for connector in connector_list:
-                    connector.obj.update()
-        for port_name, connectorList in copy.copy(self.inputPorts.items()):
+                    try:
+                        connector.obj.update()
+                    except ModuleWasSuspended, e:
+                        was_suspended = e
+                    except ModuleSuspended, e:
+                        suspended.append(e)
+        if len(suspended) == 1:
+            raise suspended[0]
+        elif suspended:
+            raise ModuleSuspended(
+                    self,
+                    "multiple suspended upstream modules",
+                    children=suspended)
+        elif was_suspended is not None:
+            raise was_suspended
+        for port_name, connectorList in list(self.inputPorts.items()):
             if port_name != 'FunctionPort':
                 for connector in connectorList:
                     if connector.obj.get_output(connector.port) is \
-                            InvalidOutput:
-                        self.removeInputConnector(port_name, connector)
+                            InvalidOutput: # pragma: no cover
+                        self.remove_input_connector(port_name, connector)
 
     def compute(self):
-        name_output = self.getInputFromPort('OutputPort')
-        name_condition = self.forceGetInputFromPort('ConditionPort')
-        name_state_input = self.forceGetInputFromPort('StateInputPorts')
-        name_state_output = self.forceGetInputFromPort('StateOutputPorts')
-        max_iterations = self.getInputFromPort('MaxIterations')
-        delay = self.forceGetInputFromPort('Delay')
+        name_output = self.get_input('OutputPort')
+        name_condition = self.force_get_input('ConditionPort')
+        name_state_input = self.force_get_input('StateInputPorts')
+        name_state_output = self.force_get_input('StateOutputPorts')
+        max_iterations = self.get_input('MaxIterations')
+        delay = self.force_get_input('Delay')
 
         if (name_condition is None and
-                not self.hasInputFromPort('MaxIterations')):
+                not self.has_input('MaxIterations')):
             raise ModuleError(self,
                               "Please set MaxIterations or use ConditionPort")
 
@@ -71,30 +134,35 @@ class While(Module):
 
         state = None
 
+        loop = self.logging.begin_loop_execution(self, max_iterations)
         for i in xrange(max_iterations):
             if not self.upToDate:
                 module.upToDate = False
                 module.computed = False
 
-                # For logging
-                module.is_looping = True
-                module.first_iteration = i == 0
-                module.last_iteration = False
-                module.loop_iteration = i
-
                 # Set state on input ports
                 if i > 0 and name_state_input:
-                    for value, port in izip(state, name_state_input):
-                        if port in module.inputPorts:
-                            del module.inputPorts[port]
+                    for value, input_port, output_port \
+                    in izip(state, name_state_input, name_state_output):
+                        if input_port in module.inputPorts:
+                            del module.inputPorts[input_port]
                         new_connector = ModuleConnector(
-                                create_constant(value),
-                                'value')
-                        module.set_input_port(port, new_connector)
+                                           create_constant(value), 'value',
+                                           module.output_specs.get(output_port, None))
+                        module.set_input_port(input_port, new_connector)
+                        # Affix a fake signature on the module
+                        inputPort_hash = sha1_hash()
+                        inputPort_hash.update(input_port)
+                        module.signature = b16encode(xor(
+                                b16decode(self.signature.upper()),
+                                inputPort_hash.digest()))
+
+            loop.begin_iteration(module, i)
+
+            module.update() # might raise ModuleError, ModuleSuspended,
+                            # ModuleHadError, ModuleWasSuspended
 
-            module.update()
-            if hasattr(module, 'suspended') and module.suspended:
-                raise ModuleSuspended(module._module_suspended)
+            loop.end_iteration(module)
 
             if name_condition is not None:
                 if name_condition not in module.outputPorts:
@@ -111,46 +179,66 @@ class While(Module):
             if name_state_output:
                 state = [module.get_output(port) for port in name_state_output]
 
+            self.logging.update_progress(self, i * 1.0 / max_iterations)
+
+        loop.end_loop_execution()
+
         if name_output not in module.outputPorts:
             raise ModuleError(module,
                               "Invalid output port: %s" % name_output)
         result = module.get_output(name_output)
-        self.setResult('Result', result)
-
+        self.set_output('Result', result)
 
 class For(Module):
     """
     The For Module runs a module with input from a range.
     """
 
-    def __init__(self):
-        Module.__init__(self)
-        self.is_looping_module = True
-
-    def updateUpstream(self):
-        """A modified version of the updateUpstream method."""
+    def update_upstream(self):
+        """A modified version of the update_upstream method."""
 
         # everything is the same except that we don't update the module on
         # FunctionPort
+        suspended = []
+        was_suspended = None
         for port_name, connector_list in self.inputPorts.iteritems():
             if port_name == 'FunctionPort':
                 for connector in connector_list:
-                    connector.obj.updateUpstream()
+                    try:
+                        connector.obj.update_upstream()
+                    except ModuleWasSuspended, e:
+                        was_suspended = e
+                    except ModuleSuspended, e:
+                        suspended.append(e)
             else:
                 for connector in connector_list:
-                    connector.obj.update()
-        for port_name, connectorList in copy.copy(self.inputPorts.items()):
+                    try:
+                        connector.obj.update()
+                    except ModuleWasSuspended, e:
+                        was_suspended = e
+                    except ModuleSuspended, e:
+                        suspended.append(e)
+        if len(suspended) == 1:
+            raise suspended[0]
+        elif suspended:
+            raise ModuleSuspended(
+                    self,
+                    "multiple suspended upstream modules",
+                    children=suspended)
+        elif was_suspended is not None:
+            raise was_suspended
+        for port_name, connectorList in list(self.inputPorts.items()):
             if port_name != 'FunctionPort':
                 for connector in connectorList:
                     if connector.obj.get_output(connector.port) is \
-                            InvalidOutput:
+                            InvalidOutput: # pragma: no cover
                         self.removeInputConnector(port_name, connector)
 
     def compute(self):
-        name_output = self.getInputFromPort('OutputPort') # or 'self'
-        name_input = self.forceGetInputFromPort('InputPort') # or None
-        lower_bound = self.getInputFromPort('LowerBound') # or 0
-        higher_bound = self.getInputFromPort('HigherBound') # required
+        name_output = self.get_input('OutputPort') # or 'self'
+        name_input = self.force_get_input('InputPort') # or None
+        lower_bound = self.get_input('LowerBound') # or 0
+        higher_bound = self.get_input('HigherBound') # required
 
         connectors = self.inputPorts.get('FunctionPort')
         if len(connectors) != 1:
@@ -159,6 +247,8 @@ class For(Module):
 
         outputs = []
         suspended = []
+        loop = self.logging.begin_loop_execution(self,
+                                                 higher_bound - lower_bound)
         for i in xrange(lower_bound, higher_bound):
             module = copy.copy(connectors[0].obj)
 
@@ -166,39 +256,46 @@ class For(Module):
                 module.upToDate = False
                 module.computed = False
 
-                # For logging
-                module.is_looping = True
-                module.first_iteration = i == lower_bound
-                module.last_iteration = i+1 == higher_bound
-                module.loop_iteration = i - lower_bound
-
                 # Pass iteration number on input port
                 if name_input is not None:
                     if name_input in module.inputPorts:
                         del module.inputPorts[name_input]
-                    new_connector = ModuleConnector(
-                            create_constant(i),
-                            'value')
+                    new_connector = ModuleConnector(create_constant(i),
+                                                    'value')
                     module.set_input_port(name_input, new_connector)
-
-            module.update()
-
-            if hasattr(module, 'suspended') and module.suspended:
-                suspended.append(module._module_suspended)
+                    # Affix a fake signature on the module
+                    inputPort_hash = sha1_hash()
+                    inputPort_hash.update(name_input)
+                    module.signature = b16encode(xor(
+                            b16decode(self.signature.upper()),
+                            long2bytes(i, 20),
+                            inputPort_hash.digest()))
+
+            loop.begin_iteration(module, i)
+
+            try:
+                module.update()
+            except ModuleSuspended, e:
+                suspended.append(e)
+                loop.end_iteration(module)
                 continue
 
+            loop.end_iteration(module)
+
             if name_output not in module.outputPorts:
                 raise ModuleError(module,
                                   "Invalid output port: %s" % name_output)
             outputs.append(module.get_output(name_output))
 
         if suspended:
-            self.suspended = "%d module(s) suspended: %s" % (
-                    len(suspended), suspended[0].msg)
-            self._module_suspended = suspended
-        else:
-            self.setResult('Result', outputs)
-
+            raise ModuleSuspended(
+                    self,
+                    "function module suspended in %d/%d iterations" % (
+                            len(suspended), higher_bound - lower_bound),
+                        children=suspended)
+        loop.end_loop_execution()
+
+        self.set_output('Result', outputs)
 
 ###############################################################################
 
diff --git a/vistrails/packages/controlflow/order.py b/vistrails/packages/controlflow/order.py
index 0f67878..fbd15df 100644
--- a/vistrails/packages/controlflow/order.py
+++ b/vistrails/packages/controlflow/order.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module, InvalidOutput
 import copy
 
@@ -47,16 +50,59 @@ class ExecuteInOrder(Module):
     modules.
     """
 
-    def updateUpstream(self):
+    def update_upstream(self):
         # don't do update until compute!
         pass
 
     def compute(self):
-        # do updateUpstream as compute, but sort by key
+        # do update_upstream as compute, but sort by key
         for _, connectorList in sorted(self.inputPorts.iteritems()):
             for connector in connectorList:
                 connector.obj.update()
         for iport, connectorList in copy.copy(self.inputPorts.items()):
             for connector in connectorList:
                 if connector.obj.get_output(connector.port) is InvalidOutput:
-                    self.removeInputConnector(iport, connector)
+                    self.remove_input_connector(iport, connector)
+
+
+###############################################################################
+
+import unittest
+
+from vistrails.tests.utils import capture_stdout, execute
+
+
+class TestOrder(unittest.TestCase):
+    def test_1(self):
+        with capture_stdout() as output:
+            self.assertFalse(execute([
+                    ('StandardOutput', 'org.vistrails.vistrails.basic', [
+                        ('value', [('String', 'one')]),
+                    ]),
+                    ('StandardOutput', 'org.vistrails.vistrails.basic', [
+                        ('value', [('String', 'two')]),
+                    ]),
+                    ('ExecuteInOrder', 'org.vistrails.vistrails.control_flow', []),
+                ],
+                [
+                    (0, 'self', 2, 'module1'),
+                    (1, 'self', 2, 'module2'),
+                ]))
+        self.assertEqual(output, ['one', 'two'])
+
+    def test_2(self):
+        with capture_stdout() as output:
+            self.assertFalse(execute([
+                    ('StandardOutput', 'org.vistrails.vistrails.basic', [
+                        ('value', [('String', 'two')]),
+                    ]),
+                    ('StandardOutput', 'org.vistrails.vistrails.basic', [
+                        ('value', [('String', 'one')]),
+                    ]),
+                    ('ExecuteInOrder', 'org.vistrails.vistrails.control_flow', []),
+                ],
+                [
+                    (1, 'self', 2, 'module1'),
+                    (0, 'self', 2, 'module2'),
+                ]))
+        self.assertEqual(output, ['one', 'two'])
diff --git a/vistrails/packages/controlflow/products.py b/vistrails/packages/controlflow/products.py
index 6bc74b1..d6130b0 100644
--- a/vistrails/packages/controlflow/products.py
+++ b/vistrails/packages/controlflow/products.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import itertools
 
 from vistrails.core.modules.vistrails_module import Module, ModuleError
@@ -50,40 +53,40 @@ class ElementwiseProduct(Module):
     """
 
     def compute(self):
-        list1 = self.getInputFromPort('List1')
-        list2 = self.getInputFromPort('List2')
+        list1 = self.get_input('List1')
+        list2 = self.get_input('List2')
         if len(list1) != len(list2):
             raise ModuleError(self, "Both lists must have the same size.")
 
-        numerical = self.getInputFromPort('NumericalProduct')
+        numerical = self.get_input('NumericalProduct')
         if numerical:
             result = [a*b for a, b in itertools.izip(list1, list2)]
         else:
             result = zip(list1, list2)
 
-        self.setResult('Result', result)
+        self.set_output('Result', result)
 
 
 class Dot(Module):
     """This module produces a Dot product between two lists."""
 
     def compute(self):
-        list1 = self.getInputFromPort("List1")
-        list2 = self.getInputFromPort("List2")
+        list1 = self.get_input("List1")
+        list2 = self.get_input("List2")
         if len(list1) != len(list2):
             raise ModuleError(self, 'Both lists must have the same size.')
 
         result = sum(a*b for a, b in itertools.izip(list1, list2))
 
-        self.setResult("Result", result)
+        self.set_output("Result", result)
 
 
 class Cross(Module):
     """This module produces a Cross product between two 3-D vectors."""
 
     def compute(self):
-        list1 = self.getInputFromPort("List1")
-        list2 = self.getInputFromPort("List2")
+        list1 = self.get_input("List1")
+        list2 = self.get_input("List2")
         if not (len(list1) == len(list2) == 3):
             raise ModuleError(self, 'Both lists must have size 3.')
 
@@ -94,7 +97,7 @@ class Cross(Module):
                   z1*x2 - z2*x1,
                   x1*y2 - x2*y1]
 
-        self.setResult("Result", result)
+        self.set_output("Result", result)
 
 
 class CartesianProduct(Module):
@@ -102,8 +105,8 @@ class CartesianProduct(Module):
     """
 
     def compute(self):
-        list1 = self.getInputFromPort("List1")
-        list2 = self.getInputFromPort("List2")
+        list1 = self.get_input("List1")
+        list2 = self.get_input("List2")
         result = []
         # If CombineTuple is not set or True, existing tuples will be
         # concatenated instead of put inside a new tuple, eg:
@@ -111,7 +114,7 @@ class CartesianProduct(Module):
         #     [(1, 2)], [3, 4] -> [(1, 2, 3), (1, 2, 4)]
         #   without:
         #     [(1, 2)], [3, 4] -> [((1, 2), 3), ((1, 2), 4)]
-        if not self.getInputFromPort('CombineTuple'):
+        if not self.get_input('CombineTuple'):
             for i in list1:
                 for j in list2:
                     tuple_ = (i, j)
@@ -132,4 +135,77 @@ class CartesianProduct(Module):
                         tuple_ = (i, j)
                         result.append(tuple_)
 
-        self.setResult("Result", result)
+        self.set_output("Result", result)
+
+
+###############################################################################
+
+import unittest
+
+from vistrails.tests.utils import intercept_result, execute
+
+
+class TestProducts(unittest.TestCase):
+    def test_elementwise(self):
+        with intercept_result(ElementwiseProduct, 'Result') as results:
+            self.assertFalse(execute([
+                    ('ElementwiseProduct', 'org.vistrails.vistrails.control_flow', [
+                        ('List1', [('List', "[1, 2, 0]")]),
+                        ('List2', [('List', "[4, -3, 7]")]),
+                    ]),
+                ]))
+        self.assertEqual(results, [[4, -6, 0]])
+
+    def test_elementwise_tuples(self):
+        with intercept_result(ElementwiseProduct, 'Result') as results:
+            self.assertFalse(execute([
+                    ('ElementwiseProduct', 'org.vistrails.vistrails.control_flow', [
+                        ('List1', [('List', "[1, 2, 0]")]),
+                        ('List2', [('List', "[4, -3, 7]")]),
+                        ('NumericalProduct', [('Boolean', "False")]),
+                    ]),
+                ]))
+        self.assertEqual(results, [[(1, 4), (2, -3), (0, 7)]])
+
+    def test_dot(self):
+        with intercept_result(Dot, 'Result') as results:
+            self.assertFalse(execute([
+                    ('Dot', 'org.vistrails.vistrails.control_flow', [
+                        ('List1', [('List', "[1, 2, 0]")]),
+                        ('List2', [('List', "[4, -3, 7]")]),
+                    ]),
+                ]))
+        self.assertEqual(results, [-2])
+
+    def test_cross(self):
+        with intercept_result(Cross, 'Result') as results:
+            self.assertFalse(execute([
+                    ('Cross', 'org.vistrails.vistrails.control_flow', [
+                        ('List1', [('List', "[1, 2, 0]")]),
+                        ('List2', [('List', "[4, -3, 7]")]),
+                    ]),
+                ]))
+        # ( | 2 -3 |, | 0  7 |, | 1  4 | )
+        #   | 0  7 |  | 1  4 |  | 2 -3 |
+        self.assertEqual(results, [[14, -7, -11]])
+
+    def test_cartesian_combine(self):
+        with intercept_result(CartesianProduct, 'Result') as results:
+            self.assertFalse(execute([
+                    ('CartesianProduct', 'org.vistrails.vistrails.control_flow', [
+                        ('List1', [('List', "[(1, 2)]")]),
+                        ('List2', [('List', "[3, 4]")]),
+                    ]),
+                ]))
+        self.assertEqual(results, [[(1, 2, 3), (1, 2, 4)]])
+
+    def test_cartesian_nocombine(self):
+        with intercept_result(CartesianProduct, 'Result') as results:
+            self.assertFalse(execute([
+                    ('CartesianProduct', 'org.vistrails.vistrails.control_flow', [
+                        ('List1', [('List', "[(1, 2)]")]),
+                        ('List2', [('List', "[3, 4]")]),
+                        ('CombineTuple', [('Boolean', "False")]),
+                    ]),
+                ]))
+        self.assertEqual(results, [[((1, 2), 3), ((1, 2), 4)]])
diff --git a/vistrails/packages/controlflow/utils.py b/vistrails/packages/controlflow/utils.py
index 8f5b6c8..09a706f 100644
--- a/vistrails/packages/controlflow/utils.py
+++ b/vistrails/packages/controlflow/utils.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import ModuleError
 from fold import Fold, FoldWithModule
 
@@ -114,3 +117,152 @@ class Or(Fold):
         """Defining the operation..."""
 
         self.partialResult = self.partialResult or self.element
+
+
+###############################################################################
+
+import unittest
+import urllib2
+
+from vistrails.tests.utils import intercept_result, execute
+
+
+class TestMap(unittest.TestCase):
+    def test_simple(self):
+        src = urllib2.quote('o = i + 1')
+        with intercept_result(Map, 'Result') as results:
+            self.assertFalse(execute([
+                    ('PythonSource', 'org.vistrails.vistrails.basic', [
+                        ('source', [('String', src)]),
+                    ]),
+                    ('Map', 'org.vistrails.vistrails.control_flow', [
+                        ('InputPort', [('List', "['i']")]),
+                        ('OutputPort', [('String', 'o')]),
+                        ('InputList', [('List', '[1, 2, 8, 9.1]')]),
+                    ]),
+                ],
+                [
+                    (0, 'self', 1, 'FunctionPort'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'i',
+                     'org.vistrails.vistrails.basic:Float'),
+                    (0, 'output', 'o',
+                     'org.vistrails.vistrails.basic:Float'),
+                ]))
+        self.assertEqual(results, [[2, 3, 9, 10.1]])
+
+    def test_tuple(self):
+        src = urllib2.quote('o = len(i[0]) + i[1]')
+        with intercept_result(Map, 'Result') as results:
+            self.assertFalse(execute([
+                    ('PythonSource', 'org.vistrails.vistrails.basic', [
+                        ('source', [('String', src)]),
+                    ]),
+                    ('Map', 'org.vistrails.vistrails.control_flow', [
+                        ('InputPort', [('List', "['i']")]),
+                        ('OutputPort', [('String', 'o')]),
+                        ('InputList', [('List',
+                            '[("aa", 1), ("", 8), ("a", 4)]')]),
+                    ]),
+                ],
+                [
+                    (0, 'self', 1, 'FunctionPort'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'i',
+                     'org.vistrails.vistrails.basic:String,org.vistrails.vistrails.basic:Integer'),
+                    (0, 'output', 'o',
+                     'org.vistrails.vistrails.basic:Float'),
+                ]))
+        self.assertEqual(results, [[3, 8, 5]])
+
+    def test_multiple(self):
+        src = urllib2.quote('o = i + j')
+        with intercept_result(Map, 'Result') as results:
+            self.assertFalse(execute([
+                    ('PythonSource', 'org.vistrails.vistrails.basic', [
+                        ('source', [('String', src)]),
+                    ]),
+                    ('Map', 'org.vistrails.vistrails.control_flow', [
+                        ('InputPort', [('List', "['i', 'j']")]),
+                        ('OutputPort', [('String', 'o')]),
+                        ('InputList', [('List',
+                            '[(1, 2), (3, 8), (-2, 3)]')]),
+                    ]),
+                ],
+                [
+                    (0, 'self', 1, 'FunctionPort'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'i',
+                     'org.vistrails.vistrails.basic:Integer'),
+                    (0, 'input', 'j',
+                     'org.vistrails.vistrails.basic:Integer'),
+                    (0, 'output', 'o',
+                     'org.vistrails.vistrails.basic:Integer'),
+                ]))
+        self.assertEqual(results, [[3, 11, 1]])
+
+
+class TestUtils(unittest.TestCase):
+    def test_filter(self):
+        src = urllib2.quote('o = bool(i)')
+        with intercept_result(Filter, 'Result') as results:
+            self.assertFalse(execute([
+                    ('PythonSource', 'org.vistrails.vistrails.basic', [
+                        ('source', [('String', src)]),
+                    ]),
+                    ('Filter', 'org.vistrails.vistrails.control_flow', [
+                        ('InputPort', [('List', "['i']")]),
+                        ('OutputPort', [('String', 'o')]),
+                        ('InputList', [('List',
+                            "[0, 1, 2, 3, '', 'foo', True, False]")]),
+                    ]),
+                ],
+                [
+                    (0, 'self', 1, 'FunctionPort'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'i',
+                     'org.vistrails.vistrails.basic:Module'),
+                    (0, 'output', 'o',
+                     'org.vistrails.vistrails.basic:Boolean'),
+                ]))
+        self.assertEqual(results, [[1, 2, 3, 'foo', True]])
+
+    def test_sum(self):
+        with intercept_result(Sum, 'Result') as results:
+            self.assertFalse(execute([
+                    ('Sum', 'org.vistrails.vistrails.control_flow', [
+                        ('InputList', [('List', "[1, 2, 3, 8, 14.7]")]),
+                    ]),
+                ]))
+        self.assertEqual(results, [28.7])
+
+    def do_andor(self, l):
+        with intercept_result(And, 'Result') as and_results:
+            with intercept_result(Or, 'Result') as or_results:
+                self.assertFalse(execute([
+                        ('List', 'org.vistrails.vistrails.basic', [
+                            ('value', [('List', str(l))]),
+                        ]),
+                        ('And', 'org.vistrails.vistrails.control_flow', []),
+                        ('Or', 'org.vistrails.vistrails.control_flow', []),
+                    ],
+                    [
+                        (0, 'value', 1, 'InputList'),
+                        (0, 'value', 2, 'InputList'),
+                    ]))
+        self.assertEqual(len(and_results), 1)
+        self.assertEqual(len(or_results), 1)
+        return and_results[0], or_results[0]
+
+    def test_andor(self):
+        self.assertEqual(self.do_andor([False, False]), (False, False))
+        self.assertEqual(self.do_andor([True, False]), (False, True))
+        self.assertEqual(self.do_andor([True, True]), (True, True))
+        self.assertEqual(self.do_andor([False, True]), (False, True))
+
+        # This is kind of random
+        self.assertEqual(self.do_andor([]), (True, False))
diff --git a/vistrails/packages/dialogs/__init__.py b/vistrails/packages/dialogs/__init__.py
index cb4d4e6..3f36970 100644
--- a/vistrails/packages/dialogs/__init__.py
+++ b/vistrails/packages/dialogs/__init__.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """dialogs provides modules for user-based interaction on execution.
 Users can then enter file names, numbers, strings, etc."""
 
+from __future__ import division
+
 from vistrails.core.packagemanager import get_package_manager
 
 
diff --git a/vistrails/packages/dialogs/continue_prompt.py b/vistrails/packages/dialogs/continue_prompt.py
index 7cbd285..0ab3a98 100644
--- a/vistrails/packages/dialogs/continue_prompt.py
+++ b/vistrails/packages/dialogs/continue_prompt.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
 from vistrails.core.configuration import get_vistrails_configuration
@@ -36,11 +74,11 @@ class PromptIsOkay(Module):
     def compute(self):
         vt_configuration = get_vistrails_configuration()
         if not getattr(vt_configuration, 'interactiveMode', False):
-            self.setResult('result', True)
+            self.set_output('result', True)
             return
 
-        cell = self.getInputFromPort('cell')
-        label = self.forceGetInputFromPort('label', None)
+        cell = self.get_input('cell')
+        label = self.force_get_input('label', None)
 
         # FIXME : This should be done via the spreadsheet, removing it properly
         # and then sending a new DisplayCellEvent
@@ -54,9 +92,9 @@ class PromptIsOkay(Module):
         result = dialog.exec_() == QtGui.QDialog.Accepted
         oldparent.setWidget(cell)
 
-        self.setResult('result', result)
+        self.set_output('result', result)
 
-        if not result and not self.getInputFromPort('carry_on'):
+        if not result and not self.get_input('carry_on'):
             raise ModuleError(self, "Execution aborted")
 
 
diff --git a/vistrails/packages/dialogs/init.py b/vistrails/packages/dialogs/init.py
index 6291ecf..61a94b7 100644
--- a/vistrails/packages/dialogs/init.py
+++ b/vistrails/packages/dialogs/init.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from vistrails.core.modules import basic_modules
 from vistrails.core.modules.vistrails_module import Module, ModuleError
 from vistrails.core.packagemanager import get_package_manager
@@ -45,9 +48,7 @@ class Dialog(Module):
                     ('cacheable', basic_modules.Boolean,
                      {'optional': True, 'defaults': "['False']"})]
 
-    def __init__(self, *args, **kwargs):
-        super(Dialog,self).__init__(*args, **kwargs)
-        self.cacheable_dialog = False
+    cacheable_dialog = False
 
     def is_cacheable(self):
         return self.cacheable_dialog
@@ -60,36 +61,32 @@ class TextDialog(Dialog):
                      {'optional': True, 'defaults': "['']"})]
     _output_ports = [('result', basic_modules.String)]
 
-    password = False
+    mode = QtGui.QLineEdit.Normal
 
     def compute(self):
-        if self.hasInputFromPort('title'):
-            title = self.getInputFromPort('title')
+        if self.has_input('title'):
+            title = self.get_input('title')
         else:
             title = 'VisTrails Dialog'
-        label = self.getInputFromPort('label')
-
-        default = self.getInputFromPort('default')
+        label = self.get_input('label')
 
-        self.cacheable_dialog = self.getInputFromPort('cacheable')
+        default = self.get_input('default')
 
-        mode =  QtGui.QLineEdit.Normal
-        if self.password:
-            mode = QtGui.QLineEdit.Password
+        self.cacheable_dialog = self.get_input('cacheable')
 
         (result, ok) = QtGui.QInputDialog.getText(None, title, label,
-                                                  mode,
+                                                  self.mode,
                                                   default)
         if not ok:
             raise ModuleError(self, "Canceled")
-        self.setResult('result', str(result))
+        self.set_output('result', str(result))
 
 
 class PasswordDialog(TextDialog):
     _input_ports = [('label', basic_modules.String,
                      {'optional': True, 'defaults': "['Password']"})]
 
-    password = True
+    mode = QtGui.QLineEdit.Password
 
 
 class YesNoDialog(Dialog):
@@ -98,13 +95,13 @@ class YesNoDialog(Dialog):
     _output_ports = [('result', basic_modules.Boolean)]
 
     def compute(self):
-        if self.hasInputFromPort('title'):
-            title = self.getInputFromPort('title')
+        if self.has_input('title'):
+            title = self.get_input('title')
         else:
             title = 'VisTrails Dialog'
-        label = self.getInputFromPort('label')
+        label = self.get_input('label')
 
-        self.cacheable_dialog = self.getInputFromPort('cacheable')
+        self.cacheable_dialog = self.get_input('cacheable')
 
         result = QtGui.QMessageBox.question(
                 None,
@@ -112,7 +109,7 @@ class YesNoDialog(Dialog):
                 QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
         result = result == QtGui.QMessageBox.Yes
 
-        self.setResult('result', result)
+        self.set_output('result', result)
 
 
 _modules = [(Dialog, {'abstract': True}),
diff --git a/vistrails/packages/gmaps/__init__.py b/vistrails/packages/gmaps/__init__.py
new file mode 100644
index 0000000..6cf2ff2
--- /dev/null
+++ b/vistrails/packages/gmaps/__init__.py
@@ -0,0 +1,55 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+"""Maps package for VisTrails.
+
+This package uses the Google Maps API to display information using
+Qt's WebKit in the spreadsheet.
+
+"""
+
+# 2014-02-04 -- 0.1.0
+#   * Package created (from existing local work from 2013)
+
+
+from __future__ import division
+
+from identifiers import *
+
+
+def package_dependencies():
+    return ['org.vistrails.vistrails.tabledata',
+            'org.vistrails.vistrails.spreadsheet']
diff --git a/vistrails/packages/gmaps/gmap_cell.py b/vistrails/packages/gmaps/gmap_cell.py
new file mode 100644
index 0000000..517c8c4
--- /dev/null
+++ b/vistrails/packages/gmaps/gmap_cell.py
@@ -0,0 +1,267 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from string import Template
+
+from vistrails.core.modules.config import IPort
+from vistrails.core.modules.vistrails_module import ModuleError
+
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
+from vistrails.packages.spreadsheet.widgets.webview.webview import WebViewCellWidget
+
+from .utils import *
+
+class GMapCell(SpreadsheetCell, OptionsMixin):
+    """
+    GMapCell is a custom Module to view TabularData geographically
+    
+    """
+
+    SPECS = [('zoom', None, True), 
+             'center']
+    _input_ports = [IPort("layers", "GMapVis"),
+                    IPort("zoom", "basic:Integer", optional=True, default=11),
+                    IPort("center", "basic:Float,basic:Float", optional=True)]
+
+    def compute(self):
+        """compute() -> None
+        Dispatch the URL to the spreadsheet
+
+        """
+
+        layers = self.get_input_list("layers")
+        if len(layers) < 1:
+            raise ModuleError(self, "Must provide at least one layer")
+        map_options = self.get_options(self.SPECS)
+        self.displayAndWait(GMapCellWidget, (layers, map_options, 
+                                             self.interpreter))
+
+class GMapCellWidget(WebViewCellWidget):
+    TEMPLATE = Template("""
+<html>
+  <head>
+    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+    <meta charset="utf-8">
+    <title>Google Maps</title>
+    <style>
+      html, body {
+      height: 100%%;
+      margin: 0;
+      padding: 0;
+      }
+
+      #map-canvas, #map_canvas {
+      height: 100%%;
+      }
+    </style>
+    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=visualization&sensor=false"></script>
+    <script>
+function initialize() {
+  var map = new google.maps.Map(document.getElementById('map-canvas'), $map_options);
+
+  $layers
+}
+
+google.maps.event.addDomListener(window, 'load', initialize);
+
+    </script>
+  </head>
+  <body>
+    <div id="map-canvas"></div>
+  </body>
+</html>
+""")
+
+    def updateContents(self, inputPorts):
+        self.urlSrc = None
+        
+        (layers, map_options, interpreter) = inputPorts
+ 
+        file_module = interpreter.filePool.create_file('.html')
+        fname = file_module.name
+
+        with open(fname, 'w') as f:
+            layers_js = ""
+            center = [0.0, 0.0]
+            for layer in layers:
+                layer_data = dict((k, json.dumps(v, cls=RawJsJSONEncoder))
+                                   for k, v in layer.data.iteritems())
+                layers_js += layer.init_template.substitute(layer_data)
+                center[0] += layer.center[0]
+                center[1] += layer.center[1]
+            center[0] /= float(len(layers))
+            center[1] /= float(len(layers))
+            
+            if 'center' not in map_options:
+                map_options['center'] = GMapLatLng(*center)
+            template_options = {'map_options': 
+                                json.dumps(map_options, cls=RawJsJSONEncoder),
+                                'layers':
+                                layers_js}
+            print >>f, self.TEMPLATE.substitute(template_options)
+        print "GMAP FILENAME:", fname
+
+        WebViewCellWidget.updateContents(self, (None, file_module))
+
+# def create_json_gradient(color_list):
+#     colors = []
+#     for c in color_list:
+#         if len(c) > 3:
+#             a = c[3]
+#         else:
+#             a = 1
+#         colors.append(GMapColor(c[0], c[1], c[2], a))
+#     return colors
+
+# PURPLE_GRADIENT = create_json_gradient([(252,251,253,0),
+#                                         # (239,237,245),
+#                                         # (218,218,235),
+#                                         (188,189,220),
+#                                         (158,154,200),
+#                                         (128,125,186),
+#                                         (106,81,163),
+#                                         (84,39,143),
+#                                         (63,0,125)])            
+
+# GMAP_HEATMAP_TEMPLATE = """
+# <html>
+#   <head>
+#     <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+#     <meta charset="utf-8">
+#     <title>Google Maps</title>
+#     <style>
+#       html, body {
+#       height: 100%%;
+#       margin: 0;
+#       padding: 0;
+#       }
+
+#       #map-canvas, #map_canvas {
+#       height: 100%%;
+#       }
+#     </style>
+#     <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=visualization&sensor=false"></script>
+#     <script>
+# var heatmap1, heatmap2;
+# function initialize() {
+#   var map = new google.maps.Map(document.getElementById('map-canvas'), %s);
+
+#   var weightedLocs1 = %s;
+#   var weightedLocs2 = %s;
+
+#   heatmap1 = new google.maps.visualization.HeatmapLayer({data: weightedLocs1, radius: 20.0});
+#   heatmap1.setMap(map);
+#   var gradient1 = ['rgba(255,255,191,0)',
+#                    'rgba(255,255,191,1)',
+#                    'rgba(254,224,139,1)',
+#                    'rgba(253,174,97,1)',
+#                    'rgba(244,109,67,1)',
+#                    'rgba(215,48,39,1)',
+#                    'rgba(215,48,39,1)',
+#                    'rgba(165,0,38,1)'];
+#   heatmap1.set('gradient', gradient1);
+#   heatmap2 = new google.maps.visualization.HeatmapLayer({data: weightedLocs2, radius: 20.0});
+#   heatmap2.setMap(map);
+#   var gradient2 = ['rgba(255,255,191,0)',
+#                    'rgba(255,255,191,1)',
+#                    'rgba(217,239,139,1)',
+#                    'rgba(166,217,106,1)',
+#                    'rgba(102,189,99,1)',
+#                    'rgba(26,152,80,1)',
+#                    'rgba(0,104,55,1)'];
+#   heatmap2.set('gradient', gradient2);
+# }
+
+# google.maps.event.addDomListener(window, 'load', initialize);
+
+#     </script>
+#   </head>
+#   <body>
+#     <div id="map-canvas"></div>
+#   </body>
+# </html>
+# """
+
+# class GMapHeatmapWidget(WebViewCellWidget):
+#     def updateContents(self, inputPorts):
+#         """ updateContents(inputPorts: tuple) -> None
+#         Updates the contents with a new changed in filename
+        
+#         """
+#         self.urlSrc = None
+
+#         (table, zoom, cmap, interpreter) = inputPorts
+#         header = table.names
+
+#         min_value = None
+#         max_value = None
+
+#         lat_col = table.get_column(0)
+#         long_col = table.get_column(1)
+#         value_col = table.get_column(2)
+
+#         # weighted_locs = [GMapWeightedLoc(lat_col[i], long_col[i], value_col[i])
+#         #                  for i in xrange(table.rows)]
+#         heatmap_data1 = [{"location": GMapLatLng(lat_col[i], long_col[i]),
+#                          "weight": -float(value_col[i])}
+#                          for i in xrange(table.rows)
+#                          if float(value_col[i]) < 0.0]
+#         heatmap_data2 = [{"location": GMapLatLng(lat_col[i], long_col[i]),
+#                           "weight": float(value_col[i])}
+#                          for i in xrange(table.rows)
+#                          if float(value_col[i]) >= 0.0]
+
+#         file_module = interpreter.filePool.create_file('.html')
+#         fname = file_module.name
+
+#         center = (sum(float(x) for x in lat_col)/len(lat_col),
+#                   sum(float(x) for x in long_col)/len(long_col))
+#         map_options = {"zoom": zoom,
+#                        "center": GMapLatLng(*center),
+#                        "mapTypeId": RawJavaScriptText("google.maps.MapTypeId.ROADMAP")}
+#         with open(fname, 'w') as f:
+#             print >>f, GMAP_HEATMAP_TEMPLATE % \
+#                 (json.dumps(map_options, cls=RawJsJSONEncoder),
+#                  json.dumps(heatmap_data1, cls=RawJsJSONEncoder),
+#                  json.dumps(heatmap_data2, cls=RawJsJSONEncoder))
+#         print "GMAP FILENAME:", fname
+
+#         WebViewCellWidget.updateContents(self, (None, file_module))
+
+
+_modules = [GMapCell]
diff --git a/vistrails/packages/gmaps/identifiers.py b/vistrails/packages/gmaps/identifiers.py
new file mode 100644
index 0000000..76413fb
--- /dev/null
+++ b/vistrails/packages/gmaps/identifiers.py
@@ -0,0 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+name = "Maps"
+identifier = "org.vistrails.vistrails.gmaps"
+version = "0.3.0"
diff --git a/vistrails/packages/gmaps/init.py b/vistrails/packages/gmaps/init.py
new file mode 100644
index 0000000..496f173
--- /dev/null
+++ b/vistrails/packages/gmaps/init.py
@@ -0,0 +1,242 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from .gmap_cell import _modules as gmap_modules
+from .vis import _modules as vis_modules
+from .identifiers import identifier
+
+from vistrails.core.modules.utils import create_port_spec_string
+from vistrails.core.vistrail.port import Port
+from vistrails.core.vistrail.port_spec import PortSpec
+from vistrails.core.vistrail.port_spec_item import PortSpecItem
+
+_modules = gmap_modules + vis_modules
+
+def handle_module_upgrade_request(controller, module_id, pipeline):
+    from vistrails.core.modules.module_descriptor import ModuleDescriptor
+    from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler, \
+        UpgradePackageRemap, UpgradeModuleRemap
+    from vistrails.core.modules.basic_modules import identifier as basic_pkg
+
+    def remap_functions(old_module, new_module, function_remap):
+        # FIXME need use_registry flag passed through!
+        use_registry = True
+        function_ops = []
+        for function in old_module.functions:
+            if function.name in function_remap:
+                remap = function_remap[function.name]
+                if remap is None:
+                    # don't add the function back in
+                    continue
+                elif not isinstance(remap, basestring):
+                    function_ops.extend(remap(function, new_module))
+                    continue
+                else:
+                    function_name = remap
+
+                if len(function.parameters) > 0:
+                    new_param_vals, aliases = zip(*[(p.strValue, p.alias)
+                                                    for p in function.parameters])
+                else:
+                    new_param_vals = []
+                    aliases = []
+                if use_registry:
+                    function_port_spec = function_name
+                else:
+                    def mk_psi(pos):
+                        psi = PortSpecItem(module="Module", package=basic_pkg,
+                                           namespace="", pos=pos)
+                        return psi
+                    n_items = len(new_param_vals)
+                    function_port_spec = PortSpec(name=function_name,
+                                                  items=[mk_psi(i)
+                                                         for i in xrange(n_items)])
+                new_function = controller.create_function(new_module,
+                                                          function_port_spec,
+                                                          new_param_vals,
+                                                          aliases)
+                new_module.add_function(new_function)
+
+        if None in function_remap:
+            # used to add new functions
+            remap = function_remap[None]
+            function_ops.extend(remap(None, new_module))
+        return function_ops
+
+    def remap_dst_connections(old_module, new_module, port_remap):
+        # FIXME need use_registry flag passed through!
+        use_registry = True
+        create_new_connection = UpgradeWorkflowHandler.create_new_connection
+
+        ops = []
+        for _, conn_id in pipeline.graph.edges_to(old_module.id):
+            old_conn = pipeline.connections[conn_id]
+            if old_conn.destination.name in port_remap:
+                remap = port_remap[old_conn.destination.name]
+                if remap is None:
+                    # don't add this connection back in
+                    continue
+                elif not isinstance(remap, basestring):
+                    ops.extend(remap(old_conn, new_module))
+                    continue
+                else:
+                    destination_name = remap
+
+                old_src_module = pipeline.modules[old_conn.source.moduleId]
+                if use_registry:
+                    destination_port = destination_name
+                else:
+                    destination_port = Port(name=destination_name,
+                                            type='destination',
+                                            signature=create_port_spec_string(
+                                                [(basic_pkg, 'Variant', '')]))
+
+                new_conn = create_new_connection(controller,
+                                                 old_src_module,
+                                                 old_conn.source,
+                                                 new_module,
+                                                 destination_port)
+                ops.append(('add', new_conn))
+        return ops
+
+    def insert_vis(vis_name, vis_port_remap):
+        def remap_vis(old_conn, new_cell_module):
+            ops = []
+            old_src_module = pipeline.modules[old_conn.source.moduleId]
+            old_cell_module = pipeline.modules[old_conn.destination.moduleId]
+
+            new_x = (old_src_module.location.x + new_cell_module.location.x)/2.0
+            new_y = (old_src_module.location.y + new_cell_module.location.y)/2.0
+
+            new_vis_desc = ModuleDescriptor(package=identifier,
+                                            name=vis_name,
+                                            version='0.3.0')
+            new_vis_module = \
+                controller.create_module_from_descriptor(new_vis_desc,
+                                                         new_x, new_y)
+
+            function_ops = remap_functions(old_cell_module,
+                                           new_vis_module,
+                                           vis_port_remap)
+            ops.append(('add', new_vis_module))
+            ops.extend(function_ops)
+            ops.extend(remap_dst_connections(old_cell_module,
+                                             new_vis_module,
+                                             vis_port_remap))
+
+            create_new_connection = UpgradeWorkflowHandler.create_new_connection
+            new_conn_1 = create_new_connection(controller,
+                                               old_src_module,
+                                               old_conn.source,
+                                               new_vis_module,
+                                               "table")
+            ops.append(('add', new_conn_1))
+            new_conn_2 = create_new_connection(controller,
+                                               new_vis_module,
+                                               "self",
+                                               new_cell_module,
+                                               "layers")
+            ops.append(('add', new_conn_2))
+            return ops
+
+        # returns the actual remap function
+        return remap_vis
+
+    # zoom gets moved for free from old cell to new cell
+    remap = UpgradePackageRemap()
+    def add_legacy(fname, module):
+        new_function = controller.create_function(module,
+                                                  "allowLegacy",
+                                                  ["True"])
+        return [('add', new_function, 'module', module.id)]
+    remap.add_module_remap(UpgradeModuleRemap('0.1.0', '0.3.0', '0.3.0',
+                                              new_module="GMapCell",
+                                              module_name="GMapCell",
+                            dst_port_remap={'table': insert_vis("GMapSymbols",
+                                            {None: add_legacy}),
+                                            'colormapName': None}))
+    remap.add_module_remap(UpgradeModuleRemap('0.1.0', '0.3.0', '0.3.0',
+                                              new_module="GMapCell",
+                                              module_name="GMapHeatmapCell",
+                            dst_port_remap={'table': insert_vis("GMapHeatmap",
+                                            {'dissipating': 'dissipating',
+                                             'maxIntensity': 'maxIntensity',
+                                             'opacity': 'opacity',
+                                             'radius': 'radius'}),
+                                            'dissipating': None,
+                                            'maxIntensity': None,
+                                            'opacity': None,
+                                            'radius': None,
+                                            }))
+    remap.add_module_remap(UpgradeModuleRemap('0.1.0', '0.3.0', '0.3.0',
+                                              new_module="GMapCell",
+                                              module_name="GMapCircleCell",
+                            dst_port_remap={'table': insert_vis("GMapCircles",
+                                            {'strokeColor': 'strokeColor',
+                                             'strokeWeight': 'strokeWeight',
+                                             'strokeOpacity': 'strokeOpacity',
+                                             'fillColor': 'fillColor',
+                                             'fillOpacity': 'fillOpacity'}),
+                                            'strokeColor': None,
+                                            'strokeWeight': None,
+                                            'strokeOpacity': None,
+                                            'fillColor': None,
+                                            'fillOpacity': None,
+                                            }))
+    remap.add_module_remap(UpgradeModuleRemap('0.1.0', '0.3.0', '0.3.0',
+                                              new_module="GMapCell",
+                                              module_name="GMapSymbolCell",
+                            dst_port_remap={'table': insert_vis("GMapSymbols",
+                                            {'strokeColor': 'strokeColor',
+                                             'strokeWeight': 'strokeWeight',
+                                             'strokeOpacity': 'strokeOpacity',
+                                             'fillStartColor': 'fillStartColor',
+                                             'fillEndColor': 'fillEndColor',
+                                             'fillOpacity': 'fillOpacity',
+                                             'scale': 'scale'}),
+                                            'strokeColor': None,
+                                            'strokeWeight': None,
+                                            'strokeOpacity': None,
+                                            'fillStartColor': None,
+                                            'fillEndColor': None,
+                                            'fillOpacity': None,
+                                            'scale': None,
+                                        }))
+
+    return UpgradeWorkflowHandler.remap_module(controller, module_id, pipeline,
+                                               remap)
diff --git a/vistrails/packages/gmaps/utils.py b/vistrails/packages/gmaps/utils.py
new file mode 100644
index 0000000..1dd3322
--- /dev/null
+++ b/vistrails/packages/gmaps/utils.py
@@ -0,0 +1,123 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import json
+import uuid
+
+###############################################################################
+# Utility classes
+
+class OptionsMixin(object):
+    def get_options(self, specs):
+        options = {}
+        for spec in specs:
+            convert_f = None
+            use_default = False
+            if type(spec) == tuple:
+                key = spec[0]
+                if len(spec) > 1:
+                    convert_f = spec[1]
+                if len(spec) > 2:
+                    use_default = spec[2]
+            else:
+                key = spec
+
+            if self.has_input(key) or use_default:
+                val = self.get_input(key)
+                if convert_f is not None:
+                    val = convert_f(val)
+                options[key] = val
+
+        return options
+
+class RawJavaScriptText(object):
+    def __init__(self, jstext=None):
+        self.jstext = jstext
+
+    def get_jstext(self):
+        return self.jstext
+
+class GMapLatLng(RawJavaScriptText):
+    def __init__(self, lat, lng):
+        RawJavaScriptText.__init__(self)
+        self.lat = lat
+        self.lng = lng
+
+    def get_jstext(self):
+        return "new google.maps.LatLng(%s, %s)" % (self.lat, self.lng)
+
+class GMapColor(RawJavaScriptText):
+    def __init__(self, r, g, b, a=1):
+        RawJavaScriptText.__init__(self)
+        self.r = r
+        self.g = g
+        self.b = b
+        self.a = a
+        
+    def get_jstext(self):
+        return "\"rgba(%d, %d, %d, %d)\"" % (self.r, self.g, self.b, self.a)
+
+class GMapWeightedLoc(RawJavaScriptText):
+    def __init__(self, lat, lng, val):
+        RawJavaScriptText.__init__(self)
+        self.lat = lat
+        self.lng = lng
+        self.val = val
+
+    def get_jstext(self):
+        return "new google.maps.visualization.WeightedLocation(new google.maps.LatLng(%s, %s), %s)" % (self.lat, self.lng, self.val)
+
+class RawJsJSONEncoder(json.JSONEncoder):
+    def __init__(self, *args, **kwargs):
+        json.JSONEncoder.__init__(self, *args, **kwargs)
+        self._replacement_map = {}
+
+    def default(self, o):
+        if isinstance(o, RawJavaScriptText):
+            key = uuid.uuid4().hex
+            self._replacement_map[key] = o.get_jstext()
+            return key
+        else:
+            return json.JSONEncoder.default(self, o)
+
+    def encode(self, o):
+        result = json.JSONEncoder.encode(self, o)
+        for k, v in self._replacement_map.iteritems():
+            result = result.replace('"%s"' % k, v)
+        return result
+
diff --git a/vistrails/packages/gmaps/vis.py b/vistrails/packages/gmaps/vis.py
new file mode 100644
index 0000000..54747e2
--- /dev/null
+++ b/vistrails/packages/gmaps/vis.py
@@ -0,0 +1,351 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import colorsys
+from string import Template
+
+from vistrails.core.modules.config import IPort, OPort, ModuleSettings
+from vistrails.core.modules.vistrails_module import ModuleError, Module
+from vistrails.core.utils import InstanceObject
+# FIXME make package imports better
+from vistrails.packages.tabledata.common import choose_column
+
+from .utils import *
+
+###############################################################################
+# Modules and Data
+
+class GMapVisData(object):
+    def __init__(self, gmaps_libs, init_template, data, center=None):
+        self.gmaps_libs = gmaps_libs
+        self.init_template = init_template
+        self.data = data
+        self.center = center
+
+def convert_color(c):
+    c = c.tuple
+    return GMapColor(c[0] * 255.0, c[1] * 255.0, c[2] * 255.0)
+
+class TitlesMixin(object):
+    def get_titles(self, table=None, default_col=None):
+        if table is None:
+            table = self.get_input("table")
+        title_col_idx = self.force_get_input('titleColIdx')
+        title_col_name = self.force_get_input('titleColName')
+        print "title_col_idx:", title_col_idx
+        print "title_col_name:", title_col_name
+
+        if (title_col_idx is None and
+                title_col_name is None and 
+                default_col is not None and
+                default_col < table.columns):
+                # only allow default if in range
+                title_col_idx = default_col
+
+        if title_col_idx is not None or title_col_name is not None:
+            title_idx = choose_column(table.columns, table.names, 
+                                      title_col_name, title_col_idx)
+            title_col = table.get_column(title_idx)
+            return title_col
+        return None
+
+class GMapVis(Module, OptionsMixin):
+    _input_ports = [IPort('table', 'tabledata:Table'),
+                    IPort('latitudeColIdx', 'basic:Integer', optional=True,
+                          default=0),
+                    IPort('latitudeColName', 'basic:String', optional=True),
+                    IPort('longitudeColIdx', 'basic:Integer', optional=True,
+                          default=1),
+                    IPort('longitudeColName', 'basic:String', optional=True)]
+    _output_ports = [OPort('self', 'GMapVis')]
+    _settings = ModuleSettings(abstract=True)
+
+    def get_positions(self, table=None):
+        if table is None:
+            table = self.get_input("table")
+        
+        lat_col_idx = self.force_get_input('latitudeColIdx')
+        lat_col_name = self.force_get_input('latitudeColName')
+        lng_col_idx = self.force_get_input('longitudeColIdx')
+        lng_col_name = self.force_get_input('longitudeColName')
+        if lat_col_idx is None and lat_col_name is None:
+            lat_idx = self.get_input('latitudeColIdx') # default 0
+        else:
+            lat_idx = choose_column(table.columns, table.names, 
+                                    lat_col_name, lat_col_idx)
+        if lng_col_idx is None and lng_col_name is None:
+            lng_idx = self.get_input('longitudeColIdx') # default 1
+        else:
+            lng_idx = choose_column(table.columns, table.names, 
+                                    lng_col_name, lng_col_idx)
+        lat_col = table.get_column(lat_idx, True)
+        lng_col = table.get_column(lng_idx, True)
+        center = (sum(float(x) for x in lat_col)/len(lat_col),
+                  sum(float(x) for x in lng_col)/len(lng_col))
+        positions = []
+        for i in xrange(table.rows):
+            positions.append(GMapLatLng(lat_col[i], lng_col[i]))
+        return (positions, center)
+
+class GMapMarkers(GMapVis, TitlesMixin):
+    TEMPLATE = Template("""
+  var positions = $marker_data;
+  var options = $marker_options;
+  var titles = $marker_titles;
+
+  for (var i=0; i < positions.length; i++) {
+    marker = new google.maps.Marker({"position": positions[i],
+                                      "map": map});
+    marker.setOptions(options);
+    if (titles) {
+      marker.setTitle(titles[i]);
+    }
+  }
+""")
+    SPECS = ['flat']
+    _input_ports = [IPort("flat", "basic:Boolean", optional=True),
+                    IPort('titleColIdx', 'basic:Integer', optional=True),
+                    IPort('titleColName', 'basic:String', optional=True)]
+    
+    def compute(self):
+        (positions, center) = self.get_positions()
+        marker_options = self.get_options(self.SPECS)
+        titles = self.get_titles()
+        print "got titles:", titles
+        data = {"marker_options": marker_options,
+                "marker_data": positions,
+                "marker_titles": titles}
+        
+        vis_data = GMapVisData([], self.TEMPLATE, data, center)
+        self.set_output("self", vis_data)
+
+class GMapValueVis(GMapVis):
+    _input_ports = [IPort('valueColIdx', 'basic:Integer', optional=True,
+                          default=2),
+                    IPort('valueColName', 'basic:String', optional=True),]
+    _settings = ModuleSettings(abstract=True)
+    def get_values(self, table=None):
+        if table is None:
+            table = self.get_input("table")
+        value_col_idx = self.force_get_input("valueColIdx")
+        value_col_name = self.force_get_input("valueColName")
+        if value_col_idx is None and value_col_name is None:
+            value_idx = self.get_input("valueColIdx") # default 2
+        else:
+            value_idx = choose_column(table.columns, table.names, 
+                                      value_col_name, value_col_idx)
+        value_col = table.get_column(value_idx, True)
+        return value_col
+
+class GMapCircles(GMapValueVis):
+    TEMPLATE = Template("""
+  var data = $circle_data;
+  
+  for (var i=0; i < data.length; i++) {
+    var options = $circle_options;
+    options["center"] = data[i][0];
+    options["radius"] = data[i][1];
+    options["map"] = map;
+    circle = new google.maps.Circle(options);
+  }
+""")
+    
+    SPECS = [('strokeColor', convert_color, True),
+             ('fillColor', convert_color),
+             'strokeWeight', 
+             'strokeOpacity',
+             'fillOpacity']
+    _input_ports = [IPort("strokeColor", "basic:Color", optional=True,
+                          default=InstanceObject(tuple=(0,0,0))),
+                    IPort("strokeWeight", "basic:Integer", optional=True),
+                    IPort("strokeOpacity", "basic:Float", optional=True),
+                    IPort("fillColor", "basic:Color", optional=True),
+                    IPort("fillOpacity", "basic:Float", optional=True),
+                    IPort("scale", "basic:Float", optional=True)]
+    
+    def compute(self):
+        (positions, center) = self.get_positions()
+        values = self.get_values()
+        circle_data = [[positions[i], float(values[i])/200.0]
+                       for i in xrange(len(positions))]
+        circle_options = self.get_options(self.SPECS)
+        data = {"circle_options": circle_options,
+                "circle_data": circle_data}
+        vis_data = GMapVisData([], self.TEMPLATE, data, center)
+        self.set_output("self", vis_data)
+
+class GMapSymbols(GMapValueVis, TitlesMixin):
+    TEMPLATE = Template("""
+  var data = $symbol_data;
+  var titles = $symbol_titles;
+
+  for (var i=0; i < data.length; i++) {
+    var marker_options = {"position": data[i][0],
+                          "map": map};
+    if (titles) {
+      marker_options["title"] = titles[i];
+    }
+    if ($use_values) {
+      var icon_options = $symbol_options;
+      icon_options["fillColor"] = data[i][1];
+      marker_options["icon"] = icon_options;
+    }
+    marker = new google.maps.Marker(marker_options);
+  }  
+""")
+
+    SPECS = [('strokeColor', convert_color, True),
+             ('fillStartColor', None, True),
+             ('fillEndColor', None, True),
+             ('strokeWeight', None, True),
+             'strokeOpacity',
+             ('fillOpacity', None, True),
+             ('scale', None, True)]
+    _input_ports = [IPort("strokeColor", "basic:Color", optional=True,
+                          default=InstanceObject(tuple=(0,0,0))),
+                    IPort("strokeWeight", "basic:Integer", optional=True,
+                          default=1),
+                    IPort("strokeOpacity", "basic:Float", optional=True),
+                    IPort("fillStartColor", "basic:Color", optional=True,
+                          default=InstanceObject(tuple=(1,1,1))),
+                    IPort("fillEndColor", "basic:Color", optional=True,
+                          default=InstanceObject(tuple=(1,0,0))),
+                    IPort("fillOpacity", "basic:Float", optional=True,
+                          default=1.0),
+                    IPort("scale", "basic:Float", optional=True,
+                          default=5.0),
+                    IPort('titleColIdx', 'basic:Integer', optional=True),
+                    IPort('titleColName', 'basic:String', optional=True),
+                    IPort("allowLegacy", "basic:Boolean", optional=True,
+                          default=False)]
+
+    def compute(self):
+        (positions, center) = self.get_positions()
+        legacy = self.get_input("allowLegacy")
+        use_values = True
+        try:
+            values = [float(x) for x in self.get_values()]
+        except ValueError, e:
+            # LEGACY SUPPORT
+            if legacy:
+                use_values = False
+            else:
+                raise ModuleError(self, "Must provide values column")
+        if not use_values:
+            symbol_data = positions
+            symbol_options = {}
+        else:
+            symbol_options = self.get_options(self.SPECS)
+            symbol_options["path"] = \
+                            RawJavaScriptText("google.maps.SymbolPath.CIRCLE")
+            min_value = min(values)
+            max_value = max(values)
+
+            # if we have black or white, we want hue to match the other side
+            def white_or_black(c):
+                return ((c[0] < 1e-8 and c[1] < 1e-8 and c[2] < 1e-8) or
+                        (c[0] > 1-1e-8 and c[1] > 1-1e-8 and c[2] > 1-1e-8))
+            start_c = symbol_options.pop("fillStartColor").tuple
+            end_c = symbol_options.pop("fillEndColor").tuple
+            start_wb = white_or_black(start_c)
+            end_wb = white_or_black(end_c)
+            start_c = list(colorsys.rgb_to_hsv(*start_c))
+            end_c = list(colorsys.rgb_to_hsv(*end_c))
+            if start_wb:
+                start_c[0] = end_c[0]
+            elif end_wb:
+                end_c[0] = start_c[0]
+
+            symbol_data = []
+            for i in xrange(len(positions)):
+                val = values[i]
+                if max_value - min_value < 1e-8:
+                    norm_val = 1.0
+                else:
+                    norm_val = (val - min_value) / (max_value - min_value)
+                color = []
+                for j in xrange(len(start_c)):
+                    color.append((1.0 - norm_val) * start_c[j] + 
+                                 norm_val * end_c[j])
+                color = colorsys.hsv_to_rgb(*color)
+                symbol_data.append([positions[i],
+                                    GMapColor(255 * color[0],
+                                              255 * color[1],
+                                              255 * color[2])])
+        symbol_titles = self.get_titles(default_col=(3 if legacy else None))
+        data = {"symbol_data": symbol_data,
+                "symbol_options": symbol_options,
+                "symbol_titles": symbol_titles,
+                "use_values": use_values}
+        vis_data = GMapVisData([], self.TEMPLATE, data, center)
+        self.set_output("self", vis_data)
+
+class GMapHeatmap(GMapValueVis):
+    TEMPLATE = Template("""
+  var data = $heatmap_data;
+  var options = $heatmap_options;
+  options["data"] = data;
+  options["map"] = map;
+  heatmap = new google.maps.visualization.HeatmapLayer(options);
+""")
+
+    SPECS = ['dissipating',
+             'maxIntensity',
+             'opacity',
+             'radius']
+    _input_ports = [IPort("dissipating", "basic:Boolean", optional=True,
+                          default=True),
+                    IPort("maxIntensity", "basic:Float", optional=True),
+                    IPort("opacity", "basic:Float", optional=True,
+                     default=0.6),
+                    IPort("radius", "basic:Float", optional=True)]
+    
+    def compute(self):
+        (positions, center) = self.get_positions()
+        values = self.get_values()
+        heatmap_data = [{"location": positions[i],
+                         "weight": float(values[i])} 
+                        for i in xrange(len(positions))]
+        heatmap_options = self.get_options(self.SPECS)
+        data = {"heatmap_data": heatmap_data,
+                "heatmap_options": heatmap_options}
+        vis_data = GMapVisData([], self.TEMPLATE, data, center)
+        self.set_output("self", vis_data)
+
+_modules = [GMapVis, GMapMarkers, GMapValueVis, GMapCircles, GMapSymbols,
+            GMapHeatmap]
diff --git a/vistrails/packages/matplotlib/__init__.py b/vistrails/packages/matplotlib/__init__.py
index f432dda..f777a0e 100644
--- a/vistrails/packages/matplotlib/__init__.py
+++ b/vistrails/packages/matplotlib/__init__.py
@@ -1,43 +1,47 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
 """Matplotlib package for VisTrails.
 
 This package wrap Matplotlib to provide a plotting tool for
 VisTrails. We are going to use the 'Qt4Agg' backend of the library.
-
 """
 
+from __future__ import division
+
 from identifiers import *
 
 def package_dependencies():
diff --git a/vistrails/packages/matplotlib/artists.py b/vistrails/packages/matplotlib/artists.py
index f167527..7a6a7da 100644
--- a/vistrails/packages/matplotlib/artists.py
+++ b/vistrails/packages/matplotlib/artists.py
@@ -1,3 +1,5 @@
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module
 from bases import MplProperties
 import matplotlib.artist
@@ -68,63 +70,79 @@ class MplArtistProperties(MplProperties):
                 {'optional': True, 'docstring': 'Set the :class:`~matplotlib.figure.Figure` instance the artist belongs to.'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplArtistProperties)")]
-
-    def __init__(self):
-        MplProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplProperties.compute(self)
-        if self.hasInputFromPort('picker'):
-            self.props['picker'] = self.getInputFromPort('picker')
-        if self.hasInputFromPort('contains'):
-            self.props['contains'] = self.getInputFromPort('contains')
-        if self.hasInputFromPort('clip_on'):
-            self.props['clip_on'] = self.getInputFromPort('clip_on')
-        if self.hasInputFromPort('agg_filter'):
-            self.props['agg_filter'] = self.getInputFromPort('agg_filter')
-        if self.hasInputFromPort('visible'):
-            self.props['visible'] = self.getInputFromPort('visible')
-        if self.hasInputFromPort('url'):
-            self.props['url'] = self.getInputFromPort('url')
-        if self.hasInputFromPort('transform'):
-            self.props['transform'] = self.getInputFromPort('transform')
-        if self.hasInputFromPort('axes'):
-            self.props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('clip_box'):
-            self.props['clip_box'] = self.getInputFromPort('clip_box')
-        if self.hasInputFromPort('clip_path'):
-            self.props['clip_path'] = self.getInputFromPort('clip_path')
-        if self.hasInputFromPort('lod'):
-            self.props['lod'] = self.getInputFromPort('lod')
-        if self.hasInputFromPort('label'):
-            self.props['label'] = self.getInputFromPort('label')
-        if self.hasInputFromPort('rasterized'):
-            self.props['rasterized'] = self.getInputFromPort('rasterized')
-        if self.hasInputFromPort('gid'):
-            self.props['gid'] = self.getInputFromPort('gid')
-        if self.hasInputFromPort('zorder'):
-            self.props['zorder'] = self.getInputFromPort('zorder')
-        if self.hasInputFromPort('snap'):
-            self.props['snap'] = self.getInputFromPort('snap')
-        if self.hasInputFromPort('alpha'):
-            self.props['alpha'] = self.getInputFromPort('alpha')
-        if self.hasInputFromPort('animated'):
-            self.props['animated'] = self.getInputFromPort('animated')
-        if self.hasInputFromPort('figure'):
-            self.props['figure'] = self.getInputFromPort('figure')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplArtistProperties)")]
+
+    class Artist(MplProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplArtistProperties.Artist()
+            self.set_output("value", artist)
+
+        MplProperties.compute(self, artist)
+        if self.has_input('picker'):
+            artist.props['picker'] = self.get_input('picker')
+        if self.has_input('contains'):
+            artist.props['contains'] = self.get_input('contains')
+        if self.has_input('clip_on'):
+            artist.props['clip_on'] = self.get_input('clip_on')
+        if self.has_input('agg_filter'):
+            artist.props['agg_filter'] = self.get_input('agg_filter')
+        if self.has_input('visible'):
+            artist.props['visible'] = self.get_input('visible')
+        if self.has_input('url'):
+            artist.props['url'] = self.get_input('url')
+        if self.has_input('transform'):
+            artist.props['transform'] = self.get_input('transform')
+        if self.has_input('axes'):
+            artist.props['axes'] = self.get_input('axes')
+        if self.has_input('clip_box'):
+            artist.props['clip_box'] = self.get_input('clip_box')
+        if self.has_input('clip_path'):
+            artist.props['clip_path'] = self.get_input('clip_path')
+        if self.has_input('lod'):
+            artist.props['lod'] = self.get_input('lod')
+        if self.has_input('label'):
+            artist.props['label'] = self.get_input('label')
+        if self.has_input('rasterized'):
+            artist.props['rasterized'] = self.get_input('rasterized')
+        if self.has_input('gid'):
+            artist.props['gid'] = self.get_input('gid')
+        if self.has_input('zorder'):
+            artist.props['zorder'] = self.get_input('zorder')
+        if self.has_input('snap'):
+            artist.props['snap'] = self.get_input('snap')
+        if self.has_input('alpha'):
+            artist.props['alpha'] = self.get_input('alpha')
+        if self.has_input('animated'):
+            artist.props['animated'] = self.get_input('animated')
+        if self.has_input('figure'):
+            artist.props['figure'] = self.get_input('figure')
+
 
 class Mpl_AxesImageBaseProperties(MplArtistProperties):
     """None
@@ -154,47 +172,63 @@ class Mpl_AxesImageBaseProperties(MplArtistProperties):
                 {'entry_types': "['enum']", 'docstring': "Set the interpolation method the image uses when resizing.\n\nif None, use a value from rc setting. If 'none', the image is shown as is without interpolating. 'none' is only supported in agg, ps and pdf backends and will fall back to 'nearest' mode for other backends.", 'values': "[['nearest', 'bilinear', 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitch [...]
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(Mpl_AxesImageBaseProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('origin'):
-            self.constructor_props['origin'] = self.getInputFromPort('origin')
-        if self.hasInputFromPort('resample'):
-            self.props['resample'] = self.getInputFromPort('resample')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('filternorm'):
-            self.props['filternorm'] = self.getInputFromPort('filternorm')
-        if self.hasInputFromPort('ax'):
-            self.constructor_props['ax'] = self.getInputFromPort('ax')
-        if self.hasInputFromPort('alpha'):
-            self.props['alpha'] = self.getInputFromPort('alpha')
-        if self.hasInputFromPort('array'):
-            self.props['array'] = self.getInputFromPort('array')
-        if self.hasInputFromPort('data'):
-            self.props['data'] = self.getInputFromPort('data')
-        if self.hasInputFromPort('filterrad'):
-            self.props['filterrad'] = self.getInputFromPort('filterrad')
-        if self.hasInputFromPort('interpolation'):
-            self.props['interpolation'] = self.getInputFromPort('interpolation')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(Mpl_AxesImageBaseProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = Mpl_AxesImageBaseProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('origin'):
+            artist.constructor_props['origin'] = self.get_input('origin')
+        if self.has_input('resample'):
+            artist.props['resample'] = self.get_input('resample')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('filternorm'):
+            artist.props['filternorm'] = self.get_input('filternorm')
+        if self.has_input('ax'):
+            artist.constructor_props['ax'] = self.get_input('ax')
+        if self.has_input('alpha'):
+            artist.props['alpha'] = self.get_input('alpha')
+        if self.has_input('array'):
+            artist.props['array'] = self.get_input('array')
+        if self.has_input('data'):
+            artist.props['data'] = self.get_input('data')
+        if self.has_input('filterrad'):
+            artist.props['filterrad'] = self.get_input('filterrad')
+        if self.has_input('interpolation'):
+            artist.props['interpolation'] = self.get_input('interpolation')
+
 
 class MplAxesImageProperties(Mpl_AxesImageBaseProperties):
     """None
@@ -220,43 +254,59 @@ class MplAxesImageProperties(Mpl_AxesImageBaseProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplAxesImageProperties)")]
-
-    def __init__(self):
-        Mpl_AxesImageBaseProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        Mpl_AxesImageBaseProperties.compute(self)
-        if self.hasInputFromPort('origin'):
-            self.constructor_props['origin'] = self.getInputFromPort('origin')
-        if self.hasInputFromPort('resample'):
-            self.constructor_props['resample'] = self.getInputFromPort('resample')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('filterrad'):
-            self.constructor_props['filterrad'] = self.getInputFromPort('filterrad')
-        if self.hasInputFromPort('extent'):
-            self.props['extent'] = self.getInputFromPort('extent')
-        if self.hasInputFromPort('ax'):
-            self.constructor_props['ax'] = self.getInputFromPort('ax')
-        if self.hasInputFromPort('filternorm'):
-            self.constructor_props['filternorm'] = self.getInputFromPort('filternorm')
-        if self.hasInputFromPort('interpolation'):
-            self.constructor_props['interpolation'] = self.getInputFromPort('interpolation')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplAxesImageProperties)")]
+
+    class Artist(Mpl_AxesImageBaseProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            Mpl_AxesImageBaseProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplAxesImageProperties.Artist()
+            self.set_output("value", artist)
+
+        Mpl_AxesImageBaseProperties.compute(self, artist)
+        if self.has_input('origin'):
+            artist.constructor_props['origin'] = self.get_input('origin')
+        if self.has_input('resample'):
+            artist.constructor_props['resample'] = self.get_input('resample')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('filterrad'):
+            artist.constructor_props['filterrad'] = self.get_input('filterrad')
+        if self.has_input('extent'):
+            artist.props['extent'] = self.get_input('extent')
+        if self.has_input('ax'):
+            artist.constructor_props['ax'] = self.get_input('ax')
+        if self.has_input('filternorm'):
+            artist.constructor_props['filternorm'] = self.get_input('filternorm')
+        if self.has_input('interpolation'):
+            artist.constructor_props['interpolation'] = self.get_input('interpolation')
+
 
 class MplNonUniformImageProperties(MplAxesImageProperties):
     """None
@@ -280,41 +330,57 @@ class MplNonUniformImageProperties(MplAxesImageProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplNonUniformImageProperties)")]
-
-    def __init__(self):
-        MplAxesImageProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplAxesImageProperties.compute(self)
-        if self.hasInputFromPort('norm'):
-            self.props['norm'] = self.getInputFromPort('norm')
-        if self.hasInputFromPort('cmap'):
-            self.props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('filternorm'):
-            self.props['filternorm'] = self.getInputFromPort('filternorm')
-        if self.hasInputFromPort('ax'):
-            self.constructor_props['ax'] = self.getInputFromPort('ax')
-        if self.hasInputFromPort('array'):
-            self.props['array'] = self.getInputFromPort('array')
-        if self.hasInputFromPort('data'):
-            self.props['data'] = self.getInputFromPort('data')
-        if self.hasInputFromPort('filterrad'):
-            self.props['filterrad'] = self.getInputFromPort('filterrad')
-        if self.hasInputFromPort('interpolation'):
-            self.props['interpolation'] = self.getInputFromPort('interpolation')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplNonUniformImageProperties)")]
+
+    class Artist(MplAxesImageProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplAxesImageProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplNonUniformImageProperties.Artist()
+            self.set_output("value", artist)
+
+        MplAxesImageProperties.compute(self, artist)
+        if self.has_input('norm'):
+            artist.props['norm'] = self.get_input('norm')
+        if self.has_input('cmap'):
+            artist.props['cmap'] = self.get_input('cmap')
+        if self.has_input('filternorm'):
+            artist.props['filternorm'] = self.get_input('filternorm')
+        if self.has_input('ax'):
+            artist.constructor_props['ax'] = self.get_input('ax')
+        if self.has_input('array'):
+            artist.props['array'] = self.get_input('array')
+        if self.has_input('data'):
+            artist.props['data'] = self.get_input('data')
+        if self.has_input('filterrad'):
+            artist.props['filterrad'] = self.get_input('filterrad')
+        if self.has_input('interpolation'):
+            artist.props['interpolation'] = self.get_input('interpolation')
+
 
 class MplBboxImageProperties(Mpl_AxesImageBaseProperties):
     """The Image class whose size is determined by the given bbox.
@@ -340,43 +406,59 @@ class MplBboxImageProperties(Mpl_AxesImageBaseProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplBboxImageProperties)")]
-
-    def __init__(self):
-        Mpl_AxesImageBaseProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        Mpl_AxesImageBaseProperties.compute(self)
-        if self.hasInputFromPort('origin'):
-            self.constructor_props['origin'] = self.getInputFromPort('origin')
-        if self.hasInputFromPort('interp_at_native'):
-            self.constructor_props['interp_at_native'] = self.getInputFromPort('interp_at_native')
-        if self.hasInputFromPort('resample'):
-            self.constructor_props['resample'] = self.getInputFromPort('resample')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('filternorm'):
-            self.constructor_props['filternorm'] = self.getInputFromPort('filternorm')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-        if self.hasInputFromPort('interpolation'):
-            self.constructor_props['interpolation'] = self.getInputFromPort('interpolation')
-        if self.hasInputFromPort('filterrad'):
-            self.constructor_props['filterrad'] = self.getInputFromPort('filterrad')
-        if self.hasInputFromPort('bbox'):
-            self.constructor_props['bbox'] = self.getInputFromPort('bbox')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplBboxImageProperties)")]
+
+    class Artist(Mpl_AxesImageBaseProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            Mpl_AxesImageBaseProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplBboxImageProperties.Artist()
+            self.set_output("value", artist)
+
+        Mpl_AxesImageBaseProperties.compute(self, artist)
+        if self.has_input('origin'):
+            artist.constructor_props['origin'] = self.get_input('origin')
+        if self.has_input('interp_at_native'):
+            artist.constructor_props['interp_at_native'] = self.get_input('interp_at_native')
+        if self.has_input('resample'):
+            artist.constructor_props['resample'] = self.get_input('resample')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('filternorm'):
+            artist.constructor_props['filternorm'] = self.get_input('filternorm')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+        if self.has_input('interpolation'):
+            artist.constructor_props['interpolation'] = self.get_input('interpolation')
+        if self.has_input('filterrad'):
+            artist.constructor_props['filterrad'] = self.get_input('filterrad')
+        if self.has_input('bbox'):
+            artist.constructor_props['bbox'] = self.get_input('bbox')
+
 
 class MplPcolorImageProperties(MplArtistProperties):
     """
@@ -407,43 +489,59 @@ class MplPcolorImageProperties(MplArtistProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPcolorImageProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('A'):
-            self.constructor_props['A'] = self.getInputFromPort('A')
-        if self.hasInputFromPort('ax'):
-            self.constructor_props['ax'] = self.getInputFromPort('ax')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('x'):
-            self.constructor_props['x'] = self.getInputFromPort('x')
-        if self.hasInputFromPort('y'):
-            self.constructor_props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('alpha'):
-            self.props['alpha'] = self.getInputFromPort('alpha')
-        if self.hasInputFromPort('array'):
-            self.props['array'] = self.getInputFromPort('array')
-        if self.hasInputFromPort('data'):
-            self.props['data'] = self.getInputFromPort('data')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPcolorImageProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPcolorImageProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('A'):
+            artist.constructor_props['A'] = self.get_input('A')
+        if self.has_input('ax'):
+            artist.constructor_props['ax'] = self.get_input('ax')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('x'):
+            artist.constructor_props['x'] = self.get_input('x')
+        if self.has_input('y'):
+            artist.constructor_props['y'] = self.get_input('y')
+        if self.has_input('alpha'):
+            artist.props['alpha'] = self.get_input('alpha')
+        if self.has_input('array'):
+            artist.props['array'] = self.get_input('array')
+        if self.has_input('data'):
+            artist.props['data'] = self.get_input('data')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+
 
 class MplFigureImageProperties(MplArtistProperties):
     """None
@@ -467,41 +565,57 @@ class MplFigureImageProperties(MplArtistProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplFigureImageProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('origin'):
-            self.constructor_props['origin'] = self.getInputFromPort('origin')
-        if self.hasInputFromPort('offsetx'):
-            self.constructor_props['offsetx'] = self.getInputFromPort('offsetx')
-        if self.hasInputFromPort('offsety'):
-            self.constructor_props['offsety'] = self.getInputFromPort('offsety')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('fig'):
-            self.constructor_props['fig'] = self.getInputFromPort('fig')
-        if self.hasInputFromPort('array'):
-            self.props['array'] = self.getInputFromPort('array')
-        if self.hasInputFromPort('data'):
-            self.props['data'] = self.getInputFromPort('data')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplFigureImageProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplFigureImageProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('origin'):
+            artist.constructor_props['origin'] = self.get_input('origin')
+        if self.has_input('offsetx'):
+            artist.constructor_props['offsetx'] = self.get_input('offsetx')
+        if self.has_input('offsety'):
+            artist.constructor_props['offsety'] = self.get_input('offsety')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('fig'):
+            artist.constructor_props['fig'] = self.get_input('fig')
+        if self.has_input('array'):
+            artist.props['array'] = self.get_input('array')
+        if self.has_input('data'):
+            artist.props['data'] = self.get_input('data')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+
 
 class MplCollectionProperties(MplArtistProperties):
     """
@@ -596,73 +710,89 @@ class MplCollectionProperties(MplArtistProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplCollectionProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('transOffset'):
-            self.constructor_props['transOffset'] = self.getInputFromPort('transOffset')
-        if self.hasInputFromPort('edgecolor'):
-            self.props['edgecolor'] = self.getInputFromPort('edgecolor')
-        if self.hasInputFromPort('offset_position'):
-            self.props['offset_position'] = self.getInputFromPort('offset_position')
-        if self.hasInputFromPort('edgecolors'):
-            self.constructor_props['edgecolors'] = self.getInputFromPort('edgecolors')
-        if self.hasInputFromPort('facecolor'):
-            self.props['facecolor'] = self.getInputFromPort('facecolor')
-        if self.hasInputFromPort('linestyles'):
-            self.constructor_props['linestyles'] = self.getInputFromPort('linestyles')
-        if self.hasInputFromPort('offsetsSequence'):
-            self.props['offsets'] = self.getInputFromPort('offsetsSequence')
-        elif self.hasInputFromPort('offsetsScalar'):
-            self.props['offsets'] = self.getInputFromPort('offsetsScalar')
-        if self.hasInputFromPort('color'):
-            self.props['color'] = self.getInputFromPort('color')
-        if self.hasInputFromPort('pickradius'):
-            self.props['pickradius'] = self.getInputFromPort('pickradius')
-        if self.hasInputFromPort('antialiaseds'):
-            self.constructor_props['antialiaseds'] = self.getInputFromPort('antialiaseds')
-        if self.hasInputFromPort('linewidths'):
-            self.constructor_props['linewidths'] = self.getInputFromPort('linewidths')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('antialiasedSequence'):
-            self.props['antialiased'] = self.getInputFromPort('antialiasedSequence')
-        elif self.hasInputFromPort('antialiasedScalar'):
-            self.props['antialiased'] = self.getInputFromPort('antialiasedScalar')
-        if self.hasInputFromPort('urls'):
-            self.props['urls'] = self.getInputFromPort('urls')
-        if self.hasInputFromPort('hatch'):
-            self.props['hatch'] = self.getInputFromPort('hatch')
-        if self.hasInputFromPort('alpha'):
-            self.props['alpha'] = self.getInputFromPort('alpha')
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
-        if self.hasInputFromPort('linewidthSequence'):
-            self.props['linewidth'] = self.getInputFromPort('linewidthSequence')
-        elif self.hasInputFromPort('linewidthScalar'):
-            self.props['linewidth'] = self.getInputFromPort('linewidthScalar')
-        if self.hasInputFromPort('linestyle'):
-            self.props['linestyle'] = self.getInputFromPort('linestyle')
-        if self.hasInputFromPort('facecolors'):
-            self.constructor_props['facecolors'] = self.getInputFromPort('facecolors')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplCollectionProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('transOffset'):
+            artist.constructor_props['transOffset'] = self.get_input('transOffset')
+        if self.has_input('edgecolor'):
+            artist.props['edgecolor'] = self.get_input('edgecolor')
+        if self.has_input('offset_position'):
+            artist.props['offset_position'] = self.get_input('offset_position')
+        if self.has_input('edgecolors'):
+            artist.constructor_props['edgecolors'] = self.get_input('edgecolors')
+        if self.has_input('facecolor'):
+            artist.props['facecolor'] = self.get_input('facecolor')
+        if self.has_input('linestyles'):
+            artist.constructor_props['linestyles'] = self.get_input('linestyles')
+        if self.has_input('offsetsSequence'):
+            artist.props['offsets'] = self.get_input('offsetsSequence')
+        elif self.has_input('offsetsScalar'):
+            artist.props['offsets'] = self.get_input('offsetsScalar')
+        if self.has_input('color'):
+            artist.props['color'] = self.get_input('color')
+        if self.has_input('pickradius'):
+            artist.props['pickradius'] = self.get_input('pickradius')
+        if self.has_input('antialiaseds'):
+            artist.constructor_props['antialiaseds'] = self.get_input('antialiaseds')
+        if self.has_input('linewidths'):
+            artist.constructor_props['linewidths'] = self.get_input('linewidths')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('antialiasedSequence'):
+            artist.props['antialiased'] = self.get_input('antialiasedSequence')
+        elif self.has_input('antialiasedScalar'):
+            artist.props['antialiased'] = self.get_input('antialiasedScalar')
+        if self.has_input('urls'):
+            artist.props['urls'] = self.get_input('urls')
+        if self.has_input('hatch'):
+            artist.props['hatch'] = self.get_input('hatch')
+        if self.has_input('alpha'):
+            artist.props['alpha'] = self.get_input('alpha')
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
+        if self.has_input('linewidthSequence'):
+            artist.props['linewidth'] = self.get_input('linewidthSequence')
+        elif self.has_input('linewidthScalar'):
+            artist.props['linewidth'] = self.get_input('linewidthScalar')
+        if self.has_input('linestyle'):
+            artist.props['linestyle'] = self.get_input('linestyle')
+        if self.has_input('facecolors'):
+            artist.constructor_props['facecolors'] = self.get_input('facecolors')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+
 
 class MplPathCollectionProperties(MplCollectionProperties):
     """
@@ -676,29 +806,45 @@ class MplPathCollectionProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPathCollectionProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
-        if self.hasInputFromPort('sizes'):
-            self.constructor_props['sizes'] = self.getInputFromPort('sizes')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPathCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPathCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
+        if self.has_input('sizes'):
+            artist.constructor_props['sizes'] = self.get_input('sizes')
 
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplPolyCollectionProperties(MplCollectionProperties):
     """None
@@ -714,33 +860,49 @@ class MplPolyCollectionProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPolyCollectionProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
-        if self.hasInputFromPort('verts'):
-            self.props['verts'] = self.getInputFromPort('verts')
-        if self.hasInputFromPort('closed'):
-            self.constructor_props['closed'] = self.getInputFromPort('closed')
-        if self.hasInputFromPort('sizes'):
-            self.constructor_props['sizes'] = self.getInputFromPort('sizes')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPolyCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPolyCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
+        if self.has_input('verts'):
+            artist.props['verts'] = self.get_input('verts')
+        if self.has_input('closed'):
+            artist.constructor_props['closed'] = self.get_input('closed')
+        if self.has_input('sizes'):
+            artist.constructor_props['sizes'] = self.get_input('sizes')
+
 
 class MplBrokenBarHCollectionProperties(MplPolyCollectionProperties):
     """
@@ -755,29 +917,45 @@ class MplBrokenBarHCollectionProperties(MplPolyCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplBrokenBarHCollectionProperties)")]
-
-    def __init__(self):
-        MplPolyCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPolyCollectionProperties.compute(self)
-        if self.hasInputFromPort('xranges'):
-            self.constructor_props['xranges'] = self.getInputFromPort('xranges')
-        if self.hasInputFromPort('yrange'):
-            self.constructor_props['yrange'] = self.getInputFromPort('yrange')
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplBrokenBarHCollectionProperties)")]
+
+    class Artist(MplPolyCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPolyCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplBrokenBarHCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPolyCollectionProperties.compute(self, artist)
+        if self.has_input('xranges'):
+            artist.constructor_props['xranges'] = self.get_input('xranges')
+        if self.has_input('yrange'):
+            artist.constructor_props['yrange'] = self.get_input('yrange')
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplRegularPolyCollectionProperties(MplCollectionProperties):
     """Draw a collection of regular polygons with *numsides*.
@@ -791,31 +969,47 @@ class MplRegularPolyCollectionProperties(MplCollectionProperties):
                 {'optional': True, 'defaults': "['(1,)']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplRegularPolyCollectionProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('numsides'):
-            self.constructor_props['numsides'] = self.getInputFromPort('numsides')
-        if self.hasInputFromPort('rotation'):
-            self.constructor_props['rotation'] = self.getInputFromPort('rotation')
-        if self.hasInputFromPort('sizes'):
-            self.constructor_props['sizes'] = self.getInputFromPort('sizes')
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplRegularPolyCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplRegularPolyCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('numsides'):
+            artist.constructor_props['numsides'] = self.get_input('numsides')
+        if self.has_input('rotation'):
+            artist.constructor_props['rotation'] = self.get_input('rotation')
+        if self.has_input('sizes'):
+            artist.constructor_props['sizes'] = self.get_input('sizes')
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplStarPolygonCollectionProperties(MplRegularPolyCollectionProperties):
     """
@@ -830,31 +1024,47 @@ class MplStarPolygonCollectionProperties(MplRegularPolyCollectionProperties):
                 {'optional': True, 'defaults': "['(1,)']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplStarPolygonCollectionProperties)")]
-
-    def __init__(self):
-        MplRegularPolyCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplRegularPolyCollectionProperties.compute(self)
-        if self.hasInputFromPort('numsides'):
-            self.constructor_props['numsides'] = self.getInputFromPort('numsides')
-        if self.hasInputFromPort('rotation'):
-            self.constructor_props['rotation'] = self.getInputFromPort('rotation')
-        if self.hasInputFromPort('sizes'):
-            self.constructor_props['sizes'] = self.getInputFromPort('sizes')
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplStarPolygonCollectionProperties)")]
+
+    class Artist(MplRegularPolyCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplRegularPolyCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplStarPolygonCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplRegularPolyCollectionProperties.compute(self, artist)
+        if self.has_input('numsides'):
+            artist.constructor_props['numsides'] = self.get_input('numsides')
+        if self.has_input('rotation'):
+            artist.constructor_props['rotation'] = self.get_input('rotation')
+        if self.has_input('sizes'):
+            artist.constructor_props['sizes'] = self.get_input('sizes')
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplAsteriskPolygonCollectionProperties(MplRegularPolyCollectionProperties):
     """
@@ -869,31 +1079,47 @@ class MplAsteriskPolygonCollectionProperties(MplRegularPolyCollectionProperties)
                 {'optional': True, 'defaults': "['(1,)']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplAsteriskPolygonCollectionProperties)")]
-
-    def __init__(self):
-        MplRegularPolyCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplAsteriskPolygonCollectionProperties)")]
+
+    class Artist(MplRegularPolyCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplRegularPolyCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplAsteriskPolygonCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplRegularPolyCollectionProperties.compute(self, artist)
+        if self.has_input('numsides'):
+            artist.constructor_props['numsides'] = self.get_input('numsides')
+        if self.has_input('rotation'):
+            artist.constructor_props['rotation'] = self.get_input('rotation')
+        if self.has_input('sizes'):
+            artist.constructor_props['sizes'] = self.get_input('sizes')
 
-    def compute(self):
-        MplRegularPolyCollectionProperties.compute(self)
-        if self.hasInputFromPort('numsides'):
-            self.constructor_props['numsides'] = self.getInputFromPort('numsides')
-        if self.hasInputFromPort('rotation'):
-            self.constructor_props['rotation'] = self.getInputFromPort('rotation')
-        if self.hasInputFromPort('sizes'):
-            self.constructor_props['sizes'] = self.getInputFromPort('sizes')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplLineCollectionProperties(MplCollectionProperties):
     """
@@ -936,51 +1162,67 @@ class MplLineCollectionProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplLineCollectionProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
-        if self.hasInputFromPort('antialiaseds'):
-            self.constructor_props['antialiaseds'] = self.getInputFromPort('antialiaseds')
-        if self.hasInputFromPort('linestyles'):
-            self.constructor_props['linestyles'] = self.getInputFromPort('linestyles')
-        if self.hasInputFromPort('offsets'):
-            self.constructor_props['offsets'] = self.getInputFromPort('offsets')
-        if self.hasInputFromPort('color'):
-            self.props['color'] = self.getInputFromPort('color')
-        if self.hasInputFromPort('segments'):
-            self.props['segments'] = self.getInputFromPort('segments')
-        if self.hasInputFromPort('linewidths'):
-            self.constructor_props['linewidths'] = self.getInputFromPort('linewidths')
-        if self.hasInputFromPort('colors'):
-            self.constructor_props['colors'] = self.getInputFromPort('colors')
-        if self.hasInputFromPort('cmap'):
-            self.constructor_props['cmap'] = self.getInputFromPort('cmap')
-        if self.hasInputFromPort('transOffset'):
-            self.constructor_props['transOffset'] = self.getInputFromPort('transOffset')
-        if self.hasInputFromPort('verts'):
-            self.props['verts'] = self.getInputFromPort('verts')
-        if self.hasInputFromPort('pickradius'):
-            self.constructor_props['pickradius'] = self.getInputFromPort('pickradius')
-        if self.hasInputFromPort('norm'):
-            self.constructor_props['norm'] = self.getInputFromPort('norm')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplLineCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplLineCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
+        if self.has_input('antialiaseds'):
+            artist.constructor_props['antialiaseds'] = self.get_input('antialiaseds')
+        if self.has_input('linestyles'):
+            artist.constructor_props['linestyles'] = self.get_input('linestyles')
+        if self.has_input('offsets'):
+            artist.constructor_props['offsets'] = self.get_input('offsets')
+        if self.has_input('color'):
+            artist.props['color'] = self.get_input('color')
+        if self.has_input('segments'):
+            artist.props['segments'] = self.get_input('segments')
+        if self.has_input('linewidths'):
+            artist.constructor_props['linewidths'] = self.get_input('linewidths')
+        if self.has_input('colors'):
+            artist.constructor_props['colors'] = self.get_input('colors')
+        if self.has_input('cmap'):
+            artist.constructor_props['cmap'] = self.get_input('cmap')
+        if self.has_input('transOffset'):
+            artist.constructor_props['transOffset'] = self.get_input('transOffset')
+        if self.has_input('verts'):
+            artist.props['verts'] = self.get_input('verts')
+        if self.has_input('pickradius'):
+            artist.constructor_props['pickradius'] = self.get_input('pickradius')
+        if self.has_input('norm'):
+            artist.constructor_props['norm'] = self.get_input('norm')
+
 
 class MplCircleCollectionProperties(MplCollectionProperties):
     """
@@ -992,27 +1234,43 @@ class MplCircleCollectionProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplCircleCollectionProperties)")]
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplCircleCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
 
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
 
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('sizes'):
-            self.constructor_props['sizes'] = self.getInputFromPort('sizes')
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplCircleCollectionProperties.Artist()
+            self.set_output("value", artist)
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('sizes'):
+            artist.constructor_props['sizes'] = self.get_input('sizes')
 
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplEllipseCollectionProperties(MplCollectionProperties):
     """
@@ -1030,33 +1288,49 @@ class MplEllipseCollectionProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplEllipseCollectionProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('units'):
-            self.constructor_props['units'] = self.getInputFromPort('units')
-        if self.hasInputFromPort('widths'):
-            self.constructor_props['widths'] = self.getInputFromPort('widths')
-        if self.hasInputFromPort('angles'):
-            self.constructor_props['angles'] = self.getInputFromPort('angles')
-        if self.hasInputFromPort('heights'):
-            self.constructor_props['heights'] = self.getInputFromPort('heights')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplEllipseCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplEllipseCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('units'):
+            artist.constructor_props['units'] = self.get_input('units')
+        if self.has_input('widths'):
+            artist.constructor_props['widths'] = self.get_input('widths')
+        if self.has_input('angles'):
+            artist.constructor_props['angles'] = self.get_input('angles')
+        if self.has_input('heights'):
+            artist.constructor_props['heights'] = self.get_input('heights')
+
 
 class MplPatchCollectionProperties(MplCollectionProperties):
     """
@@ -1078,31 +1352,47 @@ class MplPatchCollectionProperties(MplCollectionProperties):
                 {'optional': True, 'defaults': "['False']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPatchCollectionProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
-        if self.hasInputFromPort('patches'):
-            self.constructor_props['patches'] = self.getInputFromPort('patches')
-        if self.hasInputFromPort('match_original'):
-            self.constructor_props['match_original'] = self.getInputFromPort('match_original')
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPatchCollectionProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPatchCollectionProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
+        if self.has_input('patches'):
+            artist.constructor_props['patches'] = self.get_input('patches')
+        if self.has_input('match_original'):
+            artist.constructor_props['match_original'] = self.get_input('match_original')
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplTriMeshProperties(MplCollectionProperties):
     """
@@ -1120,29 +1410,45 @@ class MplTriMeshProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplTriMeshProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('triangulation'):
-            self.constructor_props['triangulation'] = self.getInputFromPort('triangulation')
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplTriMeshProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplTriMeshProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('triangulation'):
+            artist.constructor_props['triangulation'] = self.get_input('triangulation')
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplQuadMeshProperties(MplCollectionProperties):
     """
@@ -1191,37 +1497,53 @@ class MplQuadMeshProperties(MplCollectionProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplQuadMeshProperties)")]
-
-    def __init__(self):
-        MplCollectionProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplCollectionProperties.compute(self)
-        if self.hasInputFromPort('paths'):
-            self.props['paths'] = self.getInputFromPort('paths')
-        if self.hasInputFromPort('meshWidth'):
-            self.constructor_props['meshWidth'] = self.getInputFromPort('meshWidth')
-        if self.hasInputFromPort('coordinates'):
-            self.constructor_props['coordinates'] = self.getInputFromPort('coordinates')
-        if self.hasInputFromPort('antialiased'):
-            self.constructor_props['antialiased'] = self.getInputFromPort('antialiased')
-        if self.hasInputFromPort('shading'):
-            self.constructor_props['shading'] = self.getInputFromPort('shading')
-        if self.hasInputFromPort('meshHeight'):
-            self.constructor_props['meshHeight'] = self.getInputFromPort('meshHeight')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplQuadMeshProperties)")]
+
+    class Artist(MplCollectionProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplCollectionProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplQuadMeshProperties.Artist()
+            self.set_output("value", artist)
+
+        MplCollectionProperties.compute(self, artist)
+        if self.has_input('paths'):
+            artist.props['paths'] = self.get_input('paths')
+        if self.has_input('meshWidth'):
+            artist.constructor_props['meshWidth'] = self.get_input('meshWidth')
+        if self.has_input('coordinates'):
+            artist.constructor_props['coordinates'] = self.get_input('coordinates')
+        if self.has_input('antialiased'):
+            artist.constructor_props['antialiased'] = self.get_input('antialiased')
+        if self.has_input('shading'):
+            artist.constructor_props['shading'] = self.get_input('shading')
+        if self.has_input('meshHeight'):
+            artist.constructor_props['meshHeight'] = self.get_input('meshHeight')
+
 
 class MplPatchProperties(MplArtistProperties):
     """
@@ -1254,48 +1576,64 @@ class MplPatchProperties(MplArtistProperties):
                 {'optional': True, 'docstring': 'Set whether to fill the patch'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPatchProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('edgecolor'):
-            self.props['edgecolor'] = self.getInputFromPort('edgecolor')
-            self.props['edgecolor'] = translate_color(self.props['edgecolor'])
-        if self.hasInputFromPort('facecolor'):
-            self.props['facecolor'] = self.getInputFromPort('facecolor')
-            self.props['facecolor'] = translate_color(self.props['facecolor'])
-        if self.hasInputFromPort('path_effects'):
-            self.props['path_effects'] = self.getInputFromPort('path_effects')
-        if self.hasInputFromPort('color'):
-            self.props['color'] = self.getInputFromPort('color')
-            self.props['color'] = translate_color(self.props['color'])
-        if self.hasInputFromPort('antialiased'):
-            self.props['antialiased'] = self.getInputFromPort('antialiased')
-        if self.hasInputFromPort('hatch'):
-            self.props['hatch'] = self.getInputFromPort('hatch')
-        if self.hasInputFromPort('alpha'):
-            self.props['alpha'] = self.getInputFromPort('alpha')
-        if self.hasInputFromPort('linewidth'):
-            self.props['linewidth'] = self.getInputFromPort('linewidth')
-        if self.hasInputFromPort('linestyle'):
-            self.props['linestyle'] = self.getInputFromPort('linestyle')
-        if self.hasInputFromPort('fill'):
-            self.props['fill'] = self.getInputFromPort('fill')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPatchProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPatchProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('edgecolor'):
+            artist.props['edgecolor'] = self.get_input('edgecolor')
+            artist.props['edgecolor'] = translate_color(artist.props['edgecolor'])
+        if self.has_input('facecolor'):
+            artist.props['facecolor'] = self.get_input('facecolor')
+            artist.props['facecolor'] = translate_color(artist.props['facecolor'])
+        if self.has_input('path_effects'):
+            artist.props['path_effects'] = self.get_input('path_effects')
+        if self.has_input('color'):
+            artist.props['color'] = self.get_input('color')
+            artist.props['color'] = translate_color(artist.props['color'])
+        if self.has_input('antialiased'):
+            artist.props['antialiased'] = self.get_input('antialiased')
+        if self.has_input('hatch'):
+            artist.props['hatch'] = self.get_input('hatch')
+        if self.has_input('alpha'):
+            artist.props['alpha'] = self.get_input('alpha')
+        if self.has_input('linewidth'):
+            artist.props['linewidth'] = self.get_input('linewidth')
+        if self.has_input('linestyle'):
+            artist.props['linestyle'] = self.get_input('linestyle')
+        if self.has_input('fill'):
+            artist.props['fill'] = self.get_input('fill')
+
 
 class MplShadowProperties(MplPatchProperties):
     """None
@@ -1311,33 +1649,49 @@ class MplShadowProperties(MplPatchProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplShadowProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('patch'):
-            self.constructor_props['patch'] = self.getInputFromPort('patch')
-        if self.hasInputFromPort('props'):
-            self.constructor_props['props'] = self.getInputFromPort('props')
-        if self.hasInputFromPort('oy'):
-            self.constructor_props['oy'] = self.getInputFromPort('oy')
-        if self.hasInputFromPort('ox'):
-            self.constructor_props['ox'] = self.getInputFromPort('ox')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplShadowProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplShadowProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('patch'):
+            artist.constructor_props['patch'] = self.get_input('patch')
+        if self.has_input('props'):
+            artist.constructor_props['props'] = self.get_input('props')
+        if self.has_input('oy'):
+            artist.constructor_props['oy'] = self.get_input('oy')
+        if self.has_input('ox'):
+            artist.constructor_props['ox'] = self.get_input('ox')
+
 
 class MplRectangleProperties(MplPatchProperties):
     """
@@ -1360,37 +1714,53 @@ class MplRectangleProperties(MplPatchProperties):
                 {'optional': True, 'docstring': 'Set the left coord of the rectangle'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplRectangleProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('bounds'):
-            self.props['bounds'] = self.getInputFromPort('bounds')
-        if self.hasInputFromPort('height'):
-            self.props['height'] = self.getInputFromPort('height')
-        if self.hasInputFromPort('width'):
-            self.props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('xy'):
-            self.props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('y'):
-            self.props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('x'):
-            self.props['x'] = self.getInputFromPort('x')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplRectangleProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplRectangleProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('bounds'):
+            artist.props['bounds'] = self.get_input('bounds')
+        if self.has_input('height'):
+            artist.props['height'] = self.get_input('height')
+        if self.has_input('width'):
+            artist.props['width'] = self.get_input('width')
+        if self.has_input('xy'):
+            artist.props['xy'] = self.get_input('xy')
+        if self.has_input('y'):
+            artist.props['y'] = self.get_input('y')
+        if self.has_input('x'):
+            artist.props['x'] = self.get_input('x')
+
 
 class MplRegularPolygonProperties(MplPatchProperties):
     """
@@ -1408,33 +1778,49 @@ class MplRegularPolygonProperties(MplPatchProperties):
                 {'optional': True, 'docstring': 'the number of vertices.'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplRegularPolygonProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('radius'):
-            self.constructor_props['radius'] = self.getInputFromPort('radius')
-        if self.hasInputFromPort('orientation'):
-            self.constructor_props['orientation'] = self.getInputFromPort('orientation')
-        if self.hasInputFromPort('numVertices'):
-            self.constructor_props['numVertices'] = self.getInputFromPort('numVertices')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplRegularPolygonProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplRegularPolygonProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+        if self.has_input('radius'):
+            artist.constructor_props['radius'] = self.get_input('radius')
+        if self.has_input('orientation'):
+            artist.constructor_props['orientation'] = self.get_input('orientation')
+        if self.has_input('numVertices'):
+            artist.constructor_props['numVertices'] = self.get_input('numVertices')
+
 
 class MplCirclePolygonProperties(MplRegularPolygonProperties):
     """
@@ -1450,31 +1836,47 @@ class MplCirclePolygonProperties(MplRegularPolygonProperties):
                 {'optional': True, 'defaults': "['20']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplCirclePolygonProperties)")]
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplCirclePolygonProperties)")]
+
+    class Artist(MplRegularPolygonProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplRegularPolygonProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplCirclePolygonProperties.Artist()
+            self.set_output("value", artist)
+
+        MplRegularPolygonProperties.compute(self, artist)
+        if self.has_input('radius'):
+            artist.constructor_props['radius'] = self.get_input('radius')
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+        if self.has_input('resolution'):
+            artist.constructor_props['resolution'] = self.get_input('resolution')
 
-    def __init__(self):
-        MplRegularPolygonProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplRegularPolygonProperties.compute(self)
-        if self.hasInputFromPort('radius'):
-            self.constructor_props['radius'] = self.getInputFromPort('radius')
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('resolution'):
-            self.constructor_props['resolution'] = self.getInputFromPort('resolution')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplPathPatchProperties(MplPatchProperties):
     """
@@ -1486,27 +1888,43 @@ class MplPathPatchProperties(MplPatchProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPathPatchProperties)")]
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPathPatchProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
 
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
 
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('path'):
-            self.constructor_props['path'] = self.getInputFromPort('path')
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPathPatchProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('path'):
+            artist.constructor_props['path'] = self.get_input('path')
 
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplPolygonProperties(MplPatchProperties):
     """
@@ -1520,29 +1938,45 @@ class MplPolygonProperties(MplPatchProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplPolygonProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('xy'):
-            self.props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('closed'):
-            self.props['closed'] = self.getInputFromPort('closed')
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplPolygonProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplPolygonProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('xy'):
+            artist.props['xy'] = self.get_input('xy')
+        if self.has_input('closed'):
+            artist.props['closed'] = self.get_input('closed')
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplFancyArrowProperties(MplPolygonProperties):
     """
@@ -1574,47 +2008,63 @@ class MplFancyArrowProperties(MplPolygonProperties):
                 {'optional': True, 'defaults': "['0']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplFancyArrowProperties)")]
-
-    def __init__(self):
-        MplPolygonProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPolygonProperties.compute(self)
-        if self.hasInputFromPort('length_includes_head'):
-            self.constructor_props['length_includes_head'] = self.getInputFromPort('length_includes_head')
-        if self.hasInputFromPort('head_length'):
-            self.constructor_props['head_length'] = self.getInputFromPort('head_length')
-        if self.hasInputFromPort('head_width'):
-            self.constructor_props['head_width'] = self.getInputFromPort('head_width')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('shape'):
-            self.constructor_props['shape'] = self.getInputFromPort('shape')
-        if self.hasInputFromPort('dx'):
-            self.constructor_props['dx'] = self.getInputFromPort('dx')
-        if self.hasInputFromPort('dy'):
-            self.constructor_props['dy'] = self.getInputFromPort('dy')
-        if self.hasInputFromPort('y'):
-            self.constructor_props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('x'):
-            self.constructor_props['x'] = self.getInputFromPort('x')
-        if self.hasInputFromPort('head_starts_at_zero'):
-            self.constructor_props['head_starts_at_zero'] = self.getInputFromPort('head_starts_at_zero')
-        if self.hasInputFromPort('overhang'):
-            self.constructor_props['overhang'] = self.getInputFromPort('overhang')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplFancyArrowProperties)")]
+
+    class Artist(MplPolygonProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPolygonProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplFancyArrowProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPolygonProperties.compute(self, artist)
+        if self.has_input('length_includes_head'):
+            artist.constructor_props['length_includes_head'] = self.get_input('length_includes_head')
+        if self.has_input('head_length'):
+            artist.constructor_props['head_length'] = self.get_input('head_length')
+        if self.has_input('head_width'):
+            artist.constructor_props['head_width'] = self.get_input('head_width')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('shape'):
+            artist.constructor_props['shape'] = self.get_input('shape')
+        if self.has_input('dx'):
+            artist.constructor_props['dx'] = self.get_input('dx')
+        if self.has_input('dy'):
+            artist.constructor_props['dy'] = self.get_input('dy')
+        if self.has_input('y'):
+            artist.constructor_props['y'] = self.get_input('y')
+        if self.has_input('x'):
+            artist.constructor_props['x'] = self.get_input('x')
+        if self.has_input('head_starts_at_zero'):
+            artist.constructor_props['head_starts_at_zero'] = self.get_input('head_starts_at_zero')
+        if self.has_input('overhang'):
+            artist.constructor_props['overhang'] = self.get_input('overhang')
+
 
 class MplWedgeProperties(MplPatchProperties):
     """
@@ -1634,35 +2084,51 @@ class MplWedgeProperties(MplPatchProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplWedgeProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('theta2'):
-            self.constructor_props['theta2'] = self.getInputFromPort('theta2')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('r'):
-            self.constructor_props['r'] = self.getInputFromPort('r')
-        if self.hasInputFromPort('theta1'):
-            self.constructor_props['theta1'] = self.getInputFromPort('theta1')
-        if self.hasInputFromPort('center'):
-            self.constructor_props['center'] = self.getInputFromPort('center')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplWedgeProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplWedgeProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('theta2'):
+            artist.constructor_props['theta2'] = self.get_input('theta2')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('r'):
+            artist.constructor_props['r'] = self.get_input('r')
+        if self.has_input('theta1'):
+            artist.constructor_props['theta1'] = self.get_input('theta1')
+        if self.has_input('center'):
+            artist.constructor_props['center'] = self.get_input('center')
+
 
 class MplArrowProperties(MplPatchProperties):
     """
@@ -1682,35 +2148,51 @@ class MplArrowProperties(MplPatchProperties):
                 {'optional': True, 'defaults': "['1.0']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplArrowProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('y'):
-            self.constructor_props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('x'):
-            self.constructor_props['x'] = self.getInputFromPort('x')
-        if self.hasInputFromPort('dy'):
-            self.constructor_props['dy'] = self.getInputFromPort('dy')
-        if self.hasInputFromPort('dx'):
-            self.constructor_props['dx'] = self.getInputFromPort('dx')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplArrowProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplArrowProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('y'):
+            artist.constructor_props['y'] = self.get_input('y')
+        if self.has_input('x'):
+            artist.constructor_props['x'] = self.get_input('x')
+        if self.has_input('dy'):
+            artist.constructor_props['dy'] = self.get_input('dy')
+        if self.has_input('dx'):
+            artist.constructor_props['dx'] = self.get_input('dx')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+
 
 class MplYAArrowProperties(MplPatchProperties):
     """
@@ -1735,37 +2217,53 @@ class MplYAArrowProperties(MplPatchProperties):
                 {'optional': True, 'docstring': 'The width of the arrow in points', 'defaults': "['4']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplYAArrowProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('xytip'):
-            self.constructor_props['xytip'] = self.getInputFromPort('xytip')
-        if self.hasInputFromPort('headwidth'):
-            self.constructor_props['headwidth'] = self.getInputFromPort('headwidth')
-        if self.hasInputFromPort('frac'):
-            self.constructor_props['frac'] = self.getInputFromPort('frac')
-        if self.hasInputFromPort('figure'):
-            self.constructor_props['figure'] = self.getInputFromPort('figure')
-        if self.hasInputFromPort('xybase'):
-            self.constructor_props['xybase'] = self.getInputFromPort('xybase')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplYAArrowProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplYAArrowProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('xytip'):
+            artist.constructor_props['xytip'] = self.get_input('xytip')
+        if self.has_input('headwidth'):
+            artist.constructor_props['headwidth'] = self.get_input('headwidth')
+        if self.has_input('frac'):
+            artist.constructor_props['frac'] = self.get_input('frac')
+        if self.has_input('figure'):
+            artist.constructor_props['figure'] = self.get_input('figure')
+        if self.has_input('xybase'):
+            artist.constructor_props['xybase'] = self.get_input('xybase')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+
 
 class MplEllipseProperties(MplPatchProperties):
     """
@@ -1783,33 +2281,49 @@ class MplEllipseProperties(MplPatchProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplEllipseProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('angle'):
-            self.constructor_props['angle'] = self.getInputFromPort('angle')
-        if self.hasInputFromPort('height'):
-            self.constructor_props['height'] = self.getInputFromPort('height')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplEllipseProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplEllipseProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+        if self.has_input('angle'):
+            artist.constructor_props['angle'] = self.get_input('angle')
+        if self.has_input('height'):
+            artist.constructor_props['height'] = self.get_input('height')
+
 
 class MplCircleProperties(MplEllipseProperties):
     """
@@ -1823,29 +2337,45 @@ class MplCircleProperties(MplEllipseProperties):
                 {'optional': True, 'docstring': 'Set the radius of the circle'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplCircleProperties)")]
-
-    def __init__(self):
-        MplEllipseProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplEllipseProperties.compute(self)
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('radius'):
-            self.props['radius'] = self.getInputFromPort('radius')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplCircleProperties)")]
+
+    class Artist(MplEllipseProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplEllipseProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplCircleProperties.Artist()
+            self.set_output("value", artist)
+
+        MplEllipseProperties.compute(self, artist)
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+        if self.has_input('radius'):
+            artist.props['radius'] = self.get_input('radius')
 
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplArcProperties(MplEllipseProperties):
     """
@@ -1874,37 +2404,53 @@ class MplArcProperties(MplEllipseProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplArcProperties)")]
-
-    def __init__(self):
-        MplEllipseProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplEllipseProperties.compute(self)
-        if self.hasInputFromPort('theta2'):
-            self.constructor_props['theta2'] = self.getInputFromPort('theta2')
-        if self.hasInputFromPort('theta1'):
-            self.constructor_props['theta1'] = self.getInputFromPort('theta1')
-        if self.hasInputFromPort('angle'):
-            self.constructor_props['angle'] = self.getInputFromPort('angle')
-        if self.hasInputFromPort('height'):
-            self.constructor_props['height'] = self.getInputFromPort('height')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplArcProperties)")]
+
+    class Artist(MplEllipseProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplEllipseProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplArcProperties.Artist()
+            self.set_output("value", artist)
+
+        MplEllipseProperties.compute(self, artist)
+        if self.has_input('theta2'):
+            artist.constructor_props['theta2'] = self.get_input('theta2')
+        if self.has_input('theta1'):
+            artist.constructor_props['theta1'] = self.get_input('theta1')
+        if self.has_input('angle'):
+            artist.constructor_props['angle'] = self.get_input('angle')
+        if self.has_input('height'):
+            artist.constructor_props['height'] = self.get_input('height')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+
 
 class MplFancyBboxPatchProperties(MplPatchProperties):
     """
@@ -1941,45 +2487,61 @@ class MplFancyBboxPatchProperties(MplPatchProperties):
                 {'optional': True, 'docstring': 'Set the left coord of the rectangle'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplFancyBboxPatchProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('mutation_scale'):
-            self.props['mutation_scale'] = self.getInputFromPort('mutation_scale')
-        if self.hasInputFromPort('bbox_transmuter'):
-            self.constructor_props['bbox_transmuter'] = self.getInputFromPort('bbox_transmuter')
-        if self.hasInputFromPort('bounds'):
-            self.props['bounds'] = self.getInputFromPort('bounds')
-        if self.hasInputFromPort('height'):
-            self.props['height'] = self.getInputFromPort('height')
-        if self.hasInputFromPort('width'):
-            self.props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('boxstyle'):
-            self.props['boxstyle'] = self.getInputFromPort('boxstyle')
-        if self.hasInputFromPort('mutation_aspect'):
-            self.props['mutation_aspect'] = self.getInputFromPort('mutation_aspect')
-        if self.hasInputFromPort('y'):
-            self.props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('x'):
-            self.props['x'] = self.getInputFromPort('x')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplFancyBboxPatchProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplFancyBboxPatchProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('mutation_scale'):
+            artist.props['mutation_scale'] = self.get_input('mutation_scale')
+        if self.has_input('bbox_transmuter'):
+            artist.constructor_props['bbox_transmuter'] = self.get_input('bbox_transmuter')
+        if self.has_input('bounds'):
+            artist.props['bounds'] = self.get_input('bounds')
+        if self.has_input('height'):
+            artist.props['height'] = self.get_input('height')
+        if self.has_input('width'):
+            artist.props['width'] = self.get_input('width')
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+        if self.has_input('boxstyle'):
+            artist.props['boxstyle'] = self.get_input('boxstyle')
+        if self.has_input('mutation_aspect'):
+            artist.props['mutation_aspect'] = self.get_input('mutation_aspect')
+        if self.has_input('y'):
+            artist.props['y'] = self.get_input('y')
+        if self.has_input('x'):
+            artist.props['x'] = self.get_input('x')
+
 
 class MplFancyArrowPatchProperties(MplPatchProperties):
     """
@@ -2019,55 +2581,71 @@ class MplFancyArrowPatchProperties(MplPatchProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplFancyArrowPatchProperties)")]
-
-    def __init__(self):
-        MplPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplPatchProperties.compute(self)
-        if self.hasInputFromPort('connectionstyle'):
-            self.props['connectionstyle'] = self.getInputFromPort('connectionstyle')
-        if self.hasInputFromPort('mutation_scale'):
-            self.props['mutation_scale'] = self.getInputFromPort('mutation_scale')
-        if self.hasInputFromPort('arrowstyle'):
-            self.props['arrowstyle'] = self.getInputFromPort('arrowstyle')
-        if self.hasInputFromPort('arrow_transmuter'):
-            self.constructor_props['arrow_transmuter'] = self.getInputFromPort('arrow_transmuter')
-        if self.hasInputFromPort('positions'):
-            self.props['positions'] = self.getInputFromPort('positions')
-        if self.hasInputFromPort('shrinkA'):
-            self.constructor_props['shrinkA'] = self.getInputFromPort('shrinkA')
-        if self.hasInputFromPort('posB'):
-            self.constructor_props['posB'] = self.getInputFromPort('posB')
-        if self.hasInputFromPort('dpi_cor'):
-            self.props['dpi_cor'] = self.getInputFromPort('dpi_cor')
-        if self.hasInputFromPort('connector'):
-            self.constructor_props['connector'] = self.getInputFromPort('connector')
-        if self.hasInputFromPort('path'):
-            self.constructor_props['path'] = self.getInputFromPort('path')
-        if self.hasInputFromPort('shrinkB'):
-            self.constructor_props['shrinkB'] = self.getInputFromPort('shrinkB')
-        if self.hasInputFromPort('mutation_aspect'):
-            self.props['mutation_aspect'] = self.getInputFromPort('mutation_aspect')
-        if self.hasInputFromPort('patchA'):
-            self.props['patchA'] = self.getInputFromPort('patchA')
-        if self.hasInputFromPort('patchB'):
-            self.props['patchB'] = self.getInputFromPort('patchB')
-        if self.hasInputFromPort('posA'):
-            self.constructor_props['posA'] = self.getInputFromPort('posA')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplFancyArrowPatchProperties)")]
+
+    class Artist(MplPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplFancyArrowPatchProperties.Artist()
+            self.set_output("value", artist)
+
+        MplPatchProperties.compute(self, artist)
+        if self.has_input('connectionstyle'):
+            artist.props['connectionstyle'] = self.get_input('connectionstyle')
+        if self.has_input('mutation_scale'):
+            artist.props['mutation_scale'] = self.get_input('mutation_scale')
+        if self.has_input('arrowstyle'):
+            artist.props['arrowstyle'] = self.get_input('arrowstyle')
+        if self.has_input('arrow_transmuter'):
+            artist.constructor_props['arrow_transmuter'] = self.get_input('arrow_transmuter')
+        if self.has_input('positions'):
+            artist.props['positions'] = self.get_input('positions')
+        if self.has_input('shrinkA'):
+            artist.constructor_props['shrinkA'] = self.get_input('shrinkA')
+        if self.has_input('posB'):
+            artist.constructor_props['posB'] = self.get_input('posB')
+        if self.has_input('dpi_cor'):
+            artist.props['dpi_cor'] = self.get_input('dpi_cor')
+        if self.has_input('connector'):
+            artist.constructor_props['connector'] = self.get_input('connector')
+        if self.has_input('path'):
+            artist.constructor_props['path'] = self.get_input('path')
+        if self.has_input('shrinkB'):
+            artist.constructor_props['shrinkB'] = self.get_input('shrinkB')
+        if self.has_input('mutation_aspect'):
+            artist.props['mutation_aspect'] = self.get_input('mutation_aspect')
+        if self.has_input('patchA'):
+            artist.props['patchA'] = self.get_input('patchA')
+        if self.has_input('patchB'):
+            artist.props['patchB'] = self.get_input('patchB')
+        if self.has_input('posA'):
+            artist.constructor_props['posA'] = self.get_input('posA')
+
 
 class MplConnectionPatchProperties(MplFancyArrowPatchProperties):
     """
@@ -2120,67 +2698,83 @@ class MplConnectionPatchProperties(MplFancyArrowPatchProperties):
                 {'optional': True, 'docstring': 'any key for :class:`matplotlib.patches.PathPatch`'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplConnectionPatchProperties)")]
-
-    def __init__(self):
-        MplFancyArrowPatchProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplFancyArrowPatchProperties.compute(self)
-        if self.hasInputFromPort('connectionstyle'):
-            self.constructor_props['connectionstyle'] = self.getInputFromPort('connectionstyle')
-        if self.hasInputFromPort('coordsA'):
-            self.constructor_props['coordsA'] = self.getInputFromPort('coordsA')
-        if self.hasInputFromPort('arrowstyle'):
-            self.constructor_props['arrowstyle'] = self.getInputFromPort('arrowstyle')
-        if self.hasInputFromPort('clip_on'):
-            self.constructor_props['clip_on'] = self.getInputFromPort('clip_on')
-        if self.hasInputFromPort('arrow_transmuter'):
-            self.constructor_props['arrow_transmuter'] = self.getInputFromPort('arrow_transmuter')
-        if self.hasInputFromPort('axesA'):
-            self.constructor_props['axesA'] = self.getInputFromPort('axesA')
-        if self.hasInputFromPort('axesB'):
-            self.constructor_props['axesB'] = self.getInputFromPort('axesB')
-        if self.hasInputFromPort('annotation_clip'):
-            self.props['annotation_clip'] = self.getInputFromPort('annotation_clip')
-        if self.hasInputFromPort('dpi_cor'):
-            self.constructor_props['dpi_cor'] = self.getInputFromPort('dpi_cor')
-        if self.hasInputFromPort('connector'):
-            self.constructor_props['connector'] = self.getInputFromPort('connector')
-        if self.hasInputFromPort('xyA'):
-            self.constructor_props['xyA'] = self.getInputFromPort('xyA')
-        if self.hasInputFromPort('xyB'):
-            self.constructor_props['xyB'] = self.getInputFromPort('xyB')
-        if self.hasInputFromPort('relpos'):
-            self.constructor_props['relpos'] = self.getInputFromPort('relpos')
-        if self.hasInputFromPort('shrinkB'):
-            self.constructor_props['shrinkB'] = self.getInputFromPort('shrinkB')
-        if self.hasInputFromPort('shrinkA'):
-            self.constructor_props['shrinkA'] = self.getInputFromPort('shrinkA')
-        if self.hasInputFromPort('mutation_aspect'):
-            self.constructor_props['mutation_aspect'] = self.getInputFromPort('mutation_aspect')
-        if self.hasInputFromPort('mutation_scale'):
-            self.constructor_props['mutation_scale'] = self.getInputFromPort('mutation_scale')
-        if self.hasInputFromPort('patchA'):
-            self.constructor_props['patchA'] = self.getInputFromPort('patchA')
-        if self.hasInputFromPort('patchB'):
-            self.constructor_props['patchB'] = self.getInputFromPort('patchB')
-        if self.hasInputFromPort('coordsB'):
-            self.constructor_props['coordsB'] = self.getInputFromPort('coordsB')
-        if self.hasInputFromPort('?'):
-            self.constructor_props['?'] = self.getInputFromPort('?')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplConnectionPatchProperties)")]
+
+    class Artist(MplFancyArrowPatchProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplFancyArrowPatchProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplConnectionPatchProperties.Artist()
+            self.set_output("value", artist)
+
+        MplFancyArrowPatchProperties.compute(self, artist)
+        if self.has_input('connectionstyle'):
+            artist.constructor_props['connectionstyle'] = self.get_input('connectionstyle')
+        if self.has_input('coordsA'):
+            artist.constructor_props['coordsA'] = self.get_input('coordsA')
+        if self.has_input('arrowstyle'):
+            artist.constructor_props['arrowstyle'] = self.get_input('arrowstyle')
+        if self.has_input('clip_on'):
+            artist.constructor_props['clip_on'] = self.get_input('clip_on')
+        if self.has_input('arrow_transmuter'):
+            artist.constructor_props['arrow_transmuter'] = self.get_input('arrow_transmuter')
+        if self.has_input('axesA'):
+            artist.constructor_props['axesA'] = self.get_input('axesA')
+        if self.has_input('axesB'):
+            artist.constructor_props['axesB'] = self.get_input('axesB')
+        if self.has_input('annotation_clip'):
+            artist.props['annotation_clip'] = self.get_input('annotation_clip')
+        if self.has_input('dpi_cor'):
+            artist.constructor_props['dpi_cor'] = self.get_input('dpi_cor')
+        if self.has_input('connector'):
+            artist.constructor_props['connector'] = self.get_input('connector')
+        if self.has_input('xyA'):
+            artist.constructor_props['xyA'] = self.get_input('xyA')
+        if self.has_input('xyB'):
+            artist.constructor_props['xyB'] = self.get_input('xyB')
+        if self.has_input('relpos'):
+            artist.constructor_props['relpos'] = self.get_input('relpos')
+        if self.has_input('shrinkB'):
+            artist.constructor_props['shrinkB'] = self.get_input('shrinkB')
+        if self.has_input('shrinkA'):
+            artist.constructor_props['shrinkA'] = self.get_input('shrinkA')
+        if self.has_input('mutation_aspect'):
+            artist.constructor_props['mutation_aspect'] = self.get_input('mutation_aspect')
+        if self.has_input('mutation_scale'):
+            artist.constructor_props['mutation_scale'] = self.get_input('mutation_scale')
+        if self.has_input('patchA'):
+            artist.constructor_props['patchA'] = self.get_input('patchA')
+        if self.has_input('patchB'):
+            artist.constructor_props['patchB'] = self.get_input('patchB')
+        if self.has_input('coordsB'):
+            artist.constructor_props['coordsB'] = self.get_input('coordsB')
+        if self.has_input('?'):
+            artist.constructor_props['?'] = self.get_input('?')
+
 
 class MplLine2DProperties(MplArtistProperties):
     """
@@ -2245,81 +2839,97 @@ class MplLine2DProperties(MplArtistProperties):
                 {'optional': True, 'docstring': 'Set the data np.array for y'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplLine2DProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('picker'):
-            self.props['picker'] = self.getInputFromPort('picker')
-        if self.hasInputFromPort('dash_capstyle'):
-            self.props['dash_capstyle'] = self.getInputFromPort('dash_capstyle')
-        if self.hasInputFromPort('color'):
-            self.props['color'] = self.getInputFromPort('color')
-            self.props['color'] = translate_color(self.props['color'])
-        if self.hasInputFromPort('markevery'):
-            self.props['markevery'] = self.getInputFromPort('markevery')
-        if self.hasInputFromPort('markeredgecolor'):
-            self.props['markeredgecolor'] = self.getInputFromPort('markeredgecolor')
-            self.props['markeredgecolor'] = translate_color(self.props['markeredgecolor'])
-        if self.hasInputFromPort('marker'):
-            self.props['marker'] = self.getInputFromPort('marker')
-            self.props['marker'] = translate_MplLine2DProperties_marker(self.props['marker'])
-        if self.hasInputFromPort('markerfacecoloralt'):
-            self.props['markerfacecoloralt'] = self.getInputFromPort('markerfacecoloralt')
-            self.props['markerfacecoloralt'] = translate_color(self.props['markerfacecoloralt'])
-        if self.hasInputFromPort('linewidth'):
-            self.props['linewidth'] = self.getInputFromPort('linewidth')
-        if self.hasInputFromPort('linestyle'):
-            self.props['linestyle'] = self.getInputFromPort('linestyle')
-            self.props['linestyle'] = translate_MplLine2DProperties_linestyle(self.props['linestyle'])
-        if self.hasInputFromPort('solid_joinstyle'):
-            self.props['solid_joinstyle'] = self.getInputFromPort('solid_joinstyle')
-        if self.hasInputFromPort('markerfacecolor'):
-            self.props['markerfacecolor'] = self.getInputFromPort('markerfacecolor')
-            self.props['markerfacecolor'] = translate_color(self.props['markerfacecolor'])
-        if self.hasInputFromPort('axes'):
-            self.props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('transform'):
-            self.props['transform'] = self.getInputFromPort('transform')
-        if self.hasInputFromPort('fillstyle'):
-            self.props['fillstyle'] = self.getInputFromPort('fillstyle')
-        if self.hasInputFromPort('markeredgewidth'):
-            self.props['markeredgewidth'] = self.getInputFromPort('markeredgewidth')
-        if self.hasInputFromPort('solid_capstyle'):
-            self.props['solid_capstyle'] = self.getInputFromPort('solid_capstyle')
-        if self.hasInputFromPort('dashes'):
-            self.props['dashes'] = self.getInputFromPort('dashes')
-        if self.hasInputFromPort('markersize'):
-            self.props['markersize'] = self.getInputFromPort('markersize')
-        if self.hasInputFromPort('antialiased'):
-            self.props['antialiased'] = self.getInputFromPort('antialiased')
-        if self.hasInputFromPort('xdata'):
-            self.props['xdata'] = self.getInputFromPort('xdata')
-        if self.hasInputFromPort('drawstyle'):
-            self.props['drawstyle'] = self.getInputFromPort('drawstyle')
-        if self.hasInputFromPort('data'):
-            self.props['data'] = self.getInputFromPort('data')
-        if self.hasInputFromPort('dash_joinstyle'):
-            self.props['dash_joinstyle'] = self.getInputFromPort('dash_joinstyle')
-        if self.hasInputFromPort('pickradius'):
-            self.props['pickradius'] = self.getInputFromPort('pickradius')
-        if self.hasInputFromPort('ydata'):
-            self.props['ydata'] = self.getInputFromPort('ydata')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplLine2DProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplLine2DProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('picker'):
+            artist.props['picker'] = self.get_input('picker')
+        if self.has_input('dash_capstyle'):
+            artist.props['dash_capstyle'] = self.get_input('dash_capstyle')
+        if self.has_input('color'):
+            artist.props['color'] = self.get_input('color')
+            artist.props['color'] = translate_color(artist.props['color'])
+        if self.has_input('markevery'):
+            artist.props['markevery'] = self.get_input('markevery')
+        if self.has_input('markeredgecolor'):
+            artist.props['markeredgecolor'] = self.get_input('markeredgecolor')
+            artist.props['markeredgecolor'] = translate_color(artist.props['markeredgecolor'])
+        if self.has_input('marker'):
+            artist.props['marker'] = self.get_input('marker')
+            artist.props['marker'] = translate_MplLine2DProperties_marker(artist.props['marker'])
+        if self.has_input('markerfacecoloralt'):
+            artist.props['markerfacecoloralt'] = self.get_input('markerfacecoloralt')
+            artist.props['markerfacecoloralt'] = translate_color(artist.props['markerfacecoloralt'])
+        if self.has_input('linewidth'):
+            artist.props['linewidth'] = self.get_input('linewidth')
+        if self.has_input('linestyle'):
+            artist.props['linestyle'] = self.get_input('linestyle')
+            artist.props['linestyle'] = translate_MplLine2DProperties_linestyle(artist.props['linestyle'])
+        if self.has_input('solid_joinstyle'):
+            artist.props['solid_joinstyle'] = self.get_input('solid_joinstyle')
+        if self.has_input('markerfacecolor'):
+            artist.props['markerfacecolor'] = self.get_input('markerfacecolor')
+            artist.props['markerfacecolor'] = translate_color(artist.props['markerfacecolor'])
+        if self.has_input('axes'):
+            artist.props['axes'] = self.get_input('axes')
+        if self.has_input('transform'):
+            artist.props['transform'] = self.get_input('transform')
+        if self.has_input('fillstyle'):
+            artist.props['fillstyle'] = self.get_input('fillstyle')
+        if self.has_input('markeredgewidth'):
+            artist.props['markeredgewidth'] = self.get_input('markeredgewidth')
+        if self.has_input('solid_capstyle'):
+            artist.props['solid_capstyle'] = self.get_input('solid_capstyle')
+        if self.has_input('dashes'):
+            artist.props['dashes'] = self.get_input('dashes')
+        if self.has_input('markersize'):
+            artist.props['markersize'] = self.get_input('markersize')
+        if self.has_input('antialiased'):
+            artist.props['antialiased'] = self.get_input('antialiased')
+        if self.has_input('xdata'):
+            artist.props['xdata'] = self.get_input('xdata')
+        if self.has_input('drawstyle'):
+            artist.props['drawstyle'] = self.get_input('drawstyle')
+        if self.has_input('data'):
+            artist.props['data'] = self.get_input('data')
+        if self.has_input('dash_joinstyle'):
+            artist.props['dash_joinstyle'] = self.get_input('dash_joinstyle')
+        if self.has_input('pickradius'):
+            artist.props['pickradius'] = self.get_input('pickradius')
+        if self.has_input('ydata'):
+            artist.props['ydata'] = self.get_input('ydata')
+
 
 class MplTextProperties(MplArtistProperties):
     """
@@ -2371,69 +2981,85 @@ class MplTextProperties(MplArtistProperties):
                 {'entry_types': "['enum']", 'docstring': 'Set the font size.  May be either a size string, relative to the default font size, or an absolute font size in points.', 'values': "[['size in points', 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large']]", 'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplTextProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('rotation_mode'):
-            self.props['rotation_mode'] = self.getInputFromPort('rotation_mode')
-        if self.hasInputFromPort('style'):
-            self.props['style'] = self.getInputFromPort('style')
-        if self.hasInputFromPort('linespacing'):
-            self.props['linespacing'] = self.getInputFromPort('linespacing')
-        if self.hasInputFromPort('family'):
-            self.props['family'] = self.getInputFromPort('family')
-        if self.hasInputFromPort('x'):
-            self.props['x'] = self.getInputFromPort('x')
-        if self.hasInputFromPort('color'):
-            self.props['color'] = self.getInputFromPort('color')
-            self.props['color'] = translate_color(self.props['color'])
-        if self.hasInputFromPort('text'):
-            self.props['text'] = self.getInputFromPort('text')
-        if self.hasInputFromPort('verticalalignment'):
-            self.props['verticalalignment'] = self.getInputFromPort('verticalalignment')
-        if self.hasInputFromPort('variant'):
-            self.props['variant'] = self.getInputFromPort('variant')
-        if self.hasInputFromPort('path_effects'):
-            self.props['path_effects'] = self.getInputFromPort('path_effects')
-        if self.hasInputFromPort('weight'):
-            self.props['weight'] = self.getInputFromPort('weight')
-        if self.hasInputFromPort('stretch'):
-            self.props['stretch'] = self.getInputFromPort('stretch')
-        if self.hasInputFromPort('fontproperties'):
-            self.props['fontproperties'] = self.getInputFromPort('fontproperties')
-        if self.hasInputFromPort('horizontalalignment'):
-            self.props['horizontalalignment'] = self.getInputFromPort('horizontalalignment')
-        if self.hasInputFromPort('bbox'):
-            self.props['bbox'] = self.getInputFromPort('bbox')
-        if self.hasInputFromPort('backgroundcolor'):
-            self.props['backgroundcolor'] = self.getInputFromPort('backgroundcolor')
-            self.props['backgroundcolor'] = translate_color(self.props['backgroundcolor'])
-        if self.hasInputFromPort('position'):
-            self.props['position'] = self.getInputFromPort('position')
-        if self.hasInputFromPort('y'):
-            self.props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('multialignment'):
-            self.props['multialignment'] = self.getInputFromPort('multialignment')
-        if self.hasInputFromPort('rotation'):
-            self.props['rotation'] = self.getInputFromPort('rotation')
-        if self.hasInputFromPort('size'):
-            self.props['size'] = self.getInputFromPort('size')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplTextProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplTextProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('rotation_mode'):
+            artist.props['rotation_mode'] = self.get_input('rotation_mode')
+        if self.has_input('style'):
+            artist.props['style'] = self.get_input('style')
+        if self.has_input('linespacing'):
+            artist.props['linespacing'] = self.get_input('linespacing')
+        if self.has_input('family'):
+            artist.props['family'] = self.get_input('family')
+        if self.has_input('x'):
+            artist.props['x'] = self.get_input('x')
+        if self.has_input('color'):
+            artist.props['color'] = self.get_input('color')
+            artist.props['color'] = translate_color(artist.props['color'])
+        if self.has_input('text'):
+            artist.props['text'] = self.get_input('text')
+        if self.has_input('verticalalignment'):
+            artist.props['verticalalignment'] = self.get_input('verticalalignment')
+        if self.has_input('variant'):
+            artist.props['variant'] = self.get_input('variant')
+        if self.has_input('path_effects'):
+            artist.props['path_effects'] = self.get_input('path_effects')
+        if self.has_input('weight'):
+            artist.props['weight'] = self.get_input('weight')
+        if self.has_input('stretch'):
+            artist.props['stretch'] = self.get_input('stretch')
+        if self.has_input('fontproperties'):
+            artist.props['fontproperties'] = self.get_input('fontproperties')
+        if self.has_input('horizontalalignment'):
+            artist.props['horizontalalignment'] = self.get_input('horizontalalignment')
+        if self.has_input('bbox'):
+            artist.props['bbox'] = self.get_input('bbox')
+        if self.has_input('backgroundcolor'):
+            artist.props['backgroundcolor'] = self.get_input('backgroundcolor')
+            artist.props['backgroundcolor'] = translate_color(artist.props['backgroundcolor'])
+        if self.has_input('position'):
+            artist.props['position'] = self.get_input('position')
+        if self.has_input('y'):
+            artist.props['y'] = self.get_input('y')
+        if self.has_input('multialignment'):
+            artist.props['multialignment'] = self.get_input('multialignment')
+        if self.has_input('rotation'):
+            artist.props['rotation'] = self.get_input('rotation')
+        if self.has_input('size'):
+            artist.props['size'] = self.get_input('size')
+
 
 class MplTextWithDashProperties(MplTextProperties):
     """
@@ -2529,61 +3155,77 @@ class MplTextWithDashProperties(MplTextProperties):
                 {'optional': True, 'defaults': "['center']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplTextWithDashProperties)")]
-
-    def __init__(self):
-        MplTextProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplTextProperties.compute(self)
-        if self.hasInputFromPort('dashpush'):
-            self.props['dashpush'] = self.getInputFromPort('dashpush')
-        if self.hasInputFromPort('dashdirection'):
-            self.props['dashdirection'] = self.getInputFromPort('dashdirection')
-        if self.hasInputFromPort('linespacing'):
-            self.constructor_props['linespacing'] = self.getInputFromPort('linespacing')
-        if self.hasInputFromPort('figure'):
-            self.props['figure'] = self.getInputFromPort('figure')
-        if self.hasInputFromPort('color'):
-            self.constructor_props['color'] = self.getInputFromPort('color')
-        if self.hasInputFromPort('text'):
-            self.constructor_props['text'] = self.getInputFromPort('text')
-        if self.hasInputFromPort('verticalalignment'):
-            self.constructor_props['verticalalignment'] = self.getInputFromPort('verticalalignment')
-        if self.hasInputFromPort('dashpad'):
-            self.props['dashpad'] = self.getInputFromPort('dashpad')
-        if self.hasInputFromPort('dashrotation'):
-            self.props['dashrotation'] = self.getInputFromPort('dashrotation')
-        if self.hasInputFromPort('transform'):
-            self.props['transform'] = self.getInputFromPort('transform')
-        if self.hasInputFromPort('fontproperties'):
-            self.constructor_props['fontproperties'] = self.getInputFromPort('fontproperties')
-        if self.hasInputFromPort('multialignment'):
-            self.constructor_props['multialignment'] = self.getInputFromPort('multialignment')
-        if self.hasInputFromPort('x'):
-            self.props['x'] = self.getInputFromPort('x')
-        if self.hasInputFromPort('y'):
-            self.props['y'] = self.getInputFromPort('y')
-        if self.hasInputFromPort('position'):
-            self.props['position'] = self.getInputFromPort('position')
-        if self.hasInputFromPort('dashlength'):
-            self.props['dashlength'] = self.getInputFromPort('dashlength')
-        if self.hasInputFromPort('rotation'):
-            self.constructor_props['rotation'] = self.getInputFromPort('rotation')
-        if self.hasInputFromPort('horizontalalignment'):
-            self.constructor_props['horizontalalignment'] = self.getInputFromPort('horizontalalignment')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplTextWithDashProperties)")]
+
+    class Artist(MplTextProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplTextProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplTextWithDashProperties.Artist()
+            self.set_output("value", artist)
+
+        MplTextProperties.compute(self, artist)
+        if self.has_input('dashpush'):
+            artist.props['dashpush'] = self.get_input('dashpush')
+        if self.has_input('dashdirection'):
+            artist.props['dashdirection'] = self.get_input('dashdirection')
+        if self.has_input('linespacing'):
+            artist.constructor_props['linespacing'] = self.get_input('linespacing')
+        if self.has_input('figure'):
+            artist.props['figure'] = self.get_input('figure')
+        if self.has_input('color'):
+            artist.constructor_props['color'] = self.get_input('color')
+        if self.has_input('text'):
+            artist.constructor_props['text'] = self.get_input('text')
+        if self.has_input('verticalalignment'):
+            artist.constructor_props['verticalalignment'] = self.get_input('verticalalignment')
+        if self.has_input('dashpad'):
+            artist.props['dashpad'] = self.get_input('dashpad')
+        if self.has_input('dashrotation'):
+            artist.props['dashrotation'] = self.get_input('dashrotation')
+        if self.has_input('transform'):
+            artist.props['transform'] = self.get_input('transform')
+        if self.has_input('fontproperties'):
+            artist.constructor_props['fontproperties'] = self.get_input('fontproperties')
+        if self.has_input('multialignment'):
+            artist.constructor_props['multialignment'] = self.get_input('multialignment')
+        if self.has_input('x'):
+            artist.props['x'] = self.get_input('x')
+        if self.has_input('y'):
+            artist.props['y'] = self.get_input('y')
+        if self.has_input('position'):
+            artist.props['position'] = self.get_input('position')
+        if self.has_input('dashlength'):
+            artist.props['dashlength'] = self.get_input('dashlength')
+        if self.has_input('rotation'):
+            artist.constructor_props['rotation'] = self.get_input('rotation')
+        if self.has_input('horizontalalignment'):
+            artist.constructor_props['horizontalalignment'] = self.get_input('horizontalalignment')
+
 
 class MplTickProperties(MplArtistProperties):
     """
@@ -2635,12 +3277,8 @@ class MplTickProperties(MplArtistProperties):
                 {'optional': True, 'defaults': "['True']"}),
               ("label2On", "basic:Boolean",
                 {'optional': True, 'defaults': "['False']"}),
-              ("color", "basic:String",
+              ("color", "basic:Color",
                 {'optional': True}),
-              ("label1", "basic:String",
-                {'optional': True, 'docstring': 'Set the text of ticklabel'}),
-              ("label2", "basic:String",
-                {'optional': True, 'docstring': 'Set the text of ticklabel2'}),
               ("axes", "basic:String",
                 {'optional': True}),
               ("clip_path", "basic:String",
@@ -2653,81 +3291,129 @@ class MplTickProperties(MplArtistProperties):
                 {'optional': True}),
               ("pad", "basic:Float",
                 {'optional': True, 'docstring': 'Set the tick label pad in points'}),
-              ("gridOn", "basic:String",
-                {'optional': True}),
+              ("gridOn", "basic:Boolean",
+                {'optional': True, 'docstring': 'a boolean which determines whether to draw the tickline'}),
               ("zorder", "basic:String",
                 {'optional': True}),
               ("tick2On", "basic:Boolean",
-                {'optional': True, 'defaults': "['True']"}),
+                {'optional': True, 'docstring': 'a boolean which determines whether to draw the 2nd tickline', 'defaults': "['True']"}),
               ("labelsize", "basic:String",
                 {'optional': True}),
               ("width", "basic:String",
                 {'optional': True}),
               ("tick1On", "basic:Boolean",
-                {'optional': True, 'defaults': "['True']"}),
+                {'optional': True, 'docstring': 'a boolean which determines whether to draw the 1st tickline', 'defaults': "['True']"}),
               ("size", "basic:String",
                 {'optional': True}),
+              ("label1Properties", "MplTextProperties",
+                {'docstring': 'Set the text of ticklabel'}),
+              ("label2Properties", "MplTextProperties",
+                {'docstring': 'Set the text of ticklabel2'}),
+              ("tick1lineProperties", "MplLine2DProperties",
+                {}),
+              ("tick2lineProperties", "MplLine2DProperties",
+                {}),
+              ("gridlineProperties", "MplLine2DProperties",
+                {}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplTickProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('label1On'):
-            self.constructor_props['label1On'] = self.getInputFromPort('label1On')
-        if self.hasInputFromPort('loc'):
-            self.constructor_props['loc'] = self.getInputFromPort('loc')
-        if self.hasInputFromPort('major'):
-            self.constructor_props['major'] = self.getInputFromPort('major')
-        if self.hasInputFromPort('label2On'):
-            self.constructor_props['label2On'] = self.getInputFromPort('label2On')
-        if self.hasInputFromPort('color'):
-            self.constructor_props['color'] = self.getInputFromPort('color')
-        if self.hasInputFromPort('label1'):
-            self.props['label1'] = self.getInputFromPort('label1')
-        if self.hasInputFromPort('label2'):
-            self.props['label2'] = self.getInputFromPort('label2')
-        if self.hasInputFromPort('axes'):
-            self.constructor_props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('clip_path'):
-            self.props['clip_path'] = self.getInputFromPort('clip_path')
-        if self.hasInputFromPort('label'):
-            self.props['label'] = self.getInputFromPort('label')
-        if self.hasInputFromPort('labelcolor'):
-            self.constructor_props['labelcolor'] = self.getInputFromPort('labelcolor')
-        if self.hasInputFromPort('tickdir'):
-            self.constructor_props['tickdir'] = self.getInputFromPort('tickdir')
-        if self.hasInputFromPort('pad'):
-            self.props['pad'] = self.getInputFromPort('pad')
-        if self.hasInputFromPort('gridOn'):
-            self.constructor_props['gridOn'] = self.getInputFromPort('gridOn')
-        if self.hasInputFromPort('zorder'):
-            self.constructor_props['zorder'] = self.getInputFromPort('zorder')
-        if self.hasInputFromPort('tick2On'):
-            self.constructor_props['tick2On'] = self.getInputFromPort('tick2On')
-        if self.hasInputFromPort('labelsize'):
-            self.constructor_props['labelsize'] = self.getInputFromPort('labelsize')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('tick1On'):
-            self.constructor_props['tick1On'] = self.getInputFromPort('tick1On')
-        if self.hasInputFromPort('size'):
-            self.constructor_props['size'] = self.getInputFromPort('size')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplTickProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                if 'label1' in self.sub_props:
+                    self.sub_props['label1'].update_props(obj.label1)
+                if 'label2' in self.sub_props:
+                    self.sub_props['label2'].update_props(obj.label2)
+                if 'tick1line' in self.sub_props:
+                    self.sub_props['tick1line'].update_props(obj.tick1line)
+                if 'tick2line' in self.sub_props:
+                    self.sub_props['tick2line'].update_props(obj.tick2line)
+                if 'gridline' in self.sub_props:
+                    self.sub_props['gridline'].update_props(obj.gridline)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplTickProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('label1On'):
+            artist.not_setp_props['label1On'] = self.get_input('label1On')
+        if self.has_input('loc'):
+            artist.constructor_props['loc'] = self.get_input('loc')
+        if self.has_input('major'):
+            artist.constructor_props['major'] = self.get_input('major')
+        if self.has_input('label2On'):
+            artist.not_setp_props['label2On'] = self.get_input('label2On')
+        if self.has_input('color'):
+            artist.constructor_props['color'] = self.get_input('color')
+            artist.constructor_props['color'] = translate_color(artist.constructor_props['color'])
+        if self.has_input('axes'):
+            artist.constructor_props['axes'] = self.get_input('axes')
+        if self.has_input('clip_path'):
+            artist.props['clip_path'] = self.get_input('clip_path')
+        if self.has_input('label'):
+            artist.props['label'] = self.get_input('label')
+        if self.has_input('labelcolor'):
+            artist.constructor_props['labelcolor'] = self.get_input('labelcolor')
+        if self.has_input('tickdir'):
+            artist.constructor_props['tickdir'] = self.get_input('tickdir')
+        if self.has_input('pad'):
+            artist.props['pad'] = self.get_input('pad')
+        if self.has_input('gridOn'):
+            artist.not_setp_props['gridOn'] = self.get_input('gridOn')
+        if self.has_input('zorder'):
+            artist.constructor_props['zorder'] = self.get_input('zorder')
+        if self.has_input('tick2On'):
+            artist.not_setp_props['tick2On'] = self.get_input('tick2On')
+        if self.has_input('labelsize'):
+            artist.constructor_props['labelsize'] = self.get_input('labelsize')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('tick1On'):
+            artist.not_setp_props['tick1On'] = self.get_input('tick1On')
+        if self.has_input('size'):
+            artist.constructor_props['size'] = self.get_input('size')
+        if self.has_input('label1Properties'):
+            artist.sub_props['label1'] = self.get_input('label1Properties')
+        if self.has_input('label2Properties'):
+            artist.sub_props['label2'] = self.get_input('label2Properties')
+        if self.has_input('tick1lineProperties'):
+            artist.sub_props['tick1line'] = self.get_input('tick1lineProperties')
+        if self.has_input('tick2lineProperties'):
+            artist.sub_props['tick2line'] = self.get_input('tick2lineProperties')
+        if self.has_input('gridlineProperties'):
+            artist.sub_props['gridline'] = self.get_input('gridlineProperties')
+
 
 class MplXTickProperties(MplTickProperties):
     """
@@ -2772,59 +3458,75 @@ class MplXTickProperties(MplTickProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplXTickProperties)")]
-
-    def __init__(self):
-        MplTickProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplTickProperties.compute(self)
-        if self.hasInputFromPort('label1On'):
-            self.constructor_props['label1On'] = self.getInputFromPort('label1On')
-        if self.hasInputFromPort('loc'):
-            self.constructor_props['loc'] = self.getInputFromPort('loc')
-        if self.hasInputFromPort('major'):
-            self.constructor_props['major'] = self.getInputFromPort('major')
-        if self.hasInputFromPort('label2On'):
-            self.constructor_props['label2On'] = self.getInputFromPort('label2On')
-        if self.hasInputFromPort('color'):
-            self.constructor_props['color'] = self.getInputFromPort('color')
-        if self.hasInputFromPort('axes'):
-            self.constructor_props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('label'):
-            self.constructor_props['label'] = self.getInputFromPort('label')
-        if self.hasInputFromPort('labelcolor'):
-            self.constructor_props['labelcolor'] = self.getInputFromPort('labelcolor')
-        if self.hasInputFromPort('tickdir'):
-            self.constructor_props['tickdir'] = self.getInputFromPort('tickdir')
-        if self.hasInputFromPort('pad'):
-            self.constructor_props['pad'] = self.getInputFromPort('pad')
-        if self.hasInputFromPort('gridOn'):
-            self.constructor_props['gridOn'] = self.getInputFromPort('gridOn')
-        if self.hasInputFromPort('zorder'):
-            self.constructor_props['zorder'] = self.getInputFromPort('zorder')
-        if self.hasInputFromPort('tick2On'):
-            self.constructor_props['tick2On'] = self.getInputFromPort('tick2On')
-        if self.hasInputFromPort('labelsize'):
-            self.constructor_props['labelsize'] = self.getInputFromPort('labelsize')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('tick1On'):
-            self.constructor_props['tick1On'] = self.getInputFromPort('tick1On')
-        if self.hasInputFromPort('size'):
-            self.constructor_props['size'] = self.getInputFromPort('size')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplXTickProperties)")]
+
+    class Artist(MplTickProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplTickProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplXTickProperties.Artist()
+            self.set_output("value", artist)
+
+        MplTickProperties.compute(self, artist)
+        if self.has_input('label1On'):
+            artist.constructor_props['label1On'] = self.get_input('label1On')
+        if self.has_input('loc'):
+            artist.constructor_props['loc'] = self.get_input('loc')
+        if self.has_input('major'):
+            artist.constructor_props['major'] = self.get_input('major')
+        if self.has_input('label2On'):
+            artist.constructor_props['label2On'] = self.get_input('label2On')
+        if self.has_input('color'):
+            artist.constructor_props['color'] = self.get_input('color')
+        if self.has_input('axes'):
+            artist.constructor_props['axes'] = self.get_input('axes')
+        if self.has_input('label'):
+            artist.constructor_props['label'] = self.get_input('label')
+        if self.has_input('labelcolor'):
+            artist.constructor_props['labelcolor'] = self.get_input('labelcolor')
+        if self.has_input('tickdir'):
+            artist.constructor_props['tickdir'] = self.get_input('tickdir')
+        if self.has_input('pad'):
+            artist.constructor_props['pad'] = self.get_input('pad')
+        if self.has_input('gridOn'):
+            artist.constructor_props['gridOn'] = self.get_input('gridOn')
+        if self.has_input('zorder'):
+            artist.constructor_props['zorder'] = self.get_input('zorder')
+        if self.has_input('tick2On'):
+            artist.constructor_props['tick2On'] = self.get_input('tick2On')
+        if self.has_input('labelsize'):
+            artist.constructor_props['labelsize'] = self.get_input('labelsize')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('tick1On'):
+            artist.constructor_props['tick1On'] = self.get_input('tick1On')
+        if self.has_input('size'):
+            artist.constructor_props['size'] = self.get_input('size')
+
 
 class MplYTickProperties(MplTickProperties):
     """
@@ -2869,59 +3571,75 @@ class MplYTickProperties(MplTickProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplYTickProperties)")]
-
-    def __init__(self):
-        MplTickProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplTickProperties.compute(self)
-        if self.hasInputFromPort('label1On'):
-            self.constructor_props['label1On'] = self.getInputFromPort('label1On')
-        if self.hasInputFromPort('loc'):
-            self.constructor_props['loc'] = self.getInputFromPort('loc')
-        if self.hasInputFromPort('major'):
-            self.constructor_props['major'] = self.getInputFromPort('major')
-        if self.hasInputFromPort('label2On'):
-            self.constructor_props['label2On'] = self.getInputFromPort('label2On')
-        if self.hasInputFromPort('color'):
-            self.constructor_props['color'] = self.getInputFromPort('color')
-        if self.hasInputFromPort('axes'):
-            self.constructor_props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('label'):
-            self.constructor_props['label'] = self.getInputFromPort('label')
-        if self.hasInputFromPort('labelcolor'):
-            self.constructor_props['labelcolor'] = self.getInputFromPort('labelcolor')
-        if self.hasInputFromPort('tickdir'):
-            self.constructor_props['tickdir'] = self.getInputFromPort('tickdir')
-        if self.hasInputFromPort('pad'):
-            self.constructor_props['pad'] = self.getInputFromPort('pad')
-        if self.hasInputFromPort('gridOn'):
-            self.constructor_props['gridOn'] = self.getInputFromPort('gridOn')
-        if self.hasInputFromPort('zorder'):
-            self.constructor_props['zorder'] = self.getInputFromPort('zorder')
-        if self.hasInputFromPort('tick2On'):
-            self.constructor_props['tick2On'] = self.getInputFromPort('tick2On')
-        if self.hasInputFromPort('labelsize'):
-            self.constructor_props['labelsize'] = self.getInputFromPort('labelsize')
-        if self.hasInputFromPort('width'):
-            self.constructor_props['width'] = self.getInputFromPort('width')
-        if self.hasInputFromPort('tick1On'):
-            self.constructor_props['tick1On'] = self.getInputFromPort('tick1On')
-        if self.hasInputFromPort('size'):
-            self.constructor_props['size'] = self.getInputFromPort('size')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplYTickProperties)")]
+
+    class Artist(MplTickProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplTickProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplYTickProperties.Artist()
+            self.set_output("value", artist)
+
+        MplTickProperties.compute(self, artist)
+        if self.has_input('label1On'):
+            artist.constructor_props['label1On'] = self.get_input('label1On')
+        if self.has_input('loc'):
+            artist.constructor_props['loc'] = self.get_input('loc')
+        if self.has_input('major'):
+            artist.constructor_props['major'] = self.get_input('major')
+        if self.has_input('label2On'):
+            artist.constructor_props['label2On'] = self.get_input('label2On')
+        if self.has_input('color'):
+            artist.constructor_props['color'] = self.get_input('color')
+        if self.has_input('axes'):
+            artist.constructor_props['axes'] = self.get_input('axes')
+        if self.has_input('label'):
+            artist.constructor_props['label'] = self.get_input('label')
+        if self.has_input('labelcolor'):
+            artist.constructor_props['labelcolor'] = self.get_input('labelcolor')
+        if self.has_input('tickdir'):
+            artist.constructor_props['tickdir'] = self.get_input('tickdir')
+        if self.has_input('pad'):
+            artist.constructor_props['pad'] = self.get_input('pad')
+        if self.has_input('gridOn'):
+            artist.constructor_props['gridOn'] = self.get_input('gridOn')
+        if self.has_input('zorder'):
+            artist.constructor_props['zorder'] = self.get_input('zorder')
+        if self.has_input('tick2On'):
+            artist.constructor_props['tick2On'] = self.get_input('tick2On')
+        if self.has_input('labelsize'):
+            artist.constructor_props['labelsize'] = self.get_input('labelsize')
+        if self.has_input('width'):
+            artist.constructor_props['width'] = self.get_input('width')
+        if self.has_input('tick1On'):
+            artist.constructor_props['tick1On'] = self.get_input('tick1On')
+        if self.has_input('size'):
+            artist.constructor_props['size'] = self.get_input('size')
+
 
 class MplAxisProperties(MplArtistProperties):
     """
@@ -2973,67 +3691,100 @@ class MplAxisProperties(MplArtistProperties):
                 {'optional': True, 'docstring': 'set the units for axis'}),
               ("tick_params", "basic:String",
                 {'optional': True, 'docstring': 'Set appearance parameters for ticks and ticklabels.\n\nFor documentation of keyword arguments, see :meth:`matplotlib.axes.Axes.tick_params`.'}),
+              ("majorTickProperties", "MplTickProperties",
+                {}),
+              ("minorTickProperties", "MplTickProperties",
+                {}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplAxisProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('pickradius'):
-            self.props['pickradius'] = self.getInputFromPort('pickradius')
-        if self.hasInputFromPort('minor_formatter'):
-            self.props['minor_formatter'] = self.getInputFromPort('minor_formatter')
-        if self.hasInputFromPort('smart_bounds'):
-            self.props['smart_bounds'] = self.getInputFromPort('smart_bounds')
-        if self.hasInputFromPort('ticksSequence'):
-            self.props['ticks'] = self.getInputFromPort('ticksSequence')
-        elif self.hasInputFromPort('ticksScalar'):
-            self.props['ticks'] = self.getInputFromPort('ticksScalar')
-        if self.hasInputFromPort('axes'):
-            self.constructor_props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('view_interval'):
-            self.props['view_interval'] = self.getInputFromPort('view_interval')
-        if self.hasInputFromPort('major_locator'):
-            self.props['major_locator'] = self.getInputFromPort('major_locator')
-        if self.hasInputFromPort('major_formatter'):
-            self.props['major_formatter'] = self.getInputFromPort('major_formatter')
-        if self.hasInputFromPort('ticklabelsSequence'):
-            self.props['ticklabels'] = self.getInputFromPort('ticklabelsSequence')
-        elif self.hasInputFromPort('ticklabelsScalar'):
-            self.props['ticklabels'] = self.getInputFromPort('ticklabelsScalar')
-        if self.hasInputFromPort('clip_path'):
-            self.props['clip_path'] = self.getInputFromPort('clip_path')
-        if self.hasInputFromPort('minor_locator'):
-            self.props['minor_locator'] = self.getInputFromPort('minor_locator')
-        if self.hasInputFromPort('default_intervals'):
-            self.props['default_intervals'] = self.getInputFromPort('default_intervals')
-        if self.hasInputFromPort('scale'):
-            self.props['scale'] = self.getInputFromPort('scale')
-        if self.hasInputFromPort('data_interval'):
-            self.props['data_interval'] = self.getInputFromPort('data_interval')
-        if self.hasInputFromPort('label_text'):
-            self.props['label_text'] = self.getInputFromPort('label_text')
-        if self.hasInputFromPort('label_coords'):
-            self.props['label_coords'] = self.getInputFromPort('label_coords')
-        if self.hasInputFromPort('units'):
-            self.props['units'] = self.getInputFromPort('units')
-        if self.hasInputFromPort('tick_params'):
-            self.props['tick_params'] = self.getInputFromPort('tick_params')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplAxisProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                if 'major_ticks' in self.sub_props:
+                    self.sub_props['major_ticks'].update_props(obj.get_major_ticks())
+                if 'minor_ticks' in self.sub_props:
+                    self.sub_props['minor_ticks'].update_props(obj.get_minor_ticks())
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplAxisProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('pickradius'):
+            artist.props['pickradius'] = self.get_input('pickradius')
+        if self.has_input('minor_formatter'):
+            artist.props['minor_formatter'] = self.get_input('minor_formatter')
+        if self.has_input('smart_bounds'):
+            artist.props['smart_bounds'] = self.get_input('smart_bounds')
+        if self.has_input('ticksSequence'):
+            artist.props['ticks'] = self.get_input('ticksSequence')
+        elif self.has_input('ticksScalar'):
+            artist.props['ticks'] = self.get_input('ticksScalar')
+        if self.has_input('axes'):
+            artist.constructor_props['axes'] = self.get_input('axes')
+        if self.has_input('view_interval'):
+            artist.props['view_interval'] = self.get_input('view_interval')
+        if self.has_input('major_locator'):
+            artist.props['major_locator'] = self.get_input('major_locator')
+        if self.has_input('major_formatter'):
+            artist.props['major_formatter'] = self.get_input('major_formatter')
+        if self.has_input('ticklabelsSequence'):
+            artist.props['ticklabels'] = self.get_input('ticklabelsSequence')
+        elif self.has_input('ticklabelsScalar'):
+            artist.props['ticklabels'] = self.get_input('ticklabelsScalar')
+        if self.has_input('clip_path'):
+            artist.props['clip_path'] = self.get_input('clip_path')
+        if self.has_input('minor_locator'):
+            artist.props['minor_locator'] = self.get_input('minor_locator')
+        if self.has_input('default_intervals'):
+            artist.props['default_intervals'] = self.get_input('default_intervals')
+        if self.has_input('scale'):
+            artist.props['scale'] = self.get_input('scale')
+        if self.has_input('data_interval'):
+            artist.props['data_interval'] = self.get_input('data_interval')
+        if self.has_input('label_text'):
+            artist.props['label_text'] = self.get_input('label_text')
+        if self.has_input('label_coords'):
+            artist.props['label_coords'] = self.get_input('label_coords')
+        if self.has_input('units'):
+            artist.props['units'] = self.get_input('units')
+        if self.has_input('tick_params'):
+            artist.props['tick_params'] = self.get_input('tick_params')
+        if self.has_input('majorTickProperties'):
+            artist.sub_props['major_ticks'] = self.get_input('majorTickProperties')
+        if self.has_input('minorTickProperties'):
+            artist.sub_props['minor_ticks'] = self.get_input('minorTickProperties')
+
 
 class MplXAxisProperties(MplAxisProperties):
     """None
@@ -3055,39 +3806,55 @@ class MplXAxisProperties(MplAxisProperties):
                 {'optional': True, 'defaults': "['15']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplXAxisProperties)")]
-
-    def __init__(self):
-        MplAxisProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplAxisProperties.compute(self)
-        if self.hasInputFromPort('view_interval'):
-            self.props['view_interval'] = self.getInputFromPort('view_interval')
-        if self.hasInputFromPort('ticks_position'):
-            self.props['ticks_position'] = self.getInputFromPort('ticks_position')
-        if self.hasInputFromPort('axes'):
-            self.constructor_props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('label_position'):
-            self.props['label_position'] = self.getInputFromPort('label_position')
-        if self.hasInputFromPort('default_intervals'):
-            self.props['default_intervals'] = self.getInputFromPort('default_intervals')
-        if self.hasInputFromPort('data_interval'):
-            self.props['data_interval'] = self.getInputFromPort('data_interval')
-        if self.hasInputFromPort('pickradius'):
-            self.constructor_props['pickradius'] = self.getInputFromPort('pickradius')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplXAxisProperties)")]
+
+    class Artist(MplAxisProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplAxisProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplXAxisProperties.Artist()
+            self.set_output("value", artist)
+
+        MplAxisProperties.compute(self, artist)
+        if self.has_input('view_interval'):
+            artist.props['view_interval'] = self.get_input('view_interval')
+        if self.has_input('ticks_position'):
+            artist.props['ticks_position'] = self.get_input('ticks_position')
+        if self.has_input('axes'):
+            artist.constructor_props['axes'] = self.get_input('axes')
+        if self.has_input('label_position'):
+            artist.props['label_position'] = self.get_input('label_position')
+        if self.has_input('default_intervals'):
+            artist.props['default_intervals'] = self.get_input('default_intervals')
+        if self.has_input('data_interval'):
+            artist.props['data_interval'] = self.get_input('data_interval')
+        if self.has_input('pickradius'):
+            artist.constructor_props['pickradius'] = self.get_input('pickradius')
+
 
 class MplYAxisProperties(MplAxisProperties):
     """None
@@ -3111,41 +3878,57 @@ class MplYAxisProperties(MplAxisProperties):
                 {'optional': True, 'defaults': "['15']"}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplYAxisProperties)")]
-
-    def __init__(self):
-        MplAxisProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplAxisProperties.compute(self)
-        if self.hasInputFromPort('offset_position'):
-            self.props['offset_position'] = self.getInputFromPort('offset_position')
-        if self.hasInputFromPort('view_interval'):
-            self.props['view_interval'] = self.getInputFromPort('view_interval')
-        if self.hasInputFromPort('ticks_position'):
-            self.props['ticks_position'] = self.getInputFromPort('ticks_position')
-        if self.hasInputFromPort('axes'):
-            self.constructor_props['axes'] = self.getInputFromPort('axes')
-        if self.hasInputFromPort('label_position'):
-            self.props['label_position'] = self.getInputFromPort('label_position')
-        if self.hasInputFromPort('default_intervals'):
-            self.props['default_intervals'] = self.getInputFromPort('default_intervals')
-        if self.hasInputFromPort('data_interval'):
-            self.props['data_interval'] = self.getInputFromPort('data_interval')
-        if self.hasInputFromPort('pickradius'):
-            self.constructor_props['pickradius'] = self.getInputFromPort('pickradius')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplYAxisProperties)")]
+
+    class Artist(MplAxisProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplAxisProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplYAxisProperties.Artist()
+            self.set_output("value", artist)
+
+        MplAxisProperties.compute(self, artist)
+        if self.has_input('offset_position'):
+            artist.props['offset_position'] = self.get_input('offset_position')
+        if self.has_input('view_interval'):
+            artist.props['view_interval'] = self.get_input('view_interval')
+        if self.has_input('ticks_position'):
+            artist.props['ticks_position'] = self.get_input('ticks_position')
+        if self.has_input('axes'):
+            artist.constructor_props['axes'] = self.get_input('axes')
+        if self.has_input('label_position'):
+            artist.props['label_position'] = self.get_input('label_position')
+        if self.has_input('default_intervals'):
+            artist.props['default_intervals'] = self.get_input('default_intervals')
+        if self.has_input('data_interval'):
+            artist.props['data_interval'] = self.get_input('data_interval')
+        if self.has_input('pickradius'):
+            artist.constructor_props['pickradius'] = self.get_input('pickradius')
+
 
 class MplLegendProperties(MplArtistProperties):
     """
@@ -3241,91 +4024,107 @@ class MplLegendProperties(MplArtistProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplLegendProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('fancybox'):
-            self.constructor_props['fancybox'] = self.getInputFromPort('fancybox')
-        if self.hasInputFromPort('handlelength'):
-            self.constructor_props['handlelength'] = self.getInputFromPort('handlelength')
-        if self.hasInputFromPort('labels'):
-            self.constructor_props['labels'] = self.getInputFromPort('labels')
-        if self.hasInputFromPort('labelspacing'):
-            self.constructor_props['labelspacing'] = self.getInputFromPort('labelspacing')
-        if self.hasInputFromPort('columnspacing'):
-            self.constructor_props['columnspacing'] = self.getInputFromPort('columnspacing')
-        if self.hasInputFromPort('handletextpad'):
-            self.constructor_props['handletextpad'] = self.getInputFromPort('handletextpad')
-        if self.hasInputFromPort('ncol'):
-            self.constructor_props['ncol'] = self.getInputFromPort('ncol')
-        if self.hasInputFromPort('borderaxespad'):
-            self.constructor_props['borderaxespad'] = self.getInputFromPort('borderaxespad')
-        if self.hasInputFromPort('loc'):
-            self.constructor_props['loc'] = self.getInputFromPort('loc')
-        if self.hasInputFromPort('bbox_to_anchor'):
-            self.props['bbox_to_anchor'] = self.getInputFromPort('bbox_to_anchor')
-        if self.hasInputFromPort('title'):
-            self.props['title'] = self.getInputFromPort('title')
-        if self.hasInputFromPort('handletextsep'):
-            self.constructor_props['handletextsep'] = self.getInputFromPort('handletextsep')
-        if self.hasInputFromPort('numpoints'):
-            self.constructor_props['numpoints'] = self.getInputFromPort('numpoints')
-        if self.hasInputFromPort('prop'):
-            self.constructor_props['prop'] = self.getInputFromPort('prop')
-        if self.hasInputFromPort('handles'):
-            self.constructor_props['handles'] = self.getInputFromPort('handles')
-        if self.hasInputFromPort('pad'):
-            self.constructor_props['pad'] = self.getInputFromPort('pad')
-        if self.hasInputFromPort('borderpad'):
-            self.constructor_props['borderpad'] = self.getInputFromPort('borderpad')
-        if self.hasInputFromPort('parent'):
-            self.constructor_props['parent'] = self.getInputFromPort('parent')
-        if self.hasInputFromPort('axespad'):
-            self.constructor_props['axespad'] = self.getInputFromPort('axespad')
-        if self.hasInputFromPort('labelsep'):
-            self.constructor_props['labelsep'] = self.getInputFromPort('labelsep')
-        if self.hasInputFromPort('frame_on'):
-            self.props['frame_on'] = self.getInputFromPort('frame_on')
-        if self.hasInputFromPort('scatterpoints'):
-            self.constructor_props['scatterpoints'] = self.getInputFromPort('scatterpoints')
-        if self.hasInputFromPort('fontsize'):
-            self.constructor_props['fontsize'] = self.getInputFromPort('fontsize')
-        if self.hasInputFromPort('shadow'):
-            self.constructor_props['shadow'] = self.getInputFromPort('shadow')
-        if self.hasInputFromPort('handler_map'):
-            self.constructor_props['handler_map'] = self.getInputFromPort('handler_map')
-        if self.hasInputFromPort('handleheight'):
-            self.constructor_props['handleheight'] = self.getInputFromPort('handleheight')
-        if self.hasInputFromPort('scatteryoffsets'):
-            self.constructor_props['scatteryoffsets'] = self.getInputFromPort('scatteryoffsets')
-        if self.hasInputFromPort('markerscale'):
-            self.constructor_props['markerscale'] = self.getInputFromPort('markerscale')
-        if self.hasInputFromPort('frameon'):
-            self.constructor_props['frameon'] = self.getInputFromPort('frameon')
-        if self.hasInputFromPort('mode'):
-            self.constructor_props['mode'] = self.getInputFromPort('mode')
-        if self.hasInputFromPort('handlelen'):
-            self.constructor_props['handlelen'] = self.getInputFromPort('handlelen')
-        if self.hasInputFromPort('default_handler_map'):
-            self.props['default_handler_map'] = self.getInputFromPort('default_handler_map')
-        if self.hasInputFromPort('bbox_transform'):
-            self.constructor_props['bbox_transform'] = self.getInputFromPort('bbox_transform')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplLegendProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplLegendProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('fancybox'):
+            artist.constructor_props['fancybox'] = self.get_input('fancybox')
+        if self.has_input('handlelength'):
+            artist.constructor_props['handlelength'] = self.get_input('handlelength')
+        if self.has_input('labels'):
+            artist.constructor_props['labels'] = self.get_input('labels')
+        if self.has_input('labelspacing'):
+            artist.constructor_props['labelspacing'] = self.get_input('labelspacing')
+        if self.has_input('columnspacing'):
+            artist.constructor_props['columnspacing'] = self.get_input('columnspacing')
+        if self.has_input('handletextpad'):
+            artist.constructor_props['handletextpad'] = self.get_input('handletextpad')
+        if self.has_input('ncol'):
+            artist.constructor_props['ncol'] = self.get_input('ncol')
+        if self.has_input('borderaxespad'):
+            artist.constructor_props['borderaxespad'] = self.get_input('borderaxespad')
+        if self.has_input('loc'):
+            artist.constructor_props['loc'] = self.get_input('loc')
+        if self.has_input('bbox_to_anchor'):
+            artist.props['bbox_to_anchor'] = self.get_input('bbox_to_anchor')
+        if self.has_input('title'):
+            artist.props['title'] = self.get_input('title')
+        if self.has_input('handletextsep'):
+            artist.constructor_props['handletextsep'] = self.get_input('handletextsep')
+        if self.has_input('numpoints'):
+            artist.constructor_props['numpoints'] = self.get_input('numpoints')
+        if self.has_input('prop'):
+            artist.constructor_props['prop'] = self.get_input('prop')
+        if self.has_input('handles'):
+            artist.constructor_props['handles'] = self.get_input('handles')
+        if self.has_input('pad'):
+            artist.constructor_props['pad'] = self.get_input('pad')
+        if self.has_input('borderpad'):
+            artist.constructor_props['borderpad'] = self.get_input('borderpad')
+        if self.has_input('parent'):
+            artist.constructor_props['parent'] = self.get_input('parent')
+        if self.has_input('axespad'):
+            artist.constructor_props['axespad'] = self.get_input('axespad')
+        if self.has_input('labelsep'):
+            artist.constructor_props['labelsep'] = self.get_input('labelsep')
+        if self.has_input('frame_on'):
+            artist.props['frame_on'] = self.get_input('frame_on')
+        if self.has_input('scatterpoints'):
+            artist.constructor_props['scatterpoints'] = self.get_input('scatterpoints')
+        if self.has_input('fontsize'):
+            artist.constructor_props['fontsize'] = self.get_input('fontsize')
+        if self.has_input('shadow'):
+            artist.constructor_props['shadow'] = self.get_input('shadow')
+        if self.has_input('handler_map'):
+            artist.constructor_props['handler_map'] = self.get_input('handler_map')
+        if self.has_input('handleheight'):
+            artist.constructor_props['handleheight'] = self.get_input('handleheight')
+        if self.has_input('scatteryoffsets'):
+            artist.constructor_props['scatteryoffsets'] = self.get_input('scatteryoffsets')
+        if self.has_input('markerscale'):
+            artist.constructor_props['markerscale'] = self.get_input('markerscale')
+        if self.has_input('frameon'):
+            artist.constructor_props['frameon'] = self.get_input('frameon')
+        if self.has_input('mode'):
+            artist.constructor_props['mode'] = self.get_input('mode')
+        if self.has_input('handlelen'):
+            artist.constructor_props['handlelen'] = self.get_input('handlelen')
+        if self.has_input('default_handler_map'):
+            artist.props['default_handler_map'] = self.get_input('default_handler_map')
+        if self.has_input('bbox_transform'):
+            artist.constructor_props['bbox_transform'] = self.get_input('bbox_transform')
+
 
 class MplAxesProperties(MplArtistProperties):
     """
@@ -3435,129 +4234,157 @@ class MplAxesProperties(MplArtistProperties):
                {'docstring': "Call signature:\n\nset_xticklabels(labels, fontdict=None, minor=False, **kwargs)\n\nSet the xtick labels with list of strings labels. Return a list of axis text instances.\n\nkwargs set the :class:`~matplotlib.text.Text` properties. Valid properties are\n\nagg_filter: unknown alpha: float (0.0 transparent through 1.0 opaque) animated: [True | False] axes: an :class:`~matplotlib.axes.Axes` instance backgroundcolor: any matplotlib color bbox: rectangle prop di [...]
               ("titleProperties", "MplTextProperties",
                 {}),
+              ("xaxisProperties", "MplXAxisProperties",
+                {}),
+              ("yaxisProperties", "MplYAxisProperties",
+                {}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplAxesProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('adjustable'):
-            self.props['adjustable'] = self.getInputFromPort('adjustable')
-        if self.hasInputFromPort('cursor_props'):
-            self.props['cursor_props'] = self.getInputFromPort('cursor_props')
-        if self.hasInputFromPort('figure'):
-            self.props['figure'] = self.getInputFromPort('figure')
-        if self.hasInputFromPort('yscale'):
-            self.props['yscale'] = self.getInputFromPort('yscale')
-        if self.hasInputFromPort('navigate'):
-            self.props['navigate'] = self.getInputFromPort('navigate')
-        if self.hasInputFromPort('aspect'):
-            self.props['aspect'] = self.getInputFromPort('aspect')
-        if self.hasInputFromPort('axis_bgcolor'):
-            self.props['axis_bgcolor'] = self.getInputFromPort('axis_bgcolor')
-            self.props['axis_bgcolor'] = translate_color(self.props['axis_bgcolor'])
-        if self.hasInputFromPort('ylimSequence'):
-            self.props['ylim'] = self.getInputFromPort('ylimSequence')
-        elif self.hasInputFromPort('ylimScalar'):
-            self.props['ylim'] = self.getInputFromPort('ylimScalar')
-        if self.hasInputFromPort('sharey'):
-            self.constructor_props['sharey'] = self.getInputFromPort('sharey')
-        if self.hasInputFromPort('xlimSequence'):
-            self.props['xlim'] = self.getInputFromPort('xlimSequence')
-        elif self.hasInputFromPort('xlimScalar'):
-            self.props['xlim'] = self.getInputFromPort('xlimScalar')
-        if self.hasInputFromPort('axis_on'):
-            self.props['axis_on'] = self.getInputFromPort('axis_on')
-        if self.hasInputFromPort('title'):
-            self.props['title'] = self.getInputFromPort('title')
-        if self.hasInputFromPort('axisbg'):
-            self.constructor_props['axisbg'] = self.getInputFromPort('axisbg')
-        if self.hasInputFromPort('label'):
-            self.constructor_props['label'] = self.getInputFromPort('label')
-        if self.hasInputFromPort('xticks'):
-            self.props['xticks'] = self.getInputFromPort('xticks')
-        if self.hasInputFromPort('fig'):
-            self.constructor_props['fig'] = self.getInputFromPort('fig')
-        if self.hasInputFromPort('ylabel'):
-            self.props['ylabel'] = self.getInputFromPort('ylabel')
-        if self.hasInputFromPort('autoscalex_on'):
-            self.props['autoscalex_on'] = self.getInputFromPort('autoscalex_on')
-        if self.hasInputFromPort('rasterization_zorder'):
-            self.props['rasterization_zorder'] = self.getInputFromPort('rasterization_zorder')
-        if self.hasInputFromPort('axes_locator'):
-            self.props['axes_locator'] = self.getInputFromPort('axes_locator')
-        if self.hasInputFromPort('axisbelow'):
-            self.props['axisbelow'] = self.getInputFromPort('axisbelow')
-        if self.hasInputFromPort('frame_on'):
-            self.props['frame_on'] = self.getInputFromPort('frame_on')
-        if self.hasInputFromPort('navigate_mode'):
-            self.props['navigate_mode'] = self.getInputFromPort('navigate_mode')
-        if self.hasInputFromPort('xscale'):
-            self.props['xscale'] = self.getInputFromPort('xscale')
-        if self.hasInputFromPort('axis_off'):
-            self.props['axis_off'] = self.getInputFromPort('axis_off')
-        if self.hasInputFromPort('autoscale_on'):
-            self.props['autoscale_on'] = self.getInputFromPort('autoscale_on')
-        if self.hasInputFromPort('ybound'):
-            self.props['ybound'] = self.getInputFromPort('ybound')
-        if self.hasInputFromPort('rect'):
-            self.constructor_props['rect'] = self.getInputFromPort('rect')
-        if self.hasInputFromPort('sharex'):
-            self.constructor_props['sharex'] = self.getInputFromPort('sharex')
-        if self.hasInputFromPort('yticklabelsSequence'):
-            self.props['yticklabels'] = self.getInputFromPort('yticklabelsSequence')
-        elif self.hasInputFromPort('yticklabelsScalar'):
-            self.props['yticklabels'] = self.getInputFromPort('yticklabelsScalar')
-        if self.hasInputFromPort('autoscaley_on'):
-            self.props['autoscaley_on'] = self.getInputFromPort('autoscaley_on')
-        if self.hasInputFromPort('xmargin'):
-            self.props['xmargin'] = self.getInputFromPort('xmargin')
-        if self.hasInputFromPort('color_cycle'):
-            self.props['color_cycle'] = self.getInputFromPort('color_cycle')
-            self.props['color_cycle'] = translate_color(self.props['color_cycle'])
-        if self.hasInputFromPort('frameon'):
-            self.constructor_props['frameon'] = self.getInputFromPort('frameon')
-        if self.hasInputFromPort('xlabel'):
-            self.props['xlabel'] = self.getInputFromPort('xlabel')
-        if self.hasInputFromPort('xbound'):
-            self.props['xbound'] = self.getInputFromPort('xbound')
-        if self.hasInputFromPort('yticks'):
-            self.props['yticks'] = self.getInputFromPort('yticks')
-        if self.hasInputFromPort('ymargin'):
-            self.props['ymargin'] = self.getInputFromPort('ymargin')
-        if self.hasInputFromPort('position'):
-            self.props['position'] = self.getInputFromPort('position')
-        if self.hasInputFromPort('anchor'):
-            self.props['anchor'] = self.getInputFromPort('anchor')
-            self.props['anchor'] = translate_MplAxesProperties_anchor(self.props['anchor'])
-        if self.hasInputFromPort('xticklabelsSequence'):
-            self.props['xticklabels'] = self.getInputFromPort('xticklabelsSequence')
-        elif self.hasInputFromPort('xticklabelsScalar'):
-            self.props['xticklabels'] = self.getInputFromPort('xticklabelsScalar')
-        if self.hasInputFromPort('titleProperties'):
-            self.sub_props['title'] = self.getInputFromPort('titleProperties')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-        if not matplotlib.cbook.iterable(objs):
-            objs = [objs]
-        else:
-            objs = matplotlib.cbook.flatten(objs)
-        for obj in objs:
-            if 'title' in self.sub_props:
-                self.sub_props['title'].update_props(obj.title)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplAxesProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                if 'title' in self.sub_props:
+                    self.sub_props['title'].update_props(obj.title)
+                if 'xaxis' in self.sub_props:
+                    self.sub_props['xaxis'].update_props(obj.xaxis)
+                if 'yaxis' in self.sub_props:
+                    self.sub_props['yaxis'].update_props(obj.yaxis)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplAxesProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('adjustable'):
+            artist.props['adjustable'] = self.get_input('adjustable')
+        if self.has_input('cursor_props'):
+            artist.props['cursor_props'] = self.get_input('cursor_props')
+        if self.has_input('figure'):
+            artist.props['figure'] = self.get_input('figure')
+        if self.has_input('yscale'):
+            artist.props['yscale'] = self.get_input('yscale')
+        if self.has_input('navigate'):
+            artist.props['navigate'] = self.get_input('navigate')
+        if self.has_input('aspect'):
+            artist.props['aspect'] = self.get_input('aspect')
+        if self.has_input('axis_bgcolor'):
+            artist.props['axis_bgcolor'] = self.get_input('axis_bgcolor')
+            artist.props['axis_bgcolor'] = translate_color(artist.props['axis_bgcolor'])
+        if self.has_input('ylimSequence'):
+            artist.props['ylim'] = self.get_input('ylimSequence')
+        elif self.has_input('ylimScalar'):
+            artist.props['ylim'] = self.get_input('ylimScalar')
+        if self.has_input('sharey'):
+            artist.constructor_props['sharey'] = self.get_input('sharey')
+        if self.has_input('xlimSequence'):
+            artist.props['xlim'] = self.get_input('xlimSequence')
+        elif self.has_input('xlimScalar'):
+            artist.props['xlim'] = self.get_input('xlimScalar')
+        if self.has_input('axis_on'):
+            artist.props['axis_on'] = self.get_input('axis_on')
+        if self.has_input('title'):
+            artist.props['title'] = self.get_input('title')
+        if self.has_input('axisbg'):
+            artist.constructor_props['axisbg'] = self.get_input('axisbg')
+        if self.has_input('label'):
+            artist.constructor_props['label'] = self.get_input('label')
+        if self.has_input('xticks'):
+            artist.props['xticks'] = self.get_input('xticks')
+        if self.has_input('fig'):
+            artist.constructor_props['fig'] = self.get_input('fig')
+        if self.has_input('ylabel'):
+            artist.props['ylabel'] = self.get_input('ylabel')
+        if self.has_input('autoscalex_on'):
+            artist.props['autoscalex_on'] = self.get_input('autoscalex_on')
+        if self.has_input('rasterization_zorder'):
+            artist.props['rasterization_zorder'] = self.get_input('rasterization_zorder')
+        if self.has_input('axes_locator'):
+            artist.props['axes_locator'] = self.get_input('axes_locator')
+        if self.has_input('axisbelow'):
+            artist.props['axisbelow'] = self.get_input('axisbelow')
+        if self.has_input('frame_on'):
+            artist.props['frame_on'] = self.get_input('frame_on')
+        if self.has_input('navigate_mode'):
+            artist.props['navigate_mode'] = self.get_input('navigate_mode')
+        if self.has_input('xscale'):
+            artist.props['xscale'] = self.get_input('xscale')
+        if self.has_input('axis_off'):
+            artist.props['axis_off'] = self.get_input('axis_off')
+        if self.has_input('autoscale_on'):
+            artist.props['autoscale_on'] = self.get_input('autoscale_on')
+        if self.has_input('ybound'):
+            artist.props['ybound'] = self.get_input('ybound')
+        if self.has_input('rect'):
+            artist.constructor_props['rect'] = self.get_input('rect')
+        if self.has_input('sharex'):
+            artist.constructor_props['sharex'] = self.get_input('sharex')
+        if self.has_input('yticklabelsSequence'):
+            artist.props['yticklabels'] = self.get_input('yticklabelsSequence')
+        elif self.has_input('yticklabelsScalar'):
+            artist.props['yticklabels'] = self.get_input('yticklabelsScalar')
+        if self.has_input('autoscaley_on'):
+            artist.props['autoscaley_on'] = self.get_input('autoscaley_on')
+        if self.has_input('xmargin'):
+            artist.props['xmargin'] = self.get_input('xmargin')
+        if self.has_input('color_cycle'):
+            artist.props['color_cycle'] = self.get_input('color_cycle')
+            artist.props['color_cycle'] = translate_color(artist.props['color_cycle'])
+        if self.has_input('frameon'):
+            artist.constructor_props['frameon'] = self.get_input('frameon')
+        if self.has_input('xlabel'):
+            artist.props['xlabel'] = self.get_input('xlabel')
+        if self.has_input('xbound'):
+            artist.props['xbound'] = self.get_input('xbound')
+        if self.has_input('yticks'):
+            artist.props['yticks'] = self.get_input('yticks')
+        if self.has_input('ymargin'):
+            artist.props['ymargin'] = self.get_input('ymargin')
+        if self.has_input('position'):
+            artist.props['position'] = self.get_input('position')
+        if self.has_input('anchor'):
+            artist.props['anchor'] = self.get_input('anchor')
+            artist.props['anchor'] = translate_MplAxesProperties_anchor(artist.props['anchor'])
+        if self.has_input('xticklabelsSequence'):
+            artist.props['xticklabels'] = self.get_input('xticklabelsSequence')
+        elif self.has_input('xticklabelsScalar'):
+            artist.props['xticklabels'] = self.get_input('xticklabelsScalar')
+        if self.has_input('titleProperties'):
+            artist.sub_props['title'] = self.get_input('titleProperties')
+        if self.has_input('xaxisProperties'):
+            artist.sub_props['xaxis'] = self.get_input('xaxisProperties')
+        if self.has_input('yaxisProperties'):
+            artist.sub_props['yaxis'] = self.get_input('yaxisProperties')
+
 
 class MplAxesSubplotProperties(MplAxesProperties):
     """None
@@ -3567,27 +4394,43 @@ class MplAxesSubplotProperties(MplAxesProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplAxesSubplotProperties)")]
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplAxesSubplotProperties)")]
 
-    def __init__(self):
-        MplAxesProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
+    class Artist(MplAxesProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
 
-    def compute(self):
-        MplAxesProperties.compute(self)
-        if self.hasInputFromPort('fig'):
-            self.constructor_props['fig'] = self.getInputFromPort('fig')
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
 
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
+        def update_sub_props(self, objs):
+            MplAxesProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplAxesSubplotProperties.Artist()
+            self.set_output("value", artist)
+
+        MplAxesProperties.compute(self, artist)
+        if self.has_input('fig'):
+            artist.constructor_props['fig'] = self.get_input('fig')
 
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 class MplFigureProperties(MplArtistProperties):
     """
@@ -3635,51 +4478,67 @@ class MplFigureProperties(MplArtistProperties):
                 {'optional': True, 'docstring': 'Set the dots-per-inch of the figure'}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplFigureProperties)")]
-
-    def __init__(self):
-        MplArtistProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplArtistProperties.compute(self)
-        if self.hasInputFromPort('edgecolor'):
-            self.props['edgecolor'] = self.getInputFromPort('edgecolor')
-            self.props['edgecolor'] = translate_color(self.props['edgecolor'])
-        if self.hasInputFromPort('canvas'):
-            self.props['canvas'] = self.getInputFromPort('canvas')
-        if self.hasInputFromPort('facecolor'):
-            self.props['facecolor'] = self.getInputFromPort('facecolor')
-            self.props['facecolor'] = translate_color(self.props['facecolor'])
-        if self.hasInputFromPort('size_inches'):
-            self.props['size_inches'] = self.getInputFromPort('size_inches')
-        if self.hasInputFromPort('figwidth'):
-            self.props['figwidth'] = self.getInputFromPort('figwidth')
-        if self.hasInputFromPort('frameon'):
-            self.props['frameon'] = self.getInputFromPort('frameon')
-        if self.hasInputFromPort('subplotpars'):
-            self.constructor_props['subplotpars'] = self.getInputFromPort('subplotpars')
-        if self.hasInputFromPort('figheight'):
-            self.props['figheight'] = self.getInputFromPort('figheight')
-        if self.hasInputFromPort('figsize'):
-            self.constructor_props['figsize'] = self.getInputFromPort('figsize')
-        if self.hasInputFromPort('linewidth'):
-            self.constructor_props['linewidth'] = self.getInputFromPort('linewidth')
-        if self.hasInputFromPort('tight_layout'):
-            self.props['tight_layout'] = self.getInputFromPort('tight_layout')
-        if self.hasInputFromPort('dpi'):
-            self.props['dpi'] = self.getInputFromPort('dpi')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplFigureProperties)")]
+
+    class Artist(MplArtistProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplArtistProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplFigureProperties.Artist()
+            self.set_output("value", artist)
+
+        MplArtistProperties.compute(self, artist)
+        if self.has_input('edgecolor'):
+            artist.props['edgecolor'] = self.get_input('edgecolor')
+            artist.props['edgecolor'] = translate_color(artist.props['edgecolor'])
+        if self.has_input('canvas'):
+            artist.props['canvas'] = self.get_input('canvas')
+        if self.has_input('facecolor'):
+            artist.props['facecolor'] = self.get_input('facecolor')
+            artist.props['facecolor'] = translate_color(artist.props['facecolor'])
+        if self.has_input('size_inches'):
+            artist.props['size_inches'] = self.get_input('size_inches')
+        if self.has_input('figwidth'):
+            artist.props['figwidth'] = self.get_input('figwidth')
+        if self.has_input('frameon'):
+            artist.props['frameon'] = self.get_input('frameon')
+        if self.has_input('subplotpars'):
+            artist.constructor_props['subplotpars'] = self.get_input('subplotpars')
+        if self.has_input('figheight'):
+            artist.props['figheight'] = self.get_input('figheight')
+        if self.has_input('figsize'):
+            artist.constructor_props['figsize'] = self.get_input('figsize')
+        if self.has_input('linewidth'):
+            artist.constructor_props['linewidth'] = self.get_input('linewidth')
+        if self.has_input('tight_layout'):
+            artist.props['tight_layout'] = self.get_input('tight_layout')
+        if self.has_input('dpi'):
+            artist.props['dpi'] = self.get_input('dpi')
+
 
 class MplAnnotationProperties(MplTextProperties):
     """
@@ -3708,41 +4567,57 @@ class MplAnnotationProperties(MplTextProperties):
                 {'optional': True}),
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(MplAnnotationProperties)")]
-
-    def __init__(self):
-        MplTextProperties.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-
-    def compute(self):
-        MplTextProperties.compute(self)
-        if self.hasInputFromPort('xycoords'):
-            self.constructor_props['xycoords'] = self.getInputFromPort('xycoords')
-        if self.hasInputFromPort('figure'):
-            self.props['figure'] = self.getInputFromPort('figure')
-        if self.hasInputFromPort('annotation_clip'):
-            self.constructor_props['annotation_clip'] = self.getInputFromPort('annotation_clip')
-        if self.hasInputFromPort('xytext'):
-            self.constructor_props['xytext'] = self.getInputFromPort('xytext')
-        if self.hasInputFromPort('s'):
-            self.constructor_props['s'] = self.getInputFromPort('s')
-        if self.hasInputFromPort('xy'):
-            self.constructor_props['xy'] = self.getInputFromPort('xy')
-        if self.hasInputFromPort('textcoords'):
-            self.constructor_props['textcoords'] = self.getInputFromPort('textcoords')
-        if self.hasInputFromPort('arrowprops'):
-            self.constructor_props['arrowprops'] = self.getInputFromPort('arrowprops')
-
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
+    # only one output port: 'value'
+    _output_ports = [("value", "(MplAnnotationProperties)")]
+
+    class Artist(MplTextProperties.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            MplTextProperties.Artist.update_sub_props(self, objs)
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = MplAnnotationProperties.Artist()
+            self.set_output("value", artist)
+
+        MplTextProperties.compute(self, artist)
+        if self.has_input('xycoords'):
+            artist.constructor_props['xycoords'] = self.get_input('xycoords')
+        if self.has_input('figure'):
+            artist.props['figure'] = self.get_input('figure')
+        if self.has_input('annotation_clip'):
+            artist.constructor_props['annotation_clip'] = self.get_input('annotation_clip')
+        if self.has_input('xytext'):
+            artist.constructor_props['xytext'] = self.get_input('xytext')
+        if self.has_input('s'):
+            artist.constructor_props['s'] = self.get_input('s')
+        if self.has_input('xy'):
+            artist.constructor_props['xy'] = self.get_input('xy')
+        if self.has_input('textcoords'):
+            artist.constructor_props['textcoords'] = self.get_input('textcoords')
+        if self.has_input('arrowprops'):
+            artist.constructor_props['arrowprops'] = self.get_input('arrowprops')
+
 
 
 _modules = [
diff --git a/vistrails/packages/matplotlib/artists_template.py.mako b/vistrails/packages/matplotlib/artists_template.py.mako
index af51b1d..2e5ff9a 100644
--- a/vistrails/packages/matplotlib/artists_template.py.mako
+++ b/vistrails/packages/matplotlib/artists_template.py.mako
@@ -9,9 +9,11 @@ ${specs.custom_code}
 
 <%def name="get_props(t_ps)">\
 % if t_ps.constructor_arg:
-self.constructor_props['${t_ps.arg}']\
+artist.constructor_props['${t_ps.arg}']\
+% elif t_ps.not_setp:
+artist.not_setp_props['${t_ps.arg}']\
 % else:
-self.props['${t_ps.arg}']\
+artist.props['${t_ps.arg}']\
 % endif
 </%def>
 
@@ -63,35 +65,71 @@ class ${spec.name}(${spec.superklass}):
         % endfor
         ]
 
-    # no output ports except self
-    _output_ports = [("self", "(${spec.name})")]
+    # only one output port: 'value'
+    _output_ports = [("value", "(${spec.name})")]
 
-    def __init__(self):
-        ${spec.superklass}.__init__(self)
-        self.props = {}
-        self.constructor_props = {}
-        self.sub_props = {}
-        % if spec.get_init():
-        ${spec.get_init()}
-        % endif
+    class Artist(${spec.superklass}.Artist):
+        def __init__(self):
+            self.props = {}
+            self.constructor_props = {}
+            self.not_setp_props = {}
+            self.sub_props = {}
+            % if spec.get_init():
+            ${spec.get_init()}
+            % endif
+
+        def update_props(self, objs):
+            matplotlib.artist.setp(objs, **self.props)
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                for attr_name, attr_val in self.not_setp_props.iteritems():
+                    setattr(obj, attr_name, attr_val)
+            self.update_sub_props(objs)
+
+        def update_sub_props(self, objs):
+            ${spec.superklass}.Artist.update_sub_props(self, objs)
+            % if any(ps.is_property() for ps in spec.output_port_specs):
+            if not matplotlib.cbook.iterable(objs):
+                objs_iter = [objs]
+            else:
+                objs_iter = matplotlib.cbook.flatten(objs)
+            for obj in objs_iter:
+                % for ps in spec.output_port_specs:
+                % if ps.is_property():
+                if '${ps.arg}' in self.sub_props:
+                    self.sub_props['${ps.arg}'].update_props(obj.${ps.compute_parent})
+                % endif
+                % endfor
+            % endif
+
+        def update_kwargs(self, kwargs):
+            kwargs.update(self.constructor_props)
+            kwargs.update(self.props)
+
+    def compute(self, artist=None):
+        if artist is None:
+            artist = ${spec.name}.Artist()
+            self.set_output("value", artist)
 
-    def compute(self):
         % if spec.get_compute_before():
         ${spec.get_compute_before()}
         % endif
-        ${spec.superklass}.compute(self)
+        ${spec.superklass}.compute(self, artist)
         % for ps in spec.port_specs:
         % if not ps.hide and ps.in_kwargs:
         % if ps.required:
         % if ps.has_alternate_versions():
-        if self.hasInputFromPort('${ps.name}'):
-            ${get_props(ps)} = self.getInputFromPort('${ps.name}')
+        if self.has_input('${ps.name}'):
+            ${get_props(ps)} = self.get_input('${ps.name}')
             % if ps.translations:
             ${do_translate(spec, ps)}
             % endif
         % for alt_ps in ps.alternate_specs:
-        elif self.hasInputFromPort('${alt_ps.name}'):
-            ${get_props(ps)} = self.getInputFromPort('${alt_ps.name}')
+        elif self.has_input('${alt_ps.name}'):
+            ${get_props(ps)} = self.get_input('${alt_ps.name}')
             % if alt_ps.translations:
             ${do_translate(spec, alt_ps, ps)}
             % endif
@@ -100,66 +138,37 @@ class ${spec.name}(${spec.superklass}):
             raise ModuleError(self, 'Must set one of "${ps.name}", ' \
                                   '${', '.join('"%s"' % alt_ps.name for alt_ps in ps.alternate_specs)}')
         % else:
-        ${get_props(ps)} = self.getInputFromPort('${ps.name}')
+        ${get_props(ps)} = self.get_input('${ps.name}')
         % if ps.translations:
         ${do_translate(spec, ps)}
         % endif
         % endif
-        ## self.props['${ps.arg}'] = self.getInputFromPort('${ps.name}')
-        ## % if ps.translations:
-        ## ${do_translate(spec, ps)}
-        ## % endif
         % else:
-        if self.hasInputFromPort('${ps.name}'):
-            ${get_props(ps)} = self.getInputFromPort('${ps.name}')
+        if self.has_input('${ps.name}'):
+            ${get_props(ps)} = self.get_input('${ps.name}')
             % if ps.translations:
             ${do_translate(spec, ps)}
             % endif
         % for alt_ps in ps.alternate_specs:
-        elif self.hasInputFromPort('${alt_ps.name}'):
-            ${get_props(ps)} = self.getInputFromPort('${alt_ps.name}')
+        elif self.has_input('${alt_ps.name}'):
+            ${get_props(ps)} = self.get_input('${alt_ps.name}')
             % if alt_ps.translations:
             ${do_translate(spec, alt_ps, ps)}
             % endif
         % endfor
-        ## if self.hasInputFromPort('${ps.name}'):
-        ##     self.props['${ps.arg}'] = self.getInputFromPort('${ps.name}')
-        ##     % if ps.translations:
-        ##     ${do_translate(spec, ps)}
-        ##     % endif
         % endif
         % endif
         % endfor
         % for ps in spec.output_port_specs:
         % if ps.is_property():
-        if self.hasInputFromPort('${ps.name}'):
-            self.sub_props['${ps.arg}'] = self.getInputFromPort('${ps.name}')
+        if self.has_input('${ps.name}'):
+            artist.sub_props['${ps.arg}'] = self.get_input('${ps.name}')
         % endif
-        % endfor            
+        % endfor
 
         % if spec.get_compute_after():
         ${spec.get_compute_after()}
         % endif
-        
-    def update_props(self, objs):
-        matplotlib.artist.setp(objs, **self.props)
-        % if any(ps.is_property() for ps in spec.output_port_specs):
-        if not matplotlib.cbook.iterable(objs):
-            objs = [objs]
-        else:
-            objs = matplotlib.cbook.flatten(objs)
-        for obj in objs:
-            % for ps in spec.output_port_specs:
-            % if ps.is_property():
-            if '${ps.arg}' in self.sub_props:
-                self.sub_props['${ps.arg}'].update_props(obj.${ps.compute_parent})
-            % endif
-            % endfor
-        % endif
-
-    def update_kwargs(self, kwargs):
-        kwargs.update(self.constructor_props)
-        kwargs.update(self.props)
 
 % endfor
 
diff --git a/vistrails/packages/matplotlib/bases.py b/vistrails/packages/matplotlib/bases.py
index 428505d..74a9290 100644
--- a/vistrails/packages/matplotlib/bases.py
+++ b/vistrails/packages/matplotlib/bases.py
@@ -1,104 +1,67 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import pylab
 import urllib
 
+from matplotlib.backend_bases import FigureCanvasBase
+
+from vistrails.core.configuration import ConfigField
 from vistrails.core.modules.basic_modules import CodeRunnerMixin
+from vistrails.core.modules.config import ModuleSettings, IPort
+from vistrails.core.modules.output_modules import ImageFileMode, \
+    ImageFileModeConfig, OutputModule, IPythonModeConfig, IPythonMode
 from vistrails.core.modules.vistrails_module import Module, NotCacheable
 
 ################################################################################
 
 class MplProperties(Module):
-    _output_ports = [("self", "(MplProperties)")]
-    
-    def update_props(self, objs):
-        # must implement in subclass
+    def compute(self, artist):
         pass
-        
+
+    class Artist(object):
+        def update_sub_props(self, objs):
+            # must implement in subclass
+            pass
 
 #base class for 2D plots
 class MplPlot(NotCacheable, Module):
-    # _input_ports = [("subfigRow", "(edu.utah.sci.vistrails.basic:Integer)",
-    #                  {"defaults": ["1"]}),
-    #                 ("subfigCol", "(edu.utah.sci.vistrails.basic:Integer)",
-    #                  {"defaults": ["1"]})]
-    _output_ports = [("self", "(MplPlot)")]
-
-    def __init__(self):
-        Module.__init__(self)
-        # self.figInstance = None
-
-    # def set_fig(self, fig):
-    #     self.figInstance = fig
-
-    # def get_fig(self):
-    #     if self.figInstance is None:
-    #         self.figInstance = pylab.figure()
-    #     return self.figInstance
-
-    # def get_translation(self, port, val):
-    #     '''doing translation for enum type of the input ports'''
-        
-    #     for klass in self.__class__.mro():
-    #         if '_mpl_translations' in klass.__dict__ and \
-    #                 port in klass._mpl_translations:
-    #             obj = klass._mpl_translations[port]
-    #             if isinstance(obj, dict):
-    #                 if val in obj:
-    #                     return obj[val]
-    #                 else:
-    #                     raise ArtistException(
-    #                         "Value '%s' for input '%s' invalid." % (val, port))
-    #             else:
-    #                 print "trying to call"
-    #                 return obj(val)
-    #     return None
-    
-    # def get_kwargs_except(self, listExcepts):
-    #     ''' getting all the input ports except those ports listed inside listExcepts
-    #         return format: {port_name:value,...}'''
-    #     kwargs = {}
-    #     for port in self.inputPorts:
-    #         if port not in listExcepts:
-    #             val = self.getInputFromPort(port)
-    #             translation = self.get_translation(port, val)
-    #             if translation is not None:
-    #                 kwargs[port] = translation
-    #             else:
-    #                 kwargs[port] = val
-    #     return kwargs
+    pass
 
 class MplSource(CodeRunnerMixin, MplPlot):
     """
@@ -111,62 +74,108 @@ class MplSource(CodeRunnerMixin, MplPlot):
     
     """
     _input_ports = [('source', '(basic:String)')]
+    _output_ports = [('value', '(MplSource)')]
 
     def compute(self):
-        """ compute() -> None
-        """
-        source = self.getInputFromPort('source')
-        s = ('from pylab import *\n' +
+        source = self.get_input('source')
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 source))
+
+    def plot_figure(self, figure, source):
+        s = ('from pylab import *\n'
              'from numpy import *\n' +
+             'figure(%d)\n' % figure.number +
              urllib.unquote(source))
-
         self.run_code(s, use_input=True, use_output=True)
 
 class MplFigure(Module):
-    _input_ports = [("addPlot", "(MplPlot)"),
+    _input_ports = [IPort("addPlot", "(MplPlot)", depth=1),
                     ("axesProperties", "(MplAxesProperties)"),
                     ("figureProperties", "(MplFigureProperties)"),
                     ("setLegend", "(MplLegend)")]
 
     _output_ports = [("self", "(MplFigure)")]
 
-    def __init__(self):
-        Module.__init__(self)
-        self.figInstance = None
-
-    def updateUpstream(self):
-        if self.figInstance is None:
-            self.figInstance = pylab.figure()
+    def compute(self):
+        # Create a figure
+        self.figInstance = pylab.figure()
         pylab.hold(True)
-        Module.updateUpstream(self)
 
-    def compute(self):
-        plots = self.getInputListFromPort("addPlot")
+        # Run the plots
+        plots = self.get_input("addPlot")
+        for plot in plots:
+            plot(self.figInstance)
 
-        if self.hasInputFromPort("figureProperties"):
-            figure_props = self.getInputFromPort("figureProperties")
+        if self.has_input("figureProperties"):
+            figure_props = self.get_input("figureProperties")
             figure_props.update_props(self.figInstance)
-        if self.hasInputFromPort("axesProperties"):
-            axes_props = self.getInputFromPort("axesProperties")
+        if self.has_input("axesProperties"):
+            axes_props = self.get_input("axesProperties")
             axes_props.update_props(self.figInstance.gca())
-        if self.hasInputFromPort("setLegend"):
-            legend = self.getInputFromPort("setLegend")
+        if self.has_input("setLegend"):
+            legend = self.get_input("setLegend")
             self.figInstance.gca().legend()
 
-
-        self.setResult("self", self)
+        self.set_output("self", self)
 
 class MplContourSet(Module):
     pass
 
 class MplQuadContourSet(MplContourSet):
     pass
+
+class MplFigureToFile(ImageFileMode):
+    config_cls = ImageFileModeConfig
+    formats = ['pdf', 'png', 'jpg']
+
+    def compute_output(self, output_module, configuration=None):
+        value = output_module.get_input('value')
+        w = configuration["width"]
+        h = configuration["height"]
+        img_format = self.get_format(configuration)
+        filename = self.get_filename(configuration, suffix='.%s' % img_format)
+
+        w_inches = w / 72.0
+        h_inches = h / 72.0
+        figure = value.figInstance
         
+        previous_size = tuple(figure.get_size_inches())
+        figure.set_size_inches(w_inches, h_inches)
+        canvas = FigureCanvasBase(figure)
+        canvas.print_figure(filename, dpi=72, format=img_format)
+        figure.set_size_inches(previous_size[0],previous_size[1])
+        canvas.draw()
+
+class MplIPythonModeConfig(IPythonModeConfig):
+    mode_type = "ipython"
+    _fields = [ConfigField('width', None, int),
+               ConfigField('height', None, int)]
+
+class MplIPythonMode(IPythonMode):
+    mode_type = "ipython"
+    config_cls = MplIPythonModeConfig
+
+    def compute_output(self, output_module, configuration=None):
+        from IPython.display import set_matplotlib_formats
+        from IPython.core.display import display
+
+        set_matplotlib_formats('png')
+
+        # TODO: use size from configuration
+        fig = output_module.get_input('value')
+        display(fig.figInstance)
+
+class MplFigureOutput(OutputModule):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules.output_configuration:OutputModuleConfigurationWidget")
+    _input_ports = [('value', 'MplFigure')]
+    _output_modes = [MplFigureToFile, MplIPythonMode]
+
 _modules = [(MplProperties, {'abstract': True}),
-            (MplPlot, {'abstract': True}), 
+            (MplPlot, {'abstract': True}),
             (MplSource, {'configureWidgetType': \
                              ('vistrails.packages.matplotlib.widgets',
                               'MplSourceConfigurationWidget')}),
             MplFigure,
             MplContourSet,
-            MplQuadContourSet]
+            MplQuadContourSet,
+            MplFigureOutput]
diff --git a/vistrails/packages/matplotlib/diff.py b/vistrails/packages/matplotlib/diff.py
index e5ddc9e..97c3000 100644
--- a/vistrails/packages/matplotlib/diff.py
+++ b/vistrails/packages/matplotlib/diff.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import re
 from xml.etree import ElementTree as ET
 from specs import SpecList, ModuleSpec, InputPortSpec, OutputPortSpec, \
@@ -18,8 +56,6 @@ def compute_ps_diff(root, in_ps_list, out_ps_list, code_ref, qualifier,
     in_port_specs_set = set(in_port_specs.iterkeys())
 
     for arg in in_port_specs_set - out_port_specs_set:
-        # print 'argument "%s" of code reference "%s" removed' % \
-        #     (arg, code_ref)
         print "- %s.%s.%s" % (code_ref, qualifier, arg)
         elt = ET.Element("deletePortSpec")
         elt.set("code_ref", code_ref)
@@ -33,8 +69,6 @@ def compute_ps_diff(root, in_ps_list, out_ps_list, code_ref, qualifier,
 
     for arg, out_ps in out_port_specs.iteritems():
         if arg not in in_port_specs:
-            # print 'argument "%s" of code reference "%s" added' % \
-            #     (arg, code_ref)
             print "out_ps:", out_ps
             print "+ %s.%s.%s %s" % (code_ref, qualifier, arg, 
                                      ET.tostring(out_ps.to_xml()))
@@ -54,8 +88,6 @@ def compute_ps_diff(root, in_ps_list, out_ps_list, code_ref, qualifier,
 
         in_ps = in_port_specs[arg]
 
-        # attrs = ['name', 'port_type', 'docstring', 'hide', 'entry_types',
-        #          'values', 'defaults', 'translations']
         if qualifier == "output":
             attr_list = OutputPortSpec.attrs
         elif qualifier == "input":
@@ -68,8 +100,6 @@ def compute_ps_diff(root, in_ps_list, out_ps_list, code_ref, qualifier,
             in_val = getattr(in_ps, attr) 
             out_val = getattr(out_ps, attr)
             if in_val != out_val:
-                # print '%s of argument "%s" changed from "%s" to "%s"' % \
-                #     (attr, arg, in_val, out_val)
                 print "C %s.%s.%s.%s %s" % (code_ref, qualifier, arg, attr, 
                                             out_val)
                 elt = ET.Element("changePortSpec")
@@ -110,7 +140,6 @@ def compute_diff(in_fname, out_fname, diff_fname):
         root.append(elt)
 
     for ref in in_refs_set - out_refs_set:
-        # print 'code reference "%s" removed' % ref
         print "- %s" % ref
         elt = ET.Element("deleteModule")
         elt.set("code_ref", ref)
@@ -119,7 +148,6 @@ def compute_diff(in_fname, out_fname, diff_fname):
     for code_ref, out_spec in out_refs.iteritems():
         # need to check port specs, which removed, which added
         if code_ref not in in_refs:
-            # print 'code reference "%s" added' % code_ref
             print "+ %s %s" % (ref, ET.tostring(out_spec.to_xml()))
             elt = ET.Element("addModule")
             elt.set("code_ref", ref)
@@ -143,51 +171,12 @@ def compute_diff(in_fname, out_fname, diff_fname):
                 subelt.text = str(out_val)
                 elt.append(subelt)
                 root.append(elt)
-        
-        # if in_spec.name != out_spec.name:
-        #     # print 'name of ref "%s" changed from "%s" to "%s"' % \
-        #     #     (out_spec.code_ref, in_spec.name, out_spec.name)
-        #     print "C %s.name %s" % (out_spec.code_ref, out_spec.name)
-        # if in_spec.superklass != out_spec.superklass:
-        #     print 'superclass of ref "%s" changed from "%s" to "%s"' % \
-        #         (out_spec.code_ref, in_spec.superklass, out_spec.superklass)
-            
 
         compute_ps_diff(root, in_spec.port_specs, out_spec.port_specs, 
                         code_ref, "input")
         compute_ps_diff(root, in_spec.output_port_specs, 
                         out_spec.output_port_specs,
                         code_ref, "output")
-        # out_port_specs = dict((ps.arg, ps) for ps in out_spec.port_specs)
-        # in_port_specs = dict((ps.arg, ps) for ps in in_spec.port_specs)
-
-        # out_port_specs_set = set(out_port_specs.iterkeys())
-        # in_port_specs_set = set(in_port_specs.iterkeys())
-
-        # for arg in in_port_specs_set - out_port_specs_set:
-        #     # print 'argument "%s" of code reference "%s" removed' % \
-        #     #     (arg, code_ref)
-        #     print "- %s.%s" % (code_ref, arg)
-
-        # for arg, out_ps in out_port_specs.iteritems():
-        #     if arg not in in_port_specs:
-        #         # print 'argument "%s" of code reference "%s" added' % \
-        #         #     (arg, code_ref)
-        #         print "+ %s.%s" % (code_ref, arg)
-        #         print ET.tostring(out_ps.to_xml())
-        #         continue
-            
-        #     in_ps = in_port_specs[arg]
-
-        #     # attrs = ['name', 'port_type', 'docstring', 'hide', 'entry_types',
-        #     #          'values', 'defaults', 'translations']
-        #     for attr in PortSpec.attrs:
-        #         in_val = getattr(in_ps, attr) 
-        #         out_val = getattr(out_ps, attr)
-        #         if in_val != out_val:
-        #             # print '%s of argument "%s" changed from "%s" to "%s"' % \
-        #             #     (attr, arg, in_val, out_val)
-        #             print "C %s.%s.%s %s" % (code_ref, arg, attr, out_val)
 
     tree = ET.ElementTree(root)
     def indent(elem, level=0):
@@ -264,7 +253,6 @@ def apply_diff(in_fname, diff_fname, out_fname):
                 if port_type == "input":
                     m_spec.port_specs.append(InputPortSpec.from_xml(value))
                 elif port_type == "output":
-                    # print "VALUE:", ET.tostring(value)
                     m_spec.output_port_specs.append(
                         OutputPortSpec.from_xml(value))
                 elif port_type == "alternate":
@@ -296,37 +284,6 @@ def apply_diff(in_fname, diff_fname, out_fname):
             else:
                 setattr(m_spec, attr, value)
 
-    # with f = open(diff_fname):
-    #     f_iter = f.__iter__()
-    #     for line in f_iter:
-    #         line = line.strip()
-    #         if not re.match("[+-C]", line):
-    #             raise RuntimeError("Problem parsing line\n%s" % line)
-    #         if line.startswith('-'):
-    #             arr = line.split(' ', 1)
-    #             prop = arr[1].split('.')
-    #             if len(prop) < 2:
-    #                 idx = in_refs[prop[0]][0]
-    #                 del in_specs.module_specs[idx]
-    #             else:
-    #                 m_specs = in_refs[prop[0]][1]
-    #                 if prop[1] == 'input':
-    #                     idx = in_ips_refs[prop[0], prop[2]][0]
-    #                     del m_specs.port_specs[idx]
-    #                 elif prop[1] == 'output':
-    #                     idx = in_ops_refs[prop[0], prop[2]][0]
-    #                     del m_specs.output_port_specs[idx]
-    #                 else:
-    #                     raise ValueError('Cannot access list of type "%s"' %
-    #                                      prop[1])
-    #         elif line.startswith('+'):
-    #             arr = line.split(' ', 2)
-    #             prop = arr[1].split('.')
-    #             if len(prop) < 2:
-    #                 in_specs.module_specs.append(ModuleSpec.from_xml(arr[2]))
-                
-    #         line.split(' ', 2)
-            
     in_specs.write_to_xml(out_fname)
 
 def run_compute():
diff --git a/vistrails/packages/matplotlib/figure_cell.py b/vistrails/packages/matplotlib/figure_cell.py
index 5f4029b..18510db 100644
--- a/vistrails/packages/matplotlib/figure_cell.py
+++ b/vistrails/packages/matplotlib/figure_cell.py
@@ -1,40 +1,45 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
 """ This file describe a new type of spreadsheet cell to embed
 Matplotlib viewer into our spreadsheet
-
 """
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 import os
 
@@ -43,13 +48,19 @@ import pylab
 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg, NavigationToolbar2QT
 from matplotlib.backend_bases import NavigationToolbar2, FigureManagerBase
 
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, SpreadsheetMode
 from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, QCellToolBar
 
 FigureCanvasQTAgg.DEBUG = True
 
 ################################################################################
 
+class MplFigureToSpreadsheet(SpreadsheetMode):
+    def compute_output(self, output_module, configuration=None):
+        fig = output_module.get_input('value')
+        self.display_and_wait(output_module, configuration,
+                              MplFigureCellWidget, (fig,))
+
 class MplFigureCell(SpreadsheetCell):
     """
     MplFigureCell is a spreadsheet cell for displaying Figure from
@@ -63,16 +74,22 @@ class MplFigureCell(SpreadsheetCell):
         The class will take the figure manager and embed it into the spreadsheet
         
         """
-        if self.hasInputFromPort('figure'):
-            fig = self.getInputFromPort('figure')
+        if self.has_input('figure'):
+            fig = self.get_input('figure')
             self.displayAndWait(MplFigureCellWidget, (fig, ))
 
 class MplFigureCellWidget(QCellWidget):
     """
     MplFigureCellWidget is the actual QWidget taking the FigureManager
     as a child for displaying figures
-    
+
     """
+    save_formats = ["Portable Document Format (*.pdf)",
+                    "Portable Network Graphic (*.png)",
+                    "PostScript (*.ps *.eps)",
+                    "Raw images (*.raw *.rgba)",
+                    "Scalable Vector Graphics (*.svg *.svgz)"]
+
     def __init__(self, parent=None):
         """ MplFigureCellWidget(parent: QWidget) -> MplFigureCellWidget
         Initialize the widget with its central layout
@@ -83,27 +100,13 @@ class MplFigureCellWidget(QCellWidget):
         centralLayout = QtGui.QVBoxLayout()
         self.setLayout(centralLayout)
         centralLayout.setMargin(0)
-        centralLayout.setSpacing(0)        
-        # self.figManager = pylab.get_current_fig_manager()
-        # self.figManager = None
-        # self.figNumber = None
+        centralLayout.setSpacing(0)
         self.canvas = None
         self.figure = None
         self.figManager = None
         self.toolBarType = MplFigureCellToolBar
         self.mplToolbar = None
 
-    # def getFigManager(self):
-    #     if self.figNumber is not None:
-    #         pylab.figure(self.figNumber)
-    #         return pylab.get_current_fig_manager()
-    #     return None
-
-    # def getFigure(self):
-    #     if self.figNumber is not None:
-    #         return pylab.figure(self.figNumber)
-    #     return None
-
     def updateContents(self, inputPorts):
         """ updateContents(inputPorts: tuple) -> None
         Update the widget contents based on the input data
@@ -115,51 +118,13 @@ class MplFigureCellWidget(QCellWidget):
                 self.layout().removeWidget(self.canvas)
 
             self.figure = fig.figInstance
-                
-            # self.figure.set_size_inches(8.0,6.0)
+
             self.canvas = FigureCanvasQTAgg(self.figure)
             self.mplToolbar = MplNavigationToolbar(self.canvas, None)
             self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                       QtGui.QSizePolicy.Expanding)
-            # self.figManager = FigureManagerBase(self.canvas, self.figure.number)
             self.layout().addWidget(self.canvas)
 
-            # Update the new figure canvas
-            # self.canvas.draw()
-            # self.layout().addWidget(self.getFigManager().window)
-
-        # Update the new figure canvas
-        # self.getFigManager().canvas.draw()            
-
-        # # Replace the old one with the new one
-        # if newFigManager!=self.figManager:
-            
-        #     # Remove the old figure manager
-        #     if self.figManager:
-        #         self.figManager.window.hide()
-        #         self.layout().removeWidget(self.figManager.window)
-
-        #     # Add the new one in
-        #     self.layout().addWidget(newFigManager.window)
-
-        #     # Destroy the old one if possible
-        #     if self.figManager:
-                
-        #         try:                    
-        #             pylab.close(self.figManager.canvas.figure)
-        #         # There is a bug in Matplotlib backend_qt4. It is a
-        #         # wrong command for Qt4. Just ignore it and continue
-        #         # to destroy the widget
-        #         except:
-        #             pass
-                
-        #         self.figManager.window.deleteLater()
-        #         del self.figManager
-
-        #     # Save back the manager
-        #     self.figManager = newFigManager
-        #     self.update()
-
     def keyPressEvent(self, event):
         print "KEY PRESS:",  event.key()
         self.canvas.keyPressEvent(event)
@@ -175,22 +140,10 @@ class MplFigureCellWidget(QCellWidget):
         """
         # Destroy the old one if possible
         if self.figure is not None:
-            # self.getFigManager().window.deleteLater()
             print "pylab:", pylab
             print "self.figure:", self.figure
             pylab.close(self.figure)
-            
-        # if self.figManager:
-            
-        #     try:                    
-        #         pylab.close(self.figManager.canvas.figure)
-        #     # There is a bug in Matplotlib backend_qt4. It is a
-        #     # wrong command for Qt4. Just ignore it and continue
-        #     # to destroy the widget
-        #     except:
-        #         pass
-            
-        #     self.figManager.window.deleteLater()
+
         QCellWidget.deleteLater(self)
 
     def grabWindowPixmap(self):
@@ -198,8 +151,6 @@ class MplFigureCellWidget(QCellWidget):
         Widget special grabbing function
         
         """
-        # pylab.figure(self.figNumber)
-        # figManager = pylab.get_current_fig_manager()
         return QtGui.QPixmap.grabWidget(self.canvas)
 
     def dumpToFile(self, filename):
@@ -251,13 +202,9 @@ class MplFigureCellToolBar(QCellToolBar):
             ('Back', 'Back to  previous view','back.ppm', 'back', False),
             ('Forward', 'Forward to next view','forward.ppm', 'forward', 
              False),
-            # (None, None, None, None),
             ('Pan', 'Pan axes with left mouse, zoom with right', 'move.ppm', 
              'pan', True),
             ('Zoom', 'Zoom to rectangle','zoom_to_rect.ppm', 'zoom', True),
-            # (None, None, None, None),
-            # ('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'),
-            # ('Save', 'Save the figure','filesave.ppm', 'save_figure'),
             )
         icondir = os.path.join(matplotlib.rcParams[ 'datapath' ],'images')
         exclusive_actions = {}
@@ -266,10 +213,7 @@ class MplFigureCellToolBar(QCellToolBar):
             icon = QtGui.QIcon(os.path.join(icondir, image_file))
             action = QtGui.QAction(icon, text, self)
             action.setStatusTip(tooltip_text)
-            # action.setToolTip(tooltip_text)
             action.setCheckable(checkable)
-            # self.connect(action, QtCore.SIGNAL("triggered"), 
-            #              get_callback(callback))
             actions[text] = action
             if text == 'Pan' or text == 'Zoom':
                 exclusive_actions[text] = action
diff --git a/vistrails/packages/matplotlib/generate.py b/vistrails/packages/matplotlib/generate.py
old mode 100644
new mode 100755
index 346a0fa..6472cb3
--- a/vistrails/packages/matplotlib/generate.py
+++ b/vistrails/packages/matplotlib/generate.py
@@ -1,3 +1,42 @@
+#!/usr/bin/env python
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from mako.template import Template
 import sys
 from specs import SpecList
diff --git a/vistrails/packages/matplotlib/identifiers.py b/vistrails/packages/matplotlib/identifiers.py
index 6da2f7c..a7500f8 100644
--- a/vistrails/packages/matplotlib/identifiers.py
+++ b/vistrails/packages/matplotlib/identifiers.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
-## Copyright (C) 2011-2012, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -39,8 +40,10 @@ VisTrails. We are going to use the 'Qt4Agg' backend of the library.
 
 """
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.matplotlib'
 name = 'matplotlib'
-version = '1.0.1'
+version = '1.0.5'
 old_identifiers = ['edu.utah.sci.vistrails.matplotlib',
                    'org.vistrails.matplotlib.new']
diff --git a/vistrails/packages/matplotlib/init.py b/vistrails/packages/matplotlib/init.py
index e465fe4..ed27af0 100644
--- a/vistrails/packages/matplotlib/init.py
+++ b/vistrails/packages/matplotlib/init.py
@@ -1,37 +1,41 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import matplotlib
 matplotlib.use('Qt4Agg', warn=False)
 
@@ -40,7 +44,7 @@ import vistrails.core.db.action
 from vistrails.core.vistrail.module import Module
 from vistrails.core.vistrail.operation import AddOp
 
-from bases import _modules as _base_modules
+from bases import _modules as _base_modules, MplFigureOutput
 from plots import _modules as _plot_modules
 from artists import _modules as _artist_modules
 from identifiers import identifier
@@ -54,8 +58,9 @@ def initialize(*args, **kwargs):
     reg = vistrails.core.modules.module_registry.get_module_registry()
     if reg.has_module('org.vistrails.vistrails.spreadsheet',
                       'SpreadsheetCell'):
-        from figure_cell import MplFigureCell
+        from figure_cell import MplFigureCell, MplFigureToSpreadsheet
         _modules.append(MplFigureCell)
+        MplFigureOutput.register_output_mode(MplFigureToSpreadsheet)
 
 def handle_module_upgrade_request(controller, module_id, pipeline):
     from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
@@ -128,6 +133,7 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
     to_properties = []
     to_axes = []
     old_figure = (None, None)
+    props_name = None
     if module.name == 'MplScatterplot':
         props_name = 'MplPathCollectionProperties'
         props_input = 'pathCollectionProperties'
@@ -145,12 +151,13 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
         old_loc = module.location
         old_figure = find_figure(module)
 
-    module_remap = {'MplPlot': 
+    module_remap = {'MplPlot':
                     [(None, '1.0.0', 'MplSource',
                       {'dst_port_remap': {'source': 'source',
                                           'Hide Toolbar': None},
-                       'src_port_remap': {'source': 'self'}})],
-                    'MplFigure': 
+                       'src_port_remap': {'source': 'value',
+                                          'self': 'value'}})],
+                    'MplFigure':
                     [(None, '1.0.0', None,
                       {'dst_port_remap': {'Script': 'addPlot'},
                        'src_port_remap': {'FigureManager': 'self',
@@ -166,8 +173,9 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
                                           'facecolor': None,
                                           'title': None,
                                           'xlabel': None,
-                                          'ylabel': None},
-                       'src_port_remap': {'source': 'self'}})],
+                                          'ylabel': None,
+                                          'self': 'value'},
+                       'src_port_remap': {'source': 'value'}})],
                     'MplHistogram':
                     [(None, '1.0.0', 'MplHist',
                       {'dst_port_remap': {'columnData': 'x',
@@ -175,10 +183,20 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
                                           'facecolor': None,
                                           'title': None,
                                           'xlabel': None,
-                                          'ylabel': None},
-                       'src_port_remap': {'source': 'self'}})],
+                                          'ylabel': None,
+                                          'self': 'value'},
+                       'src_port_remap': {'source': 'value'}})],
                 }
 
+    # '1.0.2' -> '1.0.3' changes 'self' output port to 'value'
+    module_remap.setdefault('MplSource', []).append(
+                (None, '1.0.3', None, {
+                 'src_port_remap': {'self': 'value'}}))
+    if module.name in (m.__name__ for m in _plot_modules + _artist_modules):
+        module_remap.setdefault(module.name, []).append(
+                (None, '1.0.3', None, {
+                 'src_port_remap': {'self': 'value'}}))
+
     action_list = []
     if old_figure[1] is not None and \
        any(p in inputs[0] or p in inputs[1] for p in to_axes):
@@ -188,13 +206,26 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
         action = vistrails.core.db.action.create_action([('delete', conn)])
         action_list.append(action)
 
-    normal_actions = UpgradeWorkflowHandler.remap_module(controller, module_id, 
-                                                        pipeline, module_remap)
+    try:
+        from vistrails.packages.spreadsheet.init import upgrade_cell_to_output
+    except ImportError:
+        pass
+    else:
+        module_remap = upgrade_cell_to_output(
+                module_remap, module_id, pipeline,
+                'MplFigureCell', 'MplFigureOutput',
+                '1.0.5', 'figure')
+
+    normal_actions = UpgradeWorkflowHandler.remap_module(
+            controller, module_id, pipeline, module_remap)
     action_list.extend(normal_actions)
 
     more_ops = []
     if any(p in inputs[0] or p in inputs[1] for p in to_properties):
         # create props module
+        if props_name is None:
+            raise RuntimeError("properties module needed for unknown module "
+                               "%s" % module.name)
         desc = reg.get_descriptor_by_name(identifier, props_name)
         props_module = \
             controller.create_module_from_descriptor(desc,
@@ -261,9 +292,5 @@ def handle_module_upgrade_request(controller, module_id, pipeline):
                                          fig_module,
                                          'axesProperties')
         more_ops.append(('add', new_conn))
-    
-    # for action in action_list:
-    #     for op in action.operations:
-    #         print "@+>:", op
+
     return action_list
-            
diff --git a/vistrails/packages/matplotlib/mixins.py b/vistrails/packages/matplotlib/mixins.py
index 8da5801..d4b6f79 100644
--- a/vistrails/packages/matplotlib/mixins.py
+++ b/vistrails/packages/matplotlib/mixins.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 class MplCorrBaseMixin(object):
     def compute_after():
         if 'usevlines' in kwargs and kwargs['usevlines']:
@@ -21,7 +59,7 @@ class MplBoxplotMixin(object):
 
 class MplContourBaseMixin(object):
     def compute_before():
-        if self.hasInputFromPort("N") and self.hasInputFromPort("V"):
+        if self.has_input("N") and self.has_input("V"):
             del args[-1]
 
 class MplContourMixin(MplContourBaseMixin):
@@ -41,12 +79,12 @@ class MplPieMixin(object):
 
 class MplAnnotateMixin(object):
     def compute_before():
-        if self.hasInputFromPort("fancyArrowProperties"):
+        if self.has_input("fancyArrowProperties"):
             kwargs['arrowprops'] = \
-                self.getInputFromPort("fancyArrowProperties").props
-        elif self.hasInputFromPort("arrowProperties"):
+                self.get_input("fancyArrowProperties").props
+        elif self.has_input("arrowProperties"):
             kwargs['arrowprops'] = \
-                self.getInputFromPort("arrowProperties").props
+                self.get_input("arrowProperties").props
 
 class MplSpyMixin(object):
     def compute_after():
diff --git a/vistrails/packages/matplotlib/mpl_artists.xml b/vistrails/packages/matplotlib/mpl_artists.xml
index c97e605..ab28418 100644
--- a/vistrails/packages/matplotlib/mpl_artists.xml
+++ b/vistrails/packages/matplotlib/mpl_artists.xml
@@ -1277,22 +1277,18 @@ If rectprops has "boxstyle" key. A FancyBboxPatch is initialized with rectprops
           a boolean which determines whether to draw tick label
 
     </docstring>
-    <inputPortSpec arg="label1On" arg_pos="14" constructor_arg="True" name="label1On" port_type="basic:Boolean">
+    <inputPortSpec arg="label1On" arg_pos="14" not_setp="True" name="label1On" port_type="basic:Boolean">
       <defaults>['True']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="loc" arg_pos="1" constructor_arg="True" name="loc" />
     <inputPortSpec arg="major" arg_pos="16" constructor_arg="True" name="major" port_type="basic:Boolean">
       <defaults>['True']</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="label2On" arg_pos="15" constructor_arg="True" name="label2On" port_type="basic:Boolean">
+    <inputPortSpec arg="label2On" arg_pos="15" not_setp="True" name="label2On" port_type="basic:Boolean">
       <defaults>['False']</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="color" arg_pos="5" constructor_arg="True" name="color" />
-    <inputPortSpec arg="label1" name="label1">
-      <docstring>Set the text of ticklabel</docstring>
-    </inputPortSpec>
-    <inputPortSpec arg="label2" name="label2">
-      <docstring>Set the text of ticklabel2</docstring>
+    <inputPortSpec arg="color" arg_pos="5" constructor_arg="True" name="color" port_type="basic:Color">
+      <translations>translate_color</translations>
     </inputPortSpec>
     <inputPortSpec arg="axes" arg_pos="0" constructor_arg="True" name="axes" />
     <inputPortSpec arg="clip_path" name="clip_path" port_type="basic:String">
@@ -1316,17 +1312,30 @@ For efficiency, if the path happens to be an axis-aligned rectangle, this method
     <inputPortSpec arg="pad" name="pad" port_type="basic:Float">
       <docstring>Set the tick label pad in points</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="gridOn" arg_pos="11" constructor_arg="True" name="gridOn" />
+    <inputPortSpec arg="gridOn" arg_pos="11" not_setp="True" name="gridOn" port_type="basic:Boolean">
+      <docstring>a boolean which determines whether to draw the tickline</docstring>
+    </inputPortSpec>
     <inputPortSpec arg="zorder" arg_pos="10" constructor_arg="True" name="zorder" />
-    <inputPortSpec arg="tick2On" arg_pos="13" constructor_arg="True" name="tick2On" port_type="basic:Boolean">
+    <inputPortSpec arg="tick2On" arg_pos="13" not_setp="True" name="tick2On" port_type="basic:Boolean">
       <defaults>['True']</defaults>
+      <docstring>a boolean which determines whether to draw the 2nd tickline</docstring>
     </inputPortSpec>
     <inputPortSpec arg="labelsize" arg_pos="8" constructor_arg="True" name="labelsize" />
     <inputPortSpec arg="width" arg_pos="4" constructor_arg="True" name="width" />
-    <inputPortSpec arg="tick1On" arg_pos="12" constructor_arg="True" name="tick1On" port_type="basic:Boolean">
+    <inputPortSpec arg="tick1On" arg_pos="12" not_setp="True" name="tick1On" port_type="basic:Boolean">
+      <docstring>a boolean which determines whether to draw the 1st tickline</docstring>
       <defaults>['True']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="size" arg_pos="3" constructor_arg="True" name="size" />
+    <outputPortSpec arg="label1" compute_name="label1" compute_parent="label1" name="label1Properties" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text">
+      <docstring>Set the text of ticklabel</docstring>
+    </outputPortSpec>
+    <outputPortSpec arg="label2" compute_name="label2" compute_parent="label2" name="label2Properties" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text">
+      <docstring>Set the text of ticklabel2</docstring>
+    </outputPortSpec>
+    <outputPortSpec arg="tick1line" compute_name="tick1line" compute_parent="tick1line" name="tick1lineProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.lines.Line2D"/>
+    <outputPortSpec arg="tick2line" compute_name="tick2line" compute_parent="tick2line" name="tick2lineProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.lines.Line2D"/>
+    <outputPortSpec arg="gridline" compute_name="gridline" compute_parent="gridline" name="gridlineProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.lines.Line2D"/>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.axis.XTick" name="MplXTickProperties" superclass="MplTickProperties">
     <docstring>
@@ -1454,6 +1463,8 @@ You can also specify the coordinate system of the label with the transform.  If
 
 For documentation of keyword arguments, see :meth:`matplotlib.axes.Axes.tick_params`.</docstring>
     </inputPortSpec>
+    <outputPortSpec arg="major_ticks" compute_name="major_ticks" compute_parent="get_major_ticks()" name="majorTickProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.Tick" />
+    <outputPortSpec arg="minor_ticks" compute_name="minor_ticks" compute_parent="get_minor_ticks()" name="minorTickProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.Tick" />
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.axis.XAxis" name="MplXAxisProperties" superclass="MplAxisProperties">
     <docstring>None</docstring>
@@ -1843,6 +1854,8 @@ agg_filter: unknown alpha: float (0.0 transparent through 1.0 opaque) animated:
       <alternateSpec arg="xticklabels" name="xticklabelsScalar" port_type="basic:String" />
     </inputPortSpec>
     <outputPortSpec arg="title" compute_name="title" compute_parent="title" name="titleProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text" />
+    <outputPortSpec arg="xaxis" compute_name="xaxis" compute_parent="xaxis" name="xaxisProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.XAxis" />
+    <outputPortSpec arg="yaxis" compute_name="yaxis" compute_parent="yaxis" name="yaxisProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.YAxis" />
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.axes.AxesSubplot" name="MplAxesSubplotProperties" superclass="MplAxesProperties">
     <docstring>None</docstring>
diff --git a/vistrails/packages/matplotlib/mpl_artists_diff.xml b/vistrails/packages/matplotlib/mpl_artists_diff.xml
index b160a37..1547ef6 100644
--- a/vistrails/packages/matplotlib/mpl_artists_diff.xml
+++ b/vistrails/packages/matplotlib/mpl_artists_diff.xml
@@ -19,11 +19,31 @@
     <value>yticks</value>
   </changePortSpec>
   <deletePortSpec altName="yticksScalar" code_ref="matplotlib.axes.Axes" port="yticks" type="alternate" />
+  <addPortSpec code_ref="matplotlib.axes.Axes" port="yaxis" type="output">
+    <value>
+      <outputPortSpec arg="yaxis" compute_name="yaxis" compute_parent="yaxis" name="yaxisProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.YAxis" />
+    </value>
+  </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axes.Axes" port="xaxis" type="output">
+    <value>
+      <outputPortSpec arg="xaxis" compute_name="xaxis" compute_parent="xaxis" name="xaxisProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.XAxis" />
+    </value>
+  </addPortSpec>
   <addPortSpec code_ref="matplotlib.axes.Axes" port="title" type="output">
     <value>
       <outputPortSpec arg="title" compute_name="title" compute_parent="title" name="titleProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text" />
     </value>
   </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Axis" port="major_ticks" type="output">
+    <value>
+      <outputPortSpec arg="major_ticks" compute_name="major_ticks" compute_parent="get_major_ticks()" name="majorTickProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.Tick" />
+    </value>
+  </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Axis" port="minor_ticks" type="output">
+    <value>
+      <outputPortSpec arg="minor_ticks" compute_name="minor_ticks" compute_parent="get_minor_ticks()" name="minorTickProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.axis.Tick" />
+    </value>
+  </addPortSpec>
   <changePortSpec attr="translations" code_ref="matplotlib.lines.Line2D" port="marker" type="input">
     <value>{'caretright': 5, 'star': '*', 'point': '.', 'mathtext': '$...$', 'triangle_right': '>', 'tickup': 2, 'hexagon1': 'h', 'plus': '+', 'hline': '_', 'vline': '|', 'tickdown': 3, 'nothing': ' ', 'caretup': 6, 'caretleft': 4, 'pentagon': 'p', 'tri_left': '3', 'tickleft': 0, 'tickright': 1, 'tri_down': '1', 'thin_diamond': 'd', 'diamond': 'D', 'caretdown': 7, 'hexagon2': 'H', 'tri_up': '2', 'square': 's', 'x': 'x', 'triangle_down': 'v', 'triangle_up': '^', 'octagon': '8', 'tri_ri [...]
   </changePortSpec>
@@ -33,4 +53,83 @@
   <changePortSpec attr="values" code_ref="matplotlib.lines.Line2D" port="marker" type="input">
     <value>[['caretdown', 'caretleft', 'caretright', 'caretup', 'circle', 'diamond', 'hexagon1', 'hexagon2', 'hline', 'nothing', 'octagon', 'pentagon', 'pixel', 'plus', 'point', 'square', 'star', 'thin_diamond', 'tickdown', 'tickleft', 'tickright', 'tickup', 'tri_down', 'tri_left', 'tri_right', 'tri_up', 'triangle_down', 'triangle_left', 'triangle_right', 'triangle_up', 'vline', 'x', 'mathtext']]</value>
   </changePortSpec>
+  <deletePortSpec code_ref="matplotlib.axis.Tick" port="label1" type="input" />
+  <deletePortSpec code_ref="matplotlib.axis.Tick" port="label2" type="input" />
+  <changePortSpec attr="not_setp" code_ref="matplotlib.axis.Tick" port="label1On" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="constructor_arg" code_ref="matplotlib.axis.Tick" port="label1On" type="input">
+    <value>False</value>
+  </changePortSpec>
+  <changePortSpec attr="not_setp" code_ref="matplotlib.axis.Tick" port="label2On" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="constructor_arg" code_ref="matplotlib.axis.Tick" port="label2On" type="input">
+    <value>False</value>
+  </changePortSpec>
+  <changePortSpec attr="translations" code_ref="matplotlib.axis.Tick" port="color" type="input">
+    <value>translate_color</value>
+  </changePortSpec>
+  <changePortSpec attr="port_type" code_ref="matplotlib.axis.Tick" port="color" type="input">
+    <value>basic:Color</value>
+  </changePortSpec>
+  <changePortSpec attr="not_setp" code_ref="matplotlib.axis.Tick" port="gridOn" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="docstring" code_ref="matplotlib.axis.Tick" port="gridOn" type="input">
+    <value>a boolean which determines whether to draw the tickline</value>
+  </changePortSpec>
+  <changePortSpec attr="port_type" code_ref="matplotlib.axis.Tick" port="gridOn" type="input">
+    <value>basic:Boolean</value>
+  </changePortSpec>
+  <changePortSpec attr="constructor_arg" code_ref="matplotlib.axis.Tick" port="gridOn" type="input">
+    <value>False</value>
+  </changePortSpec>
+  <changePortSpec attr="not_setp" code_ref="matplotlib.axis.Tick" port="tick2On" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="docstring" code_ref="matplotlib.axis.Tick" port="tick2On" type="input">
+    <value>a boolean which determines whether to draw the 2nd tickline</value>
+  </changePortSpec>
+  <changePortSpec attr="constructor_arg" code_ref="matplotlib.axis.Tick" port="tick2On" type="input">
+    <value>False</value>
+  </changePortSpec>
+  <changePortSpec attr="not_setp" code_ref="matplotlib.axis.Tick" port="tick1On" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="docstring" code_ref="matplotlib.axis.Tick" port="tick1On" type="input">
+    <value>a boolean which determines whether to draw the 1st tickline</value>
+  </changePortSpec>
+  <changePortSpec attr="constructor_arg" code_ref="matplotlib.axis.Tick" port="tick1On" type="input">
+    <value>False</value>
+  </changePortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Tick" port="label1" type="output">
+    <value>
+      <outputPortSpec arg="label1" compute_name="label1" compute_parent="label1" name="label1Properties" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text">
+        <docstring>Set the text of ticklabel</docstring>
+      </outputPortSpec>
+    </value>
+  </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Tick" port="label2" type="output">
+    <value>
+      <outputPortSpec arg="label2" compute_name="label2" compute_parent="label2" name="label2Properties" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text">
+        <docstring>Set the text of ticklabel2</docstring>
+      </outputPortSpec>
+    </value>
+  </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Tick" port="tick1line" type="output">
+    <value>
+      <outputPortSpec arg="tick1line" compute_name="tick1line" compute_parent="tick1line" name="tick1lineProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.lines.Line2D" />
+    </value>
+  </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Tick" port="tick2line" type="output">
+    <value>
+      <outputPortSpec arg="tick2line" compute_name="tick2line" compute_parent="tick2line" name="tick2lineProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.lines.Line2D" />
+    </value>
+  </addPortSpec>
+  <addPortSpec code_ref="matplotlib.axis.Tick" port="gridline" type="output">
+    <value>
+      <outputPortSpec arg="gridline" compute_name="gridline" compute_parent="gridline" name="gridlineProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.lines.Line2D" />
+    </value>
+  </addPortSpec>
 </diff>
diff --git a/vistrails/packages/matplotlib/mpl_plots.xml b/vistrails/packages/matplotlib/mpl_plots.xml
index 325ca51..60af6c4 100644
--- a/vistrails/packages/matplotlib/mpl_plots.xml
+++ b/vistrails/packages/matplotlib/mpl_plots.xml
@@ -37,14 +37,14 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="normed" arg_pos="1" name="normed" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="usevlines" arg_pos="3" name="usevlines" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="detrend" arg_pos="2" name="detrend" />
     <inputPortSpec arg="maxlags" arg_pos="4" name="maxlags" port_type="basic:Integer">
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="hold" arg_pos="1" name="hold" />
@@ -104,14 +104,14 @@ Valid kwargs are :class:`~matplotlib.lines.Line2D` properties, with the exceptio
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="y" arg_pos="0" name="y" port_type="basic:Float">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xmin" arg_pos="1" name="xmin" port_type="basic:Float">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="3" name="hold" />
     <inputPortSpec arg="xmax" arg_pos="2" name="xmax" port_type="basic:Float">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <outputPortSpec arg="line" compute_name="line" name="lineProperties" port_type="__property__" property_key="0" property_type="matplotlib.lines.Line2D" />
   </moduleSpec>
@@ -142,13 +142,13 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="xmin" arg_pos="2" name="xmin" port_type="basic:Float">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="ymin" arg_pos="0" name="ymin" port_type="basic:Float" required="True" />
     <inputPortSpec arg="ymax" arg_pos="1" name="ymax" port_type="basic:Float" required="True" />
     <inputPortSpec arg="xmax" arg_pos="3" name="xmax" port_type="basic:Float">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <outputPortSpec arg="patch" compute_name="patch" name="patchProperties" port_type="__property__" property_key="-1" property_type="matplotlib.patches.Polygon" />
   </moduleSpec>
@@ -181,14 +181,14 @@ Valid kwargs are :class:`~matplotlib.lines.Line2D` properties, with the exceptio
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:Float">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="3" name="hold" />
     <inputPortSpec arg="ymin" arg_pos="1" name="ymin" port_type="basic:Float">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="ymax" arg_pos="2" name="ymax" port_type="basic:Float">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <outputPortSpec arg="line" compute_name="line" name="lineProperties" port_type="__property__" property_key="0" property_type="matplotlib.lines.Line2D" />
   </moduleSpec>
@@ -219,10 +219,10 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="xmin" arg_pos="0" name="xmin" port_type="basic:Float" required="True" />
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="ymin" arg_pos="2" name="ymin" port_type="basic:Float">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="ymax" arg_pos="3" name="ymax" port_type="basic:Float">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xmax" arg_pos="1" name="xmax" port_type="basic:Float" required="True" />
     <outputPortSpec arg="patch" compute_name="patch" name="patchProperties" port_type="__property__" property_key="-1" property_type="matplotlib.patches.Polygon" />
@@ -270,7 +270,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="capsize" name="capsize" port_type="basic:Integer">
       <docstring>(default 3) determines the length in points of the error bar caps</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="orientation" name="orientation" port_type="basic:String">
       <docstring>'vertical' | 'horizontal'</docstring>
@@ -279,7 +279,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="bottom" arg_pos="3" name="bottom" port_type="basic:Float">
       <docstring>the y coordinates of the bottom edges of the bars</docstring>
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
       <alternateSpec arg="bottom" name="bottomSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="color" name="color" port_type="basic:Color">
@@ -305,7 +305,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="width" arg_pos="2" name="width" port_type="basic:Float">
       <docstring>the widths of the bars</docstring>
-      <defaults>['0.8']</defaults>
+      <defaults>[0.8]</defaults>
       <alternateSpec arg="width" name="widthSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="error_kw" name="error_kw">
@@ -313,7 +313,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="log" name="log" port_type="basic:Boolean">
       <docstring>[False|True] False (default) leaves the orientation axis as-is; True sets it to log scale</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="yerr" name="yerr">
@@ -368,11 +368,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="capsize" name="capsize" port_type="basic:Integer">
       <docstring>(default 3) determines the length in points of the error bar caps</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="log" name="log" port_type="basic:Boolean">
       <docstring>[False|True] False (default) leaves the horizontal axis as-is; True sets it to log scale</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="bottom" arg_pos="0" name="bottom" port_type="basic:List" required="True">
       <docstring>the vertical positions of the bottom edges of the bars</docstring>
@@ -397,7 +397,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="height" arg_pos="2" name="height" port_type="basic:Float">
       <docstring>the heights (thicknesses) of the bars</docstring>
-      <defaults>['0.8']</defaults>
+      <defaults>[0.8]</defaults>
       <alternateSpec arg="height" name="heightSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="width" arg_pos="1" name="width" port_type="basic:List" required="True">
@@ -410,12 +410,12 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="left" arg_pos="3" name="left" port_type="basic:Float">
       <docstring>the x coordinates of the left edges of the bars</docstring>
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
       <alternateSpec arg="left" name="leftSequence" port_type="basic:List" />
     </inputPortSpec>
     <outputPortSpec arg="rectangle" compute_name="rectangles" name="rectangleProperties" plural="True" port_type="__property__" property_key="0" property_type="matplotlib.artist.Rectangle" />
   </moduleSpec>
-  <moduleSpec code_ref="matplotlib.pyplot.broken_barh" name="MplBrokenBarh" superclass="MplPlot">
+  <moduleSpec code_ref="matplotlib.pyplot.broken_barh" name="MplBrokenBarh" output_type="object" superclass="MplPlot">
     <docstring>Plot horizontal bars.
 
 Call signature:
@@ -483,7 +483,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="hold" arg_pos="11" name="hold" />
     <inputPortSpec arg="vert" arg_pos="3" name="vert" port_type="basic:Boolean">
       <docstring>If True (default), makes the boxes vertical. If False, makes horizontal boxes.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="positions" arg_pos="5" name="positions">
       <docstring>Sets the horizontal positions of the boxes. The ticks and limits are automatically set to match the positions.</docstring>
@@ -500,22 +500,22 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="widths" arg_pos="6" name="widths" port_type="basic:Float">
       <docstring>Either a scalar or a vector and sets the width of each box. The default is 0.5, or 0.15*(distance between extreme positions) if that is smaller.</docstring>
-      <defaults>['0.5']</defaults>
+      <defaults>[0.5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="patch_artist" arg_pos="7" name="patch_artist" port_type="basic:Boolean">
       <docstring>If False produces boxes with the Line2D artist If True produces boxes with the Patch artist</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True">
       <docstring>Array or a sequence of vectors.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="notch" arg_pos="1" name="notch" port_type="basic:Boolean">
       <docstring>If False (default), produces a rectangular box plot. If True, will produce a notched box plot</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="whis" arg_pos="4" name="whis" port_type="basic:Float">
       <docstring>Defines the length of the whiskers as a function of the inner quartile range.  They extend to the most extreme data point within ( whis*(75%-25%) ) data range.</docstring>
-      <defaults>['1.5']</defaults>
+      <defaults>[1.5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="conf_intervals" arg_pos="10" name="conf_intervals" port_type="basic:List">
       <docstring>Array or sequence whose first dimension (or length) is compatible with x and whose second dimension is 2. When the current element of conf_intervals is not None, the notch locations computed by matplotlib are overridden (assuming notch is True). When an element of conf_intervals is None, boxplot compute notches the method specified by the other kwargs (e.g. bootstrap).</docstring>
@@ -558,21 +558,21 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="3" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="8" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="10" name="scale_by_freq" />
     <inputPortSpec arg="detrend" arg_pos="5" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="6" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="4" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="2" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -581,7 +581,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="7" name="noverlap" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="line" constructor_arg="True" name="lineProperties" port_type="__property__" property_type="matplotlib.lines.Line2D" />
   </moduleSpec>
@@ -633,11 +633,11 @@ if a tuple of matplotlib color args (string, float, rgb, etc), different labels
     </inputPortSpec>
     <inputPortSpec arg="rightside_up" name="rightside_up" port_type="basic:Boolean">
       <docstring>if True (default), label rotations will always be plus or minus 90 degrees from level.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="inline" name="inline" port_type="basic:Boolean">
       <docstring>controls whether the underlying contour is removed or not. Default is True.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="v" arg_pos="1" in_args="True" name="v" port_type="basic:List" />
     <outputPortSpec arg="text" compute_name="texts" name="textProperties" plural="True" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text" />
@@ -705,36 +705,34 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
+    </inputPortSpec>
+    <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
+      <docstring>If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.
+
+linestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.</docstring>
+      <entry_types>['enum']</entry_types>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <defaults>['solid']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xunits" name="xunits" port_type="basic:String">
       <docstring>Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'registered units']]</values>
+      <values>[['registered units']]</values>
     </inputPortSpec>
     <inputPortSpec arg="extend" name="extend" port_type="basic:String">
       <docstring>Unless this is 'neither', contour levels are automatically added to one or both ends of the range so that all data are included. These added ranges are then mapped to the special colormap values which default to the ends of the colormap range, but can be set via :meth:`matplotlib.colors.Colormap.set_under` and :meth:`matplotlib.colors.Colormap.set_over` methods.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['neither', 'both', 'min', 'max']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[[0]]</values>
     </inputPortSpec>
-    <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
-      <docstring>If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.
-
-linestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
-      <defaults>['solid']</defaults>
-    </inputPortSpec>
     <inputPortSpec arg="hatches" name="hatches" port_type="basic:List">
       <docstring>A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only.</docstring>
     </inputPortSpec>
@@ -749,7 +747,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="locator" name="locator" port_type="basic:String">
       <docstring>If locator is None, the default :class:`~matplotlib.ticker.MaxNLocator` is used. The locator is used to determine the contour levels if they are not given explicitly via the V argument.</docstring>
@@ -781,12 +779,10 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', '(x0,x1,y0,y1)']]</values>
+      <values>[['(x0,x1,y0,y1)']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -794,16 +790,16 @@ This keyword is not active if X and Y are specified in the call to contour.</doc
     <inputPortSpec arg="Z" arg_pos="2" in_args="True" name="Z" port_type="basic:List" required="True" />
     <inputPortSpec arg="antialiased" name="antialiased" port_type="basic:Boolean">
       <docstring>enable antialiasing, overriding the defaults.  For filled contours, the default is True.  For line contours, it is taken from rcParams['lines.antialiased'].</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>None</entry_types>
       <values>None</values>
     </inputPortSpec>
-    <inputPortSpec arg="X" arg_pos="0" in_args="True" name="X" port_type="basic:List" />
     <inputPortSpec arg="V" arg_pos="3" in_args="True" name="V" port_type="basic:List" />
     <inputPortSpec arg="Y" arg_pos="1" in_args="True" name="Y" port_type="basic:List" />
+    <inputPortSpec arg="X" arg_pos="0" in_args="True" name="X" port_type="basic:List" />
     <inputPortSpec arg="N" arg_pos="4" in_args="True" name="N" port_type="basic:Integer" />
     <outputPortSpec arg="contourSet" compute_name="contourSet" name="contourSet" port_type="MplQuadContourSet" property_key="0" />
     <outputPortSpec arg="lineCollection" compute_name="lineCollections" name="lineCollectionProperties" plural="True" port_type="__property__" property_key="1" property_type="matplotlib.collections.LineCollection" />
@@ -875,25 +871,23 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
     </inputPortSpec>
     <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
       <docstring>If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.
 
 linestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
       <defaults>['solid']</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[[0]]</values>
+      <values>[['0']]</values>
     </inputPortSpec>
     <inputPortSpec arg="hatches" name="hatches" port_type="basic:List">
       <docstring>A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only.</docstring>
@@ -909,7 +903,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -918,18 +912,16 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
-      <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <entry_types>None</entry_types>
+      <values>None</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -938,7 +930,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
     <inputPortSpec arg="N" arg_pos="4" in_args="True" name="N" port_type="basic:Integer" />
     <inputPortSpec arg="V" arg_pos="3" in_args="True" name="V" port_type="basic:List" />
@@ -972,21 +964,21 @@ seealso:  :meth:`psd`     For a description of the optional parameters.
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="3" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="8" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="10" name="scale_by_freq" />
     <inputPortSpec arg="detrend" arg_pos="5" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="6" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="4" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="2" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -995,7 +987,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="7" name="noverlap" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="line" constructor_arg="True" name="lineProperties" port_type="__property__" property_type="matplotlib.lines.Line2D" />
   </moduleSpec>
@@ -1033,19 +1025,19 @@ Example:
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="lolims" arg_pos="9" name="lolims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="capsize" arg_pos="7" name="capsize" port_type="basic:Float">
       <docstring>The length of the error bar caps in points</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="uplims" arg_pos="10" name="uplims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xlolims" arg_pos="11" name="xlolims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="barsabove" arg_pos="8" name="barsabove">
       <docstring>if True, will plot the errorbars above the plot symbols. Default is below.</docstring>
@@ -1066,19 +1058,19 @@ If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</docstring>
     <inputPortSpec arg="ecolor" arg_pos="5" name="ecolor" port_type="basic:Color">
       <docstring>A matplotlib color arg which gives the color the errorbar lines; if None, use the marker color.</docstring>
       <translations>translate_color</translations>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'mpl color']]</values>
+      <entry_types>None</entry_types>
+      <values>None</values>
     </inputPortSpec>
     <inputPortSpec arg="errorevery" arg_pos="13" name="errorevery" port_type="basic:Integer">
       <docstring>subsamples the errorbars. Eg if everyerror=5, errorbars for every 5-th datapoint will be plotted. The data plot itself still shows all data points.</docstring>
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="capthick" arg_pos="14" name="capthick" port_type="basic:Float">
       <docstring>An alias kwarg to markeredgewidth (a.k.a. - mew). This setting is a more sensible name for the property that controls the thickness of the error bar cap in points. For backwards compatibility, if mew or markeredgewidth are given, then they will over-ride capthick.  This may change in future releases.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="xuplims" arg_pos="12" name="xuplims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="elinewidth" arg_pos="6" name="elinewidth" port_type="basic:Float">
       <docstring>The linewidth of the errorbar lines. If None, use the linewidth.</docstring>
@@ -1150,13 +1142,13 @@ kwargs control the :class:`~matplotlib.patches.Polygon` properties:
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="y2" arg_pos="2" name="y2" port_type="basic:Float">
       <docstring>A scalar y-value</docstring>
-      <defaults>['0.0']</defaults>
+      <defaults>[0]</defaults>
       <alternateSpec arg="y2" name="y2Sequence" port_type="basic:List">
         <docstring>An N-length array of the y data</docstring>
       </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="interpolate" arg_pos="4" name="interpolate" port_type="basic:Boolean">
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y1" arg_pos="1" in_args="True" name="y1" port_type="basic:List" required="True">
       <docstring>An N-length array of the y data</docstring>
@@ -1194,7 +1186,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="x2" arg_pos="2" name="x2" port_type="basic:Float">
       <docstring>A scalar x-value</docstring>
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
       <alternateSpec arg="x2" name="x2Sequence" port_type="basic:List">
         <docstring>An N-length array of the x data</docstring>
       </alternateSpec>
@@ -1248,17 +1240,18 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 If None, draws the outlines in the default color.
 
 If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the specified color.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'none', 'mpl color']]</values>
-      <defaults>['none']</defaults>
-      <alternateSpec arg="edgecolors" name="edgecolorsScalar" port_type="basic:String" />
+      <alternateSpec arg="edgecolors" name="edgecolorsScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['none', 'mpl color']]</values>
+        <defaults>['none']</defaults>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="C" arg_pos="2" name="C" port_type="basic:List" />
     <inputPortSpec arg="gridsize" arg_pos="3" name="gridsize" port_type="basic:Integer">
       <docstring>The number of hexagons in the x-direction, default is 100. The corresponding number of hexagons in the y-direction is chosen such that the hexagons are approximately regular. Alternatively, gridsize can be a tuple with two elements specifying the number of hexagons in the x-direction and the y-direction.</docstring>
       <entry_types>None</entry_types>
       <values>None</values>
-      <defaults>['100']</defaults>
+      <defaults>[100]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="vmin" arg_pos="10" name="vmin" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.</docstring>
@@ -1267,12 +1260,10 @@ If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the
       <defaults>['linear']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="reduce_C_function" arg_pos="15" name="reduce_C_function">
-      <defaults>['<function mean at 0x0277B3B0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="linewidths" arg_pos="13" name="linewidths">
+    <inputPortSpec arg="linewidths" arg_pos="13" name="linewidths" port_type="basic:List">
       <docstring>If None, defaults to rc lines.linewidth. Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="xscale" arg_pos="5" name="xscale" port_type="basic:String">
       <docstring>Use a linear or log10 scale on the horizontal axis.</docstring>
@@ -1283,17 +1274,15 @@ If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the
     <inputPortSpec arg="cmap" arg_pos="8" name="cmap" port_type="basic:String">
       <docstring>a :class:`matplotlib.colors.Colormap` instance. If None, defaults to rc image.cmap.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="norm" arg_pos="9" name="norm" port_type="basic:String">
       <docstring>:class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="extent" arg_pos="7" name="extent">
+    <inputPortSpec arg="extent" arg_pos="7" name="extent" port_type="basic:Float">
       <docstring>The limits of the bins. The default assigns the limits based on gridsize, x, y, xscale and yscale.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" arg_pos="12" name="alpha" port_type="basic:Float">
       <docstring>the alpha value for the patches</docstring>
@@ -1301,14 +1290,12 @@ If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="hold" arg_pos="18" name="hold" />
-    <inputPortSpec arg="mincnt" arg_pos="16" name="mincnt">
+    <inputPortSpec arg="mincnt" arg_pos="16" name="mincnt" port_type="basic:Integer">
       <docstring>If not None, only display cells with more than mincnt number of points in the cell</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="marginals" arg_pos="17" name="marginals" port_type="basic:Boolean">
       <docstring>if marginals is True, plot the marginal density as colormapped rectagles along the bottom of the x-axis and left of the y-axis</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="bins" arg_pos="4" name="bins" port_type="basic:Integer">
       <docstring>If None, no binning is applied; the color of each hexagon directly corresponds to its count value.
@@ -1361,13 +1348,13 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 pdf, bins, patches = ax.hist(...) print np.sum(pdf * np.diff(bins))
 
 Until numpy release 1.5, the underlying numpy histogram function was incorrect with normed*=*True if bin sizes were unequal.  MPL inherited that error.  It is now corrected within MPL when using earlier numpy versions</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="stacked" arg_pos="14" name="stacked" port_type="basic:Boolean">
       <docstring>If True, multiple data are stacked on top of each other If False multiple data are aranged side by side if histtype is 'bar' or on top of each other if histtype is 'step'
 
 .</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="orientation" arg_pos="9" name="orientation" port_type="basic:String">
       <docstring>If 'horizontal', :func:`~matplotlib.pyplot.barh` will be used for bar-type histograms and the bottom kwarg will be the left edges.</docstring>
@@ -1410,7 +1397,7 @@ Until numpy release 1.5, the underlying numpy histogram function was incorrect w
     </inputPortSpec>
     <inputPortSpec arg="cumulative" arg_pos="5" name="cumulative" port_type="basic:Boolean">
       <docstring>If True, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin gives the total number of datapoints.  If normed is also True then the histogram is normalized such that the last bin equals 1. If cumulative evaluates to less than 0 (e.g. -1), the direction of accumulation is reversed.  In this case, if normed is also True, then the histogram is normalized such that the first bin equals 1.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="label" arg_pos="13" name="labelSequence" port_type="basic:List">
       <docstring>String, or sequence of strings to match multiple datasets.  Bar charts yield multiple patches per dataset, but only the first gets the label, so that the legend command will work as expected:
@@ -1430,12 +1417,12 @@ If bins is a sequence or range is specified, autoscaling is based on the specifi
     <inputPortSpec arg="hold" arg_pos="15" name="hold" />
     <inputPortSpec arg="bins" arg_pos="1" name="bins" port_type="basic:Integer">
       <docstring>Either an integer number of bins or a sequence giving the bins.  If bins is an integer, bins + 1 bin edges will be returned, consistent with :func:`numpy.histogram` for numpy version >= 1.3, and with the new = True argument in earlier versions. Unequally spaced bins are supported if bins is a sequence.</docstring>
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
       <alternateSpec arg="bins" name="binsSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="log" arg_pos="11" name="log" port_type="basic:Boolean">
       <docstring>If True, the histogram axis will be set to a log scale. If log is True and x is a 1D array, empty bins will be filtered out and only the non-empty (n, bins, patches) will be returned.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <outputPortSpec arg="rectangle" compute_name="rectangles" name="rectangleProperties" plural="True" port_type="__property__" property_key="2" property_type="matplotlib.patches.Rectangle" />
   </moduleSpec>
@@ -1472,7 +1459,7 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="normed" arg_pos="4" name="normed" port_type="basic:Boolean">
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmin" arg_pos="6" name="cmin" />
     <inputPortSpec arg="range" arg_pos="3" name="range" />
@@ -1482,7 +1469,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="hold" arg_pos="8" name="hold" />
     <inputPortSpec arg="cmax" arg_pos="7" name="cmax" />
     <inputPortSpec arg="bins" arg_pos="2" name="bins" port_type="basic:Integer">
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.hlines" name="MplHlines" output_type="object" superclass="MplPlot">
@@ -1520,8 +1507,9 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="colors" arg_pos="3" name="colorsSequence" port_type="basic:List">
       <docstring>a line collections color argument, either a single color or a len(y) list of colors</docstring>
-      <defaults>['k']</defaults>
-      <alternateSpec arg="colors" name="colorsScalar" port_type="basic:String" />
+      <alternateSpec arg="colors" name="colorsScalar" port_type="basic:String">
+        <defaults>['k']</defaults>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="xmax" arg_pos="2" name="xmaxScalar" port_type="basic:Float" required="True">
       <docstring>can be scalars or len(x) numpy arrays.  If they are scalars, then the respective values are constant, else the widths of the lines are determined by xmin and xmax.</docstring>
@@ -1581,13 +1569,13 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 cmap is ignored when X has RGB(A) information</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="filterrad" arg_pos="12" name="filterrad" port_type="basic:Float">
-      <defaults>['4.0']</defaults>
+      <defaults>[4.0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="filternorm" arg_pos="11" name="filternorm" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="aspect" arg_pos="3" name="aspect">
       <docstring>If 'auto', changes the image aspect ratio to match that of the axes
@@ -1596,7 +1584,7 @@ If 'equal', and extent is None, changes the axes aspect ratio to match that of t
 
 If None, default to rc image.aspect value.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'auto', 'equal']]</values>
+      <values>[['auto', 'equal']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" arg_pos="5" name="alpha" />
     <inputPortSpec arg="vmax" arg_pos="7" name="vmax" />
@@ -1641,17 +1629,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="basey" name="basey" port_type="basic:Float">
       <docstring>Base of the x/y logarithm</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="subsx" name="subsxSequence" port_type="basic:List">
+    <inputPortSpec arg="subsx" name="subsx" port_type="basic:List">
       <docstring>The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="subsx" name="subsxScalar" port_type="basic:String" />
     </inputPortSpec>
-    <inputPortSpec arg="subsy" name="subsySequence" port_type="basic:List">
+    <inputPortSpec arg="subsy" name="subsy" port_type="basic:List">
       <docstring>The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="subsy" name="subsyScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" in_args="True" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" in_args="True" name="x" port_type="basic:List" required="True" />
@@ -1723,27 +1705,24 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 If 'none', edges will not be visible.
 
 An mpl color or sequence of colors will set the edge color</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'none', 'color']]</values>
-      <alternateSpec arg="edgecolors" name="edgecolorsScalar" port_type="basic:String" />
+      <alternateSpec arg="edgecolors" name="edgecolorsScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['none', 'color']]</values>
+      </alternateSpec>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>the alpha blending value</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="shading" name="shading" port_type="basic:String">
       <docstring>If 'faceted', a black grid is drawn around each rectangle; if 'flat', edges are not drawn. Default is 'flat', contrary to MATLAB.</docstring>
@@ -1754,7 +1733,7 @@ An mpl color or sequence of colors will set the edge color</docstring>
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>An :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
     <inputPortSpec arg="Y" arg_pos="1" in_args="True" name="Y" port_type="basic:List" />
     <inputPortSpec arg="X" arg_pos="0" in_args="True" name="X" port_type="basic:List" />
@@ -1793,27 +1772,24 @@ If 'None', edges will not be visible.
 If 'face', edges will have the same color as the faces.
 
 An mpl color or sequence of colors will set the edge color</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'None', 'face', 'color']]</values>
-      <alternateSpec arg="edgecolors" name="edgecolorsScalar" port_type="basic:String" />
+      <alternateSpec arg="edgecolors" name="edgecolorsScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['None', 'face', 'color']]</values>
+      </alternateSpec>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>the alpha blending value</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="shading" name="shading" port_type="basic:String">
       <docstring>'flat' indicates a solid color for each quad.  When 'gouraud', each quad will be Gouraud shaded.  When gouraud shading, edgecolors is ignored.</docstring>
@@ -1823,7 +1799,7 @@ An mpl color or sequence of colors will set the edge color</docstring>
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.pie" name="MplPie" output_type="tuple" superclass="MplPlot">
@@ -1847,46 +1823,39 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="autopct" arg_pos="4" name="autopct" port_type="basic:String">
       <docstring>If not None, is a string or function used to label the wedges with their numeric value.  The label will be placed inside the wedge.  If it is a format string, the label will be fmt%pct. If it is a function, it will be called.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'format function']]</values>
+      <values>[['format function']]</values>
     </inputPortSpec>
     <inputPortSpec arg="pctdistance" arg_pos="5" name="pctdistance" port_type="basic:Float">
       <docstring>The ratio between the center of each pie slice and the start of the text generated by autopct.  Ignored if autopct is None; default is 0.6.</docstring>
-      <defaults>['0.6']</defaults>
+      <defaults>[0.6]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="labels" arg_pos="2" name="labelsSequence" port_type="basic:List">
       <docstring>A sequence of strings providing the labels for each wedge</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
       <alternateSpec arg="labels" name="labelsScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="explode" arg_pos="1" name="explodeSequence" port_type="basic:List">
       <docstring>If not None, is a len(x) array which specifies the fraction of the radius with which to offset each wedge.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
       <alternateSpec arg="explode" name="explodeScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="colors" arg_pos="3" name="colors" port_type="basic:Color">
       <docstring>A sequence of matplotlib color args through which the pie chart will cycle.</docstring>
       <translations>translate_color</translations>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="radius" arg_pos="9" name="radius" />
     <inputPortSpec arg="startangle" arg_pos="8" name="startangle" port_type="basic:String">
       <docstring>If not None, rotates the start of the pie chart by angle degrees counterclockwise from the x-axis.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Offset angle']]</values>
+      <values>[['Offset angle']]</values>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="shadow" arg_pos="6" name="shadow" port_type="basic:Boolean">
       <docstring>Draw a shadow beneath the pie.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="10" name="hold" />
     <inputPortSpec arg="labeldistance" arg_pos="7" name="labeldistance" port_type="basic:Float">
       <docstring>The radial distance at which the pie labels are drawn</docstring>
-      <defaults>['1.1']</defaults>
+      <defaults>[1.1]</defaults>
     </inputPortSpec>
     <outputPortSpec arg="autotext" compute_name="autotexts" name="autotextProperties" plural="True" port_type="__property__" property_key="2" property_type="matplotlib.text.Text" />
     <outputPortSpec arg="wedge" compute_name="wedges" name="wedgeProperties" plural="True" port_type="__property__" property_key="0" property_type="matplotlib.artist.patches.Wedge" />
@@ -1917,7 +1886,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="tz" arg_pos="3" name="tz" port_type="basic:String">
       <docstring>The time zone to use in labeling dates. If None, defaults to rc value.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', ':class:`tzinfo` instance']]</values>
+      <values>[[':class:`tzinfo` instance']]</values>
     </inputPortSpec>
     <inputPortSpec arg="fmt" arg_pos="2" name="fmt" port_type="basic:String">
       <docstring>The plot format string.</docstring>
@@ -1925,11 +1894,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="ydate" arg_pos="5" name="ydate" port_type="basic:Boolean">
       <docstring>If True, the y-axis will be labeled with dates.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xdate" arg_pos="4" name="xdate" port_type="basic:Boolean">
       <docstring>If True, the x-axis will be labeled with dates.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" in_args="True" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" in_args="True" name="x" port_type="basic:List" required="True" />
@@ -1961,21 +1930,21 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="2" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="7" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="9" name="scale_by_freq" />
     <inputPortSpec arg="detrend" arg_pos="4" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="5" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="3" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="1" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="hold" arg_pos="10" name="hold" />
@@ -1983,7 +1952,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="6" name="noverlap" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="line" constructor_arg="True" name="lineProperties" port_type="__property__" property_type="matplotlib.lines.Line2D" />
   </moduleSpec>
@@ -2015,47 +1984,50 @@ agg_filter: unknown alpha: float or None animated: [True | False] antialiased or
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="headaxislength" name="headaxislength" port_type="basic:Float">
       <docstring>Head length at shaft intersection, default is 4.5</docstring>
-      <defaults>['4.5']</defaults>
+      <defaults>[4.5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="C" arg_pos="4" in_args="True" name="C" port_type="basic:List">
       <docstring>None</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="scale" name="scale">
+    <inputPortSpec arg="scale" name="scale" port_type="basic:List">
       <docstring>Data units per arrow length unit, e.g. m/s per plot width; a smaller scale parameter makes the arrow longer.  If None, a simple autoscaling algorithm is used, based on the average vector length and the number of vectors.  The arrow length unit is given by the scale_units parameter</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="width" name="width" port_type="basic:List">
       <docstring>Shaft width in arrow units; default depends on choice of units, above, and number of vectors; a typical starting value is about 0.005 times the width of the plot.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="headlength" name="headlength" port_type="basic:Float">
       <docstring>Head length as multiple of shaft width, default is 5</docstring>
-      <defaults>['5']</defaults>
+      <defaults>[5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="minlength" name="minlength" port_type="basic:Float">
       <docstring>Minimum length as a multiple of shaft width; if an arrow length is less than this, plot a dot (hexagon) of this diameter instead. Default is 1.</docstring>
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="minshaft" name="minshaft" port_type="basic:Float">
       <docstring>Length below which arrow scales, in units of head length. Do not set this to less than 1, or small arrows will look terrible! Default is 1</docstring>
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pivot" name="pivot" port_type="basic:String">
       <docstring>The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name pivot.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['tail', 'middle', 'tip']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="units" name="unitsSequence" port_type="basic:List">
-      <docstring>For example, if scale_units is 'inches', scale is 2.0, and (u,v) = (1,0), then the vector will be 0.5 inches long. If scale_units is 'width', then the vector will be half the width of the axes.
+    <inputPortSpec arg="units" name="units" port_type="basic:String">
+      <docstring>Arrow units; the arrow dimensions except for length are in multiples of this unit.
 
-If scale_units is 'x' then the vector will be 0.5 x-axis units.  To plot vectors in the x-y plane, with u and v having the same units as x and y, use "angles='xy', scale_units='xy', scale=1".</docstring>
+'width' or 'height': the width or height of the axes
+
+'dots' or 'inches': pixels or inches, based on the figure dpi
+
+'x', 'y', or 'xy': X, Y, or sqrt(X^2+Y^2) data units
+
+The arrows scale differently depending on the units.  For 'x' or 'y', the arrows get larger as one zooms in; for other units, the arrow size is independent of the zoom state.  For 'width or 'height', the arrow size increases with the width and height of the axes, respectively, when the the window is resized; for 'dots' or 'inches', resizing does not change the arrows.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['width', 'height', 'dots', 'inches', 'x', 'y', 'xy']]</values>
-      <alternateSpec arg="units" name="unitsScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="headwidth" name="headwidth" port_type="basic:Float">
       <docstring>Head width as multiple of shaft width, default is 3</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="U" arg_pos="2" in_args="True" name="U" port_type="basic:List" required="True">
       <docstring>None</docstring>
@@ -2115,9 +2087,10 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="coordinates" name="coordinatesSequence" port_type="basic:List">
       <docstring>Coordinate system and units for X, Y: 'axes' and 'figure' are normalized coordinate systems with 0,0 in the lower left and 1,1 in the upper right; 'data' are the axes data coordinates (used for the locations of the vectors in the quiver plot itself); 'inches' is position in the figure in inches, with 0,0 at the lower left corner.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['axes', 'figure', 'data', 'inches']]</values>
-      <alternateSpec arg="coordinates" name="coordinatesScalar" port_type="basic:String" />
+      <alternateSpec arg="coordinates" name="coordinatesScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['axes', 'figure', 'data', 'inches']]</values>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="label" arg_pos="4" name="label" port_type="basic:String" required="True">
       <docstring>A string with the length and units of the key</docstring>
@@ -2148,7 +2121,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="labelsep" name="labelsep" port_type="basic:Float">
       <docstring>Distance in inches between the arrow and the label.  Default is 0.1</docstring>
-      <defaults>['0.1']</defaults>
+      <defaults>[0.1]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.scatter" name="MplScatter" output_type="object" superclass="MplPlot">
@@ -2189,19 +2162,18 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="c" arg_pos="3" name="cSequence" port_type="basic:List">
       <docstring>a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped.  c can be a 2-D array in which the rows are RGB or RGBA, however.</docstring>
-      <defaults>['b']</defaults>
-      <alternateSpec arg="c" name="cScalar" port_type="basic:String" />
+      <alternateSpec arg="c" name="cScalar" port_type="basic:String">
+        <defaults>['b']</defaults>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="vmin" arg_pos="7" name="vmin">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="faceted" arg_pos="11" name="faceted" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="linewidths" arg_pos="10" name="linewidths">
+    <inputPortSpec arg="linewidths" arg_pos="10" name="linewidths" port_type="basic:List">
       <docstring>If None, defaults to (lines.linewidth,).  Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="marker" arg_pos="4" name="marker" port_type="basic:String">
       <docstring>can be one of:
@@ -2211,7 +2183,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="s" arg_pos="2" name="s" port_type="basic:Float">
       <docstring>size in points^2.  It is a scalar or an array of the same length as x and y.</docstring>
-      <defaults>['20']</defaults>
+      <defaults>[20]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmap" arg_pos="5" name="cmap">
       <docstring>A :class:`matplotlib.colors.Colormap` instance or registered name. If None, defaults to rc image.cmap. cmap is only used if c is an array of floats.</docstring>
@@ -2261,11 +2233,8 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['mask', 'clip']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="subsx" name="subsxSequence" port_type="basic:List">
+    <inputPortSpec arg="subsx" name="subsx" port_type="basic:List">
       <docstring>The location of the minor xticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_xscale` for details.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="subsx" name="subsxScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" in_args="True" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="y" arg_pos="1" in_args="True" name="y" port_type="basic:List" required="True" />
@@ -2297,11 +2266,8 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['mask', 'clip']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="subsy" name="subsySequence" port_type="basic:List">
+    <inputPortSpec arg="subsy" name="subsy" port_type="basic:List">
       <docstring>The location of the minor yticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_yscale` for details.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="subsy" name="subsyScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" in_args="True" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" in_args="True" name="x" port_type="basic:List" required="True" />
@@ -2338,22 +2304,22 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="2" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="9" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="11" name="scale_by_freq" />
     <inputPortSpec arg="xextent" arg_pos="8" name="xextent" />
     <inputPortSpec arg="detrend" arg_pos="4" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="5" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="3" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="1" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmap" arg_pos="7" name="cmap" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -2362,7 +2328,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="6" name="noverlap" port_type="basic:Integer">
-      <defaults>['128']</defaults>
+      <defaults>[128]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.stackplot" name="MplStackplot" superclass="MplPlot">
@@ -2451,15 +2417,15 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['-|>']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="density" arg_pos="4" name="density" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="color" arg_pos="6" name="color" />
     <inputPortSpec arg="minlength" arg_pos="11" name="minlength" port_type="basic:Float">
-      <defaults>['0.1']</defaults>
+      <defaults>[0.1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="transform" arg_pos="12" name="transform" />
     <inputPortSpec arg="arrowsize" arg_pos="9" name="arrowsize" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmap" arg_pos="7" name="cmap" />
     <inputPortSpec arg="u" arg_pos="2" name="u" required="True" />
@@ -2536,7 +2502,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
     </inputPortSpec>
     <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
       <docstring>If linestyles is None, the 'solid' is used.
@@ -2545,7 +2511,7 @@ linestyles can also be an iterable of the above strings specifying a set of line
 
 If contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
     </inputPortSpec>
     <inputPortSpec arg="levels" name="levelsSequence" port_type="basic:List">
       <docstring>A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]</docstring>
@@ -2558,7 +2524,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -2567,13 +2533,13 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
-      <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <entry_types>None</entry_types>
+      <values>None</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="antialiased" name="antialiased" port_type="basic:Boolean">
       <docstring>enable antialiasing</docstring>
@@ -2581,7 +2547,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[[0]]</values>
+      <values>[['0']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -2589,7 +2555,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.tricontourf" name="MplTricontourf" superclass="MplPlot">
@@ -2659,7 +2625,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
     </inputPortSpec>
     <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
       <docstring>If linestyles is None, the 'solid' is used.
@@ -2668,7 +2634,7 @@ linestyles can also be an iterable of the above strings specifying a set of line
 
 If contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
     </inputPortSpec>
     <inputPortSpec arg="levels" name="levelsSequence" port_type="basic:List">
       <docstring>A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]</docstring>
@@ -2681,7 +2647,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -2690,13 +2656,13 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
-      <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <entry_types>None</entry_types>
+      <values>None</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="antialiased" name="antialiased" port_type="basic:Boolean">
       <docstring>enable antialiasing</docstring>
@@ -2704,7 +2670,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[[0]]</values>
+      <values>[['0']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -2712,7 +2678,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.tripcolor" name="MplTripcolor" superclass="MplPlot">
@@ -2829,16 +2795,16 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="normed" arg_pos="2" name="normed" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="usevlines" arg_pos="4" name="usevlines" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="detrend" arg_pos="3" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>None</defaults>
     </inputPortSpec>
     <inputPortSpec arg="maxlags" arg_pos="5" name="maxlags" port_type="basic:Integer">
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -2886,8 +2852,6 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="barbcolor" name="barbcolor" port_type="basic:Color">
       <docstring>Specifies the color all parts of the barb except any flags.  This parameter is analagous to the edgecolor parameter for polygons, which can be used instead. However this parameter will override facecolor.</docstring>
       <translations>translate_color</translations>
-      <entry_types>None</entry_types>
-      <values>None</values>
       <alternateSpec arg="barbcolor" name="barbcolorSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="C" arg_pos="4" in_args="True" name="C" port_type="basic:List">
@@ -2906,7 +2870,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="rounding" name="rounding" port_type="basic:Boolean">
       <docstring>A flag to indicate whether the vector magnitude should be rounded when allocating barb components.  If True, the magnitude is rounded to the nearest multiple of the half-barb increment.  If False, the magnitude is simply truncated to the next lowest multiple.  Default is True</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pivot" name="pivot" port_type="basic:String">
       <docstring>The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name pivot.  Default is 'tip'</docstring>
@@ -2916,12 +2880,12 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="flip_barb" name="flip_barb" port_type="basic:Boolean">
       <docstring>Either a single boolean flag or an array of booleans.  Single boolean indicates whether the lines and flags should point opposite to normal for all barbs.  An array (which should be the same size as the other data arrays) indicates whether to flip for each individual barb.  Normal behavior is for the barbs and lines to point right (comes from wind barbs having these features point towards low pressure in the Northern Hemisphere.)  Default is False</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
       <alternateSpec arg="flip_barb" name="flip_barbSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="length" name="length" port_type="basic:Integer">
       <docstring>Length of the barb in points; the other parts of the barb are scaled against this. Default is 9</docstring>
-      <defaults>['9']</defaults>
+      <defaults>[9]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="barb_increments" name="barb_increments" port_type="basic:Dictionary">
       <docstring>A dictionary of increments specifying values to associate with different parts of the barb. Only those values one wishes to override need to be included.
@@ -2950,13 +2914,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="flagcolor" name="flagcolor" port_type="basic:Color">
       <docstring>Specifies the color of any flags on the barb.  This parameter is analagous to the facecolor parameter for polygons, which can be used instead. However this parameter will override facecolor.  If this is not set (and C has not either) then flagcolor will be set to match barbcolor so that the barb has a uniform color. If C has been set, flagcolor has no effect.</docstring>
       <translations>translate_color</translations>
-      <entry_types>None</entry_types>
-      <values>None</values>
       <alternateSpec arg="flagcolor" name="flagcolorSequence" port_type="basic:List" />
     </inputPortSpec>
     <inputPortSpec arg="fill_empty" name="fill_empty" port_type="basic:Boolean">
       <docstring>A flag on whether the empty barbs (circles) that are drawn should be filled with the flag color.  If they are not filled, they will be drawn such that no color is applied to the center.  Default is False</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <outputPortSpec arg="polyCollection" compute_name="polyCollection" name="polyCollectionProperties" port_type="__property__" property_key="__none__" property_type="matplotlib.collections.PolyCollection" />
   </moduleSpec>
@@ -3013,7 +2975,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="hold" arg_pos="5" name="hold" />
     <inputPortSpec arg="markersize" arg_pos="3" name="markersize" />
     <inputPortSpec arg="precision" arg_pos="1" name="precision" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="aspect" arg_pos="4" name="aspect" port_type="basic:String">
       <defaults>['equal']</defaults>
@@ -3104,10 +3066,8 @@ Example:</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left', 'center right', 'lower center', 'upper center', 'center']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="fancybox" name="fancybox">
+    <inputPortSpec arg="fancybox" name="fancybox" port_type="basic:Boolean">
       <docstring>if True, draw a frame with a round fancybox.  If None, use rc settings</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="bbox_to_anchor" name="bbox_to_anchor">
       <docstring>the bbox that the legend will be anchored.</docstring>
@@ -3118,10 +3078,8 @@ Example:</docstring>
     <inputPortSpec arg="handlelength" name="handlelength">
       <docstring>the length of the legend handles</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="markerscale" name="markerscale">
+    <inputPortSpec arg="markerscale" name="markerscale" port_type="basic:Float">
       <docstring>The relative size of legend markers vs. original. If None, use rc settings.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="numpoints" name="numpoints" port_type="basic:Integer">
       <docstring>The number of points in the legend for line</docstring>
@@ -3132,12 +3090,18 @@ Example:</docstring>
     <inputPortSpec arg="scatterpoints" name="scatterpoints" port_type="basic:Integer">
       <docstring>The number of points in the legend for scatter plot</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="frameon" name="frameon" port_type="basic:Boolean">
-      <docstring>if True, draw a frame around the legend. The default is set by the rcParam 'legend.frameon'</docstring>
+    <inputPortSpec arg="prop" name="prop" port_type="basic:String">
+      <docstring>A :class:`matplotlib.font_manager.FontProperties` instance. If prop is a dictionary, a new instance will be created with prop. If None, use rc settings.</docstring>
+      <entry_types>None</entry_types>
+      <values>None</values>
     </inputPortSpec>
     <inputPortSpec arg="columnspacing" name="columnspacing">
       <docstring>the spacing between columns</docstring>
     </inputPortSpec>
+    <inputPortSpec arg="ncol" name="ncol" port_type="basic:Integer">
+      <docstring>number of columns. default is 1</docstring>
+      <defaults>[1]</defaults>
+    </inputPortSpec>
     <inputPortSpec arg="handletextpad" name="handletextpad">
       <docstring>the pad between the legend handle and text</docstring>
     </inputPortSpec>
@@ -3148,19 +3112,11 @@ Example:</docstring>
     <inputPortSpec arg="mode" name="mode">
       <docstring>if mode is "expand", the legend will be horizontally expanded to fill the axes area (or bbox_to_anchor)</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="ncol" name="ncol" port_type="basic:Integer">
-      <docstring>number of columns. default is 1</docstring>
-      <defaults>['1']</defaults>
-    </inputPortSpec>
-    <inputPortSpec arg="shadow" name="shadow">
+    <inputPortSpec arg="shadow" name="shadow" port_type="basic:Boolean">
       <docstring>If True, draw a shadow behind legend. If None, use rc settings.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="prop" name="prop" port_type="basic:String">
-      <docstring>A :class:`matplotlib.font_manager.FontProperties` instance. If prop is a dictionary, a new instance will be created with prop. If None, use rc settings.</docstring>
-      <entry_types>None</entry_types>
-      <values>None</values>
+    <inputPortSpec arg="frameon" name="frameon" port_type="basic:Boolean">
+      <docstring>if True, draw a frame around the legend. The default is set by the rcParam 'legend.frameon'</docstring>
     </inputPortSpec>
     <inputPortSpec arg="borderpad" name="borderpad">
       <docstring>the fractional whitespace inside the legend border</docstring>
diff --git a/vistrails/packages/matplotlib/mpl_plots_diff.xml b/vistrails/packages/matplotlib/mpl_plots_diff.xml
index feaef5e..19a1489 100644
--- a/vistrails/packages/matplotlib/mpl_plots_diff.xml
+++ b/vistrails/packages/matplotlib/mpl_plots_diff.xml
@@ -14,15 +14,22 @@
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.hexbin" port="y" type="input">
     <value>basic:List</value>
   </changePortSpec>
-  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.hexbin" port="bins" type="input">
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.hexbin" port="reduce_C_function" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="values" code_ref="matplotlib.pyplot.hexbin" port="bins" type="input">
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.hexbin" port="linewidths" type="input">
+    <value>linewidths</value>
+  </changePortSpec>
+  <deletePortSpec altName="linewidthsScalar" code_ref="matplotlib.pyplot.hexbin" port="linewidths" type="alternate" />
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.hexbin" port="bins" type="input">
     <value>None</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.hexbin" port="bins" type="input">
     <value>basic:Integer</value>
   </changePortSpec>
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.hexbin" port="bins" type="input">
+    <value>None</value>
+  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.hexbin" port="x" type="input">
     <value>basic:List</value>
   </changePortSpec>
@@ -31,6 +38,18 @@
       <outputPortSpec arg="polyCollection" compute_name="polyCollection" name="polyCollectionProperties" port_type="__property__" property_key="-1" property_type="matplotlib.collections.PolyCollection" />
     </value>
   </addPortSpec>
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.tricontour" port="colors" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.tricontour" port="colors" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.specgram" port="detrend" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.specgram" port="window" type="input">
+    <value>None</value>
+  </changePortSpec>
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.clabel">
     <value>object</value>
   </changeModule>
@@ -40,22 +59,45 @@
       <inputPortSpec arg="v" arg_pos="1" in_args="True" name="v" port_type="basic:List" />
     </value>
   </addPortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.clabel" port="cs" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.clabel" port="cs" type="input">
     <value>MplContourSet</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.clabel" port="cs" type="input">
+    <value>True</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.clabel" port="text" type="output">
     <value>
       <outputPortSpec arg="text" compute_name="texts" name="textProperties" plural="True" port_type="__property__" property_key="__none__" property_type="matplotlib.text.Text" />
     </value>
   </addPortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.cohere" port="detrend" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.cohere" port="window" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.cohere" port="line" type="input">
     <value>
       <inputPortSpec arg="line" constructor_arg="True" name="lineProperties" port_type="__property__" property_type="matplotlib.lines.Line2D" />
     </value>
   </addPortSpec>
+  <changeModule attr="docstring" code_ref="matplotlib.pyplot.fill_betweenx">
+    <value>Make filled polygons between two horizontal curves.
+
+Call signature:
+
+fill_between(y, x1, x2=0, where=None, **kwargs)
+
+Create a :class:`~matplotlib.collections.PolyCollection` filling the regions between x1 and x2 where where==True
+
+
+
+kwargs control the :class:`~matplotlib.patches.Polygon` properties:
+
+%(PolyCollection)s
+
+Additional kwargs: hold = [True|False] overrides default hold state</value>
+  </changeModule>
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.fill_betweenx">
     <value>object</value>
   </changeModule>
@@ -81,12 +123,12 @@
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.fill_betweenx" port="x1" type="input">
     <value>An N-length array of the x data</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.fill_betweenx" port="x1" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.fill_betweenx" port="x1" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.fill_betweenx" port="x1" type="input">
+    <value>True</value>
+  </changePortSpec>
   <addPortSpec altName="x1Scalar" code_ref="matplotlib.pyplot.fill_betweenx" port="x1" type="alternate">
     <value>
       <alternateSpec arg="x1" name="x1Scalar" port_type="basic:Float">
@@ -128,6 +170,9 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.xcorr">
     <value>tuple</value>
   </changeModule>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.xcorr" port="detrend" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.xcorr" port="lineCollection" type="output">
     <value>
       <outputPortSpec arg="lineCollection" compute_name="lineCollection" name="lineCollectionProperties" port_type="__property__" property_key="4" property_type="matplotlib.collections.LineCollection" />
@@ -234,6 +279,12 @@
       <outputPortSpec arg="annotation" compute_name="annotation" name="annotationProperties" port_type="__property__" property_key="0" property_type="matplotlib.text.Annotation" />
     </value>
   </addPortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.csd" port="detrend" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.csd" port="window" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.csd" port="line" type="input">
     <value>
       <inputPortSpec arg="line" constructor_arg="True" name="lineProperties" port_type="__property__" property_type="matplotlib.lines.Line2D" />
@@ -304,15 +355,15 @@
       <inputPortSpec arg="X" arg_pos="0" in_args="True" name="X" port_type="basic:List" />
     </value>
   </addPortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.contour" port="Z" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.contour" port="Z" type="input">
     <value>basic:List</value>
   </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.contour" port="Z" type="input">
     <value>2</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.contour" port="Z" type="input">
+    <value>True</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.contour" port="N" type="input">
     <value>
       <inputPortSpec arg="N" arg_pos="4" in_args="True" name="N" port_type="basic:Integer" />
@@ -389,12 +440,12 @@
       <alternateSpec arg="width" name="widthSequence" port_type="basic:List" />
     </value>
   </addPortSpec>
-  <changePortSpec attr="required" code_ref="matplotlib.pyplot.bar" port="left" type="input">
-    <value>False</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.bar" port="left" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="required" code_ref="matplotlib.pyplot.bar" port="left" type="input">
+    <value>False</value>
+  </changePortSpec>
   <addPortSpec altName="leftScalar" code_ref="matplotlib.pyplot.bar" port="left" type="alternate">
     <value>
       <alternateSpec arg="left" name="leftScalar" port_type="basic:Float">
@@ -407,6 +458,43 @@
       <outputPortSpec arg="rectangle" compute_name="rectangles" name="rectangleProperties" plural="True" port_type="__property__" property_key="0" property_type="matplotlib.artist.Rectangle" />
     </value>
   </addPortSpec>
+  <changeModule attr="docstring" code_ref="matplotlib.pyplot.imshow">
+    <value>Display an image on the axes.
+
+Call signature:
+
+imshow(X, cmap=None, norm=None, aspect=None, interpolation=None,        alpha=None, vmin=None, vmax=None, origin=None, extent=None,        **kwargs)
+
+Display the image in X to current axes.  X may be a float array, a uint8 array or a PIL image. If X is an array, X can have the following shapes:
+
+MxN -- luminance (grayscale, float array only)
+
+MxNx3 -- RGB (float or uint8 array)
+
+MxNx4 -- RGBA (float or uint8 array)
+
+The value for each component of MxNx3 and MxNx4 float arrays should be in the range 0.0 to 1.0; MxN float arrays may be normalised.
+
+An :class:`matplotlib.image.AxesImage` instance is returned.
+
+Keyword arguments:
+
+interpolation:
+
+Acceptable values are None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos'
+
+If interpolation is None, default to rc image.interpolation. See also the filternorm and filterrad parameters
+
+If interpolation is 'none', then no interpolation is performed on the Agg, ps and pdf backends. Other backends will fall back to 'nearest'.
+
+Additional kwargs are :class:`~matplotlib.artist.Artist` properties:
+
+%(Artist)s
+
+Example:
+
+Additional kwargs: hold = [True|False] overrides default hold state</value>
+  </changeModule>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.imshow" port="X" type="input">
     <value>basic:List</value>
   </changePortSpec>
@@ -446,6 +534,9 @@
       <outputPortSpec arg="baseline" compute_name="baseline" name="baselineProperties" port_type="__property__" property_key="2" property_type="matplotlib.lines.Line2D" />
     </value>
   </addPortSpec>
+  <changeModule attr="output_type" code_ref="matplotlib.pyplot.broken_barh">
+    <value>object</value>
+  </changeModule>
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.broken_barh" port="yrange" type="input">
     <value>(ymin, ywidth)</value>
   </changePortSpec>
@@ -466,9 +557,6 @@
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.fill_between" port="y2" type="input">
     <value>basic:Float</value>
   </changePortSpec>
-  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.fill_between" port="y2" type="input">
-    <value>['0.0']</value>
-  </changePortSpec>
   <addPortSpec altName="y2Sequence" code_ref="matplotlib.pyplot.fill_between" port="y2" type="alternate">
     <value>
       <alternateSpec arg="y2" name="y2Sequence" port_type="basic:List">
@@ -479,12 +567,12 @@
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.fill_between" port="y1" type="input">
     <value>An N-length array of the y data</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.fill_between" port="y1" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.fill_between" port="y1" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.fill_between" port="y1" type="input">
+    <value>True</value>
+  </changePortSpec>
   <addPortSpec altName="y1Scalar" code_ref="matplotlib.pyplot.fill_between" port="y1" type="alternate">
     <value>
       <alternateSpec arg="y1" name="y1Scalar" port_type="basic:Float">
@@ -512,6 +600,12 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.hlines">
     <value>object</value>
   </changeModule>
+  <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.hlines" port="xmax" type="input">
+    <value>can be scalars or len(x) numpy arrays.  If they are scalars, then the respective values are constant, else the widths of the lines are determined by xmin and xmax.</value>
+  </changePortSpec>
+  <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.hlines" port="xmax" type="input">
+    <value>basic:Float</value>
+  </changePortSpec>
   <changePortSpec attr="name" code_ref="matplotlib.pyplot.hlines" port="xmax" type="input">
     <value>xmaxScalar</value>
   </changePortSpec>
@@ -539,77 +633,81 @@
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.quiver" port="C" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="C" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.quiver" port="C" type="input">
     <value>basic:List</value>
   </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="C" type="input">
     <value>4</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="C" type="input">
+    <value>True</value>
+  </changePortSpec>
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
     <value>basic:List</value>
   </changePortSpec>
-  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
-    <value>None</value>
-  </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
     <value>1</value>
   </changePortSpec>
-  <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.quiver" port="Y" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
-    <value>True</value>
+  <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
+    <value>None</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
+    <value>0</value>
+  </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
+    <value>True</value>
+  </changePortSpec>
   <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="X" type="input">
-    <value>0</value>
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.quiver" port="scale" type="input">
+    <value>scale</value>
   </changePortSpec>
+  <deletePortSpec altName="scaleScalar" code_ref="matplotlib.pyplot.quiver" port="scale" type="alternate" />
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.quiver" port="U" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="required" code_ref="matplotlib.pyplot.quiver" port="U" type="input">
-    <value>True</value>
+  <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="U" type="input">
+    <value>2</value>
   </changePortSpec>
   <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="U" type="input">
     <value>True</value>
   </changePortSpec>
-  <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="U" type="input">
-    <value>2</value>
+  <changePortSpec attr="required" code_ref="matplotlib.pyplot.quiver" port="U" type="input">
+    <value>True</value>
   </changePortSpec>
   <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.quiver" port="V" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="required" code_ref="matplotlib.pyplot.quiver" port="V" type="input">
-    <value>True</value>
+  <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="V" type="input">
+    <value>3</value>
   </changePortSpec>
   <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.quiver" port="V" type="input">
     <value>True</value>
   </changePortSpec>
-  <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.quiver" port="V" type="input">
-    <value>3</value>
+  <changePortSpec attr="required" code_ref="matplotlib.pyplot.quiver" port="V" type="input">
+    <value>True</value>
   </changePortSpec>
-  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.quiver" port="color" type="input">
-    <value>None</value>
+  <changePortSpec altName="colorScalar" attr="translations" code_ref="matplotlib.pyplot.quiver" port="color" type="alternate">
+    <value>translate_color</value>
   </changePortSpec>
-  <changePortSpec attr="values" code_ref="matplotlib.pyplot.quiver" port="color" type="input">
+  <changePortSpec altName="colorScalar" attr="entry_types" code_ref="matplotlib.pyplot.quiver" port="color" type="alternate">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec altName="colorScalar" attr="translations" code_ref="matplotlib.pyplot.quiver" port="color" type="alternate">
-    <value>translate_color</value>
+  <changePortSpec altName="colorScalar" attr="values" code_ref="matplotlib.pyplot.quiver" port="color" type="alternate">
+    <value>None</value>
   </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.quiver" port="polyCollection" type="output">
     <value>
@@ -619,9 +717,21 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.pie">
     <value>tuple</value>
   </changeModule>
-  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.pie" port="colors" type="input">
-    <value>None</value>
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.pie" port="explode" type="input">
+    <value>explodeSequence</value>
   </changePortSpec>
+  <addPortSpec altName="explodeScalar" code_ref="matplotlib.pyplot.pie" port="explode" type="alternate">
+    <value>
+      <alternateSpec arg="explode" name="explodeScalar" port_type="basic:String" />
+    </value>
+  </addPortSpec>
+  <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.pie" port="colors" type="input">
+    <value>basic:Color</value>
+  </changePortSpec>
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.pie" port="colors" type="input">
+    <value>colors</value>
+  </changePortSpec>
+  <deletePortSpec altName="colorsScalar" code_ref="matplotlib.pyplot.pie" port="colors" type="alternate" />
   <addPortSpec code_ref="matplotlib.pyplot.pie" port="autotext" type="output">
     <value>
       <outputPortSpec arg="autotext" compute_name="autotexts" name="autotextProperties" plural="True" port_type="__property__" property_key="2" property_type="matplotlib.text.Text" />
@@ -658,29 +768,48 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.errorbar">
     <value>tuple</value>
   </changeModule>
-  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="input">
-    <value>None</value>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.errorbar" port="barsabove" type="input">
+    <value>['below']</value>
   </changePortSpec>
-  <changePortSpec attr="values" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="input">
+  <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="input">
+    <value>If a scalar number, len(N) array-like object, or an Nx1 array-like object, errorbars are drawn +/- value.
+
+If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</value>
+  </changePortSpec>
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="input">
     <value>None</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec altName="xerrScalar" code_ref="matplotlib.pyplot.errorbar" port="xerr" type="alternate">
     <value>
       <alternateSpec arg="xerr" name="xerrScalar" port_type="basic:Float" />
     </value>
   </addPortSpec>
-  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="input">
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.errorbar" port="ecolor" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="values" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="input">
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.errorbar" port="ecolor" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="docstring" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="input">
+    <value>If a scalar number, len(N) array-like object, or an Nx1 array-like object, errorbars are drawn +/- value.
+
+If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</value>
+  </changePortSpec>
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="input">
     <value>None</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec altName="yerrScalar" code_ref="matplotlib.pyplot.errorbar" port="yerr" type="alternate">
     <value>
       <alternateSpec arg="yerr" name="yerrScalar" port_type="basic:Float" />
@@ -724,11 +853,14 @@
   <changePortSpec altName="colorScalar" attr="translations" code_ref="matplotlib.pyplot.hist" port="color" type="alternate">
     <value>translate_color</value>
   </changePortSpec>
+  <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.hist" port="bins" type="input">
+    <value>basic:Integer</value>
+  </changePortSpec>
   <changePortSpec attr="name" code_ref="matplotlib.pyplot.hist" port="bins" type="input">
     <value>bins</value>
   </changePortSpec>
-  <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.hist" port="bins" type="input">
-    <value>basic:Integer</value>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.hist" port="bins" type="input">
+    <value>[10]</value>
   </changePortSpec>
   <deletePortSpec altName="binsScalar" code_ref="matplotlib.pyplot.hist" port="bins" type="alternate" />
   <addPortSpec altName="binsSequence" code_ref="matplotlib.pyplot.hist" port="bins" type="alternate">
@@ -744,6 +876,10 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.scatter">
     <value>object</value>
   </changeModule>
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.scatter" port="linewidths" type="input">
+    <value>linewidths</value>
+  </changePortSpec>
+  <deletePortSpec altName="linewidthsScalar" code_ref="matplotlib.pyplot.scatter" port="linewidths" type="alternate" />
   <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.scatter" port="cmap" type="input">
     <value>None</value>
   </changePortSpec>
@@ -775,6 +911,12 @@
       <outputPortSpec arg="line" compute_name="lines" name="lineProperties" plural="True" port_type="__property__" property_key="0" property_type="matplotlib.artist.lines.Line2D" />
     </value>
   </addPortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.psd" port="detrend" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.psd" port="window" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.psd" port="line" type="input">
     <value>
       <inputPortSpec arg="line" constructor_arg="True" name="lineProperties" port_type="__property__" property_type="matplotlib.lines.Line2D" />
@@ -783,23 +925,29 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.polar">
     <value>object</value>
   </changeModule>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.polar" port="theta" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.polar" port="theta" type="input">
     <value>basic:List</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.polar" port="r" type="input">
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.polar" port="theta" type="input">
     <value>True</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.polar" port="r" type="input">
     <value>basic:List</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.polar" port="r" type="input">
+    <value>True</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.polar" port="line" type="output">
     <value>
       <outputPortSpec arg="line" compute_name="lines" name="lineProperties" plural="True" port_type="__property__" property_key="0" property_type="matplotlib.artist.lines.Line2D" />
     </value>
   </addPortSpec>
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.tricontourf" port="colors" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.tricontourf" port="colors" type="input">
+    <value>None</value>
+  </changePortSpec>
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.loglog">
     <value>object</value>
   </changeModule>
@@ -836,20 +984,26 @@
       <inputPortSpec arg="Y" arg_pos="1" in_args="True" name="Y" port_type="basic:List" />
     </value>
   </addPortSpec>
+  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.contourf" port="colors" type="input">
+    <value>None</value>
+  </changePortSpec>
+  <changePortSpec attr="values" code_ref="matplotlib.pyplot.contourf" port="colors" type="input">
+    <value>None</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.contourf" port="X" type="input">
     <value>
       <inputPortSpec arg="X" arg_pos="0" in_args="True" name="X" port_type="basic:List" />
     </value>
   </addPortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.contourf" port="Z" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.contourf" port="Z" type="input">
     <value>basic:List</value>
   </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.contourf" port="Z" type="input">
     <value>2</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.contourf" port="Z" type="input">
+    <value>True</value>
+  </changePortSpec>
   <addPortSpec code_ref="matplotlib.pyplot.contourf" port="contourSet" type="output">
     <value>
       <outputPortSpec arg="contourSet" compute_name="contourSet" name="contourSet" port_type="MplQuadContourSet" property_key="0" />
@@ -860,6 +1014,72 @@
       <outputPortSpec arg="polyCollection" compute_name="polyCollections" name="polyCollectionProperties" plural="True" port_type="__property__" property_key="1" property_type="matplotlib.collections.PolyCollection" />
     </value>
   </addPortSpec>
+  <changeModule attr="docstring" code_ref="matplotlib.pyplot.legend">
+    <value>Place a legend on the current axes.
+
+Call signature:
+
+legend(*args, **kwargs)
+
+Places legend at location loc.  Labels are a sequence of strings and loc can be a string or an integer specifying the legend location.
+
+To make a legend with existing lines:
+
+legend()
+
+:meth:`legend` by itself will try and build a legend using the label property of the lines/patches/collections.  You can set the label of a line by doing:
+
+plot(x, y, label='my data')
+
+or:
+
+line.set_label('my data').
+
+If label is set to '_nolegend_', the item will not be shown in legend.
+
+To automatically generate the legend from labels:
+
+legend( ('label1', 'label2', 'label3') )
+
+To make a legend for a list of lines and labels:
+
+legend( (line1, line2, line3), ('label1', 'label2', 'label3') )
+
+To make a legend at a given location, using a location argument:
+
+legend( ('label1', 'label2', 'label3'), loc='upper left')
+
+or:
+
+legend( (line1, line2, line3),  ('label1', 'label2', 'label3'), loc=2)
+
+The location codes are
+
+
+
+Users can specify any arbitrary location for the legend using the bbox_to_anchor keyword argument. bbox_to_anchor can be an instance of BboxBase(or its derivatives) or a tuple of 2 or 4 floats. For example,
+
+loc = 'upper right', bbox_to_anchor = (0.5, 0.5)
+
+will place the legend so that the upper right corner of the legend at the center of the axes.
+
+The legend location can be specified in other coordinate, by using the bbox_transform keyword.
+
+The loc itslef can be a 2-tuple giving x,y of the lower-left corner of the legend in axes coords (bbox_to_anchor is ignored).
+
+Keyword arguments:
+
+fontsize: [ size in points | 'xx-small' | 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | 'xx-large' ]
+
+Set the font size.  May be either a size string, relative to the default font size, or an absolute font size in points. This argument is only used if prop is not specified.
+
+Padding and spacing between various elements use following keywords parameters. These values are measure in font-size units. E.g., a fontsize of 10 points and a handlelength=5 implies a handlelength of 50 points.  Values from rcParams will be used if None.
+
+Not all kinds of artist are supported by the legend command. See LINK (FIXME) for details.
+
+Example:</value>
+  </changeModule>
+  <deletePortSpec code_ref="matplotlib.pyplot.legend" port="fontsize" type="input" />
   <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.legend" port="prop" type="input">
     <value>None</value>
   </changePortSpec>
@@ -939,36 +1159,30 @@
   <changeModule attr="output_type" code_ref="matplotlib.pyplot.barbs">
     <value>object</value>
   </changeModule>
-  <changePortSpec attr="name" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="input">
-    <value>barbcolor</value>
-  </changePortSpec>
   <changePortSpec attr="translations" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="input">
     <value>translate_color</value>
   </changePortSpec>
-  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="input">
-    <value>None</value>
-  </changePortSpec>
-  <changePortSpec attr="values" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="input">
-    <value>None</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="input">
     <value>basic:Color</value>
   </changePortSpec>
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="input">
+    <value>barbcolor</value>
+  </changePortSpec>
   <deletePortSpec altName="barbcolorScalar" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="alternate" />
   <addPortSpec altName="barbcolorSequence" code_ref="matplotlib.pyplot.barbs" port="barbcolor" type="alternate">
     <value>
       <alternateSpec arg="barbcolor" name="barbcolorSequence" port_type="basic:List" />
     </value>
   </addPortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="C" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="C" type="input">
     <value>basic:List</value>
   </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.barbs" port="C" type="input">
     <value>4</value>
   </changePortSpec>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="C" type="input">
+    <value>True</value>
+  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="sizes" type="input">
     <value>basic:Dictionary</value>
   </changePortSpec>
@@ -983,35 +1197,29 @@
   <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.barbs" port="barb_increments" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="required" code_ref="matplotlib.pyplot.barbs" port="U" type="input">
-    <value>True</value>
-  </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="U" type="input">
-    <value>True</value>
-  </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="U" type="input">
     <value>basic:List</value>
   </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.barbs" port="U" type="input">
     <value>2</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="X" type="input">
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="U" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="required" code_ref="matplotlib.pyplot.barbs" port="U" type="input">
     <value>True</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="X" type="input">
     <value>basic:List</value>
   </changePortSpec>
-  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.barbs" port="X" type="input">
-    <value>None</value>
-  </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.barbs" port="X" type="input">
     <value>0</value>
   </changePortSpec>
-  <changePortSpec attr="required" code_ref="matplotlib.pyplot.barbs" port="V" type="input">
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="X" type="input">
     <value>True</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="V" type="input">
-    <value>True</value>
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.barbs" port="X" type="input">
+    <value>None</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="V" type="input">
     <value>basic:List</value>
@@ -1019,33 +1227,33 @@
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.barbs" port="V" type="input">
     <value>3</value>
   </changePortSpec>
-  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="Y" type="input">
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="V" type="input">
+    <value>True</value>
+  </changePortSpec>
+  <changePortSpec attr="required" code_ref="matplotlib.pyplot.barbs" port="V" type="input">
     <value>True</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="Y" type="input">
     <value>basic:List</value>
   </changePortSpec>
-  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.barbs" port="Y" type="input">
-    <value>None</value>
-  </changePortSpec>
   <changePortSpec attr="arg_pos" code_ref="matplotlib.pyplot.barbs" port="Y" type="input">
     <value>1</value>
   </changePortSpec>
-  <changePortSpec attr="name" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
-    <value>flagcolor</value>
-  </changePortSpec>
-  <changePortSpec attr="translations" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
-    <value>translate_color</value>
+  <changePortSpec attr="in_args" code_ref="matplotlib.pyplot.barbs" port="Y" type="input">
+    <value>True</value>
   </changePortSpec>
-  <changePortSpec attr="entry_types" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
+  <changePortSpec attr="defaults" code_ref="matplotlib.pyplot.barbs" port="Y" type="input">
     <value>None</value>
   </changePortSpec>
-  <changePortSpec attr="values" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
-    <value>None</value>
+  <changePortSpec attr="translations" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
+    <value>translate_color</value>
   </changePortSpec>
   <changePortSpec attr="port_type" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
     <value>basic:Color</value>
   </changePortSpec>
+  <changePortSpec attr="name" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="input">
+    <value>flagcolor</value>
+  </changePortSpec>
   <deletePortSpec altName="flagcolorScalar" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="alternate" />
   <addPortSpec altName="flagcolorSequence" code_ref="matplotlib.pyplot.barbs" port="flagcolor" type="alternate">
     <value>
diff --git a/vistrails/packages/matplotlib/mpl_plots_raw.xml b/vistrails/packages/matplotlib/mpl_plots_raw.xml
index 2d9dc75..a544a6b 100644
--- a/vistrails/packages/matplotlib/mpl_plots_raw.xml
+++ b/vistrails/packages/matplotlib/mpl_plots_raw.xml
@@ -37,14 +37,14 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="normed" arg_pos="1" name="normed" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="usevlines" arg_pos="3" name="usevlines" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="detrend" arg_pos="2" name="detrend" />
     <inputPortSpec arg="maxlags" arg_pos="4" name="maxlags" port_type="basic:Integer">
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="hold" arg_pos="1" name="hold" />
@@ -100,14 +100,14 @@ Valid kwargs are :class:`~matplotlib.lines.Line2D` properties, with the exceptio
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="y" arg_pos="0" name="y" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xmin" arg_pos="1" name="xmin" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="3" name="hold" />
     <inputPortSpec arg="xmax" arg_pos="2" name="xmax" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.axhspan" name="MplAxhspan" superclass="MplPlot">
@@ -137,13 +137,13 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="xmin" arg_pos="2" name="xmin" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="ymin" arg_pos="0" name="ymin" required="True" />
     <inputPortSpec arg="ymax" arg_pos="1" name="ymax" required="True" />
     <inputPortSpec arg="xmax" arg_pos="3" name="xmax" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.axvline" name="MplAxvline" superclass="MplPlot">
@@ -175,14 +175,14 @@ Valid kwargs are :class:`~matplotlib.lines.Line2D` properties, with the exceptio
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="3" name="hold" />
     <inputPortSpec arg="ymin" arg_pos="1" name="ymin" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="ymax" arg_pos="2" name="ymax" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.axvspan" name="MplAxvspan" superclass="MplPlot">
@@ -212,10 +212,10 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="xmin" arg_pos="0" name="xmin" required="True" />
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="ymin" arg_pos="2" name="ymin" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="ymax" arg_pos="3" name="ymax" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xmax" arg_pos="1" name="xmax" required="True" />
   </moduleSpec>
@@ -262,7 +262,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="capsize" name="capsize" port_type="basic:Integer">
       <docstring>(default 3) determines the length in points of the error bar caps</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="orientation" name="orientation" port_type="basic:String">
       <docstring>'vertical' | 'horizontal'</docstring>
@@ -271,7 +271,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="bottom" arg_pos="3" name="bottom" port_type="basic:Integer">
       <docstring>the y coordinates of the bottom edges of the bars</docstring>
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="color" name="color" port_type="basic:Color">
       <docstring>the colors of the bars</docstring>
@@ -295,14 +295,14 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="width" arg_pos="2" name="width" port_type="basic:Float">
       <docstring>the widths of the bars</docstring>
-      <defaults>['0.8']</defaults>
+      <defaults>[0.8]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="error_kw" name="error_kw">
       <docstring>dictionary of kwargs to be passed to errorbar method. ecolor and capsize may be specified here rather than as independent kwargs.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="log" name="log" port_type="basic:Boolean">
       <docstring>[False|True] False (default) leaves the orientation axis as-is; True sets it to log scale</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="yerr" name="yerr">
@@ -353,11 +353,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="capsize" name="capsize" port_type="basic:Integer">
       <docstring>(default 3) determines the length in points of the error bar caps</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="log" name="log" port_type="basic:Boolean">
       <docstring>[False|True] False (default) leaves the horizontal axis as-is; True sets it to log scale</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="bottom" arg_pos="0" name="bottom" required="True">
       <docstring>the vertical positions of the bottom edges of the bars</docstring>
@@ -381,7 +381,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="height" arg_pos="2" name="height" port_type="basic:Float">
       <docstring>the heights (thicknesses) of the bars</docstring>
-      <defaults>['0.8']</defaults>
+      <defaults>[0.8]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="width" arg_pos="1" name="width" required="True">
       <docstring>the lengths of the bars</docstring>
@@ -392,7 +392,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="left" arg_pos="3" name="left" port_type="basic:Integer">
       <docstring>the x coordinates of the left edges of the bars</docstring>
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.broken_barh" name="MplBrokenBarh" superclass="MplPlot">
@@ -462,7 +462,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="hold" arg_pos="11" name="hold" />
     <inputPortSpec arg="vert" arg_pos="3" name="vert" port_type="basic:Boolean">
       <docstring>If True (default), makes the boxes vertical. If False, makes horizontal boxes.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="positions" arg_pos="5" name="positions">
       <docstring>Sets the horizontal positions of the boxes. The ticks and limits are automatically set to match the positions.</docstring>
@@ -479,22 +479,22 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="widths" arg_pos="6" name="widths" port_type="basic:Float">
       <docstring>Either a scalar or a vector and sets the width of each box. The default is 0.5, or 0.15*(distance between extreme positions) if that is smaller.</docstring>
-      <defaults>['0.5']</defaults>
+      <defaults>[0.5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="patch_artist" arg_pos="7" name="patch_artist" port_type="basic:Boolean">
       <docstring>If False produces boxes with the Line2D artist If True produces boxes with the Patch artist</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True">
       <docstring>Array or a sequence of vectors.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="notch" arg_pos="1" name="notch" port_type="basic:Boolean">
       <docstring>If False (default), produces a rectangular box plot. If True, will produce a notched box plot</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="whis" arg_pos="4" name="whis" port_type="basic:Float">
       <docstring>Defines the length of the whiskers as a function of the inner quartile range.  They extend to the most extreme data point within ( whis*(75%-25%) ) data range.</docstring>
-      <defaults>['1.5']</defaults>
+      <defaults>[1.5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="conf_intervals" arg_pos="10" name="conf_intervals" port_type="basic:List">
       <docstring>Array or sequence whose first dimension (or length) is compatible with x and whose second dimension is 2. When the current element of conf_intervals is not None, the notch locations computed by matplotlib are overridden (assuming notch is True). When an element of conf_intervals is None, boxplot compute notches the method specified by the other kwargs (e.g. bootstrap).</docstring>
@@ -531,21 +531,21 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="3" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="8" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="10" name="scale_by_freq" />
     <inputPortSpec arg="detrend" arg_pos="5" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>[<function detrend_none at 0x106c49398>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="6" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>[<function window_hanning at 0x106c3a488>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="4" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="2" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -554,7 +554,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="7" name="noverlap" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.clabel" name="MplClabel" superclass="MplPlot">
@@ -605,12 +605,12 @@ if a tuple of matplotlib color args (string, float, rgb, etc), different labels
     </inputPortSpec>
     <inputPortSpec arg="rightside_up" name="rightside_up" port_type="basic:Boolean">
       <docstring>if True (default), label rotations will always be plus or minus 90 degrees from level.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="CS" arg_pos="0" name="CS" required="True" />
     <inputPortSpec arg="inline" name="inline" port_type="basic:Boolean">
       <docstring>controls whether the underlying contour is removed or not. Default is True.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.contour" name="MplContour" superclass="MplPlot">
@@ -676,36 +676,34 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
+    </inputPortSpec>
+    <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
+      <docstring>If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.
+
+linestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.</docstring>
+      <entry_types>['enum']</entry_types>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <defaults>['solid']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xunits" name="xunits" port_type="basic:String">
       <docstring>Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'registered units']]</values>
+      <values>[['registered units']]</values>
     </inputPortSpec>
     <inputPortSpec arg="extend" name="extend" port_type="basic:String">
       <docstring>Unless this is 'neither', contour levels are automatically added to one or both ends of the range so that all data are included. These added ranges are then mapped to the special colormap values which default to the ends of the colormap range, but can be set via :meth:`matplotlib.colors.Colormap.set_under` and :meth:`matplotlib.colors.Colormap.set_over` methods.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['neither', 'both', 'min', 'max']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[[0]]</values>
     </inputPortSpec>
-    <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
-      <docstring>If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.
-
-linestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
-      <defaults>['solid']</defaults>
-    </inputPortSpec>
     <inputPortSpec arg="hatches" name="hatches" port_type="basic:List">
       <docstring>A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only.</docstring>
     </inputPortSpec>
@@ -720,12 +718,12 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="locator" name="locator" port_type="basic:String">
       <docstring>If locator is None, the default :class:`~matplotlib.ticker.MaxNLocator` is used. The locator is used to determine the contour levels if they are not given explicitly via the V argument.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'ticker.Locator subclass']]</values>
+      <values>[['ticker.Locator subclass']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -735,29 +733,27 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
       <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <values>[['(mpl_colors)']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="yunits" name="yunits" port_type="basic:String">
       <docstring>Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'registered units']]</values>
+      <values>[['registered units']]</values>
     </inputPortSpec>
     <inputPortSpec arg="extent" name="extent" port_type="basic:String">
       <docstring>If origin is not None, then extent is interpreted as in :func:`matplotlib.pyplot.imshow`: it gives the outer pixel boundaries. In this case, the position of Z[0,0] is the center of the pixel, not a corner. If origin is None, then (x0, y0) is the position of Z[0,0], and (x1, y1) is the position of Z[-1,-1].
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', '(x0,x1,y0,y1)']]</values>
+      <values>[['(x0,x1,y0,y1)']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -765,12 +761,12 @@ This keyword is not active if X and Y are specified in the call to contour.</doc
     <inputPortSpec arg="Z" arg_pos="0" name="Z" required="True" />
     <inputPortSpec arg="antialiased" name="antialiased" port_type="basic:Boolean">
       <docstring>enable antialiasing, overriding the defaults.  For filled contours, the default is True.  For line contours, it is taken from rcParams['lines.antialiased'].</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.contourf" name="MplContourf" superclass="MplPlot">
@@ -840,25 +836,23 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
     </inputPortSpec>
     <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
       <docstring>If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.
 
 linestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
       <defaults>['solid']</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[[0]]</values>
+      <values>[['0']]</values>
     </inputPortSpec>
     <inputPortSpec arg="hatches" name="hatches" port_type="basic:List">
       <docstring>A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only.</docstring>
@@ -874,7 +868,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -884,17 +878,15 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
       <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <values>[['(mpl_colors)']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -903,7 +895,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.csd" name="MplCsd" superclass="MplPlot">
@@ -931,21 +923,21 @@ seealso:  :meth:`psd`     For a description of the optional parameters.
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="3" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="8" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="10" name="scale_by_freq" />
     <inputPortSpec arg="detrend" arg_pos="5" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>[<function detrend_none at 0x106c49398>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="6" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>[<function window_hanning at 0x106c3a488>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="4" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="2" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -954,7 +946,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="7" name="noverlap" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.errorbar" name="MplErrorbar" superclass="MplPlot">
@@ -991,28 +983,28 @@ Example:
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="lolims" arg_pos="9" name="lolims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="capsize" arg_pos="7" name="capsize" port_type="basic:Float">
       <docstring>The length of the error bar caps in points</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="uplims" arg_pos="10" name="uplims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xlolims" arg_pos="11" name="xlolims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="barsabove" arg_pos="8" name="barsabove">
       <docstring>if True, will plot the errorbars above the plot symbols. Default is below.</docstring>
-      <defaults>['below']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xerr" arg_pos="3" name="xerr">
-      <docstring>If a scalar number, len(N) array-like object, or an Nx1 array-like object, errorbars are drawn +/- value.
+      <docstring>If a scalar number, len(N) array-like object, or an Nx1 array-like object, errorbars are drawn at +/-value relative to the data.
 
-If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</docstring>
+If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2 relative to the data.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['N, Nx1, or 2xN array-like']]</values>
     </inputPortSpec>
@@ -1024,18 +1016,18 @@ If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</docstring>
       <docstring>A matplotlib color arg which gives the color the errorbar lines; if None, use the marker color.</docstring>
       <translations>translate_color</translations>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'mpl color']]</values>
+      <values>[['mpl color']]</values>
     </inputPortSpec>
     <inputPortSpec arg="errorevery" arg_pos="13" name="errorevery" port_type="basic:Integer">
       <docstring>subsamples the errorbars. Eg if everyerror=5, errorbars for every 5-th datapoint will be plotted. The data plot itself still shows all data points.</docstring>
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="capthick" arg_pos="14" name="capthick" port_type="basic:Float">
       <docstring>An alias kwarg to markeredgewidth (a.k.a. - mew). This setting is a more sensible name for the property that controls the thickness of the error bar cap in points. For backwards compatibility, if mew or markeredgewidth are given, then they will over-ride capthick.  This may change in future releases.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="xuplims" arg_pos="12" name="xuplims" port_type="basic:Boolean">
       <docstring>These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="elinewidth" arg_pos="6" name="elinewidth" port_type="basic:Float">
       <docstring>The linewidth of the errorbar lines. If None, use the linewidth.</docstring>
@@ -1044,9 +1036,9 @@ If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</docstring>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="hold" arg_pos="15" name="hold" />
     <inputPortSpec arg="yerr" arg_pos="2" name="yerr">
-      <docstring>If a scalar number, len(N) array-like object, or an Nx1 array-like object, errorbars are drawn +/- value.
+      <docstring>If a scalar number, len(N) array-like object, or an Nx1 array-like object, errorbars are drawn at +/-value relative to the data.
 
-If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2</docstring>
+If a sequence of shape 2xN, errorbars are drawn at -row1 and +row2 relative to the data.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['N, Nx1, or 2xN array-like']]</values>
     </inputPortSpec>
@@ -1099,10 +1091,10 @@ kwargs control the :class:`~matplotlib.patches.Polygon` properties:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="y2" arg_pos="2" name="y2" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="interpolate" arg_pos="4" name="interpolate" port_type="basic:Boolean">
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y1" arg_pos="1" name="y1" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -1114,7 +1106,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 Call signature:
 
-fill_between(y, x1, x2=0, where=None, **kwargs)
+fill_betweenx(y, x1, x2=0, where=None, **kwargs)
 
 Create a :class:`~matplotlib.collections.PolyCollection` filling the regions between x1 and x2 where where==True
 
@@ -1127,7 +1119,7 @@ kwargs control the :class:`~matplotlib.patches.Polygon` properties:
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="y" arg_pos="0" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x2" arg_pos="2" name="x2" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="4" name="hold" />
     <inputPortSpec arg="x1" arg_pos="1" name="x1" required="True" />
@@ -1170,17 +1162,18 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 If None, draws the outlines in the default color.
 
 If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the specified color.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'none', 'mpl color']]</values>
-      <defaults>['none']</defaults>
-      <alternateSpec arg="" name="edgecolorsScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="edgecolorsScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['none', 'mpl color']]</values>
+        <defaults>['none']</defaults>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="C" arg_pos="2" name="C" />
     <inputPortSpec arg="gridsize" arg_pos="3" name="gridsize" port_type="basic:Integer">
       <docstring>The number of hexagons in the x-direction, default is 100. The corresponding number of hexagons in the y-direction is chosen such that the hexagons are approximately regular. Alternatively, gridsize can be a tuple with two elements specifying the number of hexagons in the x-direction and the y-direction.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[[100]]</values>
-      <defaults>['100']</defaults>
+      <defaults>[100]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="vmin" arg_pos="10" name="vmin" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.</docstring>
@@ -1189,12 +1182,11 @@ If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the
       <defaults>['linear']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="reduce_C_function" arg_pos="15" name="reduce_C_function">
-      <defaults>['<function mean at 0x0277B3B0>']</defaults>
+      <defaults>[<function mean at 0x1065e2410>]</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="linewidths" arg_pos="13" name="linewidths">
+    <inputPortSpec arg="linewidths" arg_pos="13" name="linewidthsSequence" port_type="basic:List">
       <docstring>If None, defaults to rc lines.linewidth. Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
+      <alternateSpec arg="" name="linewidthsScalar" port_type="basic:Float" />
     </inputPortSpec>
     <inputPortSpec arg="xscale" arg_pos="5" name="xscale" port_type="basic:String">
       <docstring>Use a linear or log10 scale on the horizontal axis.</docstring>
@@ -1205,17 +1197,15 @@ If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the
     <inputPortSpec arg="cmap" arg_pos="8" name="cmap" port_type="basic:String">
       <docstring>a :class:`matplotlib.colors.Colormap` instance. If None, defaults to rc image.cmap.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="norm" arg_pos="9" name="norm" port_type="basic:String">
       <docstring>:class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="extent" arg_pos="7" name="extent">
+    <inputPortSpec arg="extent" arg_pos="7" name="extent" port_type="basic:Float">
       <docstring>The limits of the bins. The default assigns the limits based on gridsize, x, y, xscale and yscale.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" arg_pos="12" name="alpha" port_type="basic:Float">
       <docstring>the alpha value for the patches</docstring>
@@ -1223,14 +1213,12 @@ If a matplotlib color arg or sequence of rgba tuples, draws the outlines in the
     <inputPortSpec arg="y" arg_pos="1" name="y" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" required="True" />
     <inputPortSpec arg="hold" arg_pos="18" name="hold" />
-    <inputPortSpec arg="mincnt" arg_pos="16" name="mincnt">
+    <inputPortSpec arg="mincnt" arg_pos="16" name="mincnt" port_type="basic:Integer">
       <docstring>If not None, only display cells with more than mincnt number of points in the cell</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="marginals" arg_pos="17" name="marginals" port_type="basic:Boolean">
       <docstring>if marginals is True, plot the marginal density as colormapped rectagles along the bottom of the x-axis and left of the y-axis</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="bins" arg_pos="4" name="bins">
       <docstring>If None, no binning is applied; the color of each hexagon directly corresponds to its count value.
@@ -1241,7 +1229,7 @@ If an integer, divide the counts in the specified number of bins, and color the
 
 If a sequence of values, the values of the lower bound of the bins to be used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'log']]</values>
+      <values>[['log']]</values>
     </inputPortSpec>
     <inputPortSpec arg="scale" name="scale" port_type="basic:String">
       <docstring>Use a linear or log10 scale on the vertical axis.</docstring>
@@ -1282,13 +1270,13 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 pdf, bins, patches = ax.hist(...) print np.sum(pdf * np.diff(bins))
 
 Until numpy release 1.5, the underlying numpy histogram function was incorrect with normed*=*True if bin sizes were unequal.  MPL inherited that error.  It is now corrected within MPL when using earlier numpy versions</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="stacked" arg_pos="14" name="stacked" port_type="basic:Boolean">
       <docstring>If True, multiple data are stacked on top of each other If False multiple data are aranged side by side if histtype is 'bar' or on top of each other if histtype is 'step'
 
 .</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="orientation" arg_pos="9" name="orientation" port_type="basic:String">
       <docstring>If 'horizontal', :func:`~matplotlib.pyplot.barh` will be used for bar-type histograms and the bottom kwarg will be the left edges.</docstring>
@@ -1330,7 +1318,7 @@ Until numpy release 1.5, the underlying numpy histogram function was incorrect w
     </inputPortSpec>
     <inputPortSpec arg="cumulative" arg_pos="5" name="cumulative" port_type="basic:Boolean">
       <docstring>If True, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin gives the total number of datapoints.  If normed is also True then the histogram is normalized such that the last bin equals 1. If cumulative evaluates to less than 0 (e.g. -1), the direction of accumulation is reversed.  In this case, if normed is also True, then the histogram is normalized such that the first bin equals 1.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="label" arg_pos="13" name="labelSequence" port_type="basic:List">
       <docstring>String, or sequence of strings to match multiple datasets.  Bar charts yield multiple patches per dataset, but only the first gets the label, so that the legend command will work as expected:
@@ -1350,12 +1338,13 @@ If bins is a sequence or range is specified, autoscaling is based on the specifi
     <inputPortSpec arg="hold" arg_pos="15" name="hold" />
     <inputPortSpec arg="bins" arg_pos="1" name="binsSequence" port_type="basic:List">
       <docstring>Either an integer number of bins or a sequence giving the bins.  If bins is an integer, bins + 1 bin edges will be returned, consistent with :func:`numpy.histogram` for numpy version >= 1.3, and with the new = True argument in earlier versions. Unequally spaced bins are supported if bins is a sequence.</docstring>
-      <defaults>['10']</defaults>
-      <alternateSpec arg="" name="binsScalar" port_type="basic:Integer" />
+      <alternateSpec arg="" name="binsScalar" port_type="basic:Integer">
+        <defaults>[10]</defaults>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="log" arg_pos="11" name="log" port_type="basic:Boolean">
       <docstring>If True, the histogram axis will be set to a log scale. If log is True and x is a 1D array, empty bins will be filtered out and only the non-empty (n, bins, patches) will be returned.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.hist2d" name="MplHist2d" superclass="MplPlot">
@@ -1391,7 +1380,7 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="normed" arg_pos="4" name="normed" port_type="basic:Boolean">
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmin" arg_pos="6" name="cmin" />
     <inputPortSpec arg="range" arg_pos="3" name="range" />
@@ -1401,7 +1390,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="hold" arg_pos="8" name="hold" />
     <inputPortSpec arg="cmax" arg_pos="7" name="cmax" />
     <inputPortSpec arg="bins" arg_pos="2" name="bins" port_type="basic:Integer">
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.hlines" name="MplHlines" superclass="MplPlot">
@@ -1438,12 +1427,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="colors" arg_pos="3" name="colorsSequence" port_type="basic:List">
       <docstring>a line collections color argument, either a single color or a len(y) list of colors</docstring>
-      <defaults>['k']</defaults>
-      <alternateSpec arg="" name="colorsScalar" port_type="basic:String" />
-    </inputPortSpec>
-    <inputPortSpec arg="xmax" arg_pos="2" name="xmax" port_type="basic:Float" required="True">
-      <docstring>can be scalars or len(x) numpy arrays.  If they are scalars, then the respective values are constant, else the widths of the lines are determined by xmin and xmax.</docstring>
+      <alternateSpec arg="" name="colorsScalar" port_type="basic:String">
+        <defaults>['k']</defaults>
+      </alternateSpec>
     </inputPortSpec>
+    <inputPortSpec arg="xmax" arg_pos="2" name="xmax" required="True" />
     <inputPortSpec arg="y" arg_pos="0" name="y" port_type="basic:List" required="True">
       <docstring>a 1-D numpy array or iterable.</docstring>
     </inputPortSpec>
@@ -1478,7 +1466,7 @@ If interpolation is None, default to rc image.interpolation. See also the filter
 
 If interpolation is 'none', then no interpolation is performed on the Agg, ps and pdf backends. Other backends will fall back to 'nearest'.
 
-Additional kwargs are :class:`~matplotlib.artist.Artist` properties:
+Additional kwargs are :class:`~matplotlib.artist.Artist` properties.
 
 %(Artist)s
 
@@ -1497,13 +1485,13 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 cmap is ignored when X has RGB(A) information</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="filterrad" arg_pos="12" name="filterrad" port_type="basic:Float">
-      <defaults>['4.0']</defaults>
+      <defaults>[4.0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="filternorm" arg_pos="11" name="filternorm" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="aspect" arg_pos="3" name="aspect">
       <docstring>If 'auto', changes the image aspect ratio to match that of the axes
@@ -1512,7 +1500,7 @@ If 'equal', and extent is None, changes the axes aspect ratio to match that of t
 
 If None, default to rc image.aspect value.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'auto', 'equal']]</values>
+      <values>[['auto', 'equal']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" arg_pos="5" name="alpha" />
     <inputPortSpec arg="vmax" arg_pos="7" name="vmax" />
@@ -1557,17 +1545,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="basey" name="basey" port_type="basic:Float">
       <docstring>Base of the x/y logarithm</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="subsx" name="subsxSequence" port_type="basic:List">
+    <inputPortSpec arg="subsx" name="subsx" port_type="basic:List">
       <docstring>The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="" name="subsxScalar" port_type="basic:String" />
     </inputPortSpec>
-    <inputPortSpec arg="subsy" name="subsySequence" port_type="basic:List">
+    <inputPortSpec arg="subsy" name="subsy" port_type="basic:List">
       <docstring>The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="" name="subsyScalar" port_type="basic:String" />
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.pcolor" name="MplPcolor" superclass="MplPlot">
@@ -1636,27 +1618,24 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 If 'none', edges will not be visible.
 
 An mpl color or sequence of colors will set the edge color</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'none', 'color']]</values>
-      <alternateSpec arg="" name="edgecolorsScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="edgecolorsScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['none', 'color']]</values>
+      </alternateSpec>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>the alpha blending value</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="shading" name="shading" port_type="basic:String">
       <docstring>If 'faceted', a black grid is drawn around each rectangle; if 'flat', edges are not drawn. Default is 'flat', contrary to MATLAB.</docstring>
@@ -1667,7 +1646,7 @@ An mpl color or sequence of colors will set the edge color</docstring>
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>An :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.pcolormesh" name="MplPcolormesh" superclass="MplPlot">
@@ -1702,27 +1681,24 @@ If 'None', edges will not be visible.
 If 'face', edges will have the same color as the faces.
 
 An mpl color or sequence of colors will set the edge color</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'None', 'face', 'color']]</values>
-      <alternateSpec arg="" name="edgecolorsScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="edgecolorsScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['None', 'face', 'color']]</values>
+      </alternateSpec>
     </inputPortSpec>
-    <inputPortSpec arg="vmin" name="vmin">
+    <inputPortSpec arg="vmin" name="vmin" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>the alpha blending value</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="vmax" name="vmax">
+    <inputPortSpec arg="vmax" name="vmax" port_type="basic:Float">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="shading" name="shading" port_type="basic:String">
       <docstring>'flat' indicates a solid color for each quad.  When 'gouraud', each quad will be Gouraud shaded.  When gouraud shading, edgecolors is ignored.</docstring>
@@ -1732,7 +1708,7 @@ An mpl color or sequence of colors will set the edge color</docstring>
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.pie" name="MplPie" superclass="MplPlot">
@@ -1756,46 +1732,39 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="autopct" arg_pos="4" name="autopct" port_type="basic:String">
       <docstring>If not None, is a string or function used to label the wedges with their numeric value.  The label will be placed inside the wedge.  If it is a format string, the label will be fmt%pct. If it is a function, it will be called.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'format function']]</values>
+      <values>[['format function']]</values>
     </inputPortSpec>
     <inputPortSpec arg="pctdistance" arg_pos="5" name="pctdistance" port_type="basic:Float">
       <docstring>The ratio between the center of each pie slice and the start of the text generated by autopct.  Ignored if autopct is None; default is 0.6.</docstring>
-      <defaults>['0.6']</defaults>
+      <defaults>[0.6]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="labels" arg_pos="2" name="labelsSequence" port_type="basic:List">
       <docstring>A sequence of strings providing the labels for each wedge</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
       <alternateSpec arg="" name="labelsScalar" port_type="basic:String" />
     </inputPortSpec>
-    <inputPortSpec arg="explode" arg_pos="1" name="explodeSequence" port_type="basic:List">
+    <inputPortSpec arg="explode" arg_pos="1" name="explode" port_type="basic:List">
       <docstring>If not None, is a len(x) array which specifies the fraction of the radius with which to offset each wedge.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="" name="explodeScalar" port_type="basic:String" />
     </inputPortSpec>
-    <inputPortSpec arg="colors" arg_pos="3" name="colors" port_type="basic:Color">
+    <inputPortSpec arg="colors" arg_pos="3" name="colorsSequence" port_type="basic:List">
       <docstring>A sequence of matplotlib color args through which the pie chart will cycle.</docstring>
       <translations>translate_color</translations>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <defaults>["('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w')"]</defaults>
+      <alternateSpec arg="" name="colorsScalar" port_type="basic:Color" />
     </inputPortSpec>
     <inputPortSpec arg="radius" arg_pos="9" name="radius" />
     <inputPortSpec arg="startangle" arg_pos="8" name="startangle" port_type="basic:String">
       <docstring>If not None, rotates the start of the pie chart by angle degrees counterclockwise from the x-axis.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Offset angle']]</values>
+      <values>[['Offset angle']]</values>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="shadow" arg_pos="6" name="shadow" port_type="basic:Boolean">
       <docstring>Draw a shadow beneath the pie.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="hold" arg_pos="10" name="hold" />
     <inputPortSpec arg="labeldistance" arg_pos="7" name="labeldistance" port_type="basic:Float">
       <docstring>The radial distance at which the pie labels are drawn</docstring>
-      <defaults>['1.1']</defaults>
+      <defaults>[1.1]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.plot_date" name="MplPlotDate" superclass="MplPlot">
@@ -1823,7 +1792,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="tz" arg_pos="3" name="tz" port_type="basic:String">
       <docstring>The time zone to use in labeling dates. If None, defaults to rc value.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', ':class:`tzinfo` instance']]</values>
+      <values>[[':class:`tzinfo` instance']]</values>
     </inputPortSpec>
     <inputPortSpec arg="fmt" arg_pos="2" name="fmt" port_type="basic:String">
       <docstring>The plot format string.</docstring>
@@ -1831,11 +1800,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="ydate" arg_pos="5" name="ydate" port_type="basic:Boolean">
       <docstring>If True, the y-axis will be labeled with dates.</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="xdate" arg_pos="4" name="xdate" port_type="basic:Boolean">
       <docstring>If True, the x-axis will be labeled with dates.</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -1866,21 +1835,21 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="2" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="7" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="9" name="scale_by_freq" />
     <inputPortSpec arg="detrend" arg_pos="4" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>[<function detrend_none at 0x106c49398>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="5" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>[<function window_hanning at 0x106c3a488>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="3" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="1" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
     <inputPortSpec arg="hold" arg_pos="10" name="hold" />
@@ -1888,7 +1857,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="6" name="noverlap" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.quiver" name="MplQuiver" superclass="MplPlot">
@@ -1919,47 +1888,51 @@ agg_filter: unknown alpha: float or None animated: [True | False] antialiased or
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="headaxislength" name="headaxislength" port_type="basic:Float">
       <docstring>Head length at shaft intersection, default is 4.5</docstring>
-      <defaults>['4.5']</defaults>
+      <defaults>[4.5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="C" name="C">
       <docstring>An optional array used to map colors to the arrows</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="scale" name="scale">
+    <inputPortSpec arg="scale" name="scaleSequence" port_type="basic:List">
       <docstring>Data units per arrow length unit, e.g. m/s per plot width; a smaller scale parameter makes the arrow longer.  If None, a simple autoscaling algorithm is used, based on the average vector length and the number of vectors.  The arrow length unit is given by the scale_units parameter</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
+      <alternateSpec arg="" name="scaleScalar" port_type="basic:Float" />
     </inputPortSpec>
     <inputPortSpec arg="width" name="width" port_type="basic:List">
       <docstring>Shaft width in arrow units; default depends on choice of units, above, and number of vectors; a typical starting value is about 0.005 times the width of the plot.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="headlength" name="headlength" port_type="basic:Float">
       <docstring>Head length as multiple of shaft width, default is 5</docstring>
-      <defaults>['5']</defaults>
+      <defaults>[5]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="minlength" name="minlength" port_type="basic:Float">
       <docstring>Minimum length as a multiple of shaft width; if an arrow length is less than this, plot a dot (hexagon) of this diameter instead. Default is 1.</docstring>
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="minshaft" name="minshaft" port_type="basic:Float">
       <docstring>Length below which arrow scales, in units of head length. Do not set this to less than 1, or small arrows will look terrible! Default is 1</docstring>
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pivot" name="pivot" port_type="basic:String">
       <docstring>The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name pivot.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['tail', 'middle', 'tip']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="units" name="unitsSequence" port_type="basic:List">
-      <docstring>For example, if scale_units is 'inches', scale is 2.0, and (u,v) = (1,0), then the vector will be 0.5 inches long. If scale_units is 'width', then the vector will be half the width of the axes.
+    <inputPortSpec arg="units" name="units" port_type="basic:String">
+      <docstring>Arrow units; the arrow dimensions except for length are in multiples of this unit.
 
-If scale_units is 'x' then the vector will be 0.5 x-axis units.  To plot vectors in the x-y plane, with u and v having the same units as x and y, use "angles='xy', scale_units='xy', scale=1".</docstring>
+'width' or 'height': the width or height of the axes
+
+'dots' or 'inches': pixels or inches, based on the figure dpi
+
+'x', 'y', or 'xy': X, Y, or sqrt(X^2+Y^2) data units
+
+The arrows scale differently depending on the units.  For 'x' or 'y', the arrows get larger as one zooms in; for other units, the arrow size is independent of the zoom state.  For 'width or 'height', the arrow size increases with the width and height of the axes, respectively, when the the window is resized; for 'dots' or 'inches', resizing does not change the arrows.</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['width', 'height', 'dots', 'inches', 'x', 'y', 'xy']]</values>
-      <alternateSpec arg="" name="unitsScalar" port_type="basic:String" />
     </inputPortSpec>
     <inputPortSpec arg="headwidth" name="headwidth" port_type="basic:Float">
       <docstring>Head width as multiple of shaft width, default is 3</docstring>
-      <defaults>['3']</defaults>
+      <defaults>[3]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="U" name="U" port_type="basic:List">
       <docstring>Give the x and y components of the arrow vectors</docstring>
@@ -1987,9 +1960,10 @@ If scale_units is 'x' then the vector will be 0.5 x-axis units.  To plot vectors
     </inputPortSpec>
     <inputPortSpec arg="color" name="colorSequence" port_type="basic:List">
       <docstring>This is a synonym for the :class:`~matplotlib.collections.PolyCollection` facecolor kwarg. If C has been set, color has no effect.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['color']]</values>
-      <alternateSpec arg="" name="colorScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="colorScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['color']]</values>
+      </alternateSpec>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.quiverkey" name="MplQuiverkey" superclass="MplPlot">
@@ -2018,9 +1992,10 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="coordinates" name="coordinatesSequence" port_type="basic:List">
       <docstring>Coordinate system and units for X, Y: 'axes' and 'figure' are normalized coordinate systems with 0,0 in the lower left and 1,1 in the upper right; 'data' are the axes data coordinates (used for the locations of the vectors in the quiver plot itself); 'inches' is position in the figure in inches, with 0,0 at the lower left corner.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['axes', 'figure', 'data', 'inches']]</values>
-      <alternateSpec arg="" name="coordinatesScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="coordinatesScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['axes', 'figure', 'data', 'inches']]</values>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="label" arg_pos="4" name="label" port_type="basic:String" required="True">
       <docstring>A string with the length and units of the key</docstring>
@@ -2051,7 +2026,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="labelsep" name="labelsep" port_type="basic:Float">
       <docstring>Distance in inches between the arrow and the label.  Default is 0.1</docstring>
-      <defaults>['0.1']</defaults>
+      <defaults>[0.1]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.scatter" name="MplScatter" superclass="MplPlot">
@@ -2092,19 +2067,19 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="c" arg_pos="3" name="cSequence" port_type="basic:List">
       <docstring>a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped.  c can be a 2-D array in which the rows are RGB or RGBA, however.</docstring>
-      <defaults>['b']</defaults>
-      <alternateSpec arg="" name="cScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="cScalar" port_type="basic:String">
+        <defaults>['b']</defaults>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="vmin" arg_pos="7" name="vmin">
       <docstring>vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.</docstring>
     </inputPortSpec>
     <inputPortSpec arg="faceted" arg_pos="11" name="faceted" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
-    <inputPortSpec arg="linewidths" arg_pos="10" name="linewidths">
+    <inputPortSpec arg="linewidths" arg_pos="10" name="linewidthsSequence" port_type="basic:List">
       <docstring>If None, defaults to (lines.linewidth,).  Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
+      <alternateSpec arg="" name="linewidthsScalar" port_type="basic:Float" />
     </inputPortSpec>
     <inputPortSpec arg="marker" arg_pos="4" name="marker" port_type="basic:String">
       <docstring>can be one of:
@@ -2114,12 +2089,12 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="s" arg_pos="2" name="s" port_type="basic:Float">
       <docstring>size in points^2.  It is a scalar or an array of the same length as x and y.</docstring>
-      <defaults>['20']</defaults>
+      <defaults>[20]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmap" arg_pos="5" name="cmap">
       <docstring>A :class:`matplotlib.colors.Colormap` instance or registered name. If None, defaults to rc image.cmap. cmap is only used if c is an array of floats.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="verts" arg_pos="12" name="verts" />
     <inputPortSpec arg="alpha" arg_pos="9" name="alpha" port_type="basic:Float">
@@ -2134,7 +2109,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="norm" arg_pos="6" name="norm">
       <docstring>A :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0, 1. If None, use the default :func:`normalize`. norm is only used if c is an array of floats.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.semilogx" name="MplSemilogx" superclass="MplPlot">
@@ -2163,11 +2138,8 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['mask', 'clip']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="subsx" name="subsxSequence" port_type="basic:List">
+    <inputPortSpec arg="subsx" name="subsx" port_type="basic:List">
       <docstring>The location of the minor xticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_xscale` for details.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="" name="subsxScalar" port_type="basic:String" />
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.semilogy" name="MplSemilogy" superclass="MplPlot">
@@ -2196,11 +2168,8 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['mask', 'clip']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="subsy" name="subsySequence" port_type="basic:List">
+    <inputPortSpec arg="subsy" name="subsy" port_type="basic:List">
       <docstring>The location of the minor yticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_yscale` for details.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
-      <alternateSpec arg="" name="subsyScalar" port_type="basic:String" />
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.specgram" name="MplSpecgram" superclass="MplPlot">
@@ -2234,22 +2203,22 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="Fs" arg_pos="2" name="Fs" port_type="basic:Integer">
-      <defaults>['2']</defaults>
+      <defaults>[2]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pad_to" arg_pos="9" name="pad_to" />
     <inputPortSpec arg="scale_by_freq" arg_pos="11" name="scale_by_freq" />
     <inputPortSpec arg="xextent" arg_pos="8" name="xextent" />
     <inputPortSpec arg="detrend" arg_pos="4" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>[<function detrend_none at 0x106c49398>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="window" arg_pos="5" name="window">
-      <defaults>['<function window_hanning at 0x02F5A2B0>']</defaults>
+      <defaults>[<function window_hanning at 0x106c3a488>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="Fc" arg_pos="3" name="Fc" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="NFFT" arg_pos="1" name="NFFT" port_type="basic:Integer">
-      <defaults>['256']</defaults>
+      <defaults>[256]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmap" arg_pos="7" name="cmap" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -2258,7 +2227,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['default']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="noverlap" arg_pos="6" name="noverlap" port_type="basic:Integer">
-      <defaults>['128']</defaults>
+      <defaults>[128]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.stackplot" name="MplStackplot" superclass="MplPlot">
@@ -2343,15 +2312,15 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
       <defaults>['-|>']</defaults>
     </inputPortSpec>
     <inputPortSpec arg="density" arg_pos="4" name="density" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="color" arg_pos="6" name="color" />
     <inputPortSpec arg="minlength" arg_pos="11" name="minlength" port_type="basic:Float">
-      <defaults>['0.1']</defaults>
+      <defaults>[0.1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="transform" arg_pos="12" name="transform" />
     <inputPortSpec arg="arrowsize" arg_pos="9" name="arrowsize" port_type="basic:Integer">
-      <defaults>['1']</defaults>
+      <defaults>[1]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="cmap" arg_pos="7" name="cmap" />
     <inputPortSpec arg="u" arg_pos="2" name="u" required="True" />
@@ -2428,7 +2397,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
     </inputPortSpec>
     <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
       <docstring>If linestyles is None, the 'solid' is used.
@@ -2437,7 +2406,7 @@ linestyles can also be an iterable of the above strings specifying a set of line
 
 If contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
     </inputPortSpec>
     <inputPortSpec arg="levels" name="levelsSequence" port_type="basic:List">
       <docstring>A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]</docstring>
@@ -2450,7 +2419,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -2460,12 +2429,12 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
       <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <values>[['(mpl_colors)']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="antialiased" name="antialiased" port_type="basic:Boolean">
       <docstring>enable antialiasing</docstring>
@@ -2473,7 +2442,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[[0]]</values>
+      <values>[['0']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -2481,7 +2450,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.tricontourf" name="MplTricontourf" superclass="MplPlot">
@@ -2551,7 +2520,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
 
 This keyword is not active if X and Y are specified in the call to contour.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'upper', 'lower', 'image']]</values>
+      <values>[['upper', 'lower', 'image']]</values>
     </inputPortSpec>
     <inputPortSpec arg="linestyles" name="linestyles" port_type="basic:String">
       <docstring>If linestyles is None, the 'solid' is used.
@@ -2560,7 +2529,7 @@ linestyles can also be an iterable of the above strings specifying a set of line
 
 If contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'solid', 'dashed', 'dashdot', 'dotted']]</values>
+      <values>[['solid', 'dashed', 'dashdot', 'dotted']]</values>
     </inputPortSpec>
     <inputPortSpec arg="levels" name="levelsSequence" port_type="basic:List">
       <docstring>A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]</docstring>
@@ -2573,7 +2542,7 @@ If a number, all levels will be plotted with this linewidth.
 
 If a tuple, different levels will be plotted with different linewidths in the order specified</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'number', 'tuple of numbers']]</values>
+      <values>[['number', 'tuple of numbers']]</values>
     </inputPortSpec>
     <inputPortSpec arg="colors" name="colors" port_type="basic:Color">
       <docstring>If None, the colormap specified by cmap will be used.
@@ -2583,12 +2552,12 @@ If a string, like 'r' or 'red', all levels will be plotted in this color.
 If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.</docstring>
       <translations>translate_color</translations>
       <entry_types>['enum']</entry_types>
-      <values>[['', '(mpl_colors)']]</values>
+      <values>[['(mpl_colors)']]</values>
     </inputPortSpec>
     <inputPortSpec arg="cmap" name="cmap" port_type="basic:String">
       <docstring>A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Colormap']]</values>
+      <values>[['Colormap']]</values>
     </inputPortSpec>
     <inputPortSpec arg="antialiased" name="antialiased" port_type="basic:Boolean">
       <docstring>enable antialiasing</docstring>
@@ -2596,7 +2565,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="nchunk" name="nchunk" port_type="basic:Integer">
       <docstring>If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[[0]]</values>
+      <values>[['0']]</values>
     </inputPortSpec>
     <inputPortSpec arg="alpha" name="alpha" port_type="basic:Float">
       <docstring>The alpha blending value</docstring>
@@ -2604,7 +2573,7 @@ If a tuple of matplotlib color args (string, float, rgb, etc), different levels
     <inputPortSpec arg="norm" name="norm" port_type="basic:String">
       <docstring>A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.</docstring>
       <entry_types>['enum']</entry_types>
-      <values>[['', 'Normalize']]</values>
+      <values>[['Normalize']]</values>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.tripcolor" name="MplTripcolor" superclass="MplPlot">
@@ -2721,16 +2690,16 @@ Example:
 
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="normed" arg_pos="2" name="normed" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="usevlines" arg_pos="4" name="usevlines" port_type="basic:Boolean">
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="detrend" arg_pos="3" name="detrend">
-      <defaults>['<function detrend_none at 0x02F5A3F0>']</defaults>
+      <defaults>[<function detrend_none at 0x106c49398>]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="maxlags" arg_pos="5" name="maxlags" port_type="basic:Integer">
-      <defaults>['10']</defaults>
+      <defaults>[10]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="y" arg_pos="1" name="y" port_type="basic:List" required="True" />
     <inputPortSpec arg="x" arg_pos="0" name="x" port_type="basic:List" required="True" />
@@ -2774,9 +2743,10 @@ Example:
 Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="barbcolor" name="barbcolorSequence" port_type="basic:List">
       <docstring>Specifies the color all parts of the barb except any flags.  This parameter is analagous to the edgecolor parameter for polygons, which can be used instead. However this parameter will override facecolor.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['color']]</values>
-      <alternateSpec arg="" name="barbcolorScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="barbcolorScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['color']]</values>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="C" name="C">
       <docstring>An optional array used to map colors to the barbs</docstring>
@@ -2794,7 +2764,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="rounding" name="rounding" port_type="basic:Boolean">
       <docstring>A flag to indicate whether the vector magnitude should be rounded when allocating barb components.  If True, the magnitude is rounded to the nearest multiple of the half-barb increment.  If False, the magnitude is simply truncated to the next lowest multiple.  Default is True</docstring>
-      <defaults>['True']</defaults>
+      <defaults>[True]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="pivot" name="pivot" port_type="basic:String">
       <docstring>The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name pivot.  Default is 'tip'</docstring>
@@ -2804,11 +2774,11 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="flip_barb" name="flip_barb" port_type="basic:Boolean">
       <docstring>Either a single boolean flag or an array of booleans.  Single boolean indicates whether the lines and flags should point opposite to normal for all barbs.  An array (which should be the same size as the other data arrays) indicates whether to flip for each individual barb.  Normal behavior is for the barbs and lines to point right (comes from wind barbs having these features point towards low pressure in the Northern Hemisphere.)  Default is False</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="length" name="length" port_type="basic:Integer">
       <docstring>Length of the barb in points; the other parts of the barb are scaled against this. Default is 9</docstring>
-      <defaults>['9']</defaults>
+      <defaults>[9]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="barb_increments" name="barb_increments" port_type="basic:String">
       <docstring>A dictionary of increments specifying values to associate with different parts of the barb. Only those values one wishes to override need to be included.
@@ -2836,13 +2806,14 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     </inputPortSpec>
     <inputPortSpec arg="flagcolor" name="flagcolorSequence" port_type="basic:List">
       <docstring>Specifies the color of any flags on the barb.  This parameter is analagous to the facecolor parameter for polygons, which can be used instead. However this parameter will override facecolor.  If this is not set (and C has not either) then flagcolor will be set to match barbcolor so that the barb has a uniform color. If C has been set, flagcolor has no effect.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['color']]</values>
-      <alternateSpec arg="" name="flagcolorScalar" port_type="basic:String" />
+      <alternateSpec arg="" name="flagcolorScalar" port_type="basic:String">
+        <entry_types>['enum']</entry_types>
+        <values>[['color']]</values>
+      </alternateSpec>
     </inputPortSpec>
     <inputPortSpec arg="fill_empty" name="fill_empty" port_type="basic:Boolean">
       <docstring>A flag on whether the empty barbs (circles) that are drawn should be filled with the flag color.  If they are not filled, they will be drawn such that no color is applied to the center.  Default is False</docstring>
-      <defaults>['False']</defaults>
+      <defaults>[False]</defaults>
     </inputPortSpec>
   </moduleSpec>
   <moduleSpec code_ref="matplotlib.pyplot.spy" name="MplSpy" superclass="MplPlot">
@@ -2898,7 +2869,7 @@ Additional kwargs: hold = [True|False] overrides default hold state</docstring>
     <inputPortSpec arg="hold" arg_pos="5" name="hold" />
     <inputPortSpec arg="markersize" arg_pos="3" name="markersize" />
     <inputPortSpec arg="precision" arg_pos="1" name="precision" port_type="basic:Integer">
-      <defaults>['0']</defaults>
+      <defaults>[0]</defaults>
     </inputPortSpec>
     <inputPortSpec arg="aspect" arg_pos="4" name="aspect" port_type="basic:String">
       <defaults>['equal']</defaults>
@@ -2972,9 +2943,7 @@ The loc itslef can be a 2-tuple giving x,y of the lower-left corner of the legen
 
 Keyword arguments:
 
-fontsize: [ size in points | 'xx-small' | 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | 'xx-large' ]
 
-Set the font size.  May be either a size string, relative to the default font size, or an absolute font size in points. This argument is only used if prop is not specified.
 
 Padding and spacing between various elements use following keywords parameters. These values are measure in font-size units. E.g., a fontsize of 10 points and a handlelength=5 implies a handlelength of 50 points.  Values from rcParams will be used if None.
 
@@ -2986,10 +2955,8 @@ Example:</docstring>
       <entry_types>['enum']</entry_types>
       <values>[['best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left', 'center right', 'lower center', 'upper center', 'center']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="fancybox" name="fancybox">
+    <inputPortSpec arg="fancybox" name="fancybox" port_type="basic:Boolean">
       <docstring>if True, draw a frame with a round fancybox.  If None, use rc settings</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="bbox_to_anchor" name="bbox_to_anchor">
       <docstring>the bbox that the legend will be anchored.</docstring>
@@ -3000,10 +2967,8 @@ Example:</docstring>
     <inputPortSpec arg="handlelength" name="handlelength">
       <docstring>the length of the legend handles</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="markerscale" name="markerscale">
+    <inputPortSpec arg="markerscale" name="markerscale" port_type="basic:Float">
       <docstring>The relative size of legend markers vs. original. If None, use rc settings.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
     <inputPortSpec arg="numpoints" name="numpoints" port_type="basic:Integer">
       <docstring>The number of points in the legend for line</docstring>
@@ -3014,12 +2979,18 @@ Example:</docstring>
     <inputPortSpec arg="scatterpoints" name="scatterpoints" port_type="basic:Integer">
       <docstring>The number of points in the legend for scatter plot</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="frameon" name="frameon" port_type="basic:Boolean">
-      <docstring>if True, draw a frame around the legend. The default is set by the rcParam 'legend.frameon'</docstring>
+    <inputPortSpec arg="prop" name="prop" port_type="basic:String">
+      <docstring>A :class:`matplotlib.font_manager.FontProperties` instance. If prop is a dictionary, a new instance will be created with prop. If None, use rc settings.</docstring>
+      <entry_types>['enum']</entry_types>
+      <values>[['FontProperties', None]]</values>
     </inputPortSpec>
     <inputPortSpec arg="columnspacing" name="columnspacing">
       <docstring>the spacing between columns</docstring>
     </inputPortSpec>
+    <inputPortSpec arg="ncol" name="ncol" port_type="basic:Integer">
+      <docstring>number of columns. default is 1</docstring>
+      <defaults>[1]</defaults>
+    </inputPortSpec>
     <inputPortSpec arg="handletextpad" name="handletextpad">
       <docstring>the pad between the legend handle and text</docstring>
     </inputPortSpec>
@@ -3030,19 +3001,16 @@ Example:</docstring>
     <inputPortSpec arg="mode" name="mode">
       <docstring>if mode is "expand", the legend will be horizontally expanded to fill the axes area (or bbox_to_anchor)</docstring>
     </inputPortSpec>
-    <inputPortSpec arg="ncol" name="ncol" port_type="basic:Integer">
-      <docstring>number of columns. default is 1</docstring>
-      <defaults>['1']</defaults>
+    <inputPortSpec arg="fontsize" name="fontsize" port_type="basic:String">
+      <docstring>Set the font size.  May be either a size string, relative to the default font size, or an absolute font size in points. This argument is only used if prop is not specified.</docstring>
+      <entry_types>['enum']</entry_types>
+      <values>[['size in points', 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="shadow" name="shadow">
+    <inputPortSpec arg="shadow" name="shadow" port_type="basic:Boolean">
       <docstring>If True, draw a shadow behind legend. If None, use rc settings.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['']]</values>
     </inputPortSpec>
-    <inputPortSpec arg="prop" name="prop" port_type="basic:String">
-      <docstring>A :class:`matplotlib.font_manager.FontProperties` instance. If prop is a dictionary, a new instance will be created with prop. If None, use rc settings.</docstring>
-      <entry_types>['enum']</entry_types>
-      <values>[['', 'FontProperties', None]]</values>
+    <inputPortSpec arg="frameon" name="frameon" port_type="basic:Boolean">
+      <docstring>if True, draw a frame around the legend. The default is set by the rcParam 'legend.frameon'</docstring>
     </inputPortSpec>
     <inputPortSpec arg="borderpad" name="borderpad">
       <docstring>the fractional whitespace inside the legend border</docstring>
diff --git a/vistrails/packages/matplotlib/object.py b/vistrails/packages/matplotlib/object.py
deleted file mode 100644
index ace8acc..0000000
--- a/vistrails/packages/matplotlib/object.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from vistrails.core.modules.vistrails_module import Module
-
-class MplObject(Module):
-    _input_ports = [("subfigRow", "(org.vistrails.vistrails.spreadsheet:Integer)",
-                     {"defaults": ["1"]}),
-                    ("subfigCol", "(org.vistrails.vistrails.spreadsheet:Integer)",
-                     {"defaults": ["1"]})]
-    _output_ports = [("self", "(org.vistrails.vistrails.matplotlib:MplObject)")]
-
-    def __init__(self):
-        Module.__init__(self)
-        self.figInstance = None
-
-    def set_fig(self, fig):
-        self.figInstance = fig
-
-    def get_fig(self):
-        if self.figInstance is None:
-            self.figInstance = pylab.figure()
-        return self.figInstance
diff --git a/vistrails/packages/matplotlib/parse.py b/vistrails/packages/matplotlib/parse.py
old mode 100644
new mode 100755
index 18ff809..dbf7ef1
--- a/vistrails/packages/matplotlib/parse.py
+++ b/vistrails/packages/matplotlib/parse.py
@@ -1,3 +1,42 @@
+#!/usr/bin/env python
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import ast
 import re
 import sys
@@ -10,19 +49,10 @@ import matplotlib
 matplotlib.use('Qt4Agg')
 import matplotlib.docstring
 def new_call(self, func):
-    # print "!!!CALLING NEW CALL!!!"
     return func
-# print id(matplotlib.docstring.interpd.__call__)
 
 matplotlib.docstring.Substitution.__call__ = new_call
 
-# def test_func():
-#     """this is something cool %(Line2D)s"""
-#     pass
-# # matplotlib.docstring.interpd(test_func)
-# print "docstring:", test_func.__doc__
-# print id(matplotlib.docstring.interpd.__call__), id(new_call)
-
 
 import matplotlib.pyplot
 from matplotlib.artist import Artist, ArtistInspector
@@ -34,7 +64,7 @@ ArtistInspector._get_valid_values_regex = re.compile(
 from specs import SpecList, ModuleSpec, InputPortSpec, OutputPortSpec, \
     AlternatePortSpec
 
-sys.path.append('/vistrails/src/git')
+# sys.path.append('/vistrails/src/git')
 from vistrails.core.modules.utils import expand_port_spec_string
 
 ##############################################################################
@@ -78,18 +108,18 @@ def parse_docutils_table(elt):
     return (header, rows)
 
 def parse_docutils_term(elt):
-    # term = ""
     terms = []
     accepts = ""
     for child in elt.children:
         if child.__class__ == docutils.nodes.emphasis:
             term = parse_docutils_elt(child)[0].strip()
-            if term in ('True', 'False'):
+            if term in ('True', 'False') or accepts != "":
                 accepts += term
-            elif term != "None":
+            elif term != "None": 
                 terms.append(term)
         elif child.__class__ == docutils.nodes.Text:
-            accepts += str(child)
+            if str(child).strip() not in [',', '/']:
+                accepts += str(child)
         else:
             accepts += parse_docutils_elt(child)[0]
     accepts = accepts.strip()
@@ -137,19 +167,14 @@ def parse_docutils_elt(elt, last_text=""):
     call_signatures = []
     for child in elt.children:
         if child.__class__ == docutils.nodes.Text:
-            # cur_block.extend(s.strip() for s in str(child).split('\n'))
             ntext = ' '.join(s for s in str(child).split('\n'))
             text += ntext
         elif child.__class__ == docutils.nodes.system_message:
             pass
         elif child.__class__ == docutils.nodes.definition_list:
-            # print "DEFLIST BLOCK:", text[-20:]
-            # print get_last_block(last_text + text)
             args.append((get_last_block(last_text + text), 
                          parse_docutils_deflist(child)))
         elif child.__class__ == docutils.nodes.table:
-            # print "TABLE BLOCK:", text[-20:]
-            # print get_last_block(last_text + text)
             tables.append((get_last_block(last_text + text),) + \
                               parse_docutils_table(child))
         elif isinstance(child, docutils.nodes.Inline):
@@ -172,17 +197,13 @@ def parse_docutils_elt(elt, last_text=""):
             tables += ntables
             call_signatures += ncall_sigs
     return (text.rstrip(), args, tables, call_signatures)
-            
+
 def parse_docutils_str(docstring, should_print=False):
     root = docutils.core.publish_doctree(docstring)
     if should_print:
         print root
-    # for child in root.children:
-    #     print "CHILD:", child.__class__, child
-    #     for subchild in child.children:
-    #         print "SUBCHILD:", subchild.__class__, subchild
     return parse_docutils_elt(root)
-    
+
 ##############################################################################
 # util methods
 ##############################################################################
@@ -208,7 +229,7 @@ def get_value_and_type(s):
         val = eval(s)
         if isinstance(val, type):
             return (None, None)
-    except:
+    except Exception:
         val = s
     port_type = get_type_from_val(val)
     return (val, port_type)
@@ -216,12 +237,12 @@ def get_value_and_type(s):
 def get_type_from_val(val):
     if isinstance(val, float):
         return "basic:Float"
+    elif isinstance(val, bool):
+        return "basic:Boolean"
     elif isinstance(val, (int, long)):
         return "basic:Integer"
     elif isinstance(val, basestring):
         return "basic:String"
-    elif isinstance(val, bool):
-        return "basic:Boolean"
     elif isinstance(val, list):
         return "basic:List"
     return None
@@ -268,6 +289,38 @@ def resolve_port_type(port_types, port_spec):
     #     port_type = None
     # return port_type
 
+def assign_port_values(port_spec, values, default_val):
+    assign_port_spec = None
+    if port_spec.defaults is not None and len(port_spec.defaults) > 0:
+        current_default = port_spec.defaults
+        port_spec.defaults = None
+    else:
+        current_default = []
+    if len(port_spec.alternate_specs) == 0:
+        assign_port_spec = port_spec
+    else:
+        port_types = set()
+        for value in values + current_default + \
+            ([default_val] if default_val is not None else []):
+            port_type = get_type_from_val(value)
+            if port_type is not None:
+                port_types.add(port_type)
+        if len(port_types) == 1:
+            for ps in [port_spec] + port_spec.alternate_specs:
+                if ps.port_type == next(iter(port_types)):
+                    assign_port_spec = ps
+        elif len(port_types) > 1:
+            raise Exception("Multiple value types found!")
+
+    if assign_port_spec is not None:
+        if len(values) > 0:
+            assign_port_spec.entry_types = ['enum']
+            assign_port_spec.values = [values]
+        if len(current_default) > 0:
+            assign_port_spec.defaults = current_default
+        elif default_val is not None:
+            assign_port_spec.defaults = [default_val]
+
 def parse_description(desc):
     key_to_type = {'string': 'basic:String',
                    'integer': 'basic:Integer',
@@ -327,11 +380,7 @@ def parse_description(desc):
                 if port_type is not None:
                     port_types.append(port_type)
                     found_type = True
-                # option_strs.append(opt)
-                # if opt.startswith("'") or opt.startswith('"'):
-                #     port_types.append("basic:String")
-                #     found_type = True
-                    
+
     if default_val is None:
         m = default_paren_re.search(desc)
         if m:
@@ -358,8 +407,6 @@ def parse_description(desc):
             if key in desc:
                 port_types.append(port_type)
 
-    # port_type = resolve_port_type(port_types)
-        
     return (port_types, option_strs, default_val, allows_none)
 
 def parse_translation(rows, should_reverse=True):
@@ -370,17 +417,16 @@ def parse_translation(rows, should_reverse=True):
         (val1, port_type1) = get_value_and_type(row[0])
         (val2, port_type2) = get_value_and_type(row[1])
         if should_reverse:
-            if val2 != None:
+            if val2 is not None:
                 port_types.append(port_type2)
                 values.append(val2)
                 t[val2] = val1
         else:
-            if val1 != None:
+            if val1 is not None:
                 port_types.append(port_type1)
                 values.append(val1)
                 t[val1] = val2
 
-    # port_type = resolve_port_type(port_types)
     return (t, port_types, values)
 
 def do_translation_override(port_specs, names, rows, opts):
@@ -451,14 +497,11 @@ def parse_argspec(obj_or_str):
             except ValueError:
                 d_val = None
             argspec_defaults.append(d_val)
-        # argspec_defaults = \
-        #     [ast.literal_eval(d) for d in tree.body[0].args.defaults]
     else:
         argspec = inspect.getargspec(obj_or_str)
         argspec_args = argspec.args
         argspec_defaults = argspec.defaults
 
-    # print argspec
     if not argspec_defaults:
         start_defaults = len(argspec_args) + 1
     else:
@@ -475,15 +518,12 @@ def parse_argspec(obj_or_str):
             port_spec.required = False
             default_val = argspec_defaults[i-start_defaults]
             if default_val is not None:
-                port_spec.defaults = [str(default_val)]
+                port_spec.defaults = [default_val]
                 port_type = get_type_from_val(default_val)
                 if port_type is not None:
                     port_spec.port_type = port_type
         else:
             port_spec.required = True
-            # port_specs[arg].entry_types = [None,]
-            # port_specs[arg].values = [[]]
-            # port_specs[arg].translations = [None,]
         port_specs_list.append(port_spec)
     return port_specs_list
 
@@ -500,15 +540,17 @@ def process_docstring(docstring, port_specs, parent, table_overrides):
                     old_port_spec = port_specs[port_spec.arg]
                     resolve_port_type([port_spec.port_type], old_port_spec)
                     if old_port_spec.defaults is None:
-                        old_port_spec.defaults = port_spec.defaults
+                        if port_spec.defaults is not None:
+                            assign_port_values(old_port_spec, [], 
+                                               port_spec.defaults[0])
+                            # old_port_spec.defaults = port_spec.defaults
                     elif old_port_spec.defaults != port_spec.defaults:
                         # keep it as the old spec is
                         print "*** Different defaults!" + \
                             str(old_port_spec.defaults) + \
                             " : " + str(port_spec.defaults)
-                        # raise RuntimeError("Different defaults! %s: %s" % (
-                        #                    old_port_spec.defaults,
-                        #                    port_spec.defaults))
+                        assign_port_values(old_port_spec, [],
+                                           old_port_spec.defaults[0])
                 else:
                     port_specs[port_spec.arg] = port_spec
 
@@ -542,11 +584,7 @@ def process_docstring(docstring, port_specs, parent, table_overrides):
                 if default_val is None:
                     default_val = dv2
                 resolve_port_type(port_types, port_specs[name])
-                if len(option_strs) > 0:
-                    port_specs[name].entry_types = ['enum']
-                    port_specs[name].values = [option_strs]
-                if default_val is not None:
-                    port_specs[name].defaults = [str(default_val)]
+                assign_port_values(port_specs[name], option_strs, default_val)
 
     for (table_intro, header, rows) in tables:
         print "GOT TABLE", table_intro, rows[0]
@@ -568,14 +606,8 @@ def process_docstring(docstring, port_specs, parent, table_overrides):
             for (name, port_doc) in rows:
                 (port_types, option_strs, default_val, allows_none) = \
                     parse_description(port_doc)
-                # (port_types, option_strs) = parse_desc(port_doc)
-                # port_type_set = set(port_types)
-                # # print port_name, "PORT_TYPES:", port_type_set
-                # port_type = "UNKNOWN"
-                # if len(port_type_set) == 1:
-                #     port_type = port_types[0]
                 oport = OutputPortSpec(name, docstring=port_doc)
-                resolve_port_type(oport, port_types)
+                resolve_port_type(port_types, oport)
                 output_port_specs.append(oport)
         elif (re.search("argument", table_intro, re.IGNORECASE) or
               re.search("kwarg", table_intro, re.IGNORECASE)):
@@ -589,25 +621,11 @@ def process_docstring(docstring, port_specs, parent, table_overrides):
                     port_specs[name].docstring = port_doc
                 (port_types, option_strs, default_val, allows_none) = \
                     parse_description(port_doc)
-                # (port_types, option_strs) = parse_desc(port_doc)
-                # port_type_set = set(port_types)
-                # # print port_name, "PORT_TYPES:", port_type_set
-                # port_type = "UNKNOWN"
-                # if len(port_type_set) == 1:
-                #     port_specs[name].port_type = port_types[0]
                 resolve_port_type(port_types, port_specs[name])
-                if len(option_strs) > 0:
-                    port_specs[name].entry_types = ['enum']
-                    port_specs[name].values = [option_strs]
-                if default_val is not None:
-                    port_specs[name].defaults = [str(default_val)]
+                assign_port_values(port_specs[name], option_strs, default_val)
         else:
             raise ValueError("Unknown table: %s\n  %s %s" % (
                              parent, table_intro, header))
-            # print "HIT SPEC:", name
-            # if name not in port_specs:
-            #     port_specs[name] = PortSpec(name, name, "UNKNOWN", "")
-            # port_specs[name].translations = dict(reversed(r) for r in rows)
     return cleaned_docstring, output_port_specs
 
 def parse_plots(plot_types, table_overrides):
@@ -632,27 +650,6 @@ def parse_plots(plot_types, table_overrides):
             print '*** CANNOT ADD PLOT "%s";' \
                 'IT DOES NOT EXIST IN THIS MPL VERSION ***' % plot
             continue
-        # argspec = inspect.getargspec(plot_obj)
-        # print argspec
-        # if argspec.defaults is None:
-        #     start_defaults = len(argspec.args) + 1
-        # else:
-        #     start_defaults = len(argspec.args) - len(argspec.defaults)
-        # for i, arg in enumerate(argspec.args):
-        #     port_specs[arg] = PortSpec(arg, arg)
-        #     if i >= start_defaults:
-        #         port_specs[arg].required = False
-        #         default_val = argspec.defaults[i-start_defaults]
-        #         if default_val is not None:
-        #             port_specs[arg].defaults = [str(default_val)]
-        #             port_type = get_type_from_val(default_val)
-        #             if port_type is not None:
-        #                 port_specs[arg].port_type = port_type
-        #     else:
-        #         port_specs[arg].required = True
-        #         # port_specs[arg].entry_types = [None,]
-        #         # port_specs[arg].values = [[]]
-        #         # port_specs[arg].translations = [None,]
         
         port_specs_list = parse_argspec(plot_obj)
         for port_spec in port_specs_list:
@@ -674,6 +671,17 @@ def parse_plots(plot_types, table_overrides):
             process_docstring(docstring, port_specs, ('pyplot', plot),
                               table_overrides)
 
+        # for port_spec in port_specs.itervalues():
+        #     if port_spec.defaults is not None:
+        #         port_spec.defaults = [str(v) for v in port_spec.defaults]
+        #     if port_spec.values is not None:
+        #         port_spec.values = [[str(v) for v in port_spec.values[0]]]
+        #     for alt_ps in port_spec.alternate_specs:
+        #         if alt_ps.defaults is not None:
+        #             alt_ps.defaults = [str(v) for v in alt_ps.defaults]
+        #         if alt_ps.values is not None:
+        #             alt_ps.values = [[str(v) for v in alt_ps.values[0]]]
+                
         module_specs.append(ModuleSpec(module_name, super_name,
                                        "matplotlib.pyplot.%s" % plot, 
                                        cleaned_docstring, port_specs.values(),
@@ -693,10 +701,6 @@ def parse_artists(artist_types, table_overrides={}):
             if issubclass(base, Artist):
                 return base.__name__
         return ""
-        # if obj.__bases__[0].__name__ != 'object':
-        #     return obj.__bases__[0].__name__
-        # else:
-        #     return ""
 
     module_specs = []
     for klass in artist_types:
@@ -726,7 +730,6 @@ def parse_artists(artist_types, table_overrides={}):
                 raise ValueError("accepts has deflists and/or tables")
             (port_types, option_strs, default_val, allows_none) = \
                 parse_description(accepts)
-            # port_spec.port_type = port_type
             if default_val is not None:
                 port_spec.default_val = default_val
             if len(option_strs) > 0:
@@ -835,20 +838,6 @@ def run_artists():
         list(sorted(artist_types, key=lambda x: list(reversed(x.mro()))))
     print "SORTED ARTIST TYPES:", artist_types
 
-    # from matplotlib.collections import Collection, PathCollection, \
-    #     LineCollection
-    # from matplotlib.lines import Line2D
-    # from matplotlib.patches import Patch, Rectangle, PathPatch, Wedge, \
-    #     FancyArrowPatch, YAArrow
-    # from matplotlib.text import Text, Annotation
-    # from matplotlib.axes import Axes
-    # from matplotlib.figure import Figure
-
-    # artist_types = [(Artist, None, "MplProperties"), 
-    #                 Line2D, Patch, Rectangle, Axes, Figure, PathPatch, Wedge, 
-    #                 Collection, PathCollection, LineCollection, Text, 
-    #                 Annotation, FancyArrowPatch, YAArrow]
-
     # FIXME want this to be indexed by artist name, too...
     artist_overrides = {('Axes', 'aspect', 'aspect'):
                             ('translation', {'reverse': False,
@@ -875,7 +864,6 @@ def run_artists():
                                              'values_only': True}),
                         }
 
-    # test_xml()
     specs = parse_artists(artist_types, artist_overrides)
     specs.write_to_xml("mpl_artists_raw.xml")
 
@@ -942,14 +930,6 @@ def run_plots():
                    'annotate',
                    ('plot', 'MplLinePlot')]
 
-    # others = ['plotfile', 'legend', 'matshow',]
-
-    # plot_types = ['acorr', 'bar', 'barbs', 'barh', 'boxplot', 'broken_barh', 'cohere', 'contour', 'contourf', 'csd', 'errorbar', 'hexbin', 'hist', 'loglog', 'pcolor', 'pcolormesh', 'pie', 'plot', 'plot_date', 'pie', 'polar', 'psd', 'quiver', 'scatter', 'semilogx', 'semilogy', 'specgram', 'spy', 'stem', 'tricontour', 'tricontourf', 'tripcolor', 'triplot', 'xcorr']
-
-    # plot_types = ['bar', 'boxplot', 'contour', 'hist', ('plot', "MplLinePlot"), 
-    #               'scatter', 'pie', 'legend', 'annotate', 'hlines', 
-    #               'axvline', 'axhline', 'errorbar']
-
     table_overrides = {('pyplot', 'plot', 'The following format string characters are accepted to control the line style or marker:'):
                            ('translation', {'name': 'marker'}),
                        ('pyplot', 'plot', 'The following color abbreviations are supported:'):
@@ -981,10 +961,6 @@ def run(which="all"):
     if which == "all" or which == "plots":
         run_plots()
 
-    # write_specs("test.xml")
-    # write_specs("mpl.xml")
-    # test_table()
-
 def get_docutils(plot):
     import matplotlib.pyplot
     plot_obj = getattr(matplotlib.pyplot, plot)
@@ -998,4 +974,3 @@ if __name__ == '__main__':
         run(sys.argv[1])
     else:
         raise TypeError("usage: python parse.py [all|artists|plots]")
-    # get_docutils("axhline")
diff --git a/vistrails/packages/matplotlib/plots.py b/vistrails/packages/matplotlib/plots.py
index 5d342ea..c4b2ba9 100644
--- a/vistrails/packages/matplotlib/plots.py
+++ b/vistrails/packages/matplotlib/plots.py
@@ -1,3 +1,5 @@
+from __future__ import division
+
 import matplotlib.pyplot
 from vistrails.core.modules.vistrails_module import Module, ModuleError
 from bases import MplPlot
@@ -55,13 +57,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("normed", "basic:Boolean",
-               {'optional': True, 'defaults': "['True']"}),
+               {'optional': True, 'defaults': '[True]'}),
               ("usevlines", "basic:Boolean",
-               {'optional': True, 'defaults': "['True']"}),
+               {'optional': True, 'defaults': '[True]'}),
               ("detrend", "basic:String",
                {'optional': True}),
               ("maxlags", "basic:Integer",
-               {'optional': True, 'defaults': "['10']"}),
+               {'optional': True, 'defaults': '[10]'}),
               ("x", "basic:List",
                {}),
               ("hold", "basic:String",
@@ -75,9 +77,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplAcorr)"),
+        ("value", "(MplAcorr)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -85,25 +87,29 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('normed'):
-            val = self.getInputFromPort('normed')
+        if self.has_input('normed'):
+            val = self.get_input('normed')
             kwargs['normed'] = val
-        if self.hasInputFromPort('usevlines'):
-            val = self.getInputFromPort('usevlines')
+        if self.has_input('usevlines'):
+            val = self.get_input('usevlines')
             kwargs['usevlines'] = val
-        if self.hasInputFromPort('detrend'):
-            val = self.getInputFromPort('detrend')
+        if self.has_input('detrend'):
+            val = self.get_input('detrend')
             kwargs['detrend'] = val
-        if self.hasInputFromPort('maxlags'):
-            val = self.getInputFromPort('maxlags')
+        if self.has_input('maxlags'):
+            val = self.get_input('maxlags')
             kwargs['maxlags'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
 
-        output = matplotlib.pyplot.acorr(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.acorr(*args, **kwargs)
         if 'usevlines' in kwargs and kwargs['usevlines']:
             output = output + (output[2],)
         else:
@@ -111,16 +117,16 @@ Additional kwargs: hold = [True|False] overrides default hold state
         lines = output[2]
         xaxis = output[3]
         lineCollection = output[4]
-        if self.hasInputFromPort('lineCollectionProperties'):
-            properties = self.getInputFromPort('lineCollectionProperties')
+        if self.has_input('lineCollectionProperties'):
+            properties = self.get_input('lineCollectionProperties')
             if lineCollection is not None:
                 properties.update_props(lineCollection)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
-        if self.hasInputFromPort('xaxisProperties'):
-            properties = self.getInputFromPort('xaxisProperties')
+        if self.has_input('xaxisProperties'):
+            properties = self.get_input('xaxisProperties')
             if xaxis is not None:
                 properties.update_props(xaxis)
 
@@ -157,9 +163,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplArrow)"),
+        ("value", "(MplArrow)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -167,22 +173,26 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        val = self.getInputFromPort('dx')
+        val = self.get_input('dx')
         kwargs['dx'] = val
-        val = self.getInputFromPort('dy')
+        val = self.get_input('dy')
         kwargs['dy'] = val
-        if self.hasInputFromPort('arrowProperties'):
-            properties = self.getInputFromPort('arrowProperties')
+        if self.has_input('arrowProperties'):
+            properties = self.get_input('arrowProperties')
             properties.update_kwargs(kwargs)
 
-        matplotlib.pyplot.arrow(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.arrow(*args, **kwargs)
 
 class MplAxhline(MplPlot):
     """Add a horizontal line across the axis.
@@ -215,21 +225,21 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("y", "basic:Float",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("xmin", "basic:Float",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("hold", "basic:String",
                {'optional': True}),
               ("xmax", "basic:Float",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("lineProperties", "MplLine2DProperties",
                {}),
         ]
 
     _output_ports = [
-        ("self", "(MplAxhline)"),
+        ("value", "(MplAxhline)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -237,22 +247,26 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('y'):
-            val = self.getInputFromPort('y')
+        if self.has_input('y'):
+            val = self.get_input('y')
             kwargs['y'] = val
-        if self.hasInputFromPort('xmin'):
-            val = self.getInputFromPort('xmin')
+        if self.has_input('xmin'):
+            val = self.get_input('xmin')
             kwargs['xmin'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('xmax'):
-            val = self.getInputFromPort('xmax')
+        if self.has_input('xmax'):
+            val = self.get_input('xmax')
             kwargs['xmax'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         line = matplotlib.pyplot.axhline(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if line is not None:
                 properties.update_props(line)
 
@@ -285,7 +299,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("xmin", "basic:Float",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("hold", "basic:String",
                {'optional': True}),
               ("ymin", "basic:Float",
@@ -293,15 +307,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("ymax", "basic:Float",
                {}),
               ("xmax", "basic:Float",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("patchProperties", "MplPolygonProperties",
                {}),
         ]
 
     _output_ports = [
-        ("self", "(MplAxhspan)"),
+        ("value", "(MplAxhspan)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -309,23 +323,27 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('xmin'):
-            val = self.getInputFromPort('xmin')
+        if self.has_input('xmin'):
+            val = self.get_input('xmin')
             kwargs['xmin'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        val = self.getInputFromPort('ymin')
+        val = self.get_input('ymin')
         kwargs['ymin'] = val
-        val = self.getInputFromPort('ymax')
+        val = self.get_input('ymax')
         kwargs['ymax'] = val
-        if self.hasInputFromPort('xmax'):
-            val = self.getInputFromPort('xmax')
+        if self.has_input('xmax'):
+            val = self.get_input('xmax')
             kwargs['xmax'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         patch = matplotlib.pyplot.axhspan(*args, **kwargs)
-        if self.hasInputFromPort('patchProperties'):
-            properties = self.getInputFromPort('patchProperties')
+        if self.has_input('patchProperties'):
+            properties = self.get_input('patchProperties')
             if patch is not None:
                 properties.update_props(patch)
 
@@ -360,21 +378,21 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("x", "basic:Float",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("hold", "basic:String",
                {'optional': True}),
               ("ymin", "basic:Float",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("ymax", "basic:Float",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("lineProperties", "MplLine2DProperties",
                {}),
         ]
 
     _output_ports = [
-        ("self", "(MplAxvline)"),
+        ("value", "(MplAxvline)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -382,22 +400,26 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('x'):
-            val = self.getInputFromPort('x')
+        if self.has_input('x'):
+            val = self.get_input('x')
             kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('ymin'):
-            val = self.getInputFromPort('ymin')
+        if self.has_input('ymin'):
+            val = self.get_input('ymin')
             kwargs['ymin'] = val
-        if self.hasInputFromPort('ymax'):
-            val = self.getInputFromPort('ymax')
+        if self.has_input('ymax'):
+            val = self.get_input('ymax')
             kwargs['ymax'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         line = matplotlib.pyplot.axvline(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if line is not None:
                 properties.update_props(line)
 
@@ -432,9 +454,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("hold", "basic:String",
                {'optional': True}),
               ("ymin", "basic:Float",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("ymax", "basic:Float",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("xmax", "basic:Float",
                {}),
               ("patchProperties", "MplPolygonProperties",
@@ -442,9 +464,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplAxvspan)"),
+        ("value", "(MplAxvspan)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -452,23 +474,27 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        val = self.getInputFromPort('xmin')
+        val = self.get_input('xmin')
         kwargs['xmin'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('ymin'):
-            val = self.getInputFromPort('ymin')
+        if self.has_input('ymin'):
+            val = self.get_input('ymin')
             kwargs['ymin'] = val
-        if self.hasInputFromPort('ymax'):
-            val = self.getInputFromPort('ymax')
+        if self.has_input('ymax'):
+            val = self.get_input('ymax')
             kwargs['ymax'] = val
-        val = self.getInputFromPort('xmax')
+        val = self.get_input('xmax')
         kwargs['xmax'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         patch = matplotlib.pyplot.axvspan(*args, **kwargs)
-        if self.hasInputFromPort('patchProperties'):
-            properties = self.getInputFromPort('patchProperties')
+        if self.has_input('patchProperties'):
+            properties = self.get_input('patchProperties')
             if patch is not None:
                 properties.update_props(patch)
 
@@ -513,11 +539,11 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("linewidth", "basic:String",
                {'optional': True, 'docstring': "width of bar edges; None means use default linewidth; 0 means don't draw edges."}),
               ("capsize", "basic:Integer",
-               {'optional': True, 'docstring': '(default 3) determines the length in points of the error bar caps', 'defaults': "['3']"}),
+               {'optional': True, 'docstring': '(default 3) determines the length in points of the error bar caps', 'defaults': '[3]'}),
               ("orientation", "basic:String",
                {'entry_types': "['enum']", 'docstring': "'vertical' | 'horizontal'", 'values': "[['vertical', 'horizontal']]", 'optional': True}),
               ("bottom", "basic:Float",
-               {'optional': True, 'docstring': 'the y coordinates of the bottom edges of the bars', 'defaults': "['0']"}),
+               {'optional': True, 'docstring': 'the y coordinates of the bottom edges of the bars', 'defaults': '[0]'}),
               ("bottomSequence", "basic:List",
                {'docstring': 'the y coordinates of the bottom edges of the bars', 'optional': True}),
               ("color", "basic:Color",
@@ -533,13 +559,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("heightScalar", "basic:Float",
                {'docstring': 'the heights of the bars', 'optional': True}),
               ("width", "basic:Float",
-               {'optional': True, 'docstring': 'the widths of the bars', 'defaults': "['0.8']"}),
+               {'optional': True, 'docstring': 'the widths of the bars', 'defaults': '[0.8]'}),
               ("widthSequence", "basic:List",
                {'docstring': 'the widths of the bars', 'optional': True}),
               ("error_kw", "basic:String",
                {'optional': True, 'docstring': 'dictionary of kwargs to be passed to errorbar method. ecolor and capsize may be specified here rather than as independent kwargs.'}),
               ("log", "basic:Boolean",
-               {'optional': True, 'docstring': '[False|True] False (default) leaves the orientation axis as-is; True sets it to log scale', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': '[False|True] False (default) leaves the orientation axis as-is; True sets it to log scale', 'defaults': '[False]'}),
               ("hold", "basic:String",
                {'optional': True}),
               ("yerr", "basic:String",
@@ -553,9 +579,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplBar)"),
+        ("value", "(MplBar)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -563,77 +589,81 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('edgecolor'):
-            val = self.getInputFromPort('edgecolor')
+        if self.has_input('edgecolor'):
+            val = self.get_input('edgecolor')
             val = translate_color(val)
             kwargs['edgecolor'] = val
-        if self.hasInputFromPort('linewidth'):
-            val = self.getInputFromPort('linewidth')
+        if self.has_input('linewidth'):
+            val = self.get_input('linewidth')
             kwargs['linewidth'] = val
-        if self.hasInputFromPort('capsize'):
-            val = self.getInputFromPort('capsize')
+        if self.has_input('capsize'):
+            val = self.get_input('capsize')
             kwargs['capsize'] = val
-        if self.hasInputFromPort('orientation'):
-            val = self.getInputFromPort('orientation')
+        if self.has_input('orientation'):
+            val = self.get_input('orientation')
             kwargs['orientation'] = val
-        if self.hasInputFromPort('bottom'):
-            val = self.getInputFromPort('bottom')
+        if self.has_input('bottom'):
+            val = self.get_input('bottom')
             kwargs['bottom'] = val
-        elif self.hasInputFromPort('bottomSequence'):
-            val = self.getInputFromPort('bottomSequence')
+        elif self.has_input('bottomSequence'):
+            val = self.get_input('bottomSequence')
             kwargs['bottom'] = val
-        if self.hasInputFromPort('color'):
-            val = self.getInputFromPort('color')
+        if self.has_input('color'):
+            val = self.get_input('color')
             val = translate_color(val)
             kwargs['color'] = val
-        if self.hasInputFromPort('xerr'):
-            val = self.getInputFromPort('xerr')
+        if self.has_input('xerr'):
+            val = self.get_input('xerr')
             kwargs['xerr'] = val
-        if self.hasInputFromPort('align'):
-            val = self.getInputFromPort('align')
+        if self.has_input('align'):
+            val = self.get_input('align')
             kwargs['align'] = val
-        if self.hasInputFromPort('ecolor'):
-            val = self.getInputFromPort('ecolor')
+        if self.has_input('ecolor'):
+            val = self.get_input('ecolor')
             val = translate_color(val)
             kwargs['ecolor'] = val
-        if self.hasInputFromPort('height'):
-            val = self.getInputFromPort('height')
+        if self.has_input('height'):
+            val = self.get_input('height')
             kwargs['height'] = val
-        elif self.hasInputFromPort('heightScalar'):
-            val = self.getInputFromPort('heightScalar')
+        elif self.has_input('heightScalar'):
+            val = self.get_input('heightScalar')
             kwargs['height'] = val
         else:
             raise ModuleError(self, 'Must set one of "height", '                                   '"heightScalar"')
-        if self.hasInputFromPort('width'):
-            val = self.getInputFromPort('width')
+        if self.has_input('width'):
+            val = self.get_input('width')
             kwargs['width'] = val
-        elif self.hasInputFromPort('widthSequence'):
-            val = self.getInputFromPort('widthSequence')
+        elif self.has_input('widthSequence'):
+            val = self.get_input('widthSequence')
             kwargs['width'] = val
-        if self.hasInputFromPort('error_kw'):
-            val = self.getInputFromPort('error_kw')
+        if self.has_input('error_kw'):
+            val = self.get_input('error_kw')
             kwargs['error_kw'] = val
-        if self.hasInputFromPort('log'):
-            val = self.getInputFromPort('log')
+        if self.has_input('log'):
+            val = self.get_input('log')
             kwargs['log'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('yerr'):
-            val = self.getInputFromPort('yerr')
+        if self.has_input('yerr'):
+            val = self.get_input('yerr')
             kwargs['yerr'] = val
-        if self.hasInputFromPort('left'):
-            val = self.getInputFromPort('left')
+        if self.has_input('left'):
+            val = self.get_input('left')
             kwargs['left'] = val
-        elif self.hasInputFromPort('leftScalar'):
-            val = self.getInputFromPort('leftScalar')
+        elif self.has_input('leftScalar'):
+            val = self.get_input('leftScalar')
             kwargs['left'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         if not kwargs.has_key('left'):
             kwargs['left'] = range(len(kwargs['height']))
         rectangles = matplotlib.pyplot.bar(*args, **kwargs)
-        if self.hasInputFromPort('rectangleProperties'):
-            properties = self.getInputFromPort('rectangleProperties')
+        if self.has_input('rectangleProperties'):
+            properties = self.get_input('rectangleProperties')
             if rectangles is not None:
                 properties.update_props(rectangles)
 
@@ -676,9 +706,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("linewidth", "basic:String",
                {'optional': True, 'docstring': "width of bar edges; None means use default linewidth; 0 means don't draw edges."}),
               ("capsize", "basic:Integer",
-               {'optional': True, 'docstring': '(default 3) determines the length in points of the error bar caps', 'defaults': "['3']"}),
+               {'optional': True, 'docstring': '(default 3) determines the length in points of the error bar caps', 'defaults': '[3]'}),
               ("log", "basic:Boolean",
-               {'optional': True, 'docstring': '[False|True] False (default) leaves the horizontal axis as-is; True sets it to log scale', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': '[False|True] False (default) leaves the horizontal axis as-is; True sets it to log scale', 'defaults': '[False]'}),
               ("bottom", "basic:List",
                {'docstring': 'the vertical positions of the bottom edges of the bars'}),
               ("bottomScalar", "basic:Float",
@@ -692,7 +722,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("ecolor", "basic:Color",
                {'optional': True, 'docstring': 'specifies the color of any errorbar'}),
               ("height", "basic:Float",
-               {'optional': True, 'docstring': 'the heights (thicknesses) of the bars', 'defaults': "['0.8']"}),
+               {'optional': True, 'docstring': 'the heights (thicknesses) of the bars', 'defaults': '[0.8]'}),
               ("heightSequence", "basic:List",
                {'docstring': 'the heights (thicknesses) of the bars', 'optional': True}),
               ("width", "basic:List",
@@ -704,7 +734,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("yerr", "basic:String",
                {'optional': True, 'docstring': 'if not None, will be used to generate errorbars on the bar chart'}),
               ("left", "basic:Float",
-               {'optional': True, 'docstring': 'the x coordinates of the left edges of the bars', 'defaults': "['0']"}),
+               {'optional': True, 'docstring': 'the x coordinates of the left edges of the bars', 'defaults': '[0]'}),
               ("leftSequence", "basic:List",
                {'docstring': 'the x coordinates of the left edges of the bars', 'optional': True}),
               ("rectangleProperties", "MplRectangleProperties",
@@ -712,9 +742,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplBarh)"),
+        ("value", "(MplBarh)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -722,71 +752,75 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('edgecolor'):
-            val = self.getInputFromPort('edgecolor')
+        if self.has_input('edgecolor'):
+            val = self.get_input('edgecolor')
             val = translate_color(val)
             kwargs['edgecolor'] = val
-        if self.hasInputFromPort('linewidth'):
-            val = self.getInputFromPort('linewidth')
+        if self.has_input('linewidth'):
+            val = self.get_input('linewidth')
             kwargs['linewidth'] = val
-        if self.hasInputFromPort('capsize'):
-            val = self.getInputFromPort('capsize')
+        if self.has_input('capsize'):
+            val = self.get_input('capsize')
             kwargs['capsize'] = val
-        if self.hasInputFromPort('log'):
-            val = self.getInputFromPort('log')
+        if self.has_input('log'):
+            val = self.get_input('log')
             kwargs['log'] = val
-        if self.hasInputFromPort('bottom'):
-            val = self.getInputFromPort('bottom')
+        if self.has_input('bottom'):
+            val = self.get_input('bottom')
             kwargs['bottom'] = val
-        elif self.hasInputFromPort('bottomScalar'):
-            val = self.getInputFromPort('bottomScalar')
+        elif self.has_input('bottomScalar'):
+            val = self.get_input('bottomScalar')
             kwargs['bottom'] = val
         else:
             raise ModuleError(self, 'Must set one of "bottom", '                                   '"bottomScalar"')
-        if self.hasInputFromPort('color'):
-            val = self.getInputFromPort('color')
+        if self.has_input('color'):
+            val = self.get_input('color')
             val = translate_color(val)
             kwargs['color'] = val
-        if self.hasInputFromPort('xerr'):
-            val = self.getInputFromPort('xerr')
+        if self.has_input('xerr'):
+            val = self.get_input('xerr')
             kwargs['xerr'] = val
-        if self.hasInputFromPort('align'):
-            val = self.getInputFromPort('align')
+        if self.has_input('align'):
+            val = self.get_input('align')
             kwargs['align'] = val
-        if self.hasInputFromPort('ecolor'):
-            val = self.getInputFromPort('ecolor')
+        if self.has_input('ecolor'):
+            val = self.get_input('ecolor')
             val = translate_color(val)
             kwargs['ecolor'] = val
-        if self.hasInputFromPort('height'):
-            val = self.getInputFromPort('height')
+        if self.has_input('height'):
+            val = self.get_input('height')
             kwargs['height'] = val
-        elif self.hasInputFromPort('heightSequence'):
-            val = self.getInputFromPort('heightSequence')
+        elif self.has_input('heightSequence'):
+            val = self.get_input('heightSequence')
             kwargs['height'] = val
-        if self.hasInputFromPort('width'):
-            val = self.getInputFromPort('width')
+        if self.has_input('width'):
+            val = self.get_input('width')
             kwargs['width'] = val
-        elif self.hasInputFromPort('widthScalar'):
-            val = self.getInputFromPort('widthScalar')
+        elif self.has_input('widthScalar'):
+            val = self.get_input('widthScalar')
             kwargs['width'] = val
         else:
             raise ModuleError(self, 'Must set one of "width", '                                   '"widthScalar"')
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('yerr'):
-            val = self.getInputFromPort('yerr')
+        if self.has_input('yerr'):
+            val = self.get_input('yerr')
             kwargs['yerr'] = val
-        if self.hasInputFromPort('left'):
-            val = self.getInputFromPort('left')
+        if self.has_input('left'):
+            val = self.get_input('left')
             kwargs['left'] = val
-        elif self.hasInputFromPort('leftSequence'):
-            val = self.getInputFromPort('leftSequence')
+        elif self.has_input('leftSequence'):
+            val = self.get_input('leftSequence')
             kwargs['left'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         rectangles = matplotlib.pyplot.barh(*args, **kwargs)
-        if self.hasInputFromPort('rectangleProperties'):
-            properties = self.getInputFromPort('rectangleProperties')
+        if self.has_input('rectangleProperties'):
+            properties = self.get_input('rectangleProperties')
             if rectangles is not None:
                 properties.update_props(rectangles)
 
@@ -831,9 +865,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplBrokenBarh)"),
+        ("value", "(MplBrokenBarh)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -841,17 +875,21 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        val = self.getInputFromPort('xranges')
+        val = self.get_input('xranges')
         kwargs['xranges'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        val = self.getInputFromPort('yrange')
+        val = self.get_input('yrange')
         kwargs['yrange'] = val
 
-        matplotlib.pyplot.broken_barh(*args, **kwargs)        
-        if self.hasInputFromPort('brokenBarHCollectionProperties'):
-            properties = self.getInputFromPort('brokenBarHCollectionProperties')
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        brokenBarHCollection = matplotlib.pyplot.broken_barh(*args, **kwargs)
+        if self.has_input('brokenBarHCollectionProperties'):
+            properties = self.get_input('brokenBarHCollectionProperties')
             if brokenBarHCollection is not None:
                 properties.update_props(brokenBarHCollection)
 
@@ -888,7 +926,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("hold", "basic:String",
                {'optional': True}),
               ("vert", "basic:Boolean",
-               {'optional': True, 'docstring': 'If True (default), makes the boxes vertical. If False, makes horizontal boxes.', 'defaults': "['True']"}),
+               {'optional': True, 'docstring': 'If True (default), makes the boxes vertical. If False, makes horizontal boxes.', 'defaults': '[True]'}),
               ("positions", "basic:String",
                {'optional': True, 'docstring': 'Sets the horizontal positions of the boxes. The ticks and limits are automatically set to match the positions.'}),
               ("bootstrap", "basic:String",
@@ -898,15 +936,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("sym", "basic:String",
                {'optional': True, 'docstring': "The default symbol for flier points. Enter an empty string ('') if you don't want to show fliers.", 'defaults': "['b+']"}),
               ("widths", "basic:Float",
-               {'optional': True, 'docstring': 'Either a scalar or a vector and sets the width of each box. The default is 0.5, or 0.15*(distance between extreme positions) if that is smaller.', 'defaults': "['0.5']"}),
+               {'optional': True, 'docstring': 'Either a scalar or a vector and sets the width of each box. The default is 0.5, or 0.15*(distance between extreme positions) if that is smaller.', 'defaults': '[0.5]'}),
               ("patch_artist", "basic:Boolean",
-               {'optional': True, 'docstring': 'If False produces boxes with the Line2D artist If True produces boxes with the Patch artist', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'If False produces boxes with the Line2D artist If True produces boxes with the Patch artist', 'defaults': '[False]'}),
               ("x", "basic:List",
                {'docstring': 'Array or a sequence of vectors.'}),
               ("notch", "basic:Boolean",
-               {'optional': True, 'docstring': 'If False (default), produces a rectangular box plot. If True, will produce a notched box plot', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'If False (default), produces a rectangular box plot. If True, will produce a notched box plot', 'defaults': '[False]'}),
               ("whis", "basic:Float",
-               {'optional': True, 'docstring': 'Defines the length of the whiskers as a function of the inner quartile range.  They extend to the most extreme data point within ( whis*(75%-25%) ) data range.', 'defaults': "['1.5']"}),
+               {'optional': True, 'docstring': 'Defines the length of the whiskers as a function of the inner quartile range.  They extend to the most extreme data point within ( whis*(75%-25%) ) data range.', 'defaults': '[1.5]'}),
               ("conf_intervals", "basic:List",
                {'optional': True, 'docstring': 'Array or sequence whose first dimension (or length) is compatible with x and whose second dimension is 2. When the current element of conf_intervals is not None, the notch locations computed by matplotlib are overridden (assuming notch is True). When an element of conf_intervals is None, boxplot compute notches the method specified by the other kwargs (e.g. bootstrap).'}),
               ("boxProperties", "MplLine2DProperties",
@@ -924,9 +962,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplBoxplot)"),
+        ("value", "(MplBoxplot)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -934,43 +972,47 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('vert'):
-            val = self.getInputFromPort('vert')
+        if self.has_input('vert'):
+            val = self.get_input('vert')
             kwargs['vert'] = val
-        if self.hasInputFromPort('positions'):
-            val = self.getInputFromPort('positions')
+        if self.has_input('positions'):
+            val = self.get_input('positions')
             kwargs['positions'] = val
-        if self.hasInputFromPort('bootstrap'):
-            val = self.getInputFromPort('bootstrap')
+        if self.has_input('bootstrap'):
+            val = self.get_input('bootstrap')
             kwargs['bootstrap'] = val
-        if self.hasInputFromPort('usermedians'):
-            val = self.getInputFromPort('usermedians')
+        if self.has_input('usermedians'):
+            val = self.get_input('usermedians')
             kwargs['usermedians'] = val
-        if self.hasInputFromPort('sym'):
-            val = self.getInputFromPort('sym')
+        if self.has_input('sym'):
+            val = self.get_input('sym')
             kwargs['sym'] = val
-        if self.hasInputFromPort('widths'):
-            val = self.getInputFromPort('widths')
+        if self.has_input('widths'):
+            val = self.get_input('widths')
             kwargs['widths'] = val
-        if self.hasInputFromPort('patch_artist'):
-            val = self.getInputFromPort('patch_artist')
+        if self.has_input('patch_artist'):
+            val = self.get_input('patch_artist')
             kwargs['patch_artist'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('notch'):
-            val = self.getInputFromPort('notch')
+        if self.has_input('notch'):
+            val = self.get_input('notch')
             kwargs['notch'] = val
-        if self.hasInputFromPort('whis'):
-            val = self.getInputFromPort('whis')
+        if self.has_input('whis'):
+            val = self.get_input('whis')
             kwargs['whis'] = val
-        if self.hasInputFromPort('conf_intervals'):
-            val = self.getInputFromPort('conf_intervals')
+        if self.has_input('conf_intervals'):
+            val = self.get_input('conf_intervals')
             kwargs['conf_intervals'] = val
 
-        output = matplotlib.pyplot.boxplot(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.boxplot(*args, **kwargs)
         if 'patch_artist' in kwargs and kwargs['patch_artist']:
             output['boxPatches'] = output['boxes']
             output['boxes'] = []
@@ -982,28 +1024,28 @@ Additional kwargs: hold = [True|False] overrides default hold state
         medians = output['medians']
         boxPatches = output['boxPatches']
         whiskers = output['whiskers']
-        if self.hasInputFromPort('boxProperties'):
-            properties = self.getInputFromPort('boxProperties')
+        if self.has_input('boxProperties'):
+            properties = self.get_input('boxProperties')
             if boxes is not None:
                 properties.update_props(boxes)
-        if self.hasInputFromPort('flierProperties'):
-            properties = self.getInputFromPort('flierProperties')
+        if self.has_input('flierProperties'):
+            properties = self.get_input('flierProperties')
             if fliers is not None:
                 properties.update_props(fliers)
-        if self.hasInputFromPort('capProperties'):
-            properties = self.getInputFromPort('capProperties')
+        if self.has_input('capProperties'):
+            properties = self.get_input('capProperties')
             if caps is not None:
                 properties.update_props(caps)
-        if self.hasInputFromPort('medianProperties'):
-            properties = self.getInputFromPort('medianProperties')
+        if self.has_input('medianProperties'):
+            properties = self.get_input('medianProperties')
             if medians is not None:
                 properties.update_props(medians)
-        if self.hasInputFromPort('boxPatchProperties'):
-            properties = self.getInputFromPort('boxPatchProperties')
+        if self.has_input('boxPatchProperties'):
+            properties = self.get_input('boxPatchProperties')
             if boxPatches is not None:
                 properties.update_props(boxPatches)
-        if self.hasInputFromPort('whiskerProperties'):
-            properties = self.getInputFromPort('whiskerProperties')
+        if self.has_input('whiskerProperties'):
+            properties = self.get_input('whiskerProperties')
             if whiskers is not None:
                 properties.update_props(whiskers)
 
@@ -1040,19 +1082,19 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("Fs", "basic:Integer",
-               {'optional': True, 'defaults': "['2']"}),
+               {'optional': True, 'defaults': '[2]'}),
               ("pad_to", "basic:String",
                {'optional': True}),
               ("scale_by_freq", "basic:String",
                {'optional': True}),
               ("detrend", "basic:String",
-               {'optional': True, 'defaults': "['<function detrend_none at 0x02F5A3F0>']"}),
+               {'optional': True}),
               ("window", "basic:String",
-               {'optional': True, 'defaults': "['<function window_hanning at 0x02F5A2B0>']"}),
+               {'optional': True}),
               ("Fc", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("NFFT", "basic:Integer",
-               {'optional': True, 'defaults': "['256']"}),
+               {'optional': True, 'defaults': '[256]'}),
               ("y", "basic:List",
                {}),
               ("x", "basic:List",
@@ -1062,15 +1104,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("sides", "basic:String",
                {'optional': True, 'defaults': "['default']"}),
               ("noverlap", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("lineProperties", "MplLine2DProperties",
                {'optional': True}),
         ]
 
     _output_ports = [
-        ("self", "(MplCohere)"),
+        ("value", "(MplCohere)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -1078,45 +1120,49 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('Fs'):
-            val = self.getInputFromPort('Fs')
+        if self.has_input('Fs'):
+            val = self.get_input('Fs')
             kwargs['Fs'] = val
-        if self.hasInputFromPort('pad_to'):
-            val = self.getInputFromPort('pad_to')
+        if self.has_input('pad_to'):
+            val = self.get_input('pad_to')
             kwargs['pad_to'] = val
-        if self.hasInputFromPort('scale_by_freq'):
-            val = self.getInputFromPort('scale_by_freq')
+        if self.has_input('scale_by_freq'):
+            val = self.get_input('scale_by_freq')
             kwargs['scale_by_freq'] = val
-        if self.hasInputFromPort('detrend'):
-            val = self.getInputFromPort('detrend')
+        if self.has_input('detrend'):
+            val = self.get_input('detrend')
             kwargs['detrend'] = val
-        if self.hasInputFromPort('window'):
-            val = self.getInputFromPort('window')
+        if self.has_input('window'):
+            val = self.get_input('window')
             kwargs['window'] = val
-        if self.hasInputFromPort('Fc'):
-            val = self.getInputFromPort('Fc')
+        if self.has_input('Fc'):
+            val = self.get_input('Fc')
             kwargs['Fc'] = val
-        if self.hasInputFromPort('NFFT'):
-            val = self.getInputFromPort('NFFT')
+        if self.has_input('NFFT'):
+            val = self.get_input('NFFT')
             kwargs['NFFT'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('sides'):
-            val = self.getInputFromPort('sides')
+        if self.has_input('sides'):
+            val = self.get_input('sides')
             kwargs['sides'] = val
-        if self.hasInputFromPort('noverlap'):
-            val = self.getInputFromPort('noverlap')
+        if self.has_input('noverlap'):
+            val = self.get_input('noverlap')
             kwargs['noverlap'] = val
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             properties.update_kwargs(kwargs)
 
-        matplotlib.pyplot.cohere(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.cohere(*args, **kwargs)
 
 class MplClabel(MplPlot):
     """Label a contour plot.
@@ -1153,9 +1199,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("fontsize", "basic:String",
                {'optional': True, 'docstring': "size in points or relative size eg 'smaller', 'x-large'"}),
               ("rightside_up", "basic:Boolean",
-               {'optional': True, 'docstring': 'if True (default), label rotations will always be plus or minus 90 degrees from level.', 'defaults': "['True']"}),
+               {'optional': True, 'docstring': 'if True (default), label rotations will always be plus or minus 90 degrees from level.', 'defaults': '[True]'}),
               ("inline", "basic:Boolean",
-               {'optional': True, 'docstring': 'controls whether the underlying contour is removed or not. Default is True.', 'defaults': "['True']"}),
+               {'optional': True, 'docstring': 'controls whether the underlying contour is removed or not. Default is True.', 'defaults': '[True]'}),
               ("v", "basic:List",
                {'optional': True}),
               ("textProperties", "MplTextProperties",
@@ -1163,50 +1209,54 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplClabel)"),
+        ("value", "(MplClabel)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('cs')
+        val = self.get_input('cs')
         args.append(val)
-        if self.hasInputFromPort('v'):
-            val = self.getInputFromPort('v')
+        if self.has_input('v'):
+            val = self.get_input('v')
             args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('inline_spacing'):
-            val = self.getInputFromPort('inline_spacing')
+        if self.has_input('inline_spacing'):
+            val = self.get_input('inline_spacing')
             kwargs['inline_spacing'] = val
-        if self.hasInputFromPort('use_clabeltext'):
-            val = self.getInputFromPort('use_clabeltext')
+        if self.has_input('use_clabeltext'):
+            val = self.get_input('use_clabeltext')
             kwargs['use_clabeltext'] = val
-        if self.hasInputFromPort('fmt'):
-            val = self.getInputFromPort('fmt')
+        if self.has_input('fmt'):
+            val = self.get_input('fmt')
             kwargs['fmt'] = val
-        if self.hasInputFromPort('manual'):
-            val = self.getInputFromPort('manual')
+        if self.has_input('manual'):
+            val = self.get_input('manual')
             kwargs['manual'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
-        if self.hasInputFromPort('fontsize'):
-            val = self.getInputFromPort('fontsize')
+        if self.has_input('fontsize'):
+            val = self.get_input('fontsize')
             kwargs['fontsize'] = val
-        if self.hasInputFromPort('rightside_up'):
-            val = self.getInputFromPort('rightside_up')
+        if self.has_input('rightside_up'):
+            val = self.get_input('rightside_up')
             kwargs['rightside_up'] = val
-        if self.hasInputFromPort('inline'):
-            val = self.getInputFromPort('inline')
+        if self.has_input('inline'):
+            val = self.get_input('inline')
             kwargs['inline'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         texts = matplotlib.pyplot.clabel(*args, **kwargs)
-        if self.hasInputFromPort('textProperties'):
-            properties = self.getInputFromPort('textProperties')
+        if self.has_input('textProperties'):
+            properties = self.get_input('textProperties')
             if texts is not None:
                 properties.update_props(texts)
 
@@ -1271,17 +1321,17 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("origin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['', 'upper', 'lower', 'image']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['upper', 'lower', 'image']]", 'optional': True}),
+              ("linestyles", "basic:String",
+               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.", 'values': "[['solid', 'dashed', 'dashdo [...]
               ("xunits", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`.', 'values': "[['', 'registered units']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`.', 'values': "[['registered units']]", 'optional': True}),
               ("extend", "basic:String",
                {'entry_types': "['enum']", 'docstring': "Unless this is 'neither', contour levels are automatically added to one or both ends of the range so that all data are included. These added ranges are then mapped to the special colormap values which default to the ends of the colormap range, but can be set via :meth:`matplotlib.colors.Colormap.set_under` and :meth:`matplotlib.colors.Colormap.set_over` methods.", 'values': "[['neither', 'both', 'min', 'max']]", 'optional': True}),
-              ("vmin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.', 'values': "[['']]", 'optional': True}),
+              ("vmin", "basic:Float",
+               {'optional': True, 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.'}),
               ("nchunk", "basic:Integer",
                {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': '[[0]]', 'optional': True}),
-              ("linestyles", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.", 'values': "[['', 'solid', 'dashed', 'da [...]
               ("hatches", "basic:List",
                {'optional': True, 'docstring': 'A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only.'}),
               ("levelsSequence", "basic:List",
@@ -1289,7 +1339,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("levelsScalar", "basic:Float",
                {'docstring': 'A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]', 'optional': True}),
               ("linewidths", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['', 'number', 'tuple of numbers']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['number', 'tuple of numbers']]", 'optional': True}),
               ("locator", "basic:String",
                {'optional': True, 'docstring': 'If locator is None, the default :class:`~matplotlib.ticker.MaxNLocator` is used. The locator is used to determine the contour levels if they are not given explicitly via the V argument.'}),
               ("colors", "basic:Color",
@@ -1299,23 +1349,23 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("yunits", "basic:String",
                {'optional': True, 'docstring': 'Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`.'}),
               ("extent", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If origin is not None, then extent is interpreted as in :func:`matplotlib.pyplot.imshow`: it gives the outer pixel boundaries. In this case, the position of Z[0,0] is the center of the pixel, not a corner. If origin is None, then (x0, y0) is the position of Z[0,0], and (x1, y1) is the position of Z[-1,-1].\n\nThis keyword is not active if X and Y are specified in the call to contour.', 'values': "[['', '(x0,x1,y0,y1)']]", 'optional [...]
-              ("vmax", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.', 'values': "[['']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If origin is not None, then extent is interpreted as in :func:`matplotlib.pyplot.imshow`: it gives the outer pixel boundaries. In this case, the position of Z[0,0] is the center of the pixel, not a corner. If origin is None, then (x0, y0) is the position of Z[0,0], and (x1, y1) is the position of Z[-1,-1].\n\nThis keyword is not active if X and Y are specified in the call to contour.', 'values': "[['(x0,x1,y0,y1)']]", 'optional': True}),
+              ("vmax", "basic:Float",
+               {'optional': True, 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.'}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'The alpha blending value'}),
               ("Z", "basic:List",
                {}),
               ("antialiased", "basic:Boolean",
-               {'optional': True, 'docstring': "enable antialiasing, overriding the defaults.  For filled contours, the default is True.  For line contours, it is taken from rcParams['lines.antialiased'].", 'defaults': "['True']"}),
+               {'optional': True, 'docstring': "enable antialiasing, overriding the defaults.  For filled contours, the default is True.  For line contours, it is taken from rcParams['lines.antialiased'].", 'defaults': '[True]'}),
               ("norm", "basic:String",
                {'optional': True, 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.'}),
-              ("X", "basic:List",
-               {'optional': True}),
               ("V", "basic:List",
                {'optional': True}),
               ("Y", "basic:List",
                {'optional': True}),
+              ("X", "basic:List",
+               {'optional': True}),
               ("N", "basic:Integer",
                {'optional': True}),
               ("lineCollectionProperties", "MplLineCollectionProperties",
@@ -1323,100 +1373,104 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplContour)"),
-              ("contourSet", "MplQuadContourSet",
-                {}),
+        ("value", "(MplContour)"),
+            # (this plot has additional output which are not exposed as ports
+            # right now)
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        if self.hasInputFromPort('X'):
-            val = self.getInputFromPort('X')
+        if self.has_input('X'):
+            val = self.get_input('X')
             args.append(val)
-        if self.hasInputFromPort('Y'):
-            val = self.getInputFromPort('Y')
+        if self.has_input('Y'):
+            val = self.get_input('Y')
             args.append(val)
-        val = self.getInputFromPort('Z')
+        val = self.get_input('Z')
         args.append(val)
-        if self.hasInputFromPort('V'):
-            val = self.getInputFromPort('V')
+        if self.has_input('V'):
+            val = self.get_input('V')
             args.append(val)
-        if self.hasInputFromPort('N'):
-            val = self.getInputFromPort('N')
+        if self.has_input('N'):
+            val = self.get_input('N')
             args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('origin'):
-            val = self.getInputFromPort('origin')
+        if self.has_input('origin'):
+            val = self.get_input('origin')
             kwargs['origin'] = val
-        if self.hasInputFromPort('xunits'):
-            val = self.getInputFromPort('xunits')
+        if self.has_input('linestyles'):
+            val = self.get_input('linestyles')
+            kwargs['linestyles'] = val
+        if self.has_input('xunits'):
+            val = self.get_input('xunits')
             kwargs['xunits'] = val
-        if self.hasInputFromPort('extend'):
-            val = self.getInputFromPort('extend')
+        if self.has_input('extend'):
+            val = self.get_input('extend')
             kwargs['extend'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('nchunk'):
-            val = self.getInputFromPort('nchunk')
+        if self.has_input('nchunk'):
+            val = self.get_input('nchunk')
             kwargs['nchunk'] = val
-        if self.hasInputFromPort('linestyles'):
-            val = self.getInputFromPort('linestyles')
-            kwargs['linestyles'] = val
-        if self.hasInputFromPort('hatches'):
-            val = self.getInputFromPort('hatches')
+        if self.has_input('hatches'):
+            val = self.get_input('hatches')
             kwargs['hatches'] = val
-        if self.hasInputFromPort('levelsSequence'):
-            val = self.getInputFromPort('levelsSequence')
+        if self.has_input('levelsSequence'):
+            val = self.get_input('levelsSequence')
             kwargs['levels'] = val
-        elif self.hasInputFromPort('levelsScalar'):
-            val = self.getInputFromPort('levelsScalar')
+        elif self.has_input('levelsScalar'):
+            val = self.get_input('levelsScalar')
             kwargs['levels'] = val
-        if self.hasInputFromPort('linewidths'):
-            val = self.getInputFromPort('linewidths')
+        if self.has_input('linewidths'):
+            val = self.get_input('linewidths')
             kwargs['linewidths'] = val
-        if self.hasInputFromPort('locator'):
-            val = self.getInputFromPort('locator')
+        if self.has_input('locator'):
+            val = self.get_input('locator')
             kwargs['locator'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('yunits'):
-            val = self.getInputFromPort('yunits')
+        if self.has_input('yunits'):
+            val = self.get_input('yunits')
             kwargs['yunits'] = val
-        if self.hasInputFromPort('extent'):
-            val = self.getInputFromPort('extent')
+        if self.has_input('extent'):
+            val = self.get_input('extent')
             kwargs['extent'] = val
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('antialiased'):
-            val = self.getInputFromPort('antialiased')
+        if self.has_input('antialiased'):
+            val = self.get_input('antialiased')
             kwargs['antialiased'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
-        if self.hasInputFromPort("N") and self.hasInputFromPort("V"):
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        if self.has_input("N") and self.has_input("V"):
             del args[-1]
         contour_set = matplotlib.pyplot.contour(*args, **kwargs)
         output = (contour_set, contour_set.collections)
         contourSet = output[0]
         lineCollections = output[1]
-        self.setResult('contourSet', contourSet)
-        if self.hasInputFromPort('lineCollectionProperties'):
-            properties = self.getInputFromPort('lineCollectionProperties')
+        self.set_output('contourSet', contourSet)
+        if self.has_input('lineCollectionProperties'):
+            properties = self.get_input('lineCollectionProperties')
             if lineCollections is not None:
                 properties.update_props(lineCollections)
 
@@ -1485,13 +1539,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("origin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['', 'upper', 'lower', 'image']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['upper', 'lower', 'image']]", 'optional': True}),
               ("linestyles", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.", 'values': "[['', 'solid', 'dashed', 'da [...]
-              ("vmin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.', 'values': "[['']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the default is 'solid' unless the lines are monochrome.  In that case, negative contours will take their linestyle from the matplotlibrc contour.negative_linestyle setting.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.", 'values': "[['solid', 'dashed', 'dashdo [...]
+              ("vmin", "basic:Float",
+               {'optional': True, 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.'}),
               ("nchunk", "basic:Integer",
-               {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': '[[0]]', 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': "[['0']]", 'optional': True}),
               ("hatches", "basic:List",
                {'optional': True, 'docstring': 'A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only.'}),
               ("levelsSequence", "basic:List",
@@ -1499,19 +1553,19 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("levelsScalar", "basic:Float",
                {'docstring': 'A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]', 'optional': True}),
               ("linewidths", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['', 'number', 'tuple of numbers']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['number', 'tuple of numbers']]", 'optional': True}),
               ("colors", "basic:Color",
-               {'entry_types': "['enum']", 'docstring': "If None, the colormap specified by cmap will be used.\n\nIf a string, like 'r' or 'red', all levels will be plotted in this color.\n\nIf a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.", 'values': "[['', '(mpl_colors)']]", 'optional': True}),
+               {'optional': True, 'docstring': "If None, the colormap specified by cmap will be used.\n\nIf a string, like 'r' or 'red', all levels will be plotted in this color.\n\nIf a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified."}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.', 'values': "[['', 'Colormap']]", 'optional': True}),
-              ("vmax", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.', 'values': "[['']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.', 'values': "[['Colormap']]", 'optional': True}),
+              ("vmax", "basic:Float",
+               {'optional': True, 'docstring': 'If not None, either or both of these values will be supplied to the :class:`matplotlib.colors.Normalize` instance, overriding the default color scaling based on levels.'}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'The alpha blending value'}),
               ("Z", "basic:List",
                {}),
               ("norm", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.', 'values': "[['', 'Normalize']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.', 'values': "[['Normalize']]", 'optional': True}),
               ("N", "basic:Integer",
                {'optional': True}),
               ("V", "basic:List",
@@ -1525,82 +1579,86 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplContourf)"),
-              ("contourSet", "MplQuadContourSet",
-                {}),
+        ("value", "(MplContourf)"),
+            # (this plot has additional output which are not exposed as ports
+            # right now)
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        if self.hasInputFromPort('X'):
-            val = self.getInputFromPort('X')
+        if self.has_input('X'):
+            val = self.get_input('X')
             args.append(val)
-        if self.hasInputFromPort('Y'):
-            val = self.getInputFromPort('Y')
+        if self.has_input('Y'):
+            val = self.get_input('Y')
             args.append(val)
-        val = self.getInputFromPort('Z')
+        val = self.get_input('Z')
         args.append(val)
-        if self.hasInputFromPort('V'):
-            val = self.getInputFromPort('V')
+        if self.has_input('V'):
+            val = self.get_input('V')
             args.append(val)
-        if self.hasInputFromPort('N'):
-            val = self.getInputFromPort('N')
+        if self.has_input('N'):
+            val = self.get_input('N')
             args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('origin'):
-            val = self.getInputFromPort('origin')
+        if self.has_input('origin'):
+            val = self.get_input('origin')
             kwargs['origin'] = val
-        if self.hasInputFromPort('linestyles'):
-            val = self.getInputFromPort('linestyles')
+        if self.has_input('linestyles'):
+            val = self.get_input('linestyles')
             kwargs['linestyles'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('nchunk'):
-            val = self.getInputFromPort('nchunk')
+        if self.has_input('nchunk'):
+            val = self.get_input('nchunk')
             kwargs['nchunk'] = val
-        if self.hasInputFromPort('hatches'):
-            val = self.getInputFromPort('hatches')
+        if self.has_input('hatches'):
+            val = self.get_input('hatches')
             kwargs['hatches'] = val
-        if self.hasInputFromPort('levelsSequence'):
-            val = self.getInputFromPort('levelsSequence')
+        if self.has_input('levelsSequence'):
+            val = self.get_input('levelsSequence')
             kwargs['levels'] = val
-        elif self.hasInputFromPort('levelsScalar'):
-            val = self.getInputFromPort('levelsScalar')
+        elif self.has_input('levelsScalar'):
+            val = self.get_input('levelsScalar')
             kwargs['levels'] = val
-        if self.hasInputFromPort('linewidths'):
-            val = self.getInputFromPort('linewidths')
+        if self.has_input('linewidths'):
+            val = self.get_input('linewidths')
             kwargs['linewidths'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
-        if self.hasInputFromPort("N") and self.hasInputFromPort("V"):
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        if self.has_input("N") and self.has_input("V"):
             del args[-1]
         contour_set = matplotlib.pyplot.contourf(*args, **kwargs)
         output = (contour_set, contour_set.collections)
         contourSet = output[0]
         polyCollections = output[1]
-        self.setResult('contourSet', contourSet)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        self.set_output('contourSet', contourSet)
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollections is not None:
                 properties.update_props(polyCollections)
 
@@ -1631,19 +1689,19 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("Fs", "basic:Integer",
-               {'optional': True, 'defaults': "['2']"}),
+               {'optional': True, 'defaults': '[2]'}),
               ("pad_to", "basic:String",
                {'optional': True}),
               ("scale_by_freq", "basic:String",
                {'optional': True}),
               ("detrend", "basic:String",
-               {'optional': True, 'defaults': "['<function detrend_none at 0x02F5A3F0>']"}),
+               {'optional': True}),
               ("window", "basic:String",
-               {'optional': True, 'defaults': "['<function window_hanning at 0x02F5A2B0>']"}),
+               {'optional': True}),
               ("Fc", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("NFFT", "basic:Integer",
-               {'optional': True, 'defaults': "['256']"}),
+               {'optional': True, 'defaults': '[256]'}),
               ("y", "basic:List",
                {}),
               ("x", "basic:List",
@@ -1653,15 +1711,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("sides", "basic:String",
                {'optional': True, 'defaults': "['default']"}),
               ("noverlap", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("lineProperties", "MplLine2DProperties",
                {'optional': True}),
         ]
 
     _output_ports = [
-        ("self", "(MplCsd)"),
+        ("value", "(MplCsd)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -1669,45 +1727,49 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('Fs'):
-            val = self.getInputFromPort('Fs')
+        if self.has_input('Fs'):
+            val = self.get_input('Fs')
             kwargs['Fs'] = val
-        if self.hasInputFromPort('pad_to'):
-            val = self.getInputFromPort('pad_to')
+        if self.has_input('pad_to'):
+            val = self.get_input('pad_to')
             kwargs['pad_to'] = val
-        if self.hasInputFromPort('scale_by_freq'):
-            val = self.getInputFromPort('scale_by_freq')
+        if self.has_input('scale_by_freq'):
+            val = self.get_input('scale_by_freq')
             kwargs['scale_by_freq'] = val
-        if self.hasInputFromPort('detrend'):
-            val = self.getInputFromPort('detrend')
+        if self.has_input('detrend'):
+            val = self.get_input('detrend')
             kwargs['detrend'] = val
-        if self.hasInputFromPort('window'):
-            val = self.getInputFromPort('window')
+        if self.has_input('window'):
+            val = self.get_input('window')
             kwargs['window'] = val
-        if self.hasInputFromPort('Fc'):
-            val = self.getInputFromPort('Fc')
+        if self.has_input('Fc'):
+            val = self.get_input('Fc')
             kwargs['Fc'] = val
-        if self.hasInputFromPort('NFFT'):
-            val = self.getInputFromPort('NFFT')
+        if self.has_input('NFFT'):
+            val = self.get_input('NFFT')
             kwargs['NFFT'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('sides'):
-            val = self.getInputFromPort('sides')
+        if self.has_input('sides'):
+            val = self.get_input('sides')
             kwargs['sides'] = val
-        if self.hasInputFromPort('noverlap'):
-            val = self.getInputFromPort('noverlap')
+        if self.has_input('noverlap'):
+            val = self.get_input('noverlap')
             kwargs['noverlap'] = val
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             properties.update_kwargs(kwargs)
 
-        matplotlib.pyplot.csd(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.csd(*args, **kwargs)
 
 class MplErrorbar(MplPlot):
     """Plot an errorbar graph.
@@ -1744,13 +1806,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("lolims", "basic:Boolean",
-               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': '[False]'}),
               ("capsize", "basic:Float",
-               {'optional': True, 'docstring': 'The length of the error bar caps in points', 'defaults': "['3']"}),
+               {'optional': True, 'docstring': 'The length of the error bar caps in points', 'defaults': '[3]'}),
               ("uplims", "basic:Boolean",
-               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': '[False]'}),
               ("xlolims", "basic:Boolean",
-               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': '[False]'}),
               ("barsabove", "basic:String",
                {'optional': True, 'docstring': 'if True, will plot the errorbars above the plot symbols. Default is below.', 'defaults': "['below']"}),
               ("xerr", "basic:List",
@@ -1760,13 +1822,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("fmt", "basic:String",
                {'optional': True, 'docstring': 'The plot format symbol. If fmt is None, only the errorbars are plotted.  This is used for adding errorbars to a bar plot, for example.', 'defaults': "['-']"}),
               ("ecolor", "basic:Color",
-               {'entry_types': "['enum']", 'docstring': 'A matplotlib color arg which gives the color the errorbar lines; if None, use the marker color.', 'values': "[['', 'mpl color']]", 'optional': True}),
+               {'optional': True, 'docstring': 'A matplotlib color arg which gives the color the errorbar lines; if None, use the marker color.'}),
               ("errorevery", "basic:Integer",
-               {'optional': True, 'docstring': 'subsamples the errorbars. Eg if everyerror=5, errorbars for every 5-th datapoint will be plotted. The data plot itself still shows all data points.', 'defaults': "['1']"}),
+               {'optional': True, 'docstring': 'subsamples the errorbars. Eg if everyerror=5, errorbars for every 5-th datapoint will be plotted. The data plot itself still shows all data points.', 'defaults': '[1]'}),
               ("capthick", "basic:Float",
                {'optional': True, 'docstring': 'An alias kwarg to markeredgewidth (a.k.a. - mew). This setting is a more sensible name for the property that controls the thickness of the error bar cap in points. For backwards compatibility, if mew or markeredgewidth are given, then they will over-ride capthick.  This may change in future releases.'}),
               ("xuplims", "basic:Boolean",
-               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr.', 'defaults': '[False]'}),
               ("elinewidth", "basic:Float",
                {'optional': True, 'docstring': 'The linewidth of the errorbar lines. If None, use the linewidth.'}),
               ("y", "basic:List",
@@ -1788,9 +1850,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplErrorbar)"),
+        ("value", "(MplErrorbar)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -1798,74 +1860,78 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('lolims'):
-            val = self.getInputFromPort('lolims')
+        if self.has_input('lolims'):
+            val = self.get_input('lolims')
             kwargs['lolims'] = val
-        if self.hasInputFromPort('capsize'):
-            val = self.getInputFromPort('capsize')
+        if self.has_input('capsize'):
+            val = self.get_input('capsize')
             kwargs['capsize'] = val
-        if self.hasInputFromPort('uplims'):
-            val = self.getInputFromPort('uplims')
+        if self.has_input('uplims'):
+            val = self.get_input('uplims')
             kwargs['uplims'] = val
-        if self.hasInputFromPort('xlolims'):
-            val = self.getInputFromPort('xlolims')
+        if self.has_input('xlolims'):
+            val = self.get_input('xlolims')
             kwargs['xlolims'] = val
-        if self.hasInputFromPort('barsabove'):
-            val = self.getInputFromPort('barsabove')
+        if self.has_input('barsabove'):
+            val = self.get_input('barsabove')
             kwargs['barsabove'] = val
-        if self.hasInputFromPort('xerr'):
-            val = self.getInputFromPort('xerr')
+        if self.has_input('xerr'):
+            val = self.get_input('xerr')
             kwargs['xerr'] = val
-        elif self.hasInputFromPort('xerrScalar'):
-            val = self.getInputFromPort('xerrScalar')
+        elif self.has_input('xerrScalar'):
+            val = self.get_input('xerrScalar')
             kwargs['xerr'] = val
-        if self.hasInputFromPort('fmt'):
-            val = self.getInputFromPort('fmt')
+        if self.has_input('fmt'):
+            val = self.get_input('fmt')
             kwargs['fmt'] = val
-        if self.hasInputFromPort('ecolor'):
-            val = self.getInputFromPort('ecolor')
+        if self.has_input('ecolor'):
+            val = self.get_input('ecolor')
             val = translate_color(val)
             kwargs['ecolor'] = val
-        if self.hasInputFromPort('errorevery'):
-            val = self.getInputFromPort('errorevery')
+        if self.has_input('errorevery'):
+            val = self.get_input('errorevery')
             kwargs['errorevery'] = val
-        if self.hasInputFromPort('capthick'):
-            val = self.getInputFromPort('capthick')
+        if self.has_input('capthick'):
+            val = self.get_input('capthick')
             kwargs['capthick'] = val
-        if self.hasInputFromPort('xuplims'):
-            val = self.getInputFromPort('xuplims')
+        if self.has_input('xuplims'):
+            val = self.get_input('xuplims')
             kwargs['xuplims'] = val
-        if self.hasInputFromPort('elinewidth'):
-            val = self.getInputFromPort('elinewidth')
+        if self.has_input('elinewidth'):
+            val = self.get_input('elinewidth')
             kwargs['elinewidth'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('yerr'):
-            val = self.getInputFromPort('yerr')
+        if self.has_input('yerr'):
+            val = self.get_input('yerr')
             kwargs['yerr'] = val
-        elif self.hasInputFromPort('yerrScalar'):
-            val = self.getInputFromPort('yerrScalar')
+        elif self.has_input('yerrScalar'):
+            val = self.get_input('yerrScalar')
             kwargs['yerr'] = val
 
-        output = matplotlib.pyplot.errorbar(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.errorbar(*args, **kwargs)
         plotline = output[0]
         caplines = output[1]
         barlines = output[2]
-        if self.hasInputFromPort('caplineProperties'):
-            properties = self.getInputFromPort('caplineProperties')
+        if self.has_input('caplineProperties'):
+            properties = self.get_input('caplineProperties')
             if caplines is not None:
                 properties.update_props(caplines)
-        if self.hasInputFromPort('barlineProperties'):
-            properties = self.getInputFromPort('barlineProperties')
+        if self.has_input('barlineProperties'):
+            properties = self.get_input('barlineProperties')
             if barlines is not None:
                 properties.update_props(barlines)
-        if self.hasInputFromPort('plotlineProperties'):
-            properties = self.getInputFromPort('plotlineProperties')
+        if self.has_input('plotlineProperties'):
+            properties = self.get_input('plotlineProperties')
             if plotline is not None:
                 properties.update_props(plotline)
 
@@ -1910,24 +1976,28 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplFill)"),
+        ("value", "(MplFill)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polygons = matplotlib.pyplot.fill(*args, **kwargs)
-        if self.hasInputFromPort('polygonProperties'):
-            properties = self.getInputFromPort('polygonProperties')
+        if self.has_input('polygonProperties'):
+            properties = self.get_input('polygonProperties')
             if polygons is not None:
                 properties.update_props(polygons)
 
@@ -1950,11 +2020,11 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("y2", "basic:Float",
-               {'optional': True, 'docstring': 'A scalar y-value', 'defaults': "['0.0']"}),
+               {'optional': True, 'docstring': 'A scalar y-value', 'defaults': '[0]'}),
               ("y2Sequence", "basic:List",
                {'optional': True, 'docstring': 'An N-length array of the y data'}),
               ("interpolate", "basic:Boolean",
-               {'optional': True, 'defaults': "['False']"}),
+               {'optional': True, 'defaults': '[False]'}),
               ("y1", "basic:List",
                {'docstring': 'An N-length array of the y data'}),
               ("y1Scalar", "basic:Float",
@@ -1970,45 +2040,49 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplFillBetween)"),
+        ("value", "(MplFillBetween)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        if self.hasInputFromPort('y1'):
-            val = self.getInputFromPort('y1')
+        if self.has_input('y1'):
+            val = self.get_input('y1')
             args.append(val)
-        elif self.hasInputFromPort('y1Scalar'):
-            val = self.getInputFromPort('y1Scalar')
+        elif self.has_input('y1Scalar'):
+            val = self.get_input('y1Scalar')
             args.append(val)
         else:
             raise ModuleError(self, 'Must set one of "y1", '                                   '"y1Scalar"')
 
         kwargs = {}
-        if self.hasInputFromPort('y2'):
-            val = self.getInputFromPort('y2')
+        if self.has_input('y2'):
+            val = self.get_input('y2')
             kwargs['y2'] = val
-        elif self.hasInputFromPort('y2Sequence'):
-            val = self.getInputFromPort('y2Sequence')
+        elif self.has_input('y2Sequence'):
+            val = self.get_input('y2Sequence')
             kwargs['y2'] = val
-        if self.hasInputFromPort('interpolate'):
-            val = self.getInputFromPort('interpolate')
+        if self.has_input('interpolate'):
+            val = self.get_input('interpolate')
             kwargs['interpolate'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('where'):
-            val = self.getInputFromPort('where')
+        if self.has_input('where'):
+            val = self.get_input('where')
             kwargs['where'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polyCollection = matplotlib.pyplot.fill_between(*args, **kwargs)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollection is not None:
                 properties.update_props(polyCollection)
 
@@ -2033,7 +2107,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("y", "basic:List",
                {'docstring': 'An N-length array of the y data'}),
               ("x2", "basic:Float",
-               {'optional': True, 'docstring': 'A scalar x-value', 'defaults': "['0']"}),
+               {'optional': True, 'docstring': 'A scalar x-value', 'defaults': '[0]'}),
               ("x2Sequence", "basic:List",
                {'optional': True, 'docstring': 'An N-length array of the x data'}),
               ("hold", "basic:String",
@@ -2049,42 +2123,46 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplFillBetweenx)"),
+        ("value", "(MplFillBetweenx)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
-        if self.hasInputFromPort('x1'):
-            val = self.getInputFromPort('x1')
+        if self.has_input('x1'):
+            val = self.get_input('x1')
             args.append(val)
-        elif self.hasInputFromPort('x1Scalar'):
-            val = self.getInputFromPort('x1Scalar')
+        elif self.has_input('x1Scalar'):
+            val = self.get_input('x1Scalar')
             args.append(val)
         else:
             raise ModuleError(self, 'Must set one of "x1", '                                   '"x1Scalar"')
 
         kwargs = {}
-        if self.hasInputFromPort('x2'):
-            val = self.getInputFromPort('x2')
+        if self.has_input('x2'):
+            val = self.get_input('x2')
             kwargs['x2'] = val
-        elif self.hasInputFromPort('x2Sequence'):
-            val = self.getInputFromPort('x2Sequence')
+        elif self.has_input('x2Sequence'):
+            val = self.get_input('x2Sequence')
             kwargs['x2'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('where'):
-            val = self.getInputFromPort('where')
+        if self.has_input('where'):
+            val = self.get_input('where')
             kwargs['where'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polyCollection = matplotlib.pyplot.fill_betweenx(*args, **kwargs)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollection is not None:
                 properties.update_props(polyCollection)
 
@@ -2121,29 +2199,29 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("vmax", "basic:Float",
                {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.'}),
               ("edgecolorsSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': "If 'none', draws the edges in the same color as the fill color. This is the default, as it avoids unsightly unpainted pixels between the hexagons.\n\nIf None, draws the outlines in the default color.\n\nIf a matplotlib color arg or sequence of rgba tuples, draws the outlines in the specified color.", 'values': "[['', 'none', 'mpl color']]", 'optional': True, 'defaults': "['none']"}),
+               {'optional': True, 'docstring': "If 'none', draws the edges in the same color as the fill color. This is the default, as it avoids unsightly unpainted pixels between the hexagons.\n\nIf None, draws the outlines in the default color.\n\nIf a matplotlib color arg or sequence of rgba tuples, draws the outlines in the specified color."}),
               ("edgecolorsScalar", "basic:String",
-               {'docstring': "If 'none', draws the edges in the same color as the fill color. This is the default, as it avoids unsightly unpainted pixels between the hexagons.\n\nIf None, draws the outlines in the default color.\n\nIf a matplotlib color arg or sequence of rgba tuples, draws the outlines in the specified color.", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If 'none', draws the edges in the same color as the fill color. This is the default, as it avoids unsightly unpainted pixels between the hexagons.\n\nIf None, draws the outlines in the default color.\n\nIf a matplotlib color arg or sequence of rgba tuples, draws the outlines in the specified color.", 'values': "[['none', 'mpl color']]", 'optional': True, 'defaults': "['none']"}),
               ("C", "basic:List",
                {'optional': True}),
               ("gridsize", "basic:Integer",
-               {'optional': True, 'docstring': 'The number of hexagons in the x-direction, default is 100. The corresponding number of hexagons in the y-direction is chosen such that the hexagons are approximately regular. Alternatively, gridsize can be a tuple with two elements specifying the number of hexagons in the x-direction and the y-direction.', 'defaults': "['100']"}),
+               {'optional': True, 'docstring': 'The number of hexagons in the x-direction, default is 100. The corresponding number of hexagons in the y-direction is chosen such that the hexagons are approximately regular. Alternatively, gridsize can be a tuple with two elements specifying the number of hexagons in the x-direction and the y-direction.', 'defaults': '[100]'}),
               ("vmin", "basic:Float",
                {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.'}),
               ("yscale", "basic:String",
                {'optional': True, 'defaults': "['linear']"}),
               ("reduce_C_function", "basic:String",
-               {'optional': True, 'defaults': "['<function mean at 0x0277B3B0>']"}),
-              ("linewidths", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If None, defaults to rc lines.linewidth. Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.', 'values': "[['']]", 'optional': True}),
+               {'optional': True}),
+              ("linewidths", "basic:List",
+               {'optional': True, 'docstring': 'If None, defaults to rc lines.linewidth. Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.'}),
               ("xscale", "basic:String",
                {'entry_types': "['enum']", 'docstring': 'Use a linear or log10 scale on the horizontal axis.', 'values': "[['linear', 'log']]", 'optional': True, 'defaults': "['linear']"}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'a :class:`matplotlib.colors.Colormap` instance. If None, defaults to rc image.cmap.', 'values': "[['', 'Colormap']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'a :class:`matplotlib.colors.Colormap` instance. If None, defaults to rc image.cmap.', 'values': "[['Colormap']]", 'optional': True}),
               ("norm", "basic:String",
-               {'entry_types': "['enum']", 'docstring': ':class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1.', 'values': "[['', 'Normalize']]", 'optional': True}),
-              ("extent", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'The limits of the bins. The default assigns the limits based on gridsize, x, y, xscale and yscale.', 'values': "[['']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': ':class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1.', 'values': "[['Normalize']]", 'optional': True}),
+              ("extent", "basic:Float",
+               {'optional': True, 'docstring': 'The limits of the bins. The default assigns the limits based on gridsize, x, y, xscale and yscale.'}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'the alpha value for the patches'}),
               ("y", "basic:List",
@@ -2152,10 +2230,10 @@ Additional kwargs: hold = [True|False] overrides default hold state
                {}),
               ("hold", "basic:String",
                {'optional': True}),
-              ("mincnt", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, only display cells with more than mincnt number of points in the cell', 'values': "[['']]", 'optional': True}),
+              ("mincnt", "basic:Integer",
+               {'optional': True, 'docstring': 'If not None, only display cells with more than mincnt number of points in the cell'}),
               ("marginals", "basic:Boolean",
-               {'optional': True, 'docstring': 'if marginals is True, plot the marginal density as colormapped rectagles along the bottom of the x-axis and left of the y-axis', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'if marginals is True, plot the marginal density as colormapped rectagles along the bottom of the x-axis and left of the y-axis', 'defaults': '[False]'}),
               ("bins", "basic:Integer",
                {'optional': True, 'docstring': "If None, no binning is applied; the color of each hexagon directly corresponds to its count value.\n\nIf 'log', use a logarithmic scale for the color map. Internally, log_{10}(i+1) is used to determine the hexagon color.\n\nIf an integer, divide the counts in the specified number of bins, and color the hexagons accordingly.\n\nIf a sequence of values, the values of the lower bound of the bins to be used."}),
               ("scale", "basic:String",
@@ -2165,9 +2243,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplHexbin)"),
+        ("value", "(MplHexbin)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -2175,71 +2253,75 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        if self.hasInputFromPort('edgecolorsSequence'):
-            val = self.getInputFromPort('edgecolorsSequence')
+        if self.has_input('edgecolorsSequence'):
+            val = self.get_input('edgecolorsSequence')
             kwargs['edgecolors'] = val
-        elif self.hasInputFromPort('edgecolorsScalar'):
-            val = self.getInputFromPort('edgecolorsScalar')
+        elif self.has_input('edgecolorsScalar'):
+            val = self.get_input('edgecolorsScalar')
             kwargs['edgecolors'] = val
-        if self.hasInputFromPort('C'):
-            val = self.getInputFromPort('C')
+        if self.has_input('C'):
+            val = self.get_input('C')
             kwargs['C'] = val
-        if self.hasInputFromPort('gridsize'):
-            val = self.getInputFromPort('gridsize')
+        if self.has_input('gridsize'):
+            val = self.get_input('gridsize')
             kwargs['gridsize'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('yscale'):
-            val = self.getInputFromPort('yscale')
+        if self.has_input('yscale'):
+            val = self.get_input('yscale')
             kwargs['yscale'] = val
-        if self.hasInputFromPort('reduce_C_function'):
-            val = self.getInputFromPort('reduce_C_function')
+        if self.has_input('reduce_C_function'):
+            val = self.get_input('reduce_C_function')
             kwargs['reduce_C_function'] = val
-        if self.hasInputFromPort('linewidths'):
-            val = self.getInputFromPort('linewidths')
+        if self.has_input('linewidths'):
+            val = self.get_input('linewidths')
             kwargs['linewidths'] = val
-        if self.hasInputFromPort('xscale'):
-            val = self.getInputFromPort('xscale')
+        if self.has_input('xscale'):
+            val = self.get_input('xscale')
             kwargs['xscale'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
-        if self.hasInputFromPort('extent'):
-            val = self.getInputFromPort('extent')
+        if self.has_input('extent'):
+            val = self.get_input('extent')
             kwargs['extent'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('mincnt'):
-            val = self.getInputFromPort('mincnt')
+        if self.has_input('mincnt'):
+            val = self.get_input('mincnt')
             kwargs['mincnt'] = val
-        if self.hasInputFromPort('marginals'):
-            val = self.getInputFromPort('marginals')
+        if self.has_input('marginals'):
+            val = self.get_input('marginals')
             kwargs['marginals'] = val
-        if self.hasInputFromPort('bins'):
-            val = self.getInputFromPort('bins')
+        if self.has_input('bins'):
+            val = self.get_input('bins')
             kwargs['bins'] = val
-        if self.hasInputFromPort('scale'):
-            val = self.getInputFromPort('scale')
+        if self.has_input('scale'):
+            val = self.get_input('scale')
             kwargs['scale'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polyCollection = matplotlib.pyplot.hexbin(*args, **kwargs)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollection is not None:
                 properties.update_props(polyCollection)
 
@@ -2272,9 +2354,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("rwidth", "basic:String",
                {'optional': True, 'docstring': "The relative width of the bars as a fraction of the bin width.  If None, automatically compute the width. Ignored if histtype = 'step' or 'stepfilled'."}),
               ("normed", "basic:Boolean",
-               {'optional': True, 'docstring': 'If True, the first element of the return tuple will be the counts normalized to form a probability density, i.e., n/(len(x)*dbin).  In a probability density, the integral of the histogram should be 1; you can verify that with a trapezoidal integration of the probability density function:\n\npdf, bins, patches = ax.hist(...) print np.sum(pdf * np.diff(bins))\n\nUntil numpy release 1.5, the underlying numpy histogram function was incorrect wi [...]
+               {'optional': True, 'docstring': 'If True, the first element of the return tuple will be the counts normalized to form a probability density, i.e., n/(len(x)*dbin).  In a probability density, the integral of the histogram should be 1; you can verify that with a trapezoidal integration of the probability density function:\n\npdf, bins, patches = ax.hist(...) print np.sum(pdf * np.diff(bins))\n\nUntil numpy release 1.5, the underlying numpy histogram function was incorrect wi [...]
               ("stacked", "basic:Boolean",
-               {'optional': True, 'docstring': "If True, multiple data are stacked on top of each other If False multiple data are aranged side by side if histtype is 'bar' or on top of each other if histtype is 'step'\n\n.", 'defaults': "['False']"}),
+               {'optional': True, 'docstring': "If True, multiple data are stacked on top of each other If False multiple data are aranged side by side if histtype is 'bar' or on top of each other if histtype is 'step'\n\n.", 'defaults': '[False]'}),
               ("orientation", "basic:String",
                {'entry_types': "['enum']", 'docstring': "If 'horizontal', :func:`~matplotlib.pyplot.barh` will be used for bar-type histograms and the bottom kwarg will be the left edges.", 'values': "[['horizontal', 'vertical']]", 'optional': True, 'defaults': "['vertical']"}),
               ("bottom", "basic:String",
@@ -2288,7 +2370,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("align", "basic:String",
                {'entry_types': "['enum']", 'docstring': "Controls how the histogram is plotted.\n\n'left': bars are centered on the left bin edges.\n\n'mid': bars are centered between the bin edges.\n\n'right': bars are centered on the right bin edges.", 'values': "[['left', 'mid', 'right']]", 'optional': True, 'defaults': "['mid']"}),
               ("cumulative", "basic:Boolean",
-               {'optional': True, 'docstring': 'If True, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin gives the total number of datapoints.  If normed is also True then the histogram is normalized such that the last bin equals 1. If cumulative evaluates to less than 0 (e.g. -1), the direction of accumulation is reversed.  In this case, if normed is also True, then the histogram is normalized such that the first bi [...]
+               {'optional': True, 'docstring': 'If True, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin gives the total number of datapoints.  If normed is also True then the histogram is normalized such that the last bin equals 1. If cumulative evaluates to less than 0 (e.g. -1), the direction of accumulation is reversed.  In this case, if normed is also True, then the histogram is normalized such that the first bi [...]
               ("labelSequence", "basic:List",
                {'optional': True, 'docstring': "String, or sequence of strings to match multiple datasets.  Bar charts yield multiple patches per dataset, but only the first gets the label, so that the legend command will work as expected:\n\nax.hist(10+2*np.random.randn(1000), label='men') ax.hist(12+3*np.random.randn(1000), label='women', alpha=0.5) ax.legend()"}),
               ("labelScalar", "basic:String",
@@ -2302,19 +2384,19 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("hold", "basic:String",
                {'optional': True}),
               ("bins", "basic:Integer",
-               {'optional': True, 'docstring': 'Either an integer number of bins or a sequence giving the bins.  If bins is an integer, bins + 1 bin edges will be returned, consistent with :func:`numpy.histogram` for numpy version >= 1.3, and with the new = True argument in earlier versions. Unequally spaced bins are supported if bins is a sequence.', 'defaults': "['10']"}),
+               {'optional': True, 'docstring': 'Either an integer number of bins or a sequence giving the bins.  If bins is an integer, bins + 1 bin edges will be returned, consistent with :func:`numpy.histogram` for numpy version >= 1.3, and with the new = True argument in earlier versions. Unequally spaced bins are supported if bins is a sequence.', 'defaults': '[10]'}),
               ("binsSequence", "basic:List",
                {'docstring': 'Either an integer number of bins or a sequence giving the bins.  If bins is an integer, bins + 1 bin edges will be returned, consistent with :func:`numpy.histogram` for numpy version >= 1.3, and with the new = True argument in earlier versions. Unequally spaced bins are supported if bins is a sequence.', 'optional': True}),
               ("log", "basic:Boolean",
-               {'optional': True, 'docstring': 'If True, the histogram axis will be set to a log scale. If log is True and x is a 1D array, empty bins will be filtered out and only the non-empty (n, bins, patches) will be returned.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'If True, the histogram axis will be set to a log scale. If log is True and x is a 1D array, empty bins will be filtered out and only the non-empty (n, bins, patches) will be returned.', 'defaults': '[False]'}),
               ("rectangleProperties", "MplRectangleProperties",
                {}),
         ]
 
     _output_ports = [
-        ("self", "(MplHist)"),
+        ("value", "(MplHist)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -2322,68 +2404,72 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('rwidth'):
-            val = self.getInputFromPort('rwidth')
+        if self.has_input('rwidth'):
+            val = self.get_input('rwidth')
             kwargs['rwidth'] = val
-        if self.hasInputFromPort('normed'):
-            val = self.getInputFromPort('normed')
+        if self.has_input('normed'):
+            val = self.get_input('normed')
             kwargs['normed'] = val
-        if self.hasInputFromPort('stacked'):
-            val = self.getInputFromPort('stacked')
+        if self.has_input('stacked'):
+            val = self.get_input('stacked')
             kwargs['stacked'] = val
-        if self.hasInputFromPort('orientation'):
-            val = self.getInputFromPort('orientation')
+        if self.has_input('orientation'):
+            val = self.get_input('orientation')
             kwargs['orientation'] = val
-        if self.hasInputFromPort('bottom'):
-            val = self.getInputFromPort('bottom')
+        if self.has_input('bottom'):
+            val = self.get_input('bottom')
             kwargs['bottom'] = val
-        if self.hasInputFromPort('colorSequence'):
-            val = self.getInputFromPort('colorSequence')
+        if self.has_input('colorSequence'):
+            val = self.get_input('colorSequence')
             kwargs['color'] = val
-        elif self.hasInputFromPort('colorScalar'):
-            val = self.getInputFromPort('colorScalar')
+        elif self.has_input('colorScalar'):
+            val = self.get_input('colorScalar')
             val = translate_color(val)
             kwargs['color'] = val
-        if self.hasInputFromPort('histtype'):
-            val = self.getInputFromPort('histtype')
+        if self.has_input('histtype'):
+            val = self.get_input('histtype')
             kwargs['histtype'] = val
-        if self.hasInputFromPort('align'):
-            val = self.getInputFromPort('align')
+        if self.has_input('align'):
+            val = self.get_input('align')
             kwargs['align'] = val
-        if self.hasInputFromPort('cumulative'):
-            val = self.getInputFromPort('cumulative')
+        if self.has_input('cumulative'):
+            val = self.get_input('cumulative')
             kwargs['cumulative'] = val
-        if self.hasInputFromPort('labelSequence'):
-            val = self.getInputFromPort('labelSequence')
+        if self.has_input('labelSequence'):
+            val = self.get_input('labelSequence')
             kwargs['label'] = val
-        elif self.hasInputFromPort('labelScalar'):
-            val = self.getInputFromPort('labelScalar')
+        elif self.has_input('labelScalar'):
+            val = self.get_input('labelScalar')
             kwargs['label'] = val
-        if self.hasInputFromPort('range'):
-            val = self.getInputFromPort('range')
+        if self.has_input('range'):
+            val = self.get_input('range')
             kwargs['range'] = val
-        if self.hasInputFromPort('weights'):
-            val = self.getInputFromPort('weights')
+        if self.has_input('weights'):
+            val = self.get_input('weights')
             kwargs['weights'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('bins'):
-            val = self.getInputFromPort('bins')
+        if self.has_input('bins'):
+            val = self.get_input('bins')
             kwargs['bins'] = val
-        elif self.hasInputFromPort('binsSequence'):
-            val = self.getInputFromPort('binsSequence')
+        elif self.has_input('binsSequence'):
+            val = self.get_input('binsSequence')
             kwargs['bins'] = val
-        if self.hasInputFromPort('log'):
-            val = self.getInputFromPort('log')
+        if self.has_input('log'):
+            val = self.get_input('log')
             kwargs['log'] = val
 
-        output = matplotlib.pyplot.hist(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.hist(*args, **kwargs)
         rectangles = output[2]
-        if self.hasInputFromPort('rectangleProperties'):
-            properties = self.getInputFromPort('rectangleProperties')
+        if self.has_input('rectangleProperties'):
+            properties = self.get_input('rectangleProperties')
             if rectangles is not None:
                 properties.update_props(rectangles)
 
@@ -2422,7 +2508,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("normed", "basic:Boolean",
-               {'optional': True, 'defaults': "['False']"}),
+               {'optional': True, 'defaults': '[False]'}),
               ("cmin", "basic:String",
                {'optional': True}),
               ("range", "basic:String",
@@ -2438,13 +2524,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("cmax", "basic:String",
                {'optional': True}),
               ("bins", "basic:Integer",
-               {'optional': True, 'defaults': "['10']"}),
+               {'optional': True, 'defaults': '[10]'}),
         ]
 
     _output_ports = [
-        ("self", "(MplHist2d)"),
+        ("value", "(MplHist2d)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -2452,33 +2538,37 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('normed'):
-            val = self.getInputFromPort('normed')
+        if self.has_input('normed'):
+            val = self.get_input('normed')
             kwargs['normed'] = val
-        if self.hasInputFromPort('cmin'):
-            val = self.getInputFromPort('cmin')
+        if self.has_input('cmin'):
+            val = self.get_input('cmin')
             kwargs['cmin'] = val
-        if self.hasInputFromPort('range'):
-            val = self.getInputFromPort('range')
+        if self.has_input('range'):
+            val = self.get_input('range')
             kwargs['range'] = val
-        if self.hasInputFromPort('weights'):
-            val = self.getInputFromPort('weights')
+        if self.has_input('weights'):
+            val = self.get_input('weights')
             kwargs['weights'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('cmax'):
-            val = self.getInputFromPort('cmax')
+        if self.has_input('cmax'):
+            val = self.get_input('cmax')
             kwargs['cmax'] = val
-        if self.hasInputFromPort('bins'):
-            val = self.getInputFromPort('bins')
+        if self.has_input('bins'):
+            val = self.get_input('bins')
             kwargs['bins'] = val
 
-        matplotlib.pyplot.hist2d(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.hist2d(*args, **kwargs)
 
 class MplHlines(MplPlot):
     """Plot horizontal lines.
@@ -2513,9 +2603,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("xminSequence", "basic:List",
                {'docstring': 'can be scalars or len(x) numpy arrays.  If they are scalars, then the respective values are constant, else the widths of the lines are determined by xmin and xmax.', 'optional': True}),
               ("colorsSequence", "basic:List",
-               {'optional': True, 'docstring': 'a line collections color argument, either a single color or a len(y) list of colors', 'defaults': "['k']"}),
+               {'optional': True, 'docstring': 'a line collections color argument, either a single color or a len(y) list of colors'}),
               ("colorsScalar", "basic:String",
-               {'docstring': 'a line collections color argument, either a single color or a len(y) list of colors', 'optional': True}),
+               {'docstring': 'a line collections color argument, either a single color or a len(y) list of colors', 'optional': True, 'defaults': "['k']"}),
               ("xmaxScalar", "basic:Float",
                {'docstring': 'can be scalars or len(x) numpy arrays.  If they are scalars, then the respective values are constant, else the widths of the lines are determined by xmin and xmax.'}),
               ("xmaxSequence", "basic:List",
@@ -2529,9 +2619,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplHlines)"),
+        ("value", "(MplHlines)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -2539,43 +2629,47 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('linestyles'):
-            val = self.getInputFromPort('linestyles')
+        if self.has_input('linestyles'):
+            val = self.get_input('linestyles')
             kwargs['linestyles'] = val
-        if self.hasInputFromPort('label'):
-            val = self.getInputFromPort('label')
+        if self.has_input('label'):
+            val = self.get_input('label')
             kwargs['label'] = val
-        if self.hasInputFromPort('xminScalar'):
-            val = self.getInputFromPort('xminScalar')
+        if self.has_input('xminScalar'):
+            val = self.get_input('xminScalar')
             kwargs['xmin'] = val
-        elif self.hasInputFromPort('xminSequence'):
-            val = self.getInputFromPort('xminSequence')
+        elif self.has_input('xminSequence'):
+            val = self.get_input('xminSequence')
             kwargs['xmin'] = val
         else:
             raise ModuleError(self, 'Must set one of "xminScalar", '                                   '"xminSequence"')
-        if self.hasInputFromPort('colorsSequence'):
-            val = self.getInputFromPort('colorsSequence')
+        if self.has_input('colorsSequence'):
+            val = self.get_input('colorsSequence')
             kwargs['colors'] = val
-        elif self.hasInputFromPort('colorsScalar'):
-            val = self.getInputFromPort('colorsScalar')
+        elif self.has_input('colorsScalar'):
+            val = self.get_input('colorsScalar')
             kwargs['colors'] = val
-        if self.hasInputFromPort('xmaxScalar'):
-            val = self.getInputFromPort('xmaxScalar')
+        if self.has_input('xmaxScalar'):
+            val = self.get_input('xmaxScalar')
             kwargs['xmax'] = val
-        elif self.hasInputFromPort('xmaxSequence'):
-            val = self.getInputFromPort('xmaxSequence')
+        elif self.has_input('xmaxSequence'):
+            val = self.get_input('xmaxSequence')
             kwargs['xmax'] = val
         else:
             raise ModuleError(self, 'Must set one of "xmaxScalar", '                                   '"xmaxSequence"')
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.hlines(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -2632,13 +2726,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("shape", "basic:String",
                {'optional': True}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Colormap` instance, eg. cm.jet. If None, default to rc image.cmap value.\n\ncmap is ignored when X has RGB(A) information', 'values': "[['', 'Colormap']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Colormap` instance, eg. cm.jet. If None, default to rc image.cmap value.\n\ncmap is ignored when X has RGB(A) information', 'values': "[['Colormap']]", 'optional': True}),
               ("filterrad", "basic:Float",
-               {'optional': True, 'defaults': "['4.0']"}),
+               {'optional': True, 'defaults': '[4.0]'}),
               ("filternorm", "basic:Integer",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("aspect", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If 'auto', changes the image aspect ratio to match that of the axes\n\nIf 'equal', and extent is None, changes the axes aspect ratio to match that of the image. If extent is not None, the axes aspect ratio is changed to match that of the extent.\n\nIf None, default to rc image.aspect value.", 'values': "[['', 'auto', 'equal']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If 'auto', changes the image aspect ratio to match that of the axes\n\nIf 'equal', and extent is None, changes the axes aspect ratio to match that of the image. If extent is not None, the axes aspect ratio is changed to match that of the extent.\n\nIf None, default to rc image.aspect value.", 'values': "[['auto', 'equal']]", 'optional': True}),
               ("alpha", "basic:String",
                {'optional': True}),
               ("vmax", "basic:String",
@@ -2654,9 +2748,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplImshow)"),
+        ("value", "(MplImshow)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -2664,58 +2758,62 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('origin'):
-            val = self.getInputFromPort('origin')
+        if self.has_input('origin'):
+            val = self.get_input('origin')
             kwargs['origin'] = val
-        if self.hasInputFromPort('imlim'):
-            val = self.getInputFromPort('imlim')
+        if self.has_input('imlim'):
+            val = self.get_input('imlim')
             kwargs['imlim'] = val
-        if self.hasInputFromPort('extent'):
-            val = self.getInputFromPort('extent')
+        if self.has_input('extent'):
+            val = self.get_input('extent')
             kwargs['extent'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('url'):
-            val = self.getInputFromPort('url')
+        if self.has_input('url'):
+            val = self.get_input('url')
             kwargs['url'] = val
-        if self.hasInputFromPort('resample'):
-            val = self.getInputFromPort('resample')
+        if self.has_input('resample'):
+            val = self.get_input('resample')
             kwargs['resample'] = val
-        if self.hasInputFromPort('shape'):
-            val = self.getInputFromPort('shape')
+        if self.has_input('shape'):
+            val = self.get_input('shape')
             kwargs['shape'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('filterrad'):
-            val = self.getInputFromPort('filterrad')
+        if self.has_input('filterrad'):
+            val = self.get_input('filterrad')
             kwargs['filterrad'] = val
-        if self.hasInputFromPort('filternorm'):
-            val = self.getInputFromPort('filternorm')
+        if self.has_input('filternorm'):
+            val = self.get_input('filternorm')
             kwargs['filternorm'] = val
-        if self.hasInputFromPort('aspect'):
-            val = self.getInputFromPort('aspect')
+        if self.has_input('aspect'):
+            val = self.get_input('aspect')
             kwargs['aspect'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        val = self.getInputFromPort('X')
+        val = self.get_input('X')
         kwargs['X'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
-        if self.hasInputFromPort('interpolation'):
-            val = self.getInputFromPort('interpolation')
+        if self.has_input('interpolation'):
+            val = self.get_input('interpolation')
             kwargs['interpolation'] = val
 
-        matplotlib.pyplot.imshow(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.imshow(*args, **kwargs)
 
 class MplLoglog(MplPlot):
     """Make a plot with log scaling on both the x and y axis.
@@ -2747,14 +2845,10 @@ Additional kwargs: hold = [True|False] overrides default hold state
                {'optional': True, 'docstring': 'Base of the x/y logarithm'}),
               ("basey", "basic:Float",
                {'optional': True, 'docstring': 'Base of the x/y logarithm'}),
-              ("subsxSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details', 'values': "[['']]", 'optional': True}),
-              ("subsxScalar", "basic:String",
-               {'docstring': 'The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details', 'optional': True}),
-              ("subsySequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details', 'values': "[['']]", 'optional': True}),
-              ("subsyScalar", "basic:String",
-               {'docstring': 'The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details', 'optional': True}),
+              ("subsx", "basic:List",
+               {'optional': True, 'docstring': 'The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details'}),
+              ("subsy", "basic:List",
+               {'optional': True, 'docstring': 'The location of the minor x/y ticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`matplotlib.axes.Axes.set_xscale` / :meth:`matplotlib.axes.Axes.set_yscale` for details'}),
               ("y", "basic:List",
                {}),
               ("x", "basic:List",
@@ -2764,48 +2858,46 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplLoglog)"),
+        ("value", "(MplLoglog)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('nonposx'):
-            val = self.getInputFromPort('nonposx')
+        if self.has_input('nonposx'):
+            val = self.get_input('nonposx')
             kwargs['nonposx'] = val
-        if self.hasInputFromPort('nonposy'):
-            val = self.getInputFromPort('nonposy')
+        if self.has_input('nonposy'):
+            val = self.get_input('nonposy')
             kwargs['nonposy'] = val
-        if self.hasInputFromPort('basex'):
-            val = self.getInputFromPort('basex')
+        if self.has_input('basex'):
+            val = self.get_input('basex')
             kwargs['basex'] = val
-        if self.hasInputFromPort('basey'):
-            val = self.getInputFromPort('basey')
+        if self.has_input('basey'):
+            val = self.get_input('basey')
             kwargs['basey'] = val
-        if self.hasInputFromPort('subsxSequence'):
-            val = self.getInputFromPort('subsxSequence')
+        if self.has_input('subsx'):
+            val = self.get_input('subsx')
             kwargs['subsx'] = val
-        elif self.hasInputFromPort('subsxScalar'):
-            val = self.getInputFromPort('subsxScalar')
-            kwargs['subsx'] = val
-        if self.hasInputFromPort('subsySequence'):
-            val = self.getInputFromPort('subsySequence')
-            kwargs['subsy'] = val
-        elif self.hasInputFromPort('subsyScalar'):
-            val = self.getInputFromPort('subsyScalar')
+        if self.has_input('subsy'):
+            val = self.get_input('subsy')
             kwargs['subsy'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.loglog(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -2872,21 +2964,21 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("edgecolorsSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': "If None, the rc setting is used by default.\n\nIf 'none', edges will not be visible.\n\nAn mpl color or sequence of colors will set the edge color", 'values': "[['', 'none', 'color']]", 'optional': True}),
+               {'optional': True, 'docstring': "If None, the rc setting is used by default.\n\nIf 'none', edges will not be visible.\n\nAn mpl color or sequence of colors will set the edge color"}),
               ("edgecolorsScalar", "basic:String",
-               {'docstring': "If None, the rc setting is used by default.\n\nIf 'none', edges will not be visible.\n\nAn mpl color or sequence of colors will set the edge color", 'optional': True}),
-              ("vmin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.', 'values': "[['']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If None, the rc setting is used by default.\n\nIf 'none', edges will not be visible.\n\nAn mpl color or sequence of colors will set the edge color", 'values': "[['none', 'color']]", 'optional': True}),
+              ("vmin", "basic:Float",
+               {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.'}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.', 'values': "[['', 'Colormap']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.', 'values': "[['Colormap']]", 'optional': True}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'the alpha blending value'}),
-              ("vmax", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.', 'values': "[['']]", 'optional': True}),
+              ("vmax", "basic:Float",
+               {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.'}),
               ("shading", "basic:String",
                {'entry_types': "['enum']", 'docstring': "If 'faceted', a black grid is drawn around each rectangle; if 'flat', edges are not drawn. Default is 'flat', contrary to MATLAB.", 'values': "[['flat', 'faceted']]", 'optional': True, 'defaults': "['flat']"}),
               ("norm", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'An :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.', 'values': "[['', 'Normalize']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'An :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.', 'values': "[['Normalize']]", 'optional': True}),
               ("Y", "basic:List",
                {'optional': True}),
               ("X", "basic:List",
@@ -2898,52 +2990,56 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplPcolor)"),
+        ("value", "(MplPcolor)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        if self.hasInputFromPort('X'):
-            val = self.getInputFromPort('X')
+        if self.has_input('X'):
+            val = self.get_input('X')
             args.append(val)
-        if self.hasInputFromPort('Y'):
-            val = self.getInputFromPort('Y')
+        if self.has_input('Y'):
+            val = self.get_input('Y')
             args.append(val)
-        val = self.getInputFromPort('Z')
+        val = self.get_input('Z')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('edgecolorsSequence'):
-            val = self.getInputFromPort('edgecolorsSequence')
+        if self.has_input('edgecolorsSequence'):
+            val = self.get_input('edgecolorsSequence')
             kwargs['edgecolors'] = val
-        elif self.hasInputFromPort('edgecolorsScalar'):
-            val = self.getInputFromPort('edgecolorsScalar')
+        elif self.has_input('edgecolorsScalar'):
+            val = self.get_input('edgecolorsScalar')
             kwargs['edgecolors'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        if self.hasInputFromPort('shading'):
-            val = self.getInputFromPort('shading')
+        if self.has_input('shading'):
+            val = self.get_input('shading')
             kwargs['shading'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polyCollection = matplotlib.pyplot.pcolor(*args, **kwargs)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollection is not None:
                 properties.update_props(polyCollection)
 
@@ -2974,27 +3070,27 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("edgecolorsSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': "If None, the rc setting is used by default.\n\nIf 'None', edges will not be visible.\n\nIf 'face', edges will have the same color as the faces.\n\nAn mpl color or sequence of colors will set the edge color", 'values': "[['', 'None', 'face', 'color']]", 'optional': True}),
+               {'optional': True, 'docstring': "If None, the rc setting is used by default.\n\nIf 'None', edges will not be visible.\n\nIf 'face', edges will have the same color as the faces.\n\nAn mpl color or sequence of colors will set the edge color"}),
               ("edgecolorsScalar", "basic:String",
-               {'docstring': "If None, the rc setting is used by default.\n\nIf 'None', edges will not be visible.\n\nIf 'face', edges will have the same color as the faces.\n\nAn mpl color or sequence of colors will set the edge color", 'optional': True}),
-              ("vmin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.', 'values': "[['']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If None, the rc setting is used by default.\n\nIf 'None', edges will not be visible.\n\nIf 'face', edges will have the same color as the faces.\n\nAn mpl color or sequence of colors will set the edge color", 'values': "[['None', 'face', 'color']]", 'optional': True}),
+              ("vmin", "basic:Float",
+               {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.'}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.', 'values': "[['', 'Colormap']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Colormap` instance. If None, use rc settings.', 'values': "[['Colormap']]", 'optional': True}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'the alpha blending value'}),
-              ("vmax", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.', 'values': "[['']]", 'optional': True}),
+              ("vmax", "basic:Float",
+               {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either is None, it is autoscaled to the respective min or max of the color array C.  If not None, vmin or vmax passed in here override any pre-existing values supplied in the norm instance.'}),
               ("shading", "basic:String",
                {'entry_types': "['enum']", 'docstring': "'flat' indicates a solid color for each quad.  When 'gouraud', each quad will be Gouraud shaded.  When gouraud shading, edgecolors is ignored.", 'values': "[['flat', 'gouraud']]", 'optional': True}),
               ("norm", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.', 'values': "[['', 'Normalize']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If None, defaults to :func:`normalize`.', 'values': "[['Normalize']]", 'optional': True}),
         ]
 
     _output_ports = [
-        ("self", "(MplPcolormesh)"),
+        ("value", "(MplPcolormesh)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3002,32 +3098,36 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('edgecolorsSequence'):
-            val = self.getInputFromPort('edgecolorsSequence')
+        if self.has_input('edgecolorsSequence'):
+            val = self.get_input('edgecolorsSequence')
             kwargs['edgecolors'] = val
-        elif self.hasInputFromPort('edgecolorsScalar'):
-            val = self.getInputFromPort('edgecolorsScalar')
+        elif self.has_input('edgecolorsScalar'):
+            val = self.get_input('edgecolorsScalar')
             kwargs['edgecolors'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        if self.hasInputFromPort('shading'):
-            val = self.getInputFromPort('shading')
+        if self.has_input('shading'):
+            val = self.get_input('shading')
             kwargs['shading'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
-        matplotlib.pyplot.pcolormesh(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.pcolormesh(*args, **kwargs)
 
 class MplPie(MplPlot):
     """Plot a pie chart.
@@ -3050,31 +3150,31 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("autopct", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, is a string or function used to label the wedges with their numeric value.  The label will be placed inside the wedge.  If it is a format string, the label will be fmt%pct. If it is a function, it will be called.', 'values': "[['', 'format function']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If not None, is a string or function used to label the wedges with their numeric value.  The label will be placed inside the wedge.  If it is a format string, the label will be fmt%pct. If it is a function, it will be called.', 'values': "[['format function']]", 'optional': True}),
               ("pctdistance", "basic:Float",
-               {'optional': True, 'docstring': 'The ratio between the center of each pie slice and the start of the text generated by autopct.  Ignored if autopct is None; default is 0.6.', 'defaults': "['0.6']"}),
+               {'optional': True, 'docstring': 'The ratio between the center of each pie slice and the start of the text generated by autopct.  Ignored if autopct is None; default is 0.6.', 'defaults': '[0.6]'}),
               ("labelsSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'A sequence of strings providing the labels for each wedge', 'values': "[['']]", 'optional': True}),
+               {'optional': True, 'docstring': 'A sequence of strings providing the labels for each wedge'}),
               ("labelsScalar", "basic:String",
                {'docstring': 'A sequence of strings providing the labels for each wedge', 'optional': True}),
               ("explodeSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'If not None, is a len(x) array which specifies the fraction of the radius with which to offset each wedge.', 'values': "[['']]", 'optional': True}),
+               {'optional': True, 'docstring': 'If not None, is a len(x) array which specifies the fraction of the radius with which to offset each wedge.'}),
               ("explodeScalar", "basic:String",
                {'docstring': 'If not None, is a len(x) array which specifies the fraction of the radius with which to offset each wedge.', 'optional': True}),
               ("colors", "basic:Color",
-               {'entry_types': "['enum']", 'docstring': 'A sequence of matplotlib color args through which the pie chart will cycle.', 'values': "[['']]", 'optional': True}),
+               {'optional': True, 'docstring': 'A sequence of matplotlib color args through which the pie chart will cycle.'}),
               ("radius", "basic:String",
                {'optional': True}),
               ("startangle", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If not None, rotates the start of the pie chart by angle degrees counterclockwise from the x-axis.', 'values': "[['', 'Offset angle']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If not None, rotates the start of the pie chart by angle degrees counterclockwise from the x-axis.', 'values': "[['Offset angle']]", 'optional': True}),
               ("x", "basic:List",
                {}),
               ("shadow", "basic:Boolean",
-               {'optional': True, 'docstring': 'Draw a shadow beneath the pie.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'Draw a shadow beneath the pie.', 'defaults': '[False]'}),
               ("hold", "basic:String",
                {'optional': True}),
               ("labeldistance", "basic:Float",
-               {'optional': True, 'docstring': 'The radial distance at which the pie labels are drawn', 'defaults': "['1.1']"}),
+               {'optional': True, 'docstring': 'The radial distance at which the pie labels are drawn', 'defaults': '[1.1]'}),
               ("autotextProperties", "MplTextProperties",
                {}),
               ("wedgeProperties", "MplWedgeProperties",
@@ -3084,9 +3184,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplPie)"),
+        ("value", "(MplPie)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3094,62 +3194,66 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('autopct'):
-            val = self.getInputFromPort('autopct')
+        if self.has_input('autopct'):
+            val = self.get_input('autopct')
             kwargs['autopct'] = val
-        if self.hasInputFromPort('pctdistance'):
-            val = self.getInputFromPort('pctdistance')
+        if self.has_input('pctdistance'):
+            val = self.get_input('pctdistance')
             kwargs['pctdistance'] = val
-        if self.hasInputFromPort('labelsSequence'):
-            val = self.getInputFromPort('labelsSequence')
+        if self.has_input('labelsSequence'):
+            val = self.get_input('labelsSequence')
             kwargs['labels'] = val
-        elif self.hasInputFromPort('labelsScalar'):
-            val = self.getInputFromPort('labelsScalar')
+        elif self.has_input('labelsScalar'):
+            val = self.get_input('labelsScalar')
             kwargs['labels'] = val
-        if self.hasInputFromPort('explodeSequence'):
-            val = self.getInputFromPort('explodeSequence')
+        if self.has_input('explodeSequence'):
+            val = self.get_input('explodeSequence')
             kwargs['explode'] = val
-        elif self.hasInputFromPort('explodeScalar'):
-            val = self.getInputFromPort('explodeScalar')
+        elif self.has_input('explodeScalar'):
+            val = self.get_input('explodeScalar')
             kwargs['explode'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
-        if self.hasInputFromPort('radius'):
-            val = self.getInputFromPort('radius')
+        if self.has_input('radius'):
+            val = self.get_input('radius')
             kwargs['radius'] = val
-        if self.hasInputFromPort('startangle'):
-            val = self.getInputFromPort('startangle')
+        if self.has_input('startangle'):
+            val = self.get_input('startangle')
             kwargs['startangle'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('shadow'):
-            val = self.getInputFromPort('shadow')
+        if self.has_input('shadow'):
+            val = self.get_input('shadow')
             kwargs['shadow'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('labeldistance'):
-            val = self.getInputFromPort('labeldistance')
+        if self.has_input('labeldistance'):
+            val = self.get_input('labeldistance')
             kwargs['labeldistance'] = val
 
-        output = matplotlib.pyplot.pie(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.pie(*args, **kwargs)
         if len(output) < 3:
             output = output + ([],)
         wedges = output[0]
         texts = output[1]
         autotexts = output[2]
-        if self.hasInputFromPort('autotextProperties'):
-            properties = self.getInputFromPort('autotextProperties')
+        if self.has_input('autotextProperties'):
+            properties = self.get_input('autotextProperties')
             if autotexts is not None:
                 properties.update_props(autotexts)
-        if self.hasInputFromPort('wedgeProperties'):
-            properties = self.getInputFromPort('wedgeProperties')
+        if self.has_input('wedgeProperties'):
+            properties = self.get_input('wedgeProperties')
             if wedges is not None:
                 properties.update_props(wedges)
-        if self.hasInputFromPort('textProperties'):
-            properties = self.getInputFromPort('textProperties')
+        if self.has_input('textProperties'):
+            properties = self.get_input('textProperties')
             if texts is not None:
                 properties.update_props(texts)
 
@@ -3178,13 +3282,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("tz", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'The time zone to use in labeling dates. If None, defaults to rc value.', 'values': "[['', ':class:`tzinfo` instance']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'The time zone to use in labeling dates. If None, defaults to rc value.', 'values': "[[':class:`tzinfo` instance']]", 'optional': True}),
               ("fmt", "basic:String",
                {'optional': True, 'docstring': 'The plot format string.', 'defaults': "['bo']"}),
               ("ydate", "basic:Boolean",
-               {'optional': True, 'docstring': 'If True, the y-axis will be labeled with dates.', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'If True, the y-axis will be labeled with dates.', 'defaults': '[False]'}),
               ("xdate", "basic:Boolean",
-               {'optional': True, 'docstring': 'If True, the x-axis will be labeled with dates.', 'defaults': "['True']"}),
+               {'optional': True, 'docstring': 'If True, the x-axis will be labeled with dates.', 'defaults': '[True]'}),
               ("y", "basic:List",
                {}),
               ("x", "basic:List",
@@ -3196,39 +3300,43 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplPlotDate)"),
+        ("value", "(MplPlotDate)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('tz'):
-            val = self.getInputFromPort('tz')
+        if self.has_input('tz'):
+            val = self.get_input('tz')
             kwargs['tz'] = val
-        if self.hasInputFromPort('fmt'):
-            val = self.getInputFromPort('fmt')
+        if self.has_input('fmt'):
+            val = self.get_input('fmt')
             kwargs['fmt'] = val
-        if self.hasInputFromPort('ydate'):
-            val = self.getInputFromPort('ydate')
+        if self.has_input('ydate'):
+            val = self.get_input('ydate')
             kwargs['ydate'] = val
-        if self.hasInputFromPort('xdate'):
-            val = self.getInputFromPort('xdate')
+        if self.has_input('xdate'):
+            val = self.get_input('xdate')
             kwargs['xdate'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.plot_date(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -3259,19 +3367,19 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("Fs", "basic:Integer",
-               {'optional': True, 'defaults': "['2']"}),
+               {'optional': True, 'defaults': '[2]'}),
               ("pad_to", "basic:String",
                {'optional': True}),
               ("scale_by_freq", "basic:String",
                {'optional': True}),
               ("detrend", "basic:String",
-               {'optional': True, 'defaults': "['<function detrend_none at 0x02F5A3F0>']"}),
+               {'optional': True}),
               ("window", "basic:String",
-               {'optional': True, 'defaults': "['<function window_hanning at 0x02F5A2B0>']"}),
+               {'optional': True}),
               ("Fc", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("NFFT", "basic:Integer",
-               {'optional': True, 'defaults': "['256']"}),
+               {'optional': True, 'defaults': '[256]'}),
               ("x", "basic:List",
                {}),
               ("hold", "basic:String",
@@ -3279,15 +3387,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("sides", "basic:String",
                {'optional': True, 'defaults': "['default']"}),
               ("noverlap", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("lineProperties", "MplLine2DProperties",
                {'optional': True}),
         ]
 
     _output_ports = [
-        ("self", "(MplPsd)"),
+        ("value", "(MplPsd)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3295,43 +3403,47 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('Fs'):
-            val = self.getInputFromPort('Fs')
+        if self.has_input('Fs'):
+            val = self.get_input('Fs')
             kwargs['Fs'] = val
-        if self.hasInputFromPort('pad_to'):
-            val = self.getInputFromPort('pad_to')
+        if self.has_input('pad_to'):
+            val = self.get_input('pad_to')
             kwargs['pad_to'] = val
-        if self.hasInputFromPort('scale_by_freq'):
-            val = self.getInputFromPort('scale_by_freq')
+        if self.has_input('scale_by_freq'):
+            val = self.get_input('scale_by_freq')
             kwargs['scale_by_freq'] = val
-        if self.hasInputFromPort('detrend'):
-            val = self.getInputFromPort('detrend')
+        if self.has_input('detrend'):
+            val = self.get_input('detrend')
             kwargs['detrend'] = val
-        if self.hasInputFromPort('window'):
-            val = self.getInputFromPort('window')
+        if self.has_input('window'):
+            val = self.get_input('window')
             kwargs['window'] = val
-        if self.hasInputFromPort('Fc'):
-            val = self.getInputFromPort('Fc')
+        if self.has_input('Fc'):
+            val = self.get_input('Fc')
             kwargs['Fc'] = val
-        if self.hasInputFromPort('NFFT'):
-            val = self.getInputFromPort('NFFT')
+        if self.has_input('NFFT'):
+            val = self.get_input('NFFT')
             kwargs['NFFT'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('sides'):
-            val = self.getInputFromPort('sides')
+        if self.has_input('sides'):
+            val = self.get_input('sides')
             kwargs['sides'] = val
-        if self.hasInputFromPort('noverlap'):
-            val = self.getInputFromPort('noverlap')
+        if self.has_input('noverlap'):
+            val = self.get_input('noverlap')
             kwargs['noverlap'] = val
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             properties.update_kwargs(kwargs)
 
-        matplotlib.pyplot.psd(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.psd(*args, **kwargs)
 
 class MplQuiver(MplPlot):
     """Plot a 2-D field of arrows.
@@ -3362,27 +3474,25 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("headaxislength", "basic:Float",
-               {'optional': True, 'docstring': 'Head length at shaft intersection, default is 4.5', 'defaults': "['4.5']"}),
+               {'optional': True, 'docstring': 'Head length at shaft intersection, default is 4.5', 'defaults': '[4.5]'}),
               ("C", "basic:List",
                {'optional': True, 'docstring': 'None'}),
-              ("scale", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'Data units per arrow length unit, e.g. m/s per plot width; a smaller scale parameter makes the arrow longer.  If None, a simple autoscaling algorithm is used, based on the average vector length and the number of vectors.  The arrow length unit is given by the scale_units parameter', 'values': "[['']]", 'optional': True}),
+              ("scale", "basic:List",
+               {'optional': True, 'docstring': 'Data units per arrow length unit, e.g. m/s per plot width; a smaller scale parameter makes the arrow longer.  If None, a simple autoscaling algorithm is used, based on the average vector length and the number of vectors.  The arrow length unit is given by the scale_units parameter'}),
               ("width", "basic:List",
                {'optional': True, 'docstring': 'Shaft width in arrow units; default depends on choice of units, above, and number of vectors; a typical starting value is about 0.005 times the width of the plot.'}),
               ("headlength", "basic:Float",
-               {'optional': True, 'docstring': 'Head length as multiple of shaft width, default is 5', 'defaults': "['5']"}),
+               {'optional': True, 'docstring': 'Head length as multiple of shaft width, default is 5', 'defaults': '[5]'}),
               ("minlength", "basic:Float",
-               {'optional': True, 'docstring': 'Minimum length as a multiple of shaft width; if an arrow length is less than this, plot a dot (hexagon) of this diameter instead. Default is 1.', 'defaults': "['1']"}),
+               {'optional': True, 'docstring': 'Minimum length as a multiple of shaft width; if an arrow length is less than this, plot a dot (hexagon) of this diameter instead. Default is 1.', 'defaults': '[1]'}),
               ("minshaft", "basic:Float",
-               {'optional': True, 'docstring': 'Length below which arrow scales, in units of head length. Do not set this to less than 1, or small arrows will look terrible! Default is 1', 'defaults': "['1']"}),
+               {'optional': True, 'docstring': 'Length below which arrow scales, in units of head length. Do not set this to less than 1, or small arrows will look terrible! Default is 1', 'defaults': '[1]'}),
               ("pivot", "basic:String",
                {'entry_types': "['enum']", 'docstring': 'The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name pivot.', 'values': "[['tail', 'middle', 'tip']]", 'optional': True}),
-              ("unitsSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'For example, if scale_units is \'inches\', scale is 2.0, and (u,v) = (1,0), then the vector will be 0.5 inches long. If scale_units is \'width\', then the vector will be half the width of the axes.\n\nIf scale_units is \'x\' then the vector will be 0.5 x-axis units.  To plot vectors in the x-y plane, with u and v having the same units as x and y, use "angles=\'xy\', scale_units=\'xy\', scale=1".', 'values': "[['width', 'height', 'd [...]
-              ("unitsScalar", "basic:String",
-               {'docstring': 'For example, if scale_units is \'inches\', scale is 2.0, and (u,v) = (1,0), then the vector will be 0.5 inches long. If scale_units is \'width\', then the vector will be half the width of the axes.\n\nIf scale_units is \'x\' then the vector will be 0.5 x-axis units.  To plot vectors in the x-y plane, with u and v having the same units as x and y, use "angles=\'xy\', scale_units=\'xy\', scale=1".', 'optional': True}),
+              ("units", "basic:String",
+               {'entry_types': "['enum']", 'docstring': "Arrow units; the arrow dimensions except for length are in multiples of this unit.\n\n'width' or 'height': the width or height of the axes\n\n'dots' or 'inches': pixels or inches, based on the figure dpi\n\n'x', 'y', or 'xy': X, Y, or sqrt(X^2+Y^2) data units\n\nThe arrows scale differently depending on the units.  For 'x' or 'y', the arrows get larger as one zooms in; for other units, the arrow size is independent of the zoom stat [...]
               ("headwidth", "basic:Float",
-               {'optional': True, 'docstring': 'Head width as multiple of shaft width, default is 3', 'defaults': "['3']"}),
+               {'optional': True, 'docstring': 'Head width as multiple of shaft width, default is 3', 'defaults': '[3]'}),
               ("U", "basic:List",
                {'docstring': 'None'}),
               ("angles", "basic:String",
@@ -3404,76 +3514,77 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplQuiver)"),
+        ("value", "(MplQuiver)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        if self.hasInputFromPort('X'):
-            val = self.getInputFromPort('X')
+        if self.has_input('X'):
+            val = self.get_input('X')
             args.append(val)
-        if self.hasInputFromPort('Y'):
-            val = self.getInputFromPort('Y')
+        if self.has_input('Y'):
+            val = self.get_input('Y')
             args.append(val)
-        val = self.getInputFromPort('U')
+        val = self.get_input('U')
         args.append(val)
-        val = self.getInputFromPort('V')
+        val = self.get_input('V')
         args.append(val)
-        if self.hasInputFromPort('C'):
-            val = self.getInputFromPort('C')
+        if self.has_input('C'):
+            val = self.get_input('C')
             args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('headaxislength'):
-            val = self.getInputFromPort('headaxislength')
+        if self.has_input('headaxislength'):
+            val = self.get_input('headaxislength')
             kwargs['headaxislength'] = val
-        if self.hasInputFromPort('scale'):
-            val = self.getInputFromPort('scale')
+        if self.has_input('scale'):
+            val = self.get_input('scale')
             kwargs['scale'] = val
-        if self.hasInputFromPort('width'):
-            val = self.getInputFromPort('width')
+        if self.has_input('width'):
+            val = self.get_input('width')
             kwargs['width'] = val
-        if self.hasInputFromPort('headlength'):
-            val = self.getInputFromPort('headlength')
+        if self.has_input('headlength'):
+            val = self.get_input('headlength')
             kwargs['headlength'] = val
-        if self.hasInputFromPort('minlength'):
-            val = self.getInputFromPort('minlength')
+        if self.has_input('minlength'):
+            val = self.get_input('minlength')
             kwargs['minlength'] = val
-        if self.hasInputFromPort('minshaft'):
-            val = self.getInputFromPort('minshaft')
+        if self.has_input('minshaft'):
+            val = self.get_input('minshaft')
             kwargs['minshaft'] = val
-        if self.hasInputFromPort('pivot'):
-            val = self.getInputFromPort('pivot')
+        if self.has_input('pivot'):
+            val = self.get_input('pivot')
             kwargs['pivot'] = val
-        if self.hasInputFromPort('unitsSequence'):
-            val = self.getInputFromPort('unitsSequence')
-            kwargs['units'] = val
-        elif self.hasInputFromPort('unitsScalar'):
-            val = self.getInputFromPort('unitsScalar')
+        if self.has_input('units'):
+            val = self.get_input('units')
             kwargs['units'] = val
-        if self.hasInputFromPort('headwidth'):
-            val = self.getInputFromPort('headwidth')
+        if self.has_input('headwidth'):
+            val = self.get_input('headwidth')
             kwargs['headwidth'] = val
-        if self.hasInputFromPort('angles'):
-            val = self.getInputFromPort('angles')
+        if self.has_input('angles'):
+            val = self.get_input('angles')
             kwargs['angles'] = val
-        if self.hasInputFromPort('scale_units'):
-            val = self.getInputFromPort('scale_units')
+        if self.has_input('scale_units'):
+            val = self.get_input('scale_units')
             kwargs['scale_units'] = val
-        if self.hasInputFromPort('colorSequence'):
-            val = self.getInputFromPort('colorSequence')
+        if self.has_input('colorSequence'):
+            val = self.get_input('colorSequence')
             kwargs['color'] = val
-        elif self.hasInputFromPort('colorScalar'):
-            val = self.getInputFromPort('colorScalar')
+        elif self.has_input('colorScalar'):
+            val = self.get_input('colorScalar')
             val = translate_color(val)
             kwargs['color'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polyCollection = matplotlib.pyplot.quiver(*args, **kwargs)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollection is not None:
                 properties.update_props(polyCollection)
 
@@ -3502,9 +3613,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("color", "basic:Color",
                {'optional': True, 'docstring': 'overrides face and edge colors from Q.'}),
               ("coordinatesSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': "Coordinate system and units for X, Y: 'axes' and 'figure' are normalized coordinate systems with 0,0 in the lower left and 1,1 in the upper right; 'data' are the axes data coordinates (used for the locations of the vectors in the quiver plot itself); 'inches' is position in the figure in inches, with 0,0 at the lower left corner.", 'values': "[['axes', 'figure', 'data', 'inches']]", 'optional': True}),
+               {'optional': True, 'docstring': "Coordinate system and units for X, Y: 'axes' and 'figure' are normalized coordinate systems with 0,0 in the lower left and 1,1 in the upper right; 'data' are the axes data coordinates (used for the locations of the vectors in the quiver plot itself); 'inches' is position in the figure in inches, with 0,0 at the lower left corner."}),
               ("coordinatesScalar", "basic:String",
-               {'docstring': "Coordinate system and units for X, Y: 'axes' and 'figure' are normalized coordinate systems with 0,0 in the lower left and 1,1 in the upper right; 'data' are the axes data coordinates (used for the locations of the vectors in the quiver plot itself); 'inches' is position in the figure in inches, with 0,0 at the lower left corner.", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "Coordinate system and units for X, Y: 'axes' and 'figure' are normalized coordinate systems with 0,0 in the lower left and 1,1 in the upper right; 'data' are the axes data coordinates (used for the locations of the vectors in the quiver plot itself); 'inches' is position in the figure in inches, with 0,0 at the lower left corner.", 'values': "[['axes', 'figure', 'data', 'inches']]", 'optional': True}),
               ("label", "basic:String",
                {'docstring': 'A string with the length and units of the key'}),
               ("Q", "basic:String",
@@ -3522,13 +3633,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("X", "basic:String",
                {'docstring': 'The location of the key; additional explanation follows.'}),
               ("labelsep", "basic:Float",
-               {'optional': True, 'docstring': 'Distance in inches between the arrow and the label.  Default is 0.1', 'defaults': "['0.1']"}),
+               {'optional': True, 'docstring': 'Distance in inches between the arrow and the label.  Default is 0.1', 'defaults': '[0.1]'}),
         ]
 
     _output_ports = [
-        ("self", "(MplQuiverkey)"),
+        ("value", "(MplQuiverkey)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3536,41 +3647,45 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('color'):
-            val = self.getInputFromPort('color')
+        if self.has_input('color'):
+            val = self.get_input('color')
             val = translate_color(val)
             kwargs['color'] = val
-        if self.hasInputFromPort('coordinatesSequence'):
-            val = self.getInputFromPort('coordinatesSequence')
+        if self.has_input('coordinatesSequence'):
+            val = self.get_input('coordinatesSequence')
             kwargs['coordinates'] = val
-        elif self.hasInputFromPort('coordinatesScalar'):
-            val = self.getInputFromPort('coordinatesScalar')
+        elif self.has_input('coordinatesScalar'):
+            val = self.get_input('coordinatesScalar')
             kwargs['coordinates'] = val
-        val = self.getInputFromPort('label')
+        val = self.get_input('label')
         kwargs['label'] = val
-        val = self.getInputFromPort('Q')
+        val = self.get_input('Q')
         kwargs['Q'] = val
-        if self.hasInputFromPort('labelcolor'):
-            val = self.getInputFromPort('labelcolor')
+        if self.has_input('labelcolor'):
+            val = self.get_input('labelcolor')
             val = translate_color(val)
             kwargs['labelcolor'] = val
-        if self.hasInputFromPort('fontproperties'):
-            val = self.getInputFromPort('fontproperties')
+        if self.has_input('fontproperties'):
+            val = self.get_input('fontproperties')
             kwargs['fontproperties'] = val
-        val = self.getInputFromPort('U')
+        val = self.get_input('U')
         kwargs['U'] = val
-        if self.hasInputFromPort('labelpos'):
-            val = self.getInputFromPort('labelpos')
+        if self.has_input('labelpos'):
+            val = self.get_input('labelpos')
             kwargs['labelpos'] = val
-        val = self.getInputFromPort('Y')
+        val = self.get_input('Y')
         kwargs['Y'] = val
-        val = self.getInputFromPort('X')
+        val = self.get_input('X')
         kwargs['X'] = val
-        if self.hasInputFromPort('labelsep'):
-            val = self.getInputFromPort('labelsep')
+        if self.has_input('labelsep'):
+            val = self.get_input('labelsep')
             kwargs['labelsep'] = val
 
-        matplotlib.pyplot.quiverkey(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.quiverkey(*args, **kwargs)
 
 class MplScatter(MplPlot):
     """Make a scatter plot.
@@ -3609,19 +3724,19 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("edgecolors", "basic:String",
                {'optional': True, 'docstring': "The string 'none' to plot faces with no outlines"}),
               ("cSequence", "basic:List",
-               {'optional': True, 'docstring': 'a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped.  c can be a 2-D array in which the rows are RGB or RGBA, however.', 'defaults': "['b']"}),
+               {'optional': True, 'docstring': 'a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped.  c can be a 2-D array in which the rows are RGB or RGBA, however.'}),
               ("cScalar", "basic:String",
-               {'docstring': 'a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped.  c can be a 2-D array in which the rows are RGB or RGBA, however.', 'optional': True}),
+               {'docstring': 'a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped.  c can be a 2-D array in which the rows are RGB or RGBA, however.', 'optional': True, 'defaults': "['b']"}),
               ("vmin", "basic:String",
                {'optional': True, 'docstring': 'vmin and vmax are used in conjunction with norm to normalize luminance data.  If either are None, the min and max of the color array C is used.  Note if you pass a norm instance, your settings for vmin and vmax will be ignored.'}),
               ("faceted", "basic:Boolean",
-               {'optional': True, 'defaults': "['True']"}),
-              ("linewidths", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If None, defaults to (lines.linewidth,).  Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.', 'values': "[['']]", 'optional': True}),
+               {'optional': True, 'defaults': '[True]'}),
+              ("linewidths", "basic:List",
+               {'optional': True, 'docstring': 'If None, defaults to (lines.linewidth,).  Note that this is a tuple, and if you set the linewidths argument you must set it as a sequence of floats, as required by :class:`~matplotlib.collections.RegularPolyCollection`.'}),
               ("marker", "basic:String",
                {'optional': True, 'docstring': 'can be one of:\n\n%(MarkerTable)s', 'defaults': "['o']"}),
               ("s", "basic:Float",
-               {'optional': True, 'docstring': 'size in points^2.  It is a scalar or an array of the same length as x and y.', 'defaults': "['20']"}),
+               {'optional': True, 'docstring': 'size in points^2.  It is a scalar or an array of the same length as x and y.', 'defaults': '[20]'}),
               ("cmap", "basic:String",
                {'optional': True, 'docstring': 'A :class:`matplotlib.colors.Colormap` instance or registered name. If None, defaults to rc image.cmap. cmap is only used if c is an array of floats.'}),
               ("verts", "basic:String",
@@ -3643,9 +3758,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplScatter)"),
+        ("value", "(MplScatter)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3653,59 +3768,63 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('vmax'):
-            val = self.getInputFromPort('vmax')
+        if self.has_input('vmax'):
+            val = self.get_input('vmax')
             kwargs['vmax'] = val
-        if self.hasInputFromPort('edgecolors'):
-            val = self.getInputFromPort('edgecolors')
+        if self.has_input('edgecolors'):
+            val = self.get_input('edgecolors')
             kwargs['edgecolors'] = val
-        if self.hasInputFromPort('cSequence'):
-            val = self.getInputFromPort('cSequence')
+        if self.has_input('cSequence'):
+            val = self.get_input('cSequence')
             kwargs['c'] = val
-        elif self.hasInputFromPort('cScalar'):
-            val = self.getInputFromPort('cScalar')
+        elif self.has_input('cScalar'):
+            val = self.get_input('cScalar')
             kwargs['c'] = val
-        if self.hasInputFromPort('vmin'):
-            val = self.getInputFromPort('vmin')
+        if self.has_input('vmin'):
+            val = self.get_input('vmin')
             kwargs['vmin'] = val
-        if self.hasInputFromPort('faceted'):
-            val = self.getInputFromPort('faceted')
+        if self.has_input('faceted'):
+            val = self.get_input('faceted')
             kwargs['faceted'] = val
-        if self.hasInputFromPort('linewidths'):
-            val = self.getInputFromPort('linewidths')
+        if self.has_input('linewidths'):
+            val = self.get_input('linewidths')
             kwargs['linewidths'] = val
-        if self.hasInputFromPort('marker'):
-            val = self.getInputFromPort('marker')
+        if self.has_input('marker'):
+            val = self.get_input('marker')
             kwargs['marker'] = val
-        if self.hasInputFromPort('s'):
-            val = self.getInputFromPort('s')
+        if self.has_input('s'):
+            val = self.get_input('s')
             kwargs['s'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('verts'):
-            val = self.getInputFromPort('verts')
+        if self.has_input('verts'):
+            val = self.get_input('verts')
             kwargs['verts'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('facecolors'):
-            val = self.getInputFromPort('facecolors')
+        if self.has_input('facecolors'):
+            val = self.get_input('facecolors')
             kwargs['facecolors'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         pathCollection = matplotlib.pyplot.scatter(*args, **kwargs)
-        if self.hasInputFromPort('pathCollectionProperties'):
-            properties = self.getInputFromPort('pathCollectionProperties')
+        if self.has_input('pathCollectionProperties'):
+            properties = self.get_input('pathCollectionProperties')
             if pathCollection is not None:
                 properties.update_props(pathCollection)
 
@@ -3733,10 +3852,8 @@ Additional kwargs: hold = [True|False] overrides default hold state
                {'optional': True, 'docstring': 'Base of the x logarithm'}),
               ("nonposx", "basic:String",
                {'entry_types': "['enum']", 'docstring': 'Non-positive values in x can be masked as invalid, or clipped to a very small positive number', 'values': "[['mask', 'clip']]", 'optional': True}),
-              ("subsxSequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'The location of the minor xticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_xscale` for details.', 'values': "[['']]", 'optional': True}),
-              ("subsxScalar", "basic:String",
-               {'docstring': 'The location of the minor xticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_xscale` for details.', 'optional': True}),
+              ("subsx", "basic:List",
+               {'optional': True, 'docstring': 'The location of the minor xticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_xscale` for details.'}),
               ("x", "basic:List",
                {}),
               ("y", "basic:List",
@@ -3746,36 +3863,37 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplSemilogx)"),
+        ("value", "(MplSemilogx)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('basex'):
-            val = self.getInputFromPort('basex')
+        if self.has_input('basex'):
+            val = self.get_input('basex')
             kwargs['basex'] = val
-        if self.hasInputFromPort('nonposx'):
-            val = self.getInputFromPort('nonposx')
+        if self.has_input('nonposx'):
+            val = self.get_input('nonposx')
             kwargs['nonposx'] = val
-        if self.hasInputFromPort('subsxSequence'):
-            val = self.getInputFromPort('subsxSequence')
-            kwargs['subsx'] = val
-        elif self.hasInputFromPort('subsxScalar'):
-            val = self.getInputFromPort('subsxScalar')
+        if self.has_input('subsx'):
+            val = self.get_input('subsx')
             kwargs['subsx'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.semilogx(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -3803,10 +3921,8 @@ Additional kwargs: hold = [True|False] overrides default hold state
                {'optional': True, 'docstring': 'Base of the y logarithm'}),
               ("nonposy", "basic:String",
                {'entry_types': "['enum']", 'docstring': 'Non-positive values in y can be masked as invalid, or clipped to a very small positive number', 'values': "[['mask', 'clip']]", 'optional': True}),
-              ("subsySequence", "basic:List",
-               {'entry_types': "['enum']", 'docstring': 'The location of the minor yticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_yscale` for details.', 'values': "[['']]", 'optional': True}),
-              ("subsyScalar", "basic:String",
-               {'docstring': 'The location of the minor yticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_yscale` for details.', 'optional': True}),
+              ("subsy", "basic:List",
+               {'optional': True, 'docstring': 'The location of the minor yticks; None defaults to autosubs, which depend on the number of decades in the plot; see :meth:`~matplotlib.axes.Axes.set_yscale` for details.'}),
               ("y", "basic:List",
                {}),
               ("x", "basic:List",
@@ -3816,36 +3932,37 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplSemilogy)"),
+        ("value", "(MplSemilogy)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('basey'):
-            val = self.getInputFromPort('basey')
+        if self.has_input('basey'):
+            val = self.get_input('basey')
             kwargs['basey'] = val
-        if self.hasInputFromPort('nonposy'):
-            val = self.getInputFromPort('nonposy')
+        if self.has_input('nonposy'):
+            val = self.get_input('nonposy')
             kwargs['nonposy'] = val
-        if self.hasInputFromPort('subsySequence'):
-            val = self.getInputFromPort('subsySequence')
-            kwargs['subsy'] = val
-        elif self.hasInputFromPort('subsyScalar'):
-            val = self.getInputFromPort('subsyScalar')
+        if self.has_input('subsy'):
+            val = self.get_input('subsy')
             kwargs['subsy'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.semilogy(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -3882,7 +3999,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("Fs", "basic:Integer",
-               {'optional': True, 'defaults': "['2']"}),
+               {'optional': True, 'defaults': '[2]'}),
               ("pad_to", "basic:String",
                {'optional': True}),
               ("scale_by_freq", "basic:String",
@@ -3890,13 +4007,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("xextent", "basic:String",
                {'optional': True}),
               ("detrend", "basic:String",
-               {'optional': True, 'defaults': "['<function detrend_none at 0x02F5A3F0>']"}),
+               {'optional': True}),
               ("window", "basic:String",
-               {'optional': True, 'defaults': "['<function window_hanning at 0x02F5A2B0>']"}),
+               {'optional': True}),
               ("Fc", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("NFFT", "basic:Integer",
-               {'optional': True, 'defaults': "['256']"}),
+               {'optional': True, 'defaults': '[256]'}),
               ("cmap", "basic:String",
                {'optional': True}),
               ("x", "basic:List",
@@ -3906,13 +4023,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("sides", "basic:String",
                {'optional': True, 'defaults': "['default']"}),
               ("noverlap", "basic:Integer",
-               {'optional': True, 'defaults': "['128']"}),
+               {'optional': True, 'defaults': '[128]'}),
         ]
 
     _output_ports = [
-        ("self", "(MplSpecgram)"),
+        ("value", "(MplSpecgram)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3920,46 +4037,50 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('Fs'):
-            val = self.getInputFromPort('Fs')
+        if self.has_input('Fs'):
+            val = self.get_input('Fs')
             kwargs['Fs'] = val
-        if self.hasInputFromPort('pad_to'):
-            val = self.getInputFromPort('pad_to')
+        if self.has_input('pad_to'):
+            val = self.get_input('pad_to')
             kwargs['pad_to'] = val
-        if self.hasInputFromPort('scale_by_freq'):
-            val = self.getInputFromPort('scale_by_freq')
+        if self.has_input('scale_by_freq'):
+            val = self.get_input('scale_by_freq')
             kwargs['scale_by_freq'] = val
-        if self.hasInputFromPort('xextent'):
-            val = self.getInputFromPort('xextent')
+        if self.has_input('xextent'):
+            val = self.get_input('xextent')
             kwargs['xextent'] = val
-        if self.hasInputFromPort('detrend'):
-            val = self.getInputFromPort('detrend')
+        if self.has_input('detrend'):
+            val = self.get_input('detrend')
             kwargs['detrend'] = val
-        if self.hasInputFromPort('window'):
-            val = self.getInputFromPort('window')
+        if self.has_input('window'):
+            val = self.get_input('window')
             kwargs['window'] = val
-        if self.hasInputFromPort('Fc'):
-            val = self.getInputFromPort('Fc')
+        if self.has_input('Fc'):
+            val = self.get_input('Fc')
             kwargs['Fc'] = val
-        if self.hasInputFromPort('NFFT'):
-            val = self.getInputFromPort('NFFT')
+        if self.has_input('NFFT'):
+            val = self.get_input('NFFT')
             kwargs['NFFT'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('sides'):
-            val = self.getInputFromPort('sides')
+        if self.has_input('sides'):
+            val = self.get_input('sides')
             kwargs['sides'] = val
-        if self.hasInputFromPort('noverlap'):
-            val = self.getInputFromPort('noverlap')
+        if self.has_input('noverlap'):
+            val = self.get_input('noverlap')
             kwargs['noverlap'] = val
 
-        matplotlib.pyplot.specgram(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.specgram(*args, **kwargs)
 
 class MplStackplot(MplPlot):
     """Draws a stacked area plot.
@@ -3980,9 +4101,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplStackplot)"),
+        ("value", "(MplStackplot)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -3990,14 +4111,18 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
 
-        matplotlib.pyplot.stackplot(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.stackplot(*args, **kwargs)
 
 class MplStem(MplPlot):
     """Create a stem plot.
@@ -4040,9 +4165,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplStem)"),
+        ("value", "(MplStem)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4050,43 +4175,47 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('bottom'):
-            val = self.getInputFromPort('bottom')
+        if self.has_input('bottom'):
+            val = self.get_input('bottom')
             kwargs['bottom'] = val
-        if self.hasInputFromPort('label'):
-            val = self.getInputFromPort('label')
+        if self.has_input('label'):
+            val = self.get_input('label')
             kwargs['label'] = val
-        if self.hasInputFromPort('linefmt'):
-            val = self.getInputFromPort('linefmt')
+        if self.has_input('linefmt'):
+            val = self.get_input('linefmt')
             kwargs['linefmt'] = val
-        if self.hasInputFromPort('markerfmt'):
-            val = self.getInputFromPort('markerfmt')
+        if self.has_input('markerfmt'):
+            val = self.get_input('markerfmt')
             kwargs['markerfmt'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('basefmt'):
-            val = self.getInputFromPort('basefmt')
+        if self.has_input('basefmt'):
+            val = self.get_input('basefmt')
             kwargs['basefmt'] = val
 
-        output = matplotlib.pyplot.stem(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.stem(*args, **kwargs)
         markerline = output[0]
         stemlines = output[1]
         baseline = output[2]
-        if self.hasInputFromPort('stemlineProperties'):
-            properties = self.getInputFromPort('stemlineProperties')
+        if self.has_input('stemlineProperties'):
+            properties = self.get_input('stemlineProperties')
             if stemlines is not None:
                 properties.update_props(stemlines)
-        if self.hasInputFromPort('markerlineProperties'):
-            properties = self.getInputFromPort('markerlineProperties')
+        if self.has_input('markerlineProperties'):
+            properties = self.get_input('markerlineProperties')
             if markerline is not None:
                 properties.update_props(markerline)
-        if self.hasInputFromPort('baselineProperties'):
-            properties = self.getInputFromPort('baselineProperties')
+        if self.has_input('baselineProperties'):
+            properties = self.get_input('baselineProperties')
             if baseline is not None:
                 properties.update_props(baseline)
 
@@ -4117,27 +4246,31 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplStep)"),
+        ("value", "(MplStep)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('where'):
-            val = self.getInputFromPort('where')
+        if self.has_input('where'):
+            val = self.get_input('where')
             kwargs['where'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.step(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -4154,15 +4287,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("arrowstyle", "basic:String",
                {'optional': True, 'defaults': "['-|>']"}),
               ("density", "basic:Integer",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("color", "basic:String",
                {'optional': True}),
               ("minlength", "basic:Float",
-               {'optional': True, 'defaults': "['0.1']"}),
+               {'optional': True, 'defaults': '[0.1]'}),
               ("transform", "basic:String",
                {'optional': True}),
               ("arrowsize", "basic:Integer",
-               {'optional': True, 'defaults': "['1']"}),
+               {'optional': True, 'defaults': '[1]'}),
               ("cmap", "basic:String",
                {'optional': True}),
               ("u", "basic:String",
@@ -4180,9 +4313,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplStreamplot)"),
+        ("value", "(MplStreamplot)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4190,46 +4323,50 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('arrowstyle'):
-            val = self.getInputFromPort('arrowstyle')
+        if self.has_input('arrowstyle'):
+            val = self.get_input('arrowstyle')
             kwargs['arrowstyle'] = val
-        if self.hasInputFromPort('density'):
-            val = self.getInputFromPort('density')
+        if self.has_input('density'):
+            val = self.get_input('density')
             kwargs['density'] = val
-        if self.hasInputFromPort('color'):
-            val = self.getInputFromPort('color')
+        if self.has_input('color'):
+            val = self.get_input('color')
             kwargs['color'] = val
-        if self.hasInputFromPort('minlength'):
-            val = self.getInputFromPort('minlength')
+        if self.has_input('minlength'):
+            val = self.get_input('minlength')
             kwargs['minlength'] = val
-        if self.hasInputFromPort('transform'):
-            val = self.getInputFromPort('transform')
+        if self.has_input('transform'):
+            val = self.get_input('transform')
             kwargs['transform'] = val
-        if self.hasInputFromPort('arrowsize'):
-            val = self.getInputFromPort('arrowsize')
+        if self.has_input('arrowsize'):
+            val = self.get_input('arrowsize')
             kwargs['arrowsize'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        val = self.getInputFromPort('u')
+        val = self.get_input('u')
         kwargs['u'] = val
-        val = self.getInputFromPort('v')
+        val = self.get_input('v')
         kwargs['v'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('linewidth'):
-            val = self.getInputFromPort('linewidth')
+        if self.has_input('linewidth'):
+            val = self.get_input('linewidth')
             kwargs['linewidth'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
-        matplotlib.pyplot.streamplot(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.streamplot(*args, **kwargs)
 
 class MplTricontour(MplPlot):
     """Draw contours on an unstructured triangular grid. :func:`~matplotlib.pyplot.tricontour` and :func:`~matplotlib.pyplot.tricontourf` draw contour lines and filled contours, respectively.  Except as noted, function signatures and return values are the same for both versions.
@@ -4296,33 +4433,33 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("origin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['', 'upper', 'lower', 'image']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['upper', 'lower', 'image']]", 'optional': True}),
               ("linestyles", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the 'solid' is used.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.\n\nIf contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.", 'values': "[['', 's [...]
+               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the 'solid' is used.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.\n\nIf contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.", 'values': "[['solid [...]
               ("levelsSequence", "basic:List",
                {'optional': True, 'docstring': 'A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]'}),
               ("levelsScalar", "basic:Float",
                {'docstring': 'A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]', 'optional': True}),
               ("linewidths", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['', 'number', 'tuple of numbers']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['number', 'tuple of numbers']]", 'optional': True}),
               ("colors", "basic:Color",
-               {'entry_types': "['enum']", 'docstring': "If None, the colormap specified by cmap will be used.\n\nIf a string, like 'r' or 'red', all levels will be plotted in this color.\n\nIf a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.", 'values': "[['', '(mpl_colors)']]", 'optional': True}),
+               {'optional': True, 'docstring': "If None, the colormap specified by cmap will be used.\n\nIf a string, like 'r' or 'red', all levels will be plotted in this color.\n\nIf a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified."}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.', 'values': "[['', 'Colormap']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.', 'values': "[['Colormap']]", 'optional': True}),
               ("antialiased", "basic:Boolean",
                {'optional': True, 'docstring': 'enable antialiasing'}),
               ("nchunk", "basic:Integer",
-               {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': '[[0]]', 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': "[['0']]", 'optional': True}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'The alpha blending value'}),
               ("norm", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.', 'values': "[['', 'Normalize']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.', 'values': "[['Normalize']]", 'optional': True}),
         ]
 
     _output_ports = [
-        ("self", "(MplTricontour)"),
+        ("value", "(MplTricontour)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4330,42 +4467,46 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('origin'):
-            val = self.getInputFromPort('origin')
+        if self.has_input('origin'):
+            val = self.get_input('origin')
             kwargs['origin'] = val
-        if self.hasInputFromPort('linestyles'):
-            val = self.getInputFromPort('linestyles')
+        if self.has_input('linestyles'):
+            val = self.get_input('linestyles')
             kwargs['linestyles'] = val
-        if self.hasInputFromPort('levelsSequence'):
-            val = self.getInputFromPort('levelsSequence')
+        if self.has_input('levelsSequence'):
+            val = self.get_input('levelsSequence')
             kwargs['levels'] = val
-        elif self.hasInputFromPort('levelsScalar'):
-            val = self.getInputFromPort('levelsScalar')
+        elif self.has_input('levelsScalar'):
+            val = self.get_input('levelsScalar')
             kwargs['levels'] = val
-        if self.hasInputFromPort('linewidths'):
-            val = self.getInputFromPort('linewidths')
+        if self.has_input('linewidths'):
+            val = self.get_input('linewidths')
             kwargs['linewidths'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('antialiased'):
-            val = self.getInputFromPort('antialiased')
+        if self.has_input('antialiased'):
+            val = self.get_input('antialiased')
             kwargs['antialiased'] = val
-        if self.hasInputFromPort('nchunk'):
-            val = self.getInputFromPort('nchunk')
+        if self.has_input('nchunk'):
+            val = self.get_input('nchunk')
             kwargs['nchunk'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
-        matplotlib.pyplot.tricontour(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.tricontour(*args, **kwargs)
 
 class MplTricontourf(MplPlot):
     """Draw contours on an unstructured triangular grid. :func:`~matplotlib.pyplot.tricontour` and :func:`~matplotlib.pyplot.tricontourf` draw contour lines and filled contours, respectively.  Except as noted, function signatures and return values are the same for both versions.
@@ -4432,33 +4573,33 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("origin", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['', 'upper', 'lower', 'image']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': "If None, the first value of Z will correspond to the lower left corner, location (0,0). If 'image', the rc value for image.origin will be used.\n\nThis keyword is not active if X and Y are specified in the call to contour.", 'values': "[['upper', 'lower', 'image']]", 'optional': True}),
               ("linestyles", "basic:String",
-               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the 'solid' is used.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.\n\nIf contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.", 'values': "[['', 's [...]
+               {'entry_types': "['enum']", 'docstring': "If linestyles is None, the 'solid' is used.\n\nlinestyles can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary.\n\nIf contour is using a monochrome colormap and the contour level is less than 0, then the linestyle specified in contour.negative_linestyle in matplotlibrc will be used.", 'values': "[['solid [...]
               ("levelsSequence", "basic:List",
                {'optional': True, 'docstring': 'A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]'}),
               ("levelsScalar", "basic:Float",
                {'docstring': 'A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass levels=[0]', 'optional': True}),
               ("linewidths", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['', 'number', 'tuple of numbers']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If linewidths is None, the default width in lines.linewidth in matplotlibrc is used.\n\nIf a number, all levels will be plotted with this linewidth.\n\nIf a tuple, different levels will be plotted with different linewidths in the order specified', 'values': "[['number', 'tuple of numbers']]", 'optional': True}),
               ("colors", "basic:Color",
-               {'entry_types': "['enum']", 'docstring': "If None, the colormap specified by cmap will be used.\n\nIf a string, like 'r' or 'red', all levels will be plotted in this color.\n\nIf a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified.", 'values': "[['', '(mpl_colors)']]", 'optional': True}),
+               {'optional': True, 'docstring': "If None, the colormap specified by cmap will be used.\n\nIf a string, like 'r' or 'red', all levels will be plotted in this color.\n\nIf a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified."}),
               ("cmap", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.', 'values': "[['', 'Colormap']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A cm :class:`~matplotlib.colors.Colormap` instance or None. If cmap is None and colors is None, a default Colormap is used.', 'values': "[['Colormap']]", 'optional': True}),
               ("antialiased", "basic:Boolean",
                {'optional': True, 'docstring': 'enable antialiasing'}),
               ("nchunk", "basic:Integer",
-               {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': '[[0]]', 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of roughly nchunk by nchunk points. This may never actually be advantageous, so this option may be removed. Chunking introduces artifacts at the chunk boundaries unless antialiased is False.', 'values': "[['0']]", 'optional': True}),
               ("alpha", "basic:Float",
                {'optional': True, 'docstring': 'The alpha blending value'}),
               ("norm", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.', 'values': "[['', 'Normalize']]", 'optional': True}),
+               {'entry_types': "['enum']", 'docstring': 'A :class:`matplotlib.colors.Normalize` instance for scaling data values to colors. If norm is None and colors is None, the default linear scaling is used.', 'values': "[['Normalize']]", 'optional': True}),
         ]
 
     _output_ports = [
-        ("self", "(MplTricontourf)"),
+        ("value", "(MplTricontourf)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4466,42 +4607,46 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('origin'):
-            val = self.getInputFromPort('origin')
+        if self.has_input('origin'):
+            val = self.get_input('origin')
             kwargs['origin'] = val
-        if self.hasInputFromPort('linestyles'):
-            val = self.getInputFromPort('linestyles')
+        if self.has_input('linestyles'):
+            val = self.get_input('linestyles')
             kwargs['linestyles'] = val
-        if self.hasInputFromPort('levelsSequence'):
-            val = self.getInputFromPort('levelsSequence')
+        if self.has_input('levelsSequence'):
+            val = self.get_input('levelsSequence')
             kwargs['levels'] = val
-        elif self.hasInputFromPort('levelsScalar'):
-            val = self.getInputFromPort('levelsScalar')
+        elif self.has_input('levelsScalar'):
+            val = self.get_input('levelsScalar')
             kwargs['levels'] = val
-        if self.hasInputFromPort('linewidths'):
-            val = self.getInputFromPort('linewidths')
+        if self.has_input('linewidths'):
+            val = self.get_input('linewidths')
             kwargs['linewidths'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             val = translate_color(val)
             kwargs['colors'] = val
-        if self.hasInputFromPort('cmap'):
-            val = self.getInputFromPort('cmap')
+        if self.has_input('cmap'):
+            val = self.get_input('cmap')
             kwargs['cmap'] = val
-        if self.hasInputFromPort('antialiased'):
-            val = self.getInputFromPort('antialiased')
+        if self.has_input('antialiased'):
+            val = self.get_input('antialiased')
             kwargs['antialiased'] = val
-        if self.hasInputFromPort('nchunk'):
-            val = self.getInputFromPort('nchunk')
+        if self.has_input('nchunk'):
+            val = self.get_input('nchunk')
             kwargs['nchunk'] = val
-        if self.hasInputFromPort('alpha'):
-            val = self.getInputFromPort('alpha')
+        if self.has_input('alpha'):
+            val = self.get_input('alpha')
             kwargs['alpha'] = val
-        if self.hasInputFromPort('norm'):
-            val = self.getInputFromPort('norm')
+        if self.has_input('norm'):
+            val = self.get_input('norm')
             kwargs['norm'] = val
 
-        matplotlib.pyplot.tricontourf(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.tricontourf(*args, **kwargs)
 
 class MplTripcolor(MplPlot):
     """Create a pseudocolor plot of an unstructured triangular grid.
@@ -4532,9 +4677,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplTripcolor)"),
+        ("value", "(MplTripcolor)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4543,7 +4688,11 @@ Additional kwargs: hold = [True|False] overrides default hold state
 
         kwargs = {}
 
-        matplotlib.pyplot.tripcolor(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.tripcolor(*args, **kwargs)
 
 class MplTriplot(MplPlot):
     """Draw a unstructured triangular grid as lines and/or markers.
@@ -4570,9 +4719,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplTriplot)"),
+        ("value", "(MplTriplot)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4581,7 +4730,11 @@ Additional kwargs: hold = [True|False] overrides default hold state
 
         kwargs = {}
 
-        matplotlib.pyplot.triplot(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.triplot(*args, **kwargs)
 
 class MplVlines(MplPlot):
     """Plot vertical lines.
@@ -4622,9 +4775,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplVlines)"),
+        ("value", "(MplVlines)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4632,29 +4785,33 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        val = self.getInputFromPort('ymax')
+        val = self.get_input('ymax')
         kwargs['ymax'] = val
-        if self.hasInputFromPort('linestyles'):
-            val = self.getInputFromPort('linestyles')
+        if self.has_input('linestyles'):
+            val = self.get_input('linestyles')
             kwargs['linestyles'] = val
-        if self.hasInputFromPort('color'):
-            val = self.getInputFromPort('color')
+        if self.has_input('color'):
+            val = self.get_input('color')
             kwargs['color'] = val
-        if self.hasInputFromPort('label'):
-            val = self.getInputFromPort('label')
+        if self.has_input('label'):
+            val = self.get_input('label')
             kwargs['label'] = val
-        if self.hasInputFromPort('colors'):
-            val = self.getInputFromPort('colors')
+        if self.has_input('colors'):
+            val = self.get_input('colors')
             kwargs['colors'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        val = self.getInputFromPort('ymin')
+        val = self.get_input('ymin')
         kwargs['ymin'] = val
 
-        matplotlib.pyplot.vlines(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.vlines(*args, **kwargs)
 
 class MplXcorr(MplPlot):
     """Plot the cross correlation between x and y.
@@ -4691,13 +4848,13 @@ Additional kwargs: hold = [True|False] overrides default hold state
     """
     _input_ports = [
               ("normed", "basic:Boolean",
-               {'optional': True, 'defaults': "['True']"}),
+               {'optional': True, 'defaults': '[True]'}),
               ("usevlines", "basic:Boolean",
-               {'optional': True, 'defaults': "['True']"}),
+               {'optional': True, 'defaults': '[True]'}),
               ("detrend", "basic:String",
-               {'optional': True, 'defaults': "['<function detrend_none at 0x02F5A3F0>']"}),
+               {'optional': True}),
               ("maxlags", "basic:Integer",
-               {'optional': True, 'defaults': "['10']"}),
+               {'optional': True, 'defaults': '[10]'}),
               ("y", "basic:List",
                {}),
               ("x", "basic:List",
@@ -4713,9 +4870,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplXcorr)"),
+        ("value", "(MplXcorr)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4723,27 +4880,31 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('normed'):
-            val = self.getInputFromPort('normed')
+        if self.has_input('normed'):
+            val = self.get_input('normed')
             kwargs['normed'] = val
-        if self.hasInputFromPort('usevlines'):
-            val = self.getInputFromPort('usevlines')
+        if self.has_input('usevlines'):
+            val = self.get_input('usevlines')
             kwargs['usevlines'] = val
-        if self.hasInputFromPort('detrend'):
-            val = self.getInputFromPort('detrend')
+        if self.has_input('detrend'):
+            val = self.get_input('detrend')
             kwargs['detrend'] = val
-        if self.hasInputFromPort('maxlags'):
-            val = self.getInputFromPort('maxlags')
+        if self.has_input('maxlags'):
+            val = self.get_input('maxlags')
             kwargs['maxlags'] = val
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         kwargs['y'] = val
-        val = self.getInputFromPort('x')
+        val = self.get_input('x')
         kwargs['x'] = val
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
 
-        output = matplotlib.pyplot.xcorr(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.xcorr(*args, **kwargs)
         if 'usevlines' in kwargs and kwargs['usevlines']:
             output = output + (output[2],)
         else:
@@ -4751,16 +4912,16 @@ Additional kwargs: hold = [True|False] overrides default hold state
         lines = output[2]
         xaxis = output[3]
         lineCollection = output[4]
-        if self.hasInputFromPort('lineCollectionProperties'):
-            properties = self.getInputFromPort('lineCollectionProperties')
+        if self.has_input('lineCollectionProperties'):
+            properties = self.get_input('lineCollectionProperties')
             if lineCollection is not None:
                 properties.update_props(lineCollection)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
-        if self.hasInputFromPort('xaxisProperties'):
-            properties = self.getInputFromPort('xaxisProperties')
+        if self.has_input('xaxisProperties'):
+            properties = self.get_input('xaxisProperties')
             if xaxis is not None:
                 properties.update_props(xaxis)
 
@@ -4811,15 +4972,15 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("sizes", "basic:Dictionary",
                {'optional': True, 'docstring': "A dictionary of coefficients specifying the ratio of a given feature to the length of the barb. Only those values one wishes to override need to be included.  These features include:\n\n'spacing' - space between features (flags, full/half barbs)\n\n'height' - height (distance from shaft to top) of a flag or full barb\n\n'width' - width of a flag, twice the width of a full barb\n\n'emptybarb' - radius of the circle used for low magnitudes"}),
               ("rounding", "basic:Boolean",
-               {'optional': True, 'docstring': 'A flag to indicate whether the vector magnitude should be rounded when allocating barb components.  If True, the magnitude is rounded to the nearest multiple of the half-barb increment.  If False, the magnitude is simply truncated to the next lowest multiple.  Default is True', 'defaults': "['True']"}),
+               {'optional': True, 'docstring': 'A flag to indicate whether the vector magnitude should be rounded when allocating barb components.  If True, the magnitude is rounded to the nearest multiple of the half-barb increment.  If False, the magnitude is simply truncated to the next lowest multiple.  Default is True', 'defaults': '[True]'}),
               ("pivot", "basic:String",
                {'entry_types': "['enum']", 'docstring': "The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name pivot.  Default is 'tip'", 'values': "[['tip', 'middle']]", 'optional': True, 'defaults': "['tip']"}),
               ("flip_barb", "basic:Boolean",
-               {'optional': True, 'docstring': 'Either a single boolean flag or an array of booleans.  Single boolean indicates whether the lines and flags should point opposite to normal for all barbs.  An array (which should be the same size as the other data arrays) indicates whether to flip for each individual barb.  Normal behavior is for the barbs and lines to point right (comes from wind barbs having these features point towards low pressure in the Northern Hemisphere.)  Default i [...]
+               {'optional': True, 'docstring': 'Either a single boolean flag or an array of booleans.  Single boolean indicates whether the lines and flags should point opposite to normal for all barbs.  An array (which should be the same size as the other data arrays) indicates whether to flip for each individual barb.  Normal behavior is for the barbs and lines to point right (comes from wind barbs having these features point towards low pressure in the Northern Hemisphere.)  Default i [...]
               ("flip_barbSequence", "basic:List",
                {'docstring': 'Either a single boolean flag or an array of booleans.  Single boolean indicates whether the lines and flags should point opposite to normal for all barbs.  An array (which should be the same size as the other data arrays) indicates whether to flip for each individual barb.  Normal behavior is for the barbs and lines to point right (comes from wind barbs having these features point towards low pressure in the Northern Hemisphere.)  Default is False', 'optiona [...]
               ("length", "basic:Integer",
-               {'optional': True, 'docstring': 'Length of the barb in points; the other parts of the barb are scaled against this. Default is 9', 'defaults': "['9']"}),
+               {'optional': True, 'docstring': 'Length of the barb in points; the other parts of the barb are scaled against this. Default is 9', 'defaults': '[9]'}),
               ("barb_increments", "basic:Dictionary",
                {'optional': True, 'docstring': "A dictionary of increments specifying values to associate with different parts of the barb. Only those values one wishes to override need to be included.\n\n'half' - half barbs (Default is 5)\n\n'full' - full barbs (Default is 10)\n\n'flag' - flags (default is 50)"}),
               ("U", "basic:List",
@@ -4835,77 +4996,81 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("flagcolorSequence", "basic:List",
                {'docstring': 'Specifies the color of any flags on the barb.  This parameter is analagous to the facecolor parameter for polygons, which can be used instead. However this parameter will override facecolor.  If this is not set (and C has not either) then flagcolor will be set to match barbcolor so that the barb has a uniform color. If C has been set, flagcolor has no effect.', 'optional': True}),
               ("fill_empty", "basic:Boolean",
-               {'optional': True, 'docstring': 'A flag on whether the empty barbs (circles) that are drawn should be filled with the flag color.  If they are not filled, they will be drawn such that no color is applied to the center.  Default is False', 'defaults': "['False']"}),
+               {'optional': True, 'docstring': 'A flag on whether the empty barbs (circles) that are drawn should be filled with the flag color.  If they are not filled, they will be drawn such that no color is applied to the center.  Default is False', 'defaults': '[False]'}),
               ("polyCollectionProperties", "MplPolyCollectionProperties",
                {}),
         ]
 
     _output_ports = [
-        ("self", "(MplBarbs)"),
+        ("value", "(MplBarbs)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        if self.hasInputFromPort('X'):
-            val = self.getInputFromPort('X')
+        if self.has_input('X'):
+            val = self.get_input('X')
             args.append(val)
-        if self.hasInputFromPort('Y'):
-            val = self.getInputFromPort('Y')
+        if self.has_input('Y'):
+            val = self.get_input('Y')
             args.append(val)
-        val = self.getInputFromPort('U')
+        val = self.get_input('U')
         args.append(val)
-        val = self.getInputFromPort('V')
+        val = self.get_input('V')
         args.append(val)
-        if self.hasInputFromPort('C'):
-            val = self.getInputFromPort('C')
+        if self.has_input('C'):
+            val = self.get_input('C')
             args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('barbcolor'):
-            val = self.getInputFromPort('barbcolor')
+        if self.has_input('barbcolor'):
+            val = self.get_input('barbcolor')
             val = translate_color(val)
             kwargs['barbcolor'] = val
-        elif self.hasInputFromPort('barbcolorSequence'):
-            val = self.getInputFromPort('barbcolorSequence')
+        elif self.has_input('barbcolorSequence'):
+            val = self.get_input('barbcolorSequence')
             kwargs['barbcolor'] = val
-        if self.hasInputFromPort('sizes'):
-            val = self.getInputFromPort('sizes')
+        if self.has_input('sizes'):
+            val = self.get_input('sizes')
             kwargs['sizes'] = val
-        if self.hasInputFromPort('rounding'):
-            val = self.getInputFromPort('rounding')
+        if self.has_input('rounding'):
+            val = self.get_input('rounding')
             kwargs['rounding'] = val
-        if self.hasInputFromPort('pivot'):
-            val = self.getInputFromPort('pivot')
+        if self.has_input('pivot'):
+            val = self.get_input('pivot')
             kwargs['pivot'] = val
-        if self.hasInputFromPort('flip_barb'):
-            val = self.getInputFromPort('flip_barb')
+        if self.has_input('flip_barb'):
+            val = self.get_input('flip_barb')
             kwargs['flip_barb'] = val
-        elif self.hasInputFromPort('flip_barbSequence'):
-            val = self.getInputFromPort('flip_barbSequence')
+        elif self.has_input('flip_barbSequence'):
+            val = self.get_input('flip_barbSequence')
             kwargs['flip_barb'] = val
-        if self.hasInputFromPort('length'):
-            val = self.getInputFromPort('length')
+        if self.has_input('length'):
+            val = self.get_input('length')
             kwargs['length'] = val
-        if self.hasInputFromPort('barb_increments'):
-            val = self.getInputFromPort('barb_increments')
+        if self.has_input('barb_increments'):
+            val = self.get_input('barb_increments')
             kwargs['barb_increments'] = val
-        if self.hasInputFromPort('flagcolor'):
-            val = self.getInputFromPort('flagcolor')
+        if self.has_input('flagcolor'):
+            val = self.get_input('flagcolor')
             val = translate_color(val)
             kwargs['flagcolor'] = val
-        elif self.hasInputFromPort('flagcolorSequence'):
-            val = self.getInputFromPort('flagcolorSequence')
+        elif self.has_input('flagcolorSequence'):
+            val = self.get_input('flagcolorSequence')
             kwargs['flagcolor'] = val
-        if self.hasInputFromPort('fill_empty'):
-            val = self.getInputFromPort('fill_empty')
+        if self.has_input('fill_empty'):
+            val = self.get_input('fill_empty')
             kwargs['fill_empty'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         polyCollection = matplotlib.pyplot.barbs(*args, **kwargs)
-        if self.hasInputFromPort('polyCollectionProperties'):
-            properties = self.getInputFromPort('polyCollectionProperties')
+        if self.has_input('polyCollectionProperties'):
+            properties = self.get_input('polyCollectionProperties')
             if polyCollection is not None:
                 properties.update_props(polyCollection)
 
@@ -4966,7 +5131,7 @@ Additional kwargs: hold = [True|False] overrides default hold state
               ("markersize", "basic:String",
                {'optional': True}),
               ("precision", "basic:Integer",
-               {'optional': True, 'defaults': "['0']"}),
+               {'optional': True, 'defaults': '[0]'}),
               ("aspect", "basic:String",
                {'optional': True, 'defaults': "['equal']"}),
               ("marker", "basic:String",
@@ -4980,9 +5145,9 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplSpy)"),
+        ("value", "(MplSpy)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -4990,25 +5155,29 @@ Additional kwargs: hold = [True|False] overrides default hold state
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('hold'):
-            val = self.getInputFromPort('hold')
+        if self.has_input('hold'):
+            val = self.get_input('hold')
             kwargs['hold'] = val
-        if self.hasInputFromPort('markersize'):
-            val = self.getInputFromPort('markersize')
+        if self.has_input('markersize'):
+            val = self.get_input('markersize')
             kwargs['markersize'] = val
-        if self.hasInputFromPort('precision'):
-            val = self.getInputFromPort('precision')
+        if self.has_input('precision'):
+            val = self.get_input('precision')
             kwargs['precision'] = val
-        if self.hasInputFromPort('aspect'):
-            val = self.getInputFromPort('aspect')
+        if self.has_input('aspect'):
+            val = self.get_input('aspect')
             kwargs['aspect'] = val
-        if self.hasInputFromPort('marker'):
-            val = self.getInputFromPort('marker')
+        if self.has_input('marker'):
+            val = self.get_input('marker')
             kwargs['marker'] = val
-        val = self.getInputFromPort('Z')
+        val = self.get_input('Z')
         kwargs['Z'] = val
 
-        output = matplotlib.pyplot.spy(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        output = matplotlib.pyplot.spy(*args, **kwargs)
         if "marker" not in kwargs and "markersize" not in kwargs and \
                 not hasattr(kwargs["Z"], 'tocoo'):
             output = (output, None)
@@ -5016,12 +5185,12 @@ Additional kwargs: hold = [True|False] overrides default hold state
             output = (None, output)
         image = output[0]
         marks = output[1]
-        if self.hasInputFromPort('imageProperties'):
-            properties = self.getInputFromPort('imageProperties')
+        if self.has_input('imageProperties'):
+            properties = self.get_input('imageProperties')
             if image is not None:
                 properties.update_props(image)
-        if self.hasInputFromPort('marksProperties'):
-            properties = self.getInputFromPort('marksProperties')
+        if self.has_input('marksProperties'):
+            properties = self.get_input('marksProperties')
             if marks is not None:
                 properties.update_props(marks)
 
@@ -5044,24 +5213,28 @@ Multiple theta, r arguments are supported, with format strings, as in :func:`~ma
         ]
 
     _output_ports = [
-        ("self", "(MplPolar)"),
+        ("value", "(MplPolar)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        val = self.getInputFromPort('theta')
+        val = self.get_input('theta')
         args.append(val)
-        val = self.getInputFromPort('r')
+        val = self.get_input('r')
         args.append(val)
 
         kwargs = {}
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.polar(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
@@ -5133,26 +5306,28 @@ Example:
     _input_ports = [
               ("loc", "basic:String",
                {'entry_types': "['enum']", 'values': "[['best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left', 'center right', 'lower center', 'upper center', 'center']]", 'optional': True}),
-              ("fancybox", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'if True, draw a frame with a round fancybox.  If None, use rc settings', 'values': "[['']]", 'optional': True}),
+              ("fancybox", "basic:Boolean",
+               {'optional': True, 'docstring': 'if True, draw a frame with a round fancybox.  If None, use rc settings'}),
               ("bbox_to_anchor", "basic:String",
                {'optional': True, 'docstring': 'the bbox that the legend will be anchored.'}),
               ("title", "basic:String",
                {'optional': True, 'docstring': 'the legend title'}),
               ("handlelength", "basic:String",
                {'optional': True, 'docstring': 'the length of the legend handles'}),
-              ("markerscale", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'The relative size of legend markers vs. original. If None, use rc settings.', 'values': "[['']]", 'optional': True}),
+              ("markerscale", "basic:Float",
+               {'optional': True, 'docstring': 'The relative size of legend markers vs. original. If None, use rc settings.'}),
               ("numpoints", "basic:Integer",
                {'optional': True, 'docstring': 'The number of points in the legend for line'}),
               ("labelspacing", "basic:String",
                {'optional': True, 'docstring': 'the vertical space between the legend entries'}),
               ("scatterpoints", "basic:Integer",
                {'optional': True, 'docstring': 'The number of points in the legend for scatter plot'}),
-              ("frameon", "basic:Boolean",
-               {'optional': True, 'docstring': "if True, draw a frame around the legend. The default is set by the rcParam 'legend.frameon'"}),
+              ("prop", "basic:String",
+               {'optional': True, 'docstring': 'A :class:`matplotlib.font_manager.FontProperties` instance. If prop is a dictionary, a new instance will be created with prop. If None, use rc settings.'}),
               ("columnspacing", "basic:String",
                {'optional': True, 'docstring': 'the spacing between columns'}),
+              ("ncol", "basic:Integer",
+               {'optional': True, 'docstring': 'number of columns. default is 1', 'defaults': '[1]'}),
               ("handletextpad", "basic:String",
                {'optional': True, 'docstring': 'the pad between the legend handle and text'}),
               ("scatteroffsetsSequence", "basic:List",
@@ -5161,12 +5336,10 @@ Example:
                {'docstring': 'a list of yoffsets for scatter symbols in legend', 'optional': True}),
               ("mode", "basic:String",
                {'optional': True, 'docstring': 'if mode is "expand", the legend will be horizontally expanded to fill the axes area (or bbox_to_anchor)'}),
-              ("ncol", "basic:Integer",
-               {'optional': True, 'docstring': 'number of columns. default is 1', 'defaults': "['1']"}),
-              ("shadow", "basic:String",
-               {'entry_types': "['enum']", 'docstring': 'If True, draw a shadow behind legend. If None, use rc settings.', 'values': "[['']]", 'optional': True}),
-              ("prop", "basic:String",
-               {'optional': True, 'docstring': 'A :class:`matplotlib.font_manager.FontProperties` instance. If prop is a dictionary, a new instance will be created with prop. If None, use rc settings.'}),
+              ("shadow", "basic:Boolean",
+               {'optional': True, 'docstring': 'If True, draw a shadow behind legend. If None, use rc settings.'}),
+              ("frameon", "basic:Boolean",
+               {'optional': True, 'docstring': "if True, draw a frame around the legend. The default is set by the rcParam 'legend.frameon'"}),
               ("borderpad", "basic:String",
                {'optional': True, 'docstring': 'the fractional whitespace inside the legend border'}),
               ("bbox_transform", "basic:String",
@@ -5176,9 +5349,9 @@ Example:
         ]
 
     _output_ports = [
-        ("self", "(MplLegend)"),
+        ("value", "(MplLegend)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -5186,72 +5359,76 @@ Example:
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('loc'):
-            val = self.getInputFromPort('loc')
+        if self.has_input('loc'):
+            val = self.get_input('loc')
             val = translate_MplLegend_loc(val)
             kwargs['loc'] = val
-        if self.hasInputFromPort('fancybox'):
-            val = self.getInputFromPort('fancybox')
+        if self.has_input('fancybox'):
+            val = self.get_input('fancybox')
             kwargs['fancybox'] = val
-        if self.hasInputFromPort('bbox_to_anchor'):
-            val = self.getInputFromPort('bbox_to_anchor')
+        if self.has_input('bbox_to_anchor'):
+            val = self.get_input('bbox_to_anchor')
             kwargs['bbox_to_anchor'] = val
-        if self.hasInputFromPort('title'):
-            val = self.getInputFromPort('title')
+        if self.has_input('title'):
+            val = self.get_input('title')
             kwargs['title'] = val
-        if self.hasInputFromPort('handlelength'):
-            val = self.getInputFromPort('handlelength')
+        if self.has_input('handlelength'):
+            val = self.get_input('handlelength')
             kwargs['handlelength'] = val
-        if self.hasInputFromPort('markerscale'):
-            val = self.getInputFromPort('markerscale')
+        if self.has_input('markerscale'):
+            val = self.get_input('markerscale')
             kwargs['markerscale'] = val
-        if self.hasInputFromPort('numpoints'):
-            val = self.getInputFromPort('numpoints')
+        if self.has_input('numpoints'):
+            val = self.get_input('numpoints')
             kwargs['numpoints'] = val
-        if self.hasInputFromPort('labelspacing'):
-            val = self.getInputFromPort('labelspacing')
+        if self.has_input('labelspacing'):
+            val = self.get_input('labelspacing')
             kwargs['labelspacing'] = val
-        if self.hasInputFromPort('scatterpoints'):
-            val = self.getInputFromPort('scatterpoints')
+        if self.has_input('scatterpoints'):
+            val = self.get_input('scatterpoints')
             kwargs['scatterpoints'] = val
-        if self.hasInputFromPort('frameon'):
-            val = self.getInputFromPort('frameon')
-            kwargs['frameon'] = val
-        if self.hasInputFromPort('columnspacing'):
-            val = self.getInputFromPort('columnspacing')
+        if self.has_input('prop'):
+            val = self.get_input('prop')
+            kwargs['prop'] = val
+        if self.has_input('columnspacing'):
+            val = self.get_input('columnspacing')
             kwargs['columnspacing'] = val
-        if self.hasInputFromPort('handletextpad'):
-            val = self.getInputFromPort('handletextpad')
+        if self.has_input('ncol'):
+            val = self.get_input('ncol')
+            kwargs['ncol'] = val
+        if self.has_input('handletextpad'):
+            val = self.get_input('handletextpad')
             kwargs['handletextpad'] = val
-        if self.hasInputFromPort('scatteroffsetsSequence'):
-            val = self.getInputFromPort('scatteroffsetsSequence')
+        if self.has_input('scatteroffsetsSequence'):
+            val = self.get_input('scatteroffsetsSequence')
             kwargs['scatteroffsets'] = val
-        elif self.hasInputFromPort('scatteroffsetsScalar'):
-            val = self.getInputFromPort('scatteroffsetsScalar')
+        elif self.has_input('scatteroffsetsScalar'):
+            val = self.get_input('scatteroffsetsScalar')
             kwargs['scatteroffsets'] = val
-        if self.hasInputFromPort('mode'):
-            val = self.getInputFromPort('mode')
+        if self.has_input('mode'):
+            val = self.get_input('mode')
             kwargs['mode'] = val
-        if self.hasInputFromPort('ncol'):
-            val = self.getInputFromPort('ncol')
-            kwargs['ncol'] = val
-        if self.hasInputFromPort('shadow'):
-            val = self.getInputFromPort('shadow')
+        if self.has_input('shadow'):
+            val = self.get_input('shadow')
             kwargs['shadow'] = val
-        if self.hasInputFromPort('prop'):
-            val = self.getInputFromPort('prop')
-            kwargs['prop'] = val
-        if self.hasInputFromPort('borderpad'):
-            val = self.getInputFromPort('borderpad')
+        if self.has_input('frameon'):
+            val = self.get_input('frameon')
+            kwargs['frameon'] = val
+        if self.has_input('borderpad'):
+            val = self.get_input('borderpad')
             kwargs['borderpad'] = val
-        if self.hasInputFromPort('bbox_transform'):
-            val = self.getInputFromPort('bbox_transform')
+        if self.has_input('bbox_transform'):
+            val = self.get_input('bbox_transform')
             kwargs['bbox_transform'] = val
-        if self.hasInputFromPort('borderaxespad'):
-            val = self.getInputFromPort('borderaxespad')
+        if self.has_input('borderaxespad'):
+            val = self.get_input('borderaxespad')
             kwargs['borderaxespad'] = val
 
-        matplotlib.pyplot.legend(*args, **kwargs)        
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        matplotlib.pyplot.legend(*args, **kwargs)
 
 class MplAnnotate(MplPlot):
     """Create an annotation: a piece of text referring to a data point.
@@ -5304,9 +5481,9 @@ Additional kwargs are Text properties:
         ]
 
     _output_ports = [
-        ("self", "(MplAnnotate)"),
+        ("value", "(MplAnnotate)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
@@ -5314,29 +5491,33 @@ Additional kwargs are Text properties:
         args = []
 
         kwargs = {}
-        if self.hasInputFromPort('xycoords'):
-            val = self.getInputFromPort('xycoords')
+        if self.has_input('xycoords'):
+            val = self.get_input('xycoords')
             kwargs['xycoords'] = val
-        if self.hasInputFromPort('xytext'):
-            val = self.getInputFromPort('xytext')
+        if self.has_input('xytext'):
+            val = self.get_input('xytext')
             kwargs['xytext'] = val
-        val = self.getInputFromPort('s')
+        val = self.get_input('s')
         kwargs['s'] = val
-        val = self.getInputFromPort('xy')
+        val = self.get_input('xy')
         kwargs['xy'] = val
-        if self.hasInputFromPort('textcoords'):
-            val = self.getInputFromPort('textcoords')
+        if self.has_input('textcoords'):
+            val = self.get_input('textcoords')
             kwargs['textcoords'] = val
 
-        if self.hasInputFromPort("fancyArrowProperties"):
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
+        if self.has_input("fancyArrowProperties"):
             kwargs['arrowprops'] = \
-                self.getInputFromPort("fancyArrowProperties").props
-        elif self.hasInputFromPort("arrowProperties"):
+                self.get_input("fancyArrowProperties").props
+        elif self.has_input("arrowProperties"):
             kwargs['arrowprops'] = \
-                self.getInputFromPort("arrowProperties").props
+                self.get_input("arrowProperties").props
         annotation = matplotlib.pyplot.annotate(*args, **kwargs)
-        if self.hasInputFromPort('annotationProperties'):
-            properties = self.getInputFromPort('annotationProperties')
+        if self.has_input('annotationProperties'):
+            properties = self.get_input('annotationProperties')
             if annotation is not None:
                 properties.update_props(annotation)
 
@@ -5399,33 +5580,37 @@ Additional kwargs: hold = [True|False] overrides default hold state
         ]
 
     _output_ports = [
-        ("self", "(MplLinePlot)"),
+        ("value", "(MplLinePlot)"),
         ]
-    
+
 
     def compute(self):
         # get args into args, kwargs
         # write out translations
         args = []
-        if self.hasInputFromPort('x'):
-            val = self.getInputFromPort('x')
+        if self.has_input('x'):
+            val = self.get_input('x')
             args.append(val)
-        val = self.getInputFromPort('y')
+        val = self.get_input('y')
         args.append(val)
 
         kwargs = {}
-        if self.hasInputFromPort('marker'):
-            val = self.getInputFromPort('marker')
+        if self.has_input('marker'):
+            val = self.get_input('marker')
             val = translate_MplLinePlot_marker(val)
             kwargs['marker'] = val
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         lines = matplotlib.pyplot.plot(*args, **kwargs)
-        if self.hasInputFromPort('lineProperties'):
-            properties = self.getInputFromPort('lineProperties')
+        if self.has_input('lineProperties'):
+            properties = self.get_input('lineProperties')
             if lines is not None:
                 properties.update_props(lines)
 
-          
+
 _modules = [
             MplAcorr,
             MplArrow,
diff --git a/vistrails/packages/matplotlib/plots_template.py.mako b/vistrails/packages/matplotlib/plots_template.py.mako
index 0ca518e..5de2f37 100644
--- a/vistrails/packages/matplotlib/plots_template.py.mako
+++ b/vistrails/packages/matplotlib/plots_template.py.mako
@@ -13,8 +13,8 @@ val = ${t_ps.translations}(val)\
 <%def name="get_port_val(spec, t_ps)">\
         % if t_ps.required:
         % if t_ps.has_alternate_versions():
-        if self.hasInputFromPort('${t_ps.name}'):
-            val = self.getInputFromPort('${t_ps.name}')
+        if self.has_input('${t_ps.name}'):
+            val = self.get_input('${t_ps.name}')
             % if t_ps.translations:
             ${do_translate(spec, t_ps)}
             % endif
@@ -24,8 +24,8 @@ val = ${t_ps.translations}(val)\
             kwargs['${t_ps.arg}'] = val
             % endif
         % for alt_ps in t_ps.alternate_specs:
-        elif self.hasInputFromPort('${alt_ps.name}'):
-            val = self.getInputFromPort('${alt_ps.name}')
+        elif self.has_input('${alt_ps.name}'):
+            val = self.get_input('${alt_ps.name}')
             % if alt_ps.translations:
             ${do_translate(spec, alt_ps)}
             % endif
@@ -39,7 +39,7 @@ val = ${t_ps.translations}(val)\
             raise ModuleError(self, 'Must set one of "${t_ps.name}", ' \
                                   '${', '.join('"%s"' % alt_ps.name for alt_ps in t_ps.alternate_specs)}')
         % else:
-        val = self.getInputFromPort('${t_ps.name}')
+        val = self.get_input('${t_ps.name}')
         % if t_ps.in_args:
         args.append(val)
         % elif t_ps.in_kwargs:
@@ -50,8 +50,8 @@ val = ${t_ps.translations}(val)\
         % endif
         % endif
         % else:
-        if self.hasInputFromPort('${t_ps.name}'):
-            val = self.getInputFromPort('${t_ps.name}')
+        if self.has_input('${t_ps.name}'):
+            val = self.get_input('${t_ps.name}')
             % if t_ps.translations:
             ${do_translate(spec, t_ps)}
             % endif
@@ -61,8 +61,8 @@ val = ${t_ps.translations}(val)\
             kwargs['${t_ps.arg}'] = val
             % endif
         % for alt_ps in t_ps.alternate_specs:
-        elif self.hasInputFromPort('${alt_ps.name}'):
-            val = self.getInputFromPort('${alt_ps.name}')
+        elif self.has_input('${alt_ps.name}'):
+            val = self.get_input('${alt_ps.name}')
             % if alt_ps.translations:
             ${do_translate(spec, alt_ps)}
             % endif
@@ -117,15 +117,13 @@ class ${spec.name}(${spec.superklass}):
         ]
 
     _output_ports = [
-        ("self", "(${spec.name})"),
-        % for ps in spec.output_port_specs:
-        % if not ps.is_property():
-              ("${ps.name}", "${ps.get_port_type()}",
-                ${ps.get_port_attrs()}),
+        ("value", "(${spec.name})"),
+        % if any(not ps.is_property() for ps in spec.output_port_specs):
+            # (this plot has additional output which are not exposed as ports
+            # right now)
         % endif
-        % endfor
         ]
-    
+
     % if spec.get_init():
     ${spec.get_init()}
     % endif
@@ -141,25 +139,29 @@ ${get_port_val(spec, ps)}\
         kwargs = {}
         % for ps in spec.port_specs:
         % if ps.is_property():
-        if self.hasInputFromPort('${ps.name}'):
-            properties = self.getInputFromPort('${ps.name}')
+        if self.has_input('${ps.name}'):
+            properties = self.get_input('${ps.name}')
             properties.update_kwargs(kwargs)
         % elif not ps.hide and not ps.in_args and ps.in_kwargs:
 ${get_port_val(spec, ps)}\
         % endif
         % endfor
 
+        self.set_output('value', lambda figure: self.plot_figure(figure,
+                                                                 args, kwargs))
+
+    def plot_figure(self, figure, args, kwargs):
         % if spec.get_compute_before():
         ${spec.get_compute_before()}
         % endif
         % if spec.get_compute_inner():
         ${spec.get_compute_inner()}
         % elif spec.output_type is None:
-        ${spec.code_ref}(*args, **kwargs)        
+        ${spec.code_ref}(*args, **kwargs)
         % elif spec.output_type == "object":
         ${spec.get_returned_output_port_specs()[0].compute_name} = ${spec.code_ref}(*args, **kwargs)
         % else:
-        output = ${spec.code_ref}(*args, **kwargs)        
+        output = ${spec.code_ref}(*args, **kwargs)
         % endif
         % if spec.get_compute_after():
         ${spec.get_compute_after()}
@@ -176,8 +178,8 @@ ${get_port_val(spec, ps)}\
         % endif
         % for ps in spec.output_port_specs:
         % if ps.is_property():
-        if self.hasInputFromPort('${ps.name}'):
-            properties = self.getInputFromPort('${ps.name}')
+        if self.has_input('${ps.name}'):
+            properties = self.get_input('${ps.name}')
             % if ps.compute_parent:
             % if spec.get_output_port_spec(ps.compute_parent).plural:
             for obj in ${spec.get_output_port_spec(ps.compute_parent).compute_name}:
@@ -186,23 +188,17 @@ ${get_port_val(spec, ps)}\
             if ${spec.get_output_port_spec(ps.compute_parent).compute_name}.${ps.compute_name} is not None:
                 properties.update(${spec.get_output_port_spec(ps.compute_parent).compute_name}.${ps.compute_name})
             % endif
-            ## % if ps.plural:
-            ## for obj in ${ps.compute_name}:
-            ##     properties.update(obj)
-            ## % else:
-            ## properties.update(${ps.compute_name})
-            ## % endif
             % else:
             if ${ps.compute_name} is not None:
                 properties.update_props(${ps.compute_name})
             % endif
         % else:
-        self.setResult('${ps.name}', ${ps.compute_name})
+        self.set_output('${ps.name}', ${ps.compute_name})
         % endif
         % endfor
 
-% endfor        
-          
+% endfor
+
 _modules = [
 % for spec in specs.module_specs:
             ${spec.name},
diff --git a/vistrails/packages/matplotlib/specs.py b/vistrails/packages/matplotlib/specs.py
index 74c90fc..be24d74 100644
--- a/vistrails/packages/matplotlib/specs.py
+++ b/vistrails/packages/matplotlib/specs.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import inspect
 import mixins
 from xml.etree import ElementTree as ET
@@ -58,12 +96,6 @@ class SpecList(object):
             elif elt.tag == "customCode":
                 custom_code = elt.text
         retval = SpecList(module_specs, custom_code)
-        # for spec in retval.module_specs:
-        #     print "==", spec.name, "=="
-        #     for ps in spec.port_specs:
-        #         print " ", ps.arg, ps.name
-        #         for alt_ps in ps.alternate_specs:
-        #             print "  !!!", ps.arg, ps.name, alt_ps.name
         return retval
 
 class ModuleSpec(object):
@@ -179,7 +211,7 @@ class PortSpec(object):
              "required": (False, False, True),
              "show_port": (False, False, True),
              "hide": (False, False, True),
-             "property_type": ""}
+             "property_type": "",}
 
     def __init__(self, arg, **kwargs):
         self.arg = arg
@@ -225,20 +257,6 @@ class PortSpec(object):
                     elt.set(attr, str(attr_val))
         return elt
 
-        # if self.name != "":
-        #     elt.set("name", self.name)
-        # if self.port_type is not None:
-        #     elt.set("port_type", self.port_type)
-        # else:
-        #     elt.set("port_type", "__unknown__")
-        # if self.port_type == "__property__":
-        #     elt.set("property_type", self.property_type)
-        # if self.required != False:
-        #     elt.set("required", str(self.required))
-        # if self.
-        # elt.set("hide", str(self.hide))
-        # elt.set("show_port", str(self.show_port))
-
     @classmethod
     def internal_from_xml(cls, elt, obj=None):
         arg = elt.get("arg", "")
@@ -249,8 +267,6 @@ class PortSpec(object):
 
         child_elts = {}
         for child in elt.getchildren():
-            # if child.tag not in obj.attrs:
-            #     raise RuntimeError('Cannot deal with tag "%s"' % child.tag)
             if child.tag not in child_elts:
                 child_elts[child.tag] = []
             child_elts[child.tag].append(child)
@@ -308,27 +324,6 @@ class PortSpec(object):
                         elt.tag)
 
 
-    # @staticmethod
-    # def from_xml(elt, obj=None):
-    #     arg = elt.get("arg", "")
-    #     if obj is None:
-    #         obj = PortSpec(arg)
-    #     else:
-    #         obj.arg = arg
-    #     obj.port_type = elt.get("port_type", "")
-    #     if obj.port_type == "__unknown__":
-    #         obj.port_type = None
-
-    #     if obj.port_type is not None and \
-    #             obj.port_type.lower() == "__property__":
-    #         obj.name = elt.get("name", obj.arg + "Properties")
-    #     else:
-    #         obj.name = elt.get("name", obj.arg)
-    #     obj.required = eval(elt.get("required", "False"))
-    #     obj.hide = eval(elt.get("hide", "False"))
-    #     obj.show_port = eval(elt.get("show_port", "False"))
-    #     return obj
-
     def is_property(self):
         return self.port_type == "__property__"
 
@@ -350,6 +345,7 @@ class InputPortSpec(PortSpec):
              "in_kwargs": (True, False, True),
              "in_args": (False, False, True),
              "constructor_arg": (False, False, True),
+             "not_setp": (False, False, True),
              "arg_pos": (-1, False, True),
              }
     attrs.update(PortSpec.attrs)
@@ -403,14 +399,7 @@ class InputPortSpec(PortSpec):
     def has_alternate_versions(self):
         return len(self.alternate_specs) > 0
 
-    # def is_property_input(self):
-    #     return self.get_port_type().lower() == "__property__"
-
 class AlternatePortSpec(InputPortSpec):
-    # attrs = ["name", "port_type", "docstring", "required", "hide", 
-    #          "entry_types", "values", "defaults", "translations", 
-    #          "property_type"]
-
     xml_name = "alternateSpec"
     def __init__(self, *args, **kwargs):
         if len(args) < 1:
@@ -432,11 +421,6 @@ class AlternatePortSpec(InputPortSpec):
             else:
                 self.name = base_name + "Scalar"
         self.arg = self._parent.arg
-            
-    # def to_xml(self, elt=None):
-    #     if elt is None:
-    #         elt = ET.Element("alternateSpec")
-    #     return PortSpec.to_xml(self, elt)
 
     def get_port_attr_dict(self):
         print "CALLING AlternatePortSpec.get_port_attr_dict", self.arg
diff --git a/vistrails/packages/matplotlib/update.py b/vistrails/packages/matplotlib/update.py
old mode 100644
new mode 100755
index 7d80c04..b9eac3a
--- a/vistrails/packages/matplotlib/update.py
+++ b/vistrails/packages/matplotlib/update.py
@@ -1,38 +1,42 @@
+#!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import os
 import shutil
 
diff --git a/vistrails/packages/matplotlib/widgets.py b/vistrails/packages/matplotlib/widgets.py
index c11560e..46aaf95 100644
--- a/vistrails/packages/matplotlib/widgets.py
+++ b/vistrails/packages/matplotlib/widgets.py
@@ -1,37 +1,41 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from vistrails.gui.modules.python_source_configure import PythonEditor
 from vistrails.gui.modules.source_configure import SourceConfigurationWidget
 
diff --git a/vistrails/packages/parallelflow/__init__.py b/vistrails/packages/parallelflow/__init__.py
index 0f26f60..4c6144a 100644
--- a/vistrails/packages/parallelflow/__init__.py
+++ b/vistrails/packages/parallelflow/__init__.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 identifier="edu.poly.vistrails.parallel_flow"
 name="Parallel Flow"
 version="0.1.1"
diff --git a/vistrails/packages/parallelflow/api.py b/vistrails/packages/parallelflow/api.py
index 7ee4a5f..dde81ea 100644
--- a/vistrails/packages/parallelflow/api.py
+++ b/vistrails/packages/parallelflow/api.py
@@ -1,3 +1,39 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
 """Provides access to IPython to packages.
 
 get_client() returns the Client object, from which you can construct a view.
@@ -24,6 +60,8 @@ prompt the user to start a cluster if none is available. It is True by default
 """
 
 
+from __future__ import division
+
 __all__ = ['get_client', 'direct_view', 'load_balanced_view', 'parallel_map']
 
 
diff --git a/vistrails/packages/parallelflow/engine_manager.py b/vistrails/packages/parallelflow/engine_manager.py
index 58763f6..7381f3f 100644
--- a/vistrails/packages/parallelflow/engine_manager.py
+++ b/vistrails/packages/parallelflow/engine_manager.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import os
 import subprocess
 import sys
@@ -12,8 +50,7 @@ from vistrails.core.system import vistrails_root_directory
 
 try:
     from PyQt4 import QtCore, QtGui
-    QtGui.QDialog
-except Exception:
+except ImportError:
     qt_available = False
 else:
     qt_available = True
@@ -271,7 +308,7 @@ class EngineManager(object):
             if qt_available:
                 bar.hide()
                 bar.deleteLater()
-            print "parallelflow: %d engines started" % (i + 1)
+            print "parallelflow: %d engines started" % nb
 
     def info(self):
         """Show some information on the cluster.
diff --git a/vistrails/packages/parallelflow/init.py b/vistrails/packages/parallelflow/init.py
index 3d36dda..9facdde 100644
--- a/vistrails/packages/parallelflow/init.py
+++ b/vistrails/packages/parallelflow/init.py
@@ -1,3 +1,41 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.modules.basic_modules import List, String
diff --git a/vistrails/packages/parallelflow/map.py b/vistrails/packages/parallelflow/map.py
index 737f978..ee2c905 100644
--- a/vistrails/packages/parallelflow/map.py
+++ b/vistrails/packages/parallelflow/map.py
@@ -1,24 +1,63 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import vistrails.core.db.action
-import vistrails.db.versions
+from vistrails.core.db.locator import XMLFileLocator
+from vistrails.core.db.io import serialize, unserialize
+from vistrails.core import debug
+from vistrails.core.interpreter.default import get_default_interpreter
+from vistrails.core.log.group_exec import GroupExec
+from vistrails.core.log.machine import Machine
+from vistrails.core.log.module_exec import ModuleExec
+from vistrails.core.modules.basic_modules import Constant
 import vistrails.core.modules.module_registry
 import vistrails.core.modules.utils
 from vistrails.core.modules.vistrails_module import Module, ModuleError, \
-    ModuleConnector, InvalidOutput
-from vistrails.core.modules.basic_modules import NotCacheable, Constant
-from vistrails.core.vistrail.pipeline import Pipeline
+    InvalidOutput
 from vistrails.core.vistrail.annotation import Annotation
+from vistrails.core.vistrail.controller import VistrailController
 from vistrails.core.vistrail.group import Group
 from vistrails.core.vistrail.module_function import ModuleFunction
 from vistrails.core.vistrail.module_param import ModuleParam
+from vistrails.core.vistrail.pipeline import Pipeline
 from vistrails.core.vistrail.vistrail import Vistrail
-from vistrails.core.db.locator import XMLFileLocator
-from vistrails.core.vistrail.controller import VistrailController
-from vistrails.core.interpreter.default import get_default_interpreter
-from vistrails.core.db.io import serialize, unserialize
-from vistrails.core.log.module_exec import ModuleExec
-from vistrails.core.log.group_exec import GroupExec
-from vistrails.core.log.machine import Machine
 from vistrails.db.domain import IdScope
+import vistrails.db.versions
 
 import copy
 import inspect
@@ -32,6 +71,13 @@ from IPython.parallel.error import CompositeError
 
 from .api import get_client
 
+try:
+    import hashlib
+    sha1_hash = hashlib.sha1
+except ImportError:
+    import sha
+    sha1_hash = sha.new
+
 
 ###############################################################################
 # This function is sent to the engines which execute it
@@ -99,13 +145,13 @@ def execute_wf(wf, output_port):
             errors.append("Module log not found")
             return dict(errors=errors)
         else:
-            machine = controller.log.machine_list[0]
+            machine = controller.log.workflow_execs[0].machines[
+                    module_log.machine_id]
             xml_log = serialize(module_log)
             machine_log = serialize(machine)
 
         # Get the output value
         output = None
-        serializable = None
         if not execution_errors:
             executed_module, = execution[0][0].executed
             executed_module = execution[0][0].objects[executed_module]
@@ -114,16 +160,12 @@ def execute_wf(wf, output_port):
             except ModuleError:
                 errors.append("Output port not found: %s" % output_port)
                 return dict(errors=errors)
-            reg = vistrails.core.modules.module_registry.get_module_registry()
-            base_classes = inspect.getmro(type(output))
-            if Module in base_classes:
-                serializable = reg.get_descriptor(type(output)).sigstring
-                output = output.serialize()
+            if isinstance(output, Module):
+                raise TypeError("Output value is a Module instance")
 
         # Return the dictionary, that will be sent back to the client
         return dict(errors=errors,
                     output=output,
-                    serializable=serializable,
                     xml_log=xml_log,
                     machine_log=machine_log)
     finally:
@@ -149,15 +191,15 @@ class Map(Module):
     def __init__(self):
         Module.__init__(self)
 
-    def updateUpstream(self):
-        """A modified version of the updateUpstream method."""
+    def update_upstream(self):
+        """A modified version of the update_upstream method."""
 
         # everything is the same except that we don't update anything
         # upstream of FunctionPort
         for port_name, connector_list in self.inputPorts.iteritems():
             if port_name == 'FunctionPort':
                 for connector in connector_list:
-                    connector.obj.updateUpstream()
+                    connector.obj.update_upstream()
             else:
                 for connector in connector_list:
                     connector.obj.update()
@@ -166,7 +208,7 @@ class Map(Module):
                 for connector in connectorList:
                     if connector.obj.get_output(connector.port) is \
                             InvalidOutput:
-                        self.removeInputConnector(port_name, connector)
+                        self.remove_input_connector(port_name, connector)
 
     @staticmethod
     def print_compositeerror(e):
@@ -191,9 +233,9 @@ class Map(Module):
         updates the module connected to the FunctionPort port, executing it in
         parallel.
         """
-        nameInput = self.getInputFromPort('InputPort')
-        nameOutput = self.getInputFromPort('OutputPort')
-        rawInputList = self.getInputFromPort('InputList')
+        nameInput = self.get_input('InputPort')
+        nameOutput = self.get_input('OutputPort')
+        rawInputList = self.get_input('InputList')
 
         # Create inputList to always have iterable elements
         # to simplify code
@@ -228,7 +270,7 @@ class Map(Module):
 
                 # checking type and setting input in the module
                 self.typeChecking(connector.obj, nameInput, inputList)
-                self.setInputValues(connector.obj, nameInput, element)
+                self.setInputValues(connector.obj, nameInput, element, i)
 
                 pipeline_db_module = original_pipeline.modules[module_id].do_copy()
 
@@ -298,8 +340,8 @@ class Map(Module):
         try:
             rc = get_client()
         except Exception, error:
-            raise ModuleError(self, "Exception while loading IPython: "
-                              "%s" % error)
+            raise ModuleError(self, "Exception while loading IPython: %s" %
+                              debug.format_exception(error))
         if rc is None:
             raise ModuleError(self, "Couldn't get an IPython connection")
         engines = rc.ids
@@ -316,7 +358,7 @@ class Map(Module):
         for eng in engines:
             try:
                 rc[eng]['init']
-            except:
+            except Exception:
                 uninitialized.append(eng)
         if uninitialized:
             init_view = rc[uninitialized]
@@ -380,19 +422,10 @@ class Map(Module):
         # setting success color
         module.logging.signalSuccess(module)
 
-        import vistrails.core.modules.module_registry
         reg = vistrails.core.modules.module_registry.get_module_registry()
         self.result = []
         for map_execution in map_result:
-            serializable = map_execution['serializable']
-            output = None
-            if not serializable:
-                output = map_execution['output']
-            else:
-                d_tuple = vistrails.core.modules.utils.parse_descriptor_string(serializable)
-                d = reg.get_descriptor_by_name(*d_tuple)
-                module_klass = d.module
-                output = module_klass().deserialize(map_execution['output'])
+            output = map_execution['output']
             self.result.append(output)
 
         # including execution logs
@@ -419,19 +452,17 @@ class Map(Module):
 
             # before adding the execution log, we need to get the machine information
             machine = unserialize(map_result[engine]['machine_log'], Machine)
-            machine.id = self.logging.log.log.id_scope.getNewId(Machine.vtType) #assigning new id
-            self.logging.log.log.add_machine(machine)
+            machine_id = self.logging.add_machine(machine)
 
             # recursively add machine information to execution items
             def add_machine_recursive(exec_):
-                for i in range(len(exec_.item_execs)):
-                    if hasattr(exec_.item_execs[i], 'machine_id'):
-                        exec_.item_execs[i].machine_id = machine.id
-                        vt_type = exec_.item_execs[i].vtType
-                        if (vt_type == 'abstraction') or (vt_type == 'group'):
-                            add_machine_recursive(exec_.item_execs[i])
-
-            exec_.machine_id = machine.id
+                for item in exec_.item_execs:
+                    if hasattr(item, 'machine_id'):
+                        item.machine_id = machine_id
+                        if item.vtType in ('abstraction', 'group'):
+                            add_machine_recursive(item)
+
+            exec_.machine_id = machine_id
             if (vtType == 'abstraction') or (vtType == 'group'):
                 add_machine_recursive(exec_)
 
@@ -459,78 +490,13 @@ class Map(Module):
 
         return serialize(pipeline)
 
-    def setInputValues(self, module, inputPorts, elementList):
-        """
-        Function used to set a value inside 'module', given the input port(s).
-        """
-        for element, inputPort in izip(elementList, inputPorts):
-            ## Cleaning the previous connector...
-            if inputPort in module.inputPorts:
-                del module.inputPorts[inputPort]
-            new_connector = ModuleConnector(create_constant(element), 'value')
-            module.set_input_port(inputPort, new_connector)
-
-    def typeChecking(self, module, inputPorts, inputList):
-        """
-        Function used to check if the types of the input list element and of the
-        inputPort of 'module' match.
-        """
-        for elementList in inputList:
-            if len(elementList) != len(inputPorts):
-                raise ModuleError(self,
-                                  'The number of input values and input ports '
-                                  'are not the same.')
-            for element, inputPort in izip(elementList, inputPorts):
-                p_modules = module.moduleInfo['pipeline'].modules
-                p_module = p_modules[module.moduleInfo['moduleId']]
-                port_spec = p_module.get_port_spec(inputPort, 'input')
-                v_module = get_module(element, port_spec.signature)
-                if v_module is not None:
-                    if not self.compare(port_spec, v_module, inputPort):
-                        raise ModuleError(self,
-                                          'The type of a list element does '
-                                          'not match with the type of the '
-                                          'port %s.' % inputPort)
-
-                    del v_module
-                else:
-                    break
-
-    def createSignature(self, v_module):
-        """
-    `   Function used to create a signature, given v_module, for a port spec.
-        """
-        if isinstance(v_module, tuple):
-            v_module_class = []
-            for module_ in v_module:
-                v_module_class.append(self.createSignature(module_))
-            return v_module_class
-        else:
-            return v_module
-
-    def compare(self, port_spec, v_module, port):
-        """
-        Function used to compare two port specs.
-        """
-        port_spec1 = port_spec
-
-        from vistrails.core.modules.module_registry import get_module_registry
-        reg = get_module_registry()
-
-        from vistrails.core.vistrail.port_spec import PortSpec
-        v_module = self.createSignature(v_module)
-        port_spec2 = PortSpec(**{'signature': v_module})
-        matched = reg.are_specs_matched(port_spec2, port_spec1)
-
-        return matched
-
     def compute(self):
         """The compute method for Map."""
 
         self.result = None
         self.updateFunctionPort()
 
-        self.setResult('Result', self.result)
+        self.set_output('Result', self.result)
 
 ###############################################################################
 
@@ -539,7 +505,7 @@ class NewConstant(Constant):
     A new Constant module to be used inside the Map module.
     """
     def setValue(self, v):
-        self.setResult("value", v)
+        self.set_output("value", v)
         self.upToDate = True
 
 def create_constant(value):
diff --git a/vistrails/packages/persistence/__init__.py b/vistrails/packages/persistence/__init__.py
index 3ac93c6..52836b0 100644
--- a/vistrails/packages/persistence/__init__.py
+++ b/vistrails/packages/persistence/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.core.configuration import ConfigurationObject
 
 from identifiers import *
diff --git a/vistrails/packages/persistence/compute_hash.py b/vistrails/packages/persistence/compute_hash.py
index fe2c8b5..747a501 100644
--- a/vistrails/packages/persistence/compute_hash.py
+++ b/vistrails/packages/persistence/compute_hash.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import os
 try:
     import hashlib
diff --git a/vistrails/packages/persistence/db_utils.py b/vistrails/packages/persistence/db_utils.py
index c564394..fe06ad5 100644
--- a/vistrails/packages/persistence/db_utils.py
+++ b/vistrails/packages/persistence/db_utils.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import os
 import sqlite3
 
diff --git a/vistrails/packages/persistence/find_files.py b/vistrails/packages/persistence/find_files.py
index 3acc6c8..a06f537 100644
--- a/vistrails/packages/persistence/find_files.py
+++ b/vistrails/packages/persistence/find_files.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import os
 import shutil
 import sys
diff --git a/vistrails/packages/persistence/find_workflows.py b/vistrails/packages/persistence/find_workflows.py
index 80140e9..5a1d460 100644
--- a/vistrails/packages/persistence/find_workflows.py
+++ b/vistrails/packages/persistence/find_workflows.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import os
 import shutil
 import sys
diff --git a/vistrails/packages/persistence/identifiers.py b/vistrails/packages/persistence/identifiers.py
index f108807..8ccfe86 100644
--- a/vistrails/packages/persistence/identifiers.py
+++ b/vistrails/packages/persistence/identifiers.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.persistence'
 version = '0.3.2'
 name = 'Persistence'
diff --git a/vistrails/packages/persistence/init.py b/vistrails/packages/persistence/init.py
index d02add9..cd7f145 100644
--- a/vistrails/packages/persistence/init.py
+++ b/vistrails/packages/persistence/init.py
@@ -1,37 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+from ast import literal_eval
 import copy
 import os
 import shutil
@@ -41,7 +45,7 @@ import uuid
 import vistrails.core.debug
 from vistrails.core.configuration import ConfigurationObject
 from vistrails.core.cache.hasher import Hasher
-from vistrails.core.modules.basic_modules import Path, File, Directory, Boolean, \
+from vistrails.core.modules.basic_modules import Path, PathObject, Directory, Boolean, \
     String, Constant
 from vistrails.core.modules.module_registry import get_module_registry, MissingModule, \
     MissingPackageVersion, MissingModuleVersion
@@ -111,10 +115,10 @@ class PersistentRef(Constant):
     def translate_to_python(x):
         try:
             res = PersistentRef()
-            s_tuple = eval(x)
+            s_tuple = literal_eval(x)
             (res.type, res.id, res.version, res.local_path, res.local_read,
              res.local_writeback, res.versioned, res.name, res.tags) = s_tuple
-        except:
+        except Exception:
             return None
 #         result.settings = dict(zip(sorted(default_settings.iterkeys()),
 #                                    s_tuple))
@@ -202,15 +206,15 @@ class PersistentPath(Module):
     def set_result(self, path):
         persistent_path = Path()
         persistent_path.name = path
-        persistent_path.setResult('value', self)
+        persistent_path.set_output('value', self)
         persistent_path.upToDate = True
-        self.setResult("value", persistent_path)
+        self.set_output("value", persistent_path)
 
-    def updateUpstream(self, is_input=None, path_type=None):
+    def update_upstream(self, is_input=None, path_type=None):
         global db_access
 
         if is_input is None:
-            if not self.hasInputFromPort('value'):
+            if not self.has_input('value'):
                 is_input = True
             else:
                 # FIXME: check if the signature is the signature of
@@ -220,21 +224,21 @@ class PersistentPath(Module):
         self.persistent_ref = None
         self.persistent_path = None
         if is_input:
-            return super(PersistentPath, self).updateUpstream()
+            return super(PersistentPath, self).update_upstream()
 
-        # can check updateUpstream
+        # can check update_upstream
         if not hasattr(self, 'signature'):
             raise ModuleError(self, 'Module has no signature')
 
         ref_exists = False
-        if not self.hasInputFromPort('ref'):
+        if not self.has_input('ref'):
             # create new reference with no name or tags
             ref = PersistentRef()
             ref.signature = self.signature
         else:
             # update single port
-            self.updateUpstreamPort('ref')
-            ref = self.getInputFromPort('ref')
+            self.update_upstream_port('ref')
+            ref = self.get_input('ref')
             if db_access.ref_exists(ref.id, ref.version):
                 ref_exists = True
                 if ref.version is None:
@@ -276,20 +280,20 @@ class PersistentPath(Module):
 
         if self.persistent_ref is None or self.persistent_path is None:
             debug_print("NOT FOUND persistent path")
-            super(PersistentPath, self).updateUpstream()
+            super(PersistentPath, self).update_upstream()
 
     def compute(self, is_input=None, path_type=None):
         global db_access
-        if not self.hasInputFromPort('value') and \
-                not self.hasInputFromPort('ref'):
+        if not self.has_input('value') and \
+                not self.has_input('ref'):
             raise ModuleError(self, "Need to specify path or reference")
 
         if self.persistent_path is not None:
             debug_print('using persistent path')
             ref = self.persistent_ref
             path = self.persistent_path
-        elif self.hasInputFromPort('ref'):
-            ref = self.getInputFromPort('ref')
+        elif self.has_input('ref'):
+            ref = self.get_input('ref')
             if ref.id is None:
                 ref.id = str(uuid.uuid1())
         else:
@@ -297,16 +301,16 @@ class PersistentPath(Module):
             ref = PersistentRef()
             ref.id = str(uuid.uuid1())
 
-        if self.hasInputFromPort('localPath'):
-            ref.local_path = self.getInputFromPort('localPath').name
-            if self.hasInputFromPort('readLocal'):
-                ref.local_read = self.getInputFromPort('readLocal')
-            if self.hasInputFromPort('writeLocal'):
-                ref.local_writeback = self.getInputFromPort('writeLocal')
+        if self.has_input('localPath'):
+            ref.local_path = self.get_input('localPath').name
+            if self.has_input('readLocal'):
+                ref.local_read = self.get_input('readLocal')
+            if self.has_input('writeLocal'):
+                ref.local_writeback = self.get_input('writeLocal')
 
         if is_input is None:
             is_input = False
-            if not self.hasInputFromPort('value'):
+            if not self.has_input('value'):
                 is_input = True
             else:
                 if ref.local_path and ref.local_read:
@@ -317,7 +321,7 @@ class PersistentPath(Module):
 
         # if just reference, pull path from repository (get latest
         # version unless specified as specific version)
-        if self.persistent_path is None and not self.hasInputFromPort('value') \
+        if self.persistent_path is None and not self.has_input('value') \
                 and is_input and not (ref.local_path and ref.local_read):
             _, suffix = os.path.splitext(ref.name)
             if not db_access.ref_exists(ref.id, ref.version):
@@ -336,7 +340,7 @@ class PersistentPath(Module):
                 debug_print('using local_path')
                 path = ref.local_path
             else:
-                path = self.getInputFromPort('value').name
+                path = self.get_input('value').name
             # this is a static method so we need to add module ourselves
             try:
                 new_hash = repo.get_current_repo().compute_hash(path)
@@ -429,49 +433,43 @@ class PersistentFile(PersistentPath):
                     ('localPath', '(basic:File)')]
     _output_ports = [('value', '(basic:File)')]
 
-    def updateUpstream(self, is_input=None):
-        PersistentPath.updateUpstream(self, is_input, 'blob')
+    def update_upstream(self, is_input=None):
+        PersistentPath.update_upstream(self, is_input, 'blob')
 
     def compute(self, is_input=None):
         PersistentPath.compute(self, is_input, 'blob')
 
     def set_result(self, path):
-        persistent_path = File()
-        persistent_path.name = path
-        persistent_path.setResult('value', self)
-        persistent_path.upToDate = True
-        self.setResult("value", persistent_path)
+        persistent_path = PathObject(path)
+        self.set_output("value", persistent_path)
 
 class PersistentDir(PersistentPath):
     _input_ports = [('value', '(basic:Directory)'),
                     ('localPath', '(basic:Directory)')]
     _output_ports = [('value', '(basic:Directory)')]
 
-    def updateUpstream(self, is_input=None):
-        PersistentPath.updateUpstream(self, is_input, 'tree')
+    def update_upstream(self, is_input=None):
+        PersistentPath.update_upstream(self, is_input, 'tree')
 
     def compute(self, is_input=None):
         PersistentPath.compute(self, is_input, 'tree')
 
     def set_result(self, path):
-        persistent_path = Directory()
-        persistent_path.name = path
-        persistent_path.setResult('value', self)
-        persistent_path.upToDate = True
-        self.setResult("value", persistent_path)
+        persistent_path = PathObject(path)
+        self.set_output("value", persistent_path)
 
 class PersistentInputDir(PersistentDir):
     _input_ports = [('value', '(basic:Directory)', True)]
 
-    def updateUpstream(self):
-        PersistentDir.updateUpstream(self, True)
+    def update_upstream(self):
+        PersistentDir.update_upstream(self, True)
 
     def compute(self):
         PersistentDir.compute(self, True)
         
 class PersistentIntermediateDir(PersistentDir):
-    def updateUpstream(self):
-        PersistentDir.updateUpstream(self, False)
+    def update_upstream(self):
+        PersistentDir.update_upstream(self, False)
 
     def compute(self):
         PersistentDir.compute(self, False)
@@ -479,8 +477,8 @@ class PersistentIntermediateDir(PersistentDir):
 class PersistentOutputDir(PersistentDir):
     _output_ports = [('value', '(basic:Directory)', True)]
 
-    def updateUpstream(self):
-        PersistentDir.updateUpstream(self, False)
+    def update_upstream(self):
+        PersistentDir.update_upstream(self, False)
 
     def compute(self):
         PersistentDir.compute(self, False)
@@ -488,15 +486,15 @@ class PersistentOutputDir(PersistentDir):
 class PersistentInputFile(PersistentFile):
     _input_ports = [('value', '(basic:File)', True)]
 
-    def updateUpstream(self):
-        PersistentFile.updateUpstream(self, True)
+    def update_upstream(self):
+        PersistentFile.update_upstream(self, True)
 
     def compute(self):
         PersistentFile.compute(self, True)
     
 class PersistentIntermediateFile(PersistentFile):
-    def updateUpstream(self):
-        PersistentFile.updateUpstream(self, False)
+    def update_upstream(self):
+        PersistentFile.update_upstream(self, False)
 
     def compute(self):
         PersistentFile.compute(self, False)
@@ -504,8 +502,8 @@ class PersistentIntermediateFile(PersistentFile):
 class PersistentOutputFile(PersistentFile):
     _output_ports = [('value', '(basic:File)', True)]
 
-    def updateUpstream(self):
-        PersistentFile.updateUpstream(self, False)
+    def update_upstream(self):
+        PersistentFile.update_upstream(self, False)
 
     def compute(self):
         PersistentFile.compute(self, False)
@@ -586,7 +584,7 @@ def initialize():
         if not os.path.exists(local_db):
             try:
                 os.mkdir(local_db)
-            except:
+            except OSError:
                 raise RuntimeError('local_db "%s" does not exist' % local_db)
 
     local_repo = repo.get_repo(local_db)
@@ -600,14 +598,15 @@ def initialize():
     search_dbs = [local_db,]
     if configuration.check('search_dbs'):
         try:
-            check_paths = eval(configuration.search_dbs)
-        except:
+            check_paths = literal_eval(configuration.search_dbs)
+        except Exception:
             print "*** persistence error: cannot parse search_dbs ***"
-        for path in check_paths:
-            if os.path.exists(path):
-                search_dbs.append(path)
-            else:
-                print '*** persistence warning: cannot find path "%s"' % path
+        else:
+            for path in check_paths:
+                if os.path.exists(path):
+                    search_dbs.append(path)
+                else:
+                    print '*** persistence warning: cannot find path "%s"' % path
 
 _configuration_widget = None
 
diff --git a/vistrails/packages/persistence/repo.py b/vistrails/packages/persistence/repo.py
index b43eec9..aff29e1 100644
--- a/vistrails/packages/persistence/repo.py
+++ b/vistrails/packages/persistence/repo.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from vistrails.core.bundles import py_import
 py_import('dulwich', {
         'pip': 'dulwich',
@@ -159,7 +162,6 @@ class GitRepo(object):
                 return f.read(chunk_size)
             my_iter = chain([head], iter(read_chunk,''))
             return iter_sha1(my_iter)
-        return None
 
     @staticmethod
     def compute_tree_hash(dirname):
diff --git a/vistrails/packages/persistence/schema.sql b/vistrails/packages/persistence/schema.sql
index 068d5ea..727ce2d 100644
--- a/vistrails/packages/persistence/schema.sql
+++ b/vistrails/packages/persistence/schema.sql
@@ -1,34 +1,35 @@
 --#############################################################################
 --
+-- Copyright (C) 2014-2015, New York University.
 -- Copyright (C) 2011-2014, NYU-Poly.
--- Copyright (C) 2006-2011, University of Utah. 
+-- Copyright (C) 2006-2011, University of Utah.
 -- All rights reserved.
 -- Contact: contact at vistrails.org
 --
 -- This file is part of VisTrails.
 --
--- "Redistribution and use in source and binary forms, with or without 
+-- "Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are met:
 --
---  - Redistributions of source code must retain the above copyright notice, 
+--  - Redistributions of source code must retain the above copyright notice,
 --    this list of conditions and the following disclaimer.
---  - Redistributions in binary form must reproduce the above copyright 
---    notice, this list of conditions and the following disclaimer in the 
+--  - Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
 --    documentation and/or other materials provided with the distribution.
---  - Neither the name of the University of Utah nor the names of its 
---    contributors may be used to endorse or promote products derived from 
+--  - Neither the name of the New York University nor the names of its
+--    contributors may be used to endorse or promote products derived from
 --    this software without specific prior written permission.
 --
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
--- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
--- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
--- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
--- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 --
 --#############################################################################
diff --git a/vistrails/packages/persistence/widgets.py b/vistrails/packages/persistence/widgets.py
index ec5b50e..bc04a42 100644
--- a/vistrails/packages/persistence/widgets.py
+++ b/vistrails/packages/persistence/widgets.py
@@ -1,44 +1,47 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 import os
 import re
 import uuid
 
 from vistrails.core.modules.basic_modules import Path
-from vistrails.gui.common_widgets import QSearchBox, QSearchEditBox
+from vistrails.gui.common_widgets import QSearchBox
 from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin
 from vistrails.gui.modules.module_configure import StandardModuleConfigurationWidget
 
@@ -269,22 +272,16 @@ class PersistentRefModel(QtCore.QAbstractItemModel):
         id = where_dict['id']
         version = where_dict.get('version', None)
         if version is not None:
-            found = False
             for idx, value_tuple in enumerate(self.id_lists[id]):
                 if value_tuple[self.idxs['version']] == version:
-                    found = True
+                    del self.id_lists[id][idx]
                     break
-            if found:
-                del self.id_lists[id][idx]
         else:
             path_type = self.id_lists[id][0][self.idxs['type']]
-            found = False
             for idx, key_id in enumerate(self.id_lists_keys):
                 if key_id == id:
-                    found = True
+                    del self.id_lists_keys[idx]
                     break
-            if found:
-                del self.id_lists_keys[idx]
             del self.id_lists[id]
         self.reset()
 
@@ -836,6 +833,8 @@ class PersistentPathConfiguration(StandardModuleConfigurationWidget):
         new_file = str(self.new_file.get_path())
         if new_file:
             base_name = os.path.basename(new_file)
+        else:
+            base_name = ''
         self.name_edit.setText(base_name)
         self.keep_local.setChecked(True)
         self.local_path.set_path(new_file)
@@ -856,11 +855,10 @@ class PersistentPathConfiguration(StandardModuleConfigurationWidget):
         def func_to_bool(function):
             try:
                 value = function.parameters[0].strValue
-                if value and value == 'True':
-                    return True
-            except:
-                pass
-            return False
+            except IndexError:
+                return False
+            if value and value == 'True':
+                return True
 
         ref_exists = False
         self.existing_ref = None
@@ -990,6 +988,7 @@ class PersistentOutputPathConfiguration(PersistentPathConfiguration):
                                           False, path_type)
 
 class PersistentRefInlineWidget(QtGui.QWidget, ConstantWidgetMixin):
+    contentsChanged = QtCore.pyqtSignal(tuple)
     def __init__(self, param, parent=None):
         self.param = param
         self.strValue = param.strValue
diff --git a/vistrails/packages/persistent_archive/__init__.py b/vistrails/packages/persistent_archive/__init__.py
new file mode 100644
index 0000000..54f46f8
--- /dev/null
+++ b/vistrails/packages/persistent_archive/__init__.py
@@ -0,0 +1,50 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.configuration import ConfigurationObject
+
+from .identifiers import *
+
+
+configuration = ConfigurationObject(file_store=(None, str))
+
+
+def package_requirements():
+    from vistrails.core.requirements import require_python_module
+    require_python_module('file_archive', {
+            'pip': 'file_archive'})
diff --git a/vistrails/packages/persistent_archive/cache.py b/vistrails/packages/persistent_archive/cache.py
new file mode 100644
index 0000000..adfb404
--- /dev/null
+++ b/vistrails/packages/persistent_archive/cache.py
@@ -0,0 +1,141 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from datetime import datetime
+import os
+
+from vistrails.core.modules.basic_modules import Directory, File, Path, \
+    PathObject
+from vistrails.core.modules.config import IPort, OPort
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+from .common import KEY_TYPE, TYPE_CACHED, KEY_TIME, KEY_SIGNATURE, \
+    get_default_store
+
+
+class CachedPath(Module):
+    """Uses the file store as a cache.
+
+    Stores the path in the cache along with the module signature, so it can be
+    retrieved in a later execution of the same pipeline.
+
+    This is very similar to PersistedPath except it doesn't record more
+    metadata than what's required for caching.
+    """
+
+    _input_ports = [
+            IPort('path', Path)]
+    _output_ports = [
+            OPort('path', Path)]
+
+    _cached = None
+
+    def update_upstream(self):
+        if not hasattr(self, 'signature'):
+            raise ModuleError(self, "Module has no signature")
+        file_store = get_default_store()
+        entries = file_store.query({KEY_SIGNATURE: self.signature})
+        best = None
+        for entry in entries:
+            if best is None or entry[KEY_TIME] > best[KEY_TIME]:
+                best = entry
+        if best is not None:
+            self._cached = best.filename
+        else:
+            super(CachedPath, self).update_upstream()
+
+    def compute(self):
+        if self._cached is not None:
+            self._set_result(self._cached)
+        else:
+            file_store = get_default_store()
+            newpath = self.get_input('path').name
+            self.check_path_type(newpath)
+            metadata = {
+                    KEY_TYPE: TYPE_CACHED,
+                    KEY_TIME: datetime.strftime(datetime.utcnow(),
+                                                '%Y-%m-%d %H:%M:%S'),
+                    KEY_SIGNATURE: self.signature}
+            entry = file_store.add(newpath, metadata)
+            self.annotate({'added_file': entry['hash']})
+            self._set_result(entry.filename)
+
+    def check_path_type(self, path):
+        pass
+
+    def _set_result(self, path):
+        self.set_output('path', PathObject(path))
+
+
+class CachedFile(CachedPath):
+    """Uses the file store as a cache.
+
+    Stores the file in the cache along with the module signature, so it can be
+    retrieved in a later execution of the same pipeline.
+
+    This is very similar to PersistedFile except it doesn't record more
+    metadata than what's required for caching.
+    """
+
+    _input_ports = [
+            IPort('path', File)]
+    _output_ports = [
+            OPort('path', File)]
+
+    def check_path_type(self, path):
+        if not os.path.isfile(path):
+            raise ModuleError(self, "Path is not a file")
+
+
+class CachedDir(CachedPath):
+    """Uses the file store as a cache.
+
+    Stores the directory in the cache along with the module signature, so it
+    can be retrieved in a later execution of the same pipeline.
+
+    This is very similar to PersistedDir except it doesn't record more metadata
+    than what's required for caching.
+    """
+
+    _input_ports = [
+            IPort('path', Directory)]
+    _output_ports = [
+            OPort('path', Directory)]
+
+    def check_path_type(self, path):
+        if not os.path.isdir(path):
+            raise ModuleError(self, "Path is not a directory")
diff --git a/vistrails/packages/persistent_archive/common.py b/vistrails/packages/persistent_archive/common.py
new file mode 100644
index 0000000..96baeb9
--- /dev/null
+++ b/vistrails/packages/persistent_archive/common.py
@@ -0,0 +1,142 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.modules.basic_modules import Constant, String
+from vistrails.core.modules.config import IPort, OPort
+from vistrails.core.modules.vistrails_module import ModuleError
+
+
+ at apply
+class StoreHolder(object):
+    def __init__(self):
+        self.store = None
+
+    def get_store(self):
+        return self.store
+
+    def set_store(self, store):
+        self.store = store
+
+set_default_store = StoreHolder.set_store
+get_default_store = StoreHolder.get_store
+
+
+# The type of the file, i.e. how VisTrails stored it
+KEY_TYPE = 'vistrails_objecttype'
+TYPE_CACHED =   'cached'    # A cached path, with very little metadata
+TYPE_INPUT =    'input'     # An input file, i.e. an external file that
+                            # VisTrails added to the store as-is
+TYPE_OUTPUT =   'output'    # An intermediate or output file, i.e. a file that
+                            # was generated by VisTrails
+
+# Timestamp for file insertion
+KEY_TIME = 'vistrails_timestamp'
+
+# Signature of the module that added the file (cached and output, not input)
+KEY_SIGNATURE = 'vistrails_signature'
+
+# Identifier for the workflow
+KEY_WORKFLOW = 'vistrails_workflow'
+
+# Module ID in the workflow
+KEY_MODULE_ID = 'vistrails_module_id'
+
+
+class PersistentHash(Constant):
+    """Reference to a specific file.
+
+    Unequivocally references a specific file (by its full hash).
+    """
+    def __init__(self, h=None):
+        Constant.__init__(self)
+        if h is not None:
+            self._set_hash(h)
+        else:
+            self._hash = None
+
+    def _set_hash(self, h):
+        if not (isinstance(h, basestring)):
+            raise TypeError("File hash should be a string")
+        elif len(h) != 40:
+            raise ValueError("File hash should be 40 characters long")
+        if not isinstance(h, bytes):
+            h = bytes(h)
+        self._hash = h
+
+    @staticmethod
+    def translate_to_python(h):
+        try:
+            return PersistentHash(h)
+        except (TypeError, ValueError):
+            return None
+
+    @staticmethod
+    def translate_to_string(ref):
+        if ref._hash is not None:
+            return ref._hash
+        else:
+            raise ValueError("Reference is invalid")
+
+    @staticmethod
+    def validate(ref):
+        return isinstance(ref, PersistentHash)
+
+    def __str__(self):
+        return self._hash
+
+    def __repr__(self):
+        if self._hash is not None:
+            return "<PersistentHash %s>" % self._hash
+        else:
+            return "<PersistentHash (invalid)>"
+
+    def compute(self):
+        if self.has_input('value') == self.has_input('hash'):
+            raise ModuleError(self, "Set either 'value' or 'hash'")
+        if self.has_input('value'):
+            self._hash = self.get_input('value')._hash
+        else:
+            try:
+                self._set_hash(self.get_input('hash'))
+            except ValueError, e:
+                raise ModuleError(self, e.message)
+
+PersistentHash._input_ports = [
+        IPort('value', PersistentHash),
+        IPort('hash', String)]
+PersistentHash._output_ports = [
+        OPort('value', PersistentHash)]
diff --git a/vistrails/packages/persistent_archive/identifiers.py b/vistrails/packages/persistent_archive/identifiers.py
new file mode 100644
index 0000000..50b1641
--- /dev/null
+++ b/vistrails/packages/persistent_archive/identifiers.py
@@ -0,0 +1,40 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+identifier = 'org.vistrails.vistrails.persistent_archive'
+version = '0.0.2'
+name = 'Persistent Archive'
diff --git a/vistrails/packages/persistent_archive/init.py b/vistrails/packages/persistent_archive/init.py
new file mode 100644
index 0000000..d632e9c
--- /dev/null
+++ b/vistrails/packages/persistent_archive/init.py
@@ -0,0 +1,101 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from file_archive import FileStore
+import os
+
+from vistrails.core.system import current_dot_vistrails
+
+from .common import set_default_store, PersistentHash
+from .cache import CachedPath, CachedFile, CachedDir
+from .queries import QueryCondition, EqualString, EqualInt, IntInRange, \
+    Metadata
+from .persistedinput import PersistedInputPath, \
+    PersistedInputFile, PersistedInputDir
+from .queriedinput import QueriedInputPath, QueriedInputFile, QueriedInputDir
+from .persistedoutput import PersistedPath, PersistedFile, PersistedDir
+
+
+def initialize():
+    if configuration.check('file_store'):
+        file_store_path = configuration.file_store
+    else:
+        file_store_path = os.path.join(current_dot_vistrails(), 'file_archive')
+    if not os.path.exists(file_store_path) or not os.listdir(file_store_path):
+        FileStore.create_store(file_store_path)
+    set_default_store(FileStore(file_store_path))
+
+
+_modules = {
+        '': [
+            # Reference to a specific file
+            PersistentHash,
+
+            # Caching modules
+            (CachedPath, {'abstract': True}),
+            CachedFile,
+            CachedDir,
+
+            # Input modules
+            (PersistedInputPath, {'abstract': True}),
+            PersistedInputFile,
+            PersistedInputDir,
+
+            # Query modules
+            (QueriedInputPath, {'abstract': True}),
+            QueriedInputFile,
+            QueriedInputDir,
+
+            # Output modules
+            (PersistedPath, {'abstract': True}),
+            PersistedFile,
+            PersistedDir,
+        ],
+        'metadata': [
+            # Condition & metadata modules
+            (QueryCondition, {'abstract': True}),
+            (Metadata, {'abstract': True}),
+            EqualString,
+            EqualInt,
+            IntInRange,
+        ],
+    }
+
+
+def menu_items():
+    from ui import show_viewer
+    return [("Show archive content", show_viewer)]
diff --git a/vistrails/packages/persistent_archive/persistedinput.py b/vistrails/packages/persistent_archive/persistedinput.py
new file mode 100644
index 0000000..9e12b79
--- /dev/null
+++ b/vistrails/packages/persistent_archive/persistedinput.py
@@ -0,0 +1,183 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from datetime import datetime
+from file_archive import hash_file, hash_directory
+import os
+
+import vistrails.core.debug as debug
+from vistrails.core.modules.basic_modules import Directory, File, Path, \
+    PathObject
+from vistrails.core.modules.config import IPort, OPort, ModuleSettings
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+from .common import KEY_TYPE, TYPE_INPUT, KEY_TIME, \
+    get_default_store, PersistentHash
+from .queries import Metadata
+
+
+def hash_path(path):
+    if os.path.isdir(path):
+        return hash_directory(path)
+    else:
+        with open(path, 'rb') as fp:
+            return hash_file(fp)
+
+
+class PersistedInputPath(Module):
+    """Records or retrieves an external file in the file store.
+
+    Because this class has the same interface for querying an existing file and
+    inserting a new one, it uses Metadata instead of QueryCondition for the
+    query. This means it only allows equality conditions.
+    """
+
+    _input_ports = [
+            IPort('path', Path, optional=True),
+            IPort('metadata', Metadata, optional=True),
+            IPort('hash', PersistentHash, optional=True)]
+    _output_ports = [
+            OPort('path', Path)]
+
+    def compute(self):
+        localpath = self.force_get_input('path')
+        hasquery = self.has_input('metadata')
+        hashash = self.has_input('hash')
+
+        file_store = get_default_store()
+
+        if hashash:
+            if localpath or hasquery:
+                raise ModuleError(self,
+                                  "Don't set other ports if 'hash' is set")
+            h = self.get_input('hash')._hash
+            self._set_result(file_store.get(h))
+        elif hasquery:
+            # Do the query
+            metadata = self.get_input_list('metadata')
+            metadata = dict(m.metadata for m in metadata)
+            # Find the most recent match
+            best = None
+            for entry in file_store.query(metadata):
+                if best is None or (KEY_TIME in entry.metadata and
+                        entry[KEY_TIME] > best[KEY_TIME]):
+                    best = entry
+            if best is not None:
+                self.check_path_type(best.filename)
+
+            if localpath and os.path.exists(localpath.name):
+                path = localpath.name
+                self.check_path_type(path)
+                if best is not None:
+                    # Compare
+                    if hash_path(path) != best['hash']:
+                        # Record new version of external file
+                        use_local = True
+                    else:
+                        # Recorded version is up to date
+                        use_local = False
+                else:
+                    # No external file: use recorded version
+                    use_local = True
+                if use_local:
+                    data = dict(metadata)
+                    data[KEY_TYPE] = TYPE_INPUT
+                    data[KEY_TIME] = datetime.strftime(datetime.utcnow(),
+                                                       '%Y-%m-%d %H:%M:%S')
+                    best = file_store.add(path, data)
+                    self.annotate({'added_file': best['hash']})
+            elif localpath:
+                debug.warning("Local file does not exist: %s" % localpath)
+            if best is None:
+                raise ModuleError(self, "Query returned no file")
+            self._set_result(best)
+        else:
+            raise ModuleError(self,
+                              "Missing input: set either 'metadata' "
+                              "(optionally with path) or hash")
+
+    def check_path_type(self, path):
+        pass
+
+    def _set_result(self, entry):
+        self.set_output('path', PathObject(entry.filename))
+        # TODO : output metadata
+
+
+class PersistedInputFile(PersistedInputPath):
+    """Records or retrieves an external file in the file store.
+
+    Because this class has the same interface for querying an existing file and
+    inserting a new one, it uses Metadata instead of QueryCondition for the
+    query. This means it only allows equality conditions.
+    """
+
+    _input_ports = [
+            IPort('path', File, optional=True),
+            IPort('metadata', Metadata, optional=True),
+            IPort('hash', PersistentHash, optional=True)]
+    _output_ports = [
+            OPort('path', File)]
+    _settings = ModuleSettings(configure_widget=
+            'vistrails.packages.persistent_archive.widgets:SetMetadataWidget')
+
+    def check_path_type(self, path):
+        if not os.path.isfile(path):
+            raise ModuleError(self, "Path is not a file")
+
+
+class PersistedInputDir(PersistedInputPath):
+    """Records or retrieves an external directory in the file store.
+
+    Because this class has the same interface for querying an existing
+    directory and inserting a new one, it uses Metadata instead of
+    QueryCondition for the query. This means it only allows equality
+    conditions.
+    """
+
+    _input_ports = [
+            IPort('path', Directory,  optional=True),
+            IPort('metadata', Metadata,  optional=True),
+            IPort('hash', PersistentHash,  optional=True)]
+    _output_ports = [
+            OPort('path', File)]
+    _settings = ModuleSettings(configure_widget=
+            'vistrails.packages.persistent_archive.widgets:SetMetadataWidget')
+
+    def check_path_type(self, path):
+        if not os.path.isdir(path):
+            raise ModuleError(self, "Path is not a directory")
diff --git a/vistrails/packages/persistent_archive/persistedoutput.py b/vistrails/packages/persistent_archive/persistedoutput.py
new file mode 100644
index 0000000..1bf4e73
--- /dev/null
+++ b/vistrails/packages/persistent_archive/persistedoutput.py
@@ -0,0 +1,142 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from datetime import datetime
+import os
+
+from vistrails.core.modules.basic_modules import Directory, File, Path, \
+    PathObject
+from vistrails.core.modules.config import IPort, OPort, ModuleSettings
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+from .common import KEY_TYPE, TYPE_OUTPUT, \
+    KEY_SIGNATURE, KEY_TIME, KEY_WORKFLOW, KEY_MODULE_ID, get_default_store
+from .queries import Metadata
+
+
+class PersistedPath(Module):
+    """Records a file in the file store.
+    """
+
+    _input_ports = [
+            IPort('path', Path),
+            IPort('metadata', Metadata, optional=True)]
+    _output_ports = [
+            OPort('path', Path)]
+
+    _cached = None
+
+    def update_upstream(self):
+        """A modified version of the update_upstream method.
+
+        Only updates upstream if the file is not found in the store.
+        """
+        if not hasattr(self, 'signature'):
+            raise ModuleError(self, "Module has no signature")
+        file_store = get_default_store()
+        entries = file_store.query({KEY_SIGNATURE: self.signature})
+        best = None
+        for entry in entries:
+            if best is None or entry[KEY_TIME] > best[KEY_TIME]:
+                best = entry
+        if best is not None:
+            self._cached = best.filename
+        else:
+            super(PersistedPath, self).update_upstream()
+
+    def compute(self):
+        if self._cached is not None:
+            self._set_result(self._cached)
+        else:
+            file_store = get_default_store()
+            newpath = self.get_input('path').name
+            self.check_path_type(newpath)
+            metadata = self.get_input_list('metadata')
+            metadata = dict(m.metadata for m in metadata)
+            metadata[KEY_TYPE] = TYPE_OUTPUT
+            metadata[KEY_TIME] = datetime.strftime(datetime.utcnow(),
+                                                   '%Y-%m-%d %H:%M:%S')
+            metadata[KEY_SIGNATURE] = self.signature
+            locator = self.moduleInfo.get('locator')
+            if locator is not None:
+                metadata[KEY_WORKFLOW] = "%s:%s" % (
+                        locator.name,
+                        self.moduleInfo['version'])
+            metadata[KEY_MODULE_ID] = self.moduleInfo['moduleId']
+            entry = file_store.add(newpath, metadata)
+            self.annotate({'added_file': entry['hash']})
+            self._set_result(entry.filename)
+
+    def check_path_type(self, path):
+        pass
+
+    def _set_result(self, path):
+        self.set_output('path', PathObject(path))
+
+
+class PersistedFile(PersistedPath):
+    """Records a file in the file store.
+    """
+
+    _input_ports = [
+            IPort('path', File),
+            IPort('metadata', Metadata, optional=True)]
+    _output_ports = [
+            OPort('path', File)]
+    _settings = ModuleSettings(configure_widget=
+            'vistrails.packages.persistent_archive.widgets:SetMetadataWidget')
+
+    def check_path_type(self, path):
+        if not os.path.isfile(path):
+            raise ModuleError(self, "Path is not a file")
+
+
+class PersistedDir(PersistedPath):
+    """Records a directory in the file store.
+    """
+
+    _input_ports = [
+            IPort('path', Directory),
+            IPort('metadata', Metadata, optional=True)]
+    _output_ports = [
+            OPort('path', Directory)]
+    _settings = ModuleSettings(configure_widget=
+            'vistrails.packages.persistent_archive.widgets:SetMetadataWidget')
+
+    def check_path_type(self, path):
+        if not os.path.isdir(path):
+            raise ModuleError(self, "Path is not a directory")
diff --git a/vistrails/packages/persistent_archive/queriedinput.py b/vistrails/packages/persistent_archive/queriedinput.py
new file mode 100644
index 0000000..812de13
--- /dev/null
+++ b/vistrails/packages/persistent_archive/queriedinput.py
@@ -0,0 +1,138 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import os
+
+from vistrails.core.modules.basic_modules import Boolean, Directory, File, \
+    Integer, List, Path, PathObject
+from vistrails.core.modules.config import IPort, OPort
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+from .common import KEY_TIME, get_default_store
+from .queries import QueryCondition
+
+
+class QueriedInputPath(Module):
+    """Base class for file-querying modules.
+
+    This uses QueryConditions instead of Metadata, allowing for more complex
+    queries than what PersistedInputPath provides (equality in metadata).
+    """
+
+    _input_ports = [
+            IPort('query', QueryCondition),
+            IPort('unique', Boolean, optional=True, default='False')]
+    # TODO: Order by more conditions than only `vistrails_timestamp`
+    _output_ports = [
+            OPort('most_recent', Path),
+            OPort('results', List),
+            OPort('count', Integer, optional=True)]
+    # TODO: Set query from `configure_widget`
+
+    def compute(self):
+        # Do the query
+        queries = self.get_input_list('query')
+        conditions = {}
+        for c in conditions:
+            conditions.update(c.conditions)
+
+        file_store = get_default_store()
+
+        nb = 0
+        best = None
+        entries = list(file_store.query(conditions))
+        for entry in entries:
+            nb += 1
+            self.check_path_type(entry.filename)
+            if best is None or (KEY_TIME in entry.metadata and
+                    KEY_TIME in best.metadata and
+                    entry[KEY_TIME] > best[KEY_TIME]):
+                best = entry
+
+        if best is None:
+            raise ModuleError(self, "No match")
+
+        if nb > 1 and self.get_input('unique'):
+            raise ModuleError(self,
+                              "Query returned %d results and 'unique' is "
+                              "True" % nb)
+
+        self._set_result(entries, best)
+
+    def check_path_type(self, path):
+        pass
+
+    def _set_result(self, results, latest):
+        self.set_output('most_recent', PathObject(latest.filename))
+        self.set_output('results', [PathObject(e.filename)
+                                   for e in results])
+        self.set_output('count', len(results))
+        # TODO : output metadata
+
+
+class QueriedInputFile(QueriedInputPath):
+    """Searches for files using a query.
+
+    This uses QueryConditions instead of Metadata, allowing for more complex
+    queries than what PersistedInputFile provides (equality in metadata).
+    """
+
+    _output_ports = [
+            OPort('most_recent', File),
+            OPort('results', List),
+            OPort('count', Integer, optional=True)]
+
+    def check_path_type(self, path):
+        if not os.path.isfile(path):
+            raise ModuleError(self, "Path is not a file")
+
+
+class QueriedInputDir(QueriedInputPath):
+    """Searches for directories using a query.
+
+    This uses QueryConditions instead of Metadata, allowing for more complex
+    queries than what PersistedInputDir provides (equality in metadata).
+    """
+
+    _output_ports = [
+            OPort('most_recent', Directory),
+            OPort('results', List),
+            OPort('count', Integer, optional=True)]
+
+    def check_path_type(self, path):
+        if not os.path.isdir(path):
+            raise ModuleError(self, "Path is not a directory")
diff --git a/vistrails/packages/persistent_archive/queries.py b/vistrails/packages/persistent_archive/queries.py
new file mode 100644
index 0000000..34f9efd
--- /dev/null
+++ b/vistrails/packages/persistent_archive/queries.py
@@ -0,0 +1,241 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from file_archive.parser import parse_expression
+
+from vistrails.core.modules.basic_modules import Constant, Integer, String
+from vistrails.core.modules.config import IPort, OPort
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+
+def find_subclass(cls, subname):
+    """Find a subclass by name.
+    """
+    l = [cls]
+    while l:
+        l2 = []
+        for c in l:
+            if c.__name__ == subname:
+                return c
+            l2 += c.__subclasses__()
+        l = l2
+    return None
+
+
+class QueryCondition(Constant):
+    """Base class for query conditions.
+
+    This is abstract and implemented by modules Query*
+    """
+    _input_ports = [
+            IPort('key', String)]
+
+    @staticmethod
+    def translate_to_python(c, top_class=None, text_query=True):
+        try:
+            i = c.index('(')
+        except ValueError:
+            if text_query:
+                return TextQuery(c)
+            raise ValueError("Invalid QueryCondition syntax")
+        clsname = c[:i]
+        cls = find_subclass(top_class or QueryCondition, clsname)
+        if cls is not None:
+            return cls(*eval(c[i+1:-1]))
+        elif text_query:
+            return TextQuery(c)
+        else:
+            raise ValueError("No such condition type: %s" % clsname)
+
+    @staticmethod
+    def translate_to_string(cond):
+        return str(cond)
+
+    @staticmethod
+    def validate(cond):
+        return isinstance(cond, QueryCondition)
+
+    def __str__(self):
+        raise NotImplementedError
+
+    def __repr__(self):
+        return self.__str__()
+
+QueryCondition._output_ports = [
+        OPort('value', QueryCondition)]
+
+
+class TextQuery(QueryCondition):
+    """A query from a text expression.
+    """
+    def __init__(self, text):
+        self.query = text
+        self.conditions = parse_expression(text)
+
+    def __str__(self):
+        return self.query
+
+
+class Metadata(QueryCondition):
+    """Base class for metadata pairs.
+
+    This is abstract and implemented by modules Equal*
+
+    This both provides a metadata pair, as the 'metadata' attribute, for
+    inserting, and conditions, through the 'conditions' attribute.
+    """
+    _input_ports = [
+            IPort('key', String),
+            IPort('value', Module)]
+
+    def __init__(self, *args):
+        super(Metadata, self).__init__()
+
+        if args:
+            self.key, self.value = args
+            self.set_results()
+        else:
+            self.key, self.value = None, None
+
+    @staticmethod
+    def translate_to_python(c):
+        return QueryCondition.translate_to_python(
+                c,
+                top_class=Metadata, text_query=False)
+
+    def compute(self):
+        self.key = self.get_input('key')
+        self.value = self.get_input('value')
+
+        self.set_results()
+
+    def set_results(self):
+        self.conditions = {self.key: {'type': self._type, 'equal': self.value}}
+        self.metadata = (self.key, self.value)
+        self.set_output('value', self)
+
+    def __str__(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.key, self.value)
+
+    @staticmethod
+    def get_widget_class():
+        from .widgets import MetadataConstantWidget
+        return MetadataConstantWidget
+
+Metadata._output_ports = [
+        OPort('value', Metadata)]
+
+
+class EqualString(Metadata):
+    """A string metadata.
+
+    A piece of metadata with a value of type string. When used in a query,
+    means "key has a value of type string equal to <value>".
+    """
+    _input_ports = [
+            IPort('key', String),
+            IPort('value', String)]
+
+    _type = 'str'
+
+
+class EqualInt(Metadata):
+    """An integer metadata.
+
+    A piece of metadata with a value of type integer. When used in a query,
+    means "key has a value of type integer equal to <value>".
+    """
+    _input_ports = [
+            IPort('key', String),
+            IPort('value', Integer)]
+
+    _type = 'int'
+
+    def __init__(self, *args):
+        if args:
+            key, value = args
+            assert isinstance(value, (int, long))
+        Metadata.__init__(self, *args)
+
+
+class IntInRange(QueryCondition):
+    """An integer range condition.
+
+    Means "key has a value of type integer which lies between <lower_bound> and
+    <higher_bound>".
+
+    Note that you can omit one of the bounds.
+    """
+    _input_ports = [
+            IPort('key', String),
+            IPort('lower_bound', Integer, optional=True),
+            IPort('higher_bound', Integer, optional=True)]
+
+    def __init__(self, *args):
+        super(IntInRange, self).__init__()
+
+        if args:
+            self.key, self.low, self.high = args
+            assert isinstance(self.low, (int, long))
+            assert isinstance(self.high, (int, long))
+            self.set_results()
+        else:
+            self.key, self.low, self.high = None, None, None
+
+    def compute(self):
+        self.key = self.get_input('key')
+        if self.has_input('lower_bound'):
+            self.low = self.get_input('lower_bound')
+        if self.has_input('higher_bound'):
+            self.high = self.get_input('higher_bound')
+        if not (self.low is not None or self.high is not None):
+            raise ModuleError(self, "No bound set")
+        self.set_results()
+
+    def set_results(self):
+        dct = {}
+        if self.low is not None:
+            dct['gt'] = self.low
+        if self.high is not None:
+            dct['lt'] = self.high
+        dct['type'] = 'int'
+
+        self.conditions = {self.key: dct}
+        self.set_output('value', self)
+
+    def __str__(self):
+        return '%s(%r, %r, %r)' % ('IntInRange', self.key, self.low, self.high)
diff --git a/vistrails/packages/persistent_archive/ui.py b/vistrails/packages/persistent_archive/ui.py
new file mode 100644
index 0000000..8be312f
--- /dev/null
+++ b/vistrails/packages/persistent_archive/ui.py
@@ -0,0 +1,143 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from PyQt4 import QtCore, QtGui
+
+import file_archive.viewer
+from file_archive.viewer import StoreViewerWindow
+
+from vistrails.core.application import get_vistrails_application
+from vistrails.core.db.locator import FileLocator
+
+from .common import get_default_store, KEY_WORKFLOW, KEY_MODULE_ID
+
+
+class VistrailsViewerWindow(StoreViewerWindow):
+    WINDOW_TITLE = "Persistent archive viewer"
+
+    _vt_only = True
+
+    def _create_buttons(self):
+        buttons = super(VistrailsViewerWindow, self)._create_buttons()
+
+        open_vt_button = QtGui.QPushButton("Go to Vistrail")
+        self.connect(open_vt_button, QtCore.SIGNAL('clicked()'),
+                     self._open_vt)
+        buttons.append(('vt', open_vt_button))
+
+        only_vt_checkbox = QtGui.QCheckBox("Only VisTrails Persisted files")
+        only_vt_checkbox.setChecked(self._vt_only)
+        self.connect(only_vt_checkbox, QtCore.SIGNAL('stateChanged(int)'),
+                     self._set_vt_only)
+        buttons.append(('alwayson', only_vt_checkbox))
+
+        return buttons
+
+    def _set_vt_only(self, state):
+        state = state == QtCore.Qt.Checked
+        if state == self._vt_only:
+            return
+        self._vt_only = state
+        self._search()
+
+    def _alter_search_conditions(self, conditions):
+        if self._vt_only and not KEY_WORKFLOW in conditions:
+            conditions[KEY_WORKFLOW] = {'type': 'str'}
+        return conditions
+
+    def _selection_changed(self):
+        super(VistrailsViewerWindow, self)._selection_changed()
+        items = self._result_tree.selectedItems()
+        for t, button in self._buttons:
+            if t == 'vt':
+                button.setEnabled(
+                        len(items) == 1 and
+                        self._find_vt(items[0]) is not None)
+
+    @staticmethod
+    def _find_vt(item):
+        if isinstance(item, file_archive.viewer.MetadataItem):
+            item = item.parent()
+        metadata = item.entry.metadata
+        try:
+            workflow = metadata[KEY_WORKFLOW]
+            module_id = metadata[KEY_MODULE_ID]
+        except KeyError:
+            return None
+        return (workflow, module_id)
+
+    def _open_vt(self):
+        items = self._result_tree.selectedItems()
+        item = items[0]
+        vt = self._find_vt(item)
+        if vt is None:
+            return
+        workflow, module_id = vt
+
+        if ':' in workflow:
+            filename, version = workflow.rsplit(':', 1)
+            try:
+                version = int(version)
+            except ValueError:
+                filename, version = workflow, None
+        else:
+            filename, version = workflow, None
+
+        app = get_vistrails_application()
+        if (not app.is_running_gui() or not hasattr(app, 'builderWindow') or
+                app.builderWindow is None):
+            return
+
+        view = app.builderWindow.open_vistrail(FileLocator(filename),
+                                               version=version)
+        if module_id is not None:
+            from vistrails.gui.pipeline_view import QGraphicsModuleItem
+
+            scene = view.controller.current_pipeline_view.scene()
+            for module_item in (i for i in scene.items()
+                                  if isinstance(i, QGraphicsModuleItem)):
+                if module_item.module.id == module_id:
+                    module_item.setSelected(True)
+                    break
+
+
+store = get_default_store()
+viewer = VistrailsViewerWindow(store)
+
+
+def show_viewer():
+    viewer.show()
diff --git a/vistrails/packages/persistent_archive/widgets.py b/vistrails/packages/persistent_archive/widgets.py
new file mode 100644
index 0000000..6b508a8
--- /dev/null
+++ b/vistrails/packages/persistent_archive/widgets.py
@@ -0,0 +1,327 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from PyQt4 import QtCore, QtGui
+
+from vistrails.core.db.action import create_action
+from vistrails.gui.modules.constant_configuration import ConstantWidgetBase
+from vistrails.gui.modules.module_configure import \
+    StandardModuleConfigurationWidget
+
+from .queries import QueryCondition, EqualString, EqualInt
+
+
+def str_repr(s):
+    if isinstance(s, unicode):
+        s = (s.replace('\\', '\\\\')
+              .replace("'", "\\'")
+              .encode('ascii', 'backslashreplace'))
+    else:
+        s = (s.replace('\\', '\\\\')
+              .replace("'", "\\'"))
+    return "'%s'" % s
+
+
+class Metadata(QtGui.QWidget):
+    remove = QtCore.pyqtSignal()
+    changed = QtCore.pyqtSignal()
+
+    def __init__(self, name, value=None):
+        QtGui.QWidget.__init__(self)
+        layout = QtGui.QHBoxLayout()
+        self.setLayout(layout)
+
+        self.key = QtGui.QLineEdit()
+        self.key.setText(name)
+        layout.addWidget(self.key, 1)
+        self.value = self.value_widget(value)
+        layout.addWidget(self.value, 2)
+
+        remove_button = QtGui.QPushButton("Remove port")
+        remove_button.setSizePolicy(QtGui.QSizePolicy.Fixed,
+                                    QtGui.QSizePolicy.Fixed)
+        layout.addWidget(remove_button)
+
+        self.connect(remove_button, QtCore.SIGNAL('clicked()'),
+                     self.remove)
+        self.connect(self.key, QtCore.SIGNAL('textEdited(const QString &)'),
+                     self.changed)
+        self.connect(self.value, QtCore.SIGNAL('textEdited(const QString &)'),
+                     self.changed)
+
+
+class StringMetadata(Metadata):
+    @staticmethod
+    def value_widget(value=None):
+        return QtGui.QLineEdit(value)
+
+    def to_string(self):
+        return 'EqualString(%s, %s)' % (str_repr(self.key.text()),
+                                        str_repr(self.value.text()))
+
+
+class IntMetadata(Metadata):
+    def value_widget(self, value=None):
+        w = QtGui.QLineEdit()
+        if value is not None:
+            w.setText('%d' % value)
+        w.setValidator(QtGui.QIntValidator(self))
+        return w
+
+    def to_string(self):
+        try:
+            i = int(self.value.text())
+        except ValueError:
+            i = 0
+        return 'EqualInt(%s, %d)' % (str_repr(self.key.text()), i)
+
+
+class SetMetadataWidget(StandardModuleConfigurationWidget):
+    """
+    Configuration widget allowing to set metadata on persisted modules.
+
+    It is a visual editor for the strings functions set on the 'metadata' port,
+    which have the form EqualString('mkey', 'mvalue') or EqualInt('mkey', 2).
+    """
+    def __init__(self, module, controller, parent=None):
+        StandardModuleConfigurationWidget.__init__(self, module,
+                                                   controller, parent)
+
+        # Window title
+        self.setWindowTitle("Metadata editor")
+
+        central_layout = QtGui.QVBoxLayout()
+        central_layout.setMargin(0)
+        central_layout.setSpacing(0)
+        self.setLayout(central_layout)
+
+        self._scroll_area = QtGui.QScrollArea()
+        inner_widget = QtGui.QWidget()
+        self._list_layout = QtGui.QVBoxLayout()
+        scroll_layout = QtGui.QVBoxLayout()
+        scroll_layout.addLayout(self._list_layout)
+        scroll_layout.addStretch()
+        inner_widget.setLayout(scroll_layout)
+        self._scroll_area.setVerticalScrollBarPolicy(
+                QtCore.Qt.ScrollBarAlwaysOn)
+        self._scroll_area.setWidget(inner_widget)
+        self._scroll_area.setWidgetResizable(True)
+        central_layout.addWidget(self._scroll_area)
+
+        add_buttons = QtGui.QHBoxLayout()
+        central_layout.addLayout(add_buttons)
+        add_string = QtGui.QPushButton("Add a string")
+        self.connect(add_string, QtCore.SIGNAL('clicked()'),
+                     self.add_string)
+        add_buttons.addWidget(add_string, 2)
+        add_int = QtGui.QPushButton("Add an integer")
+        self.connect(add_int, QtCore.SIGNAL('clicked()'),
+                     self.add_int)
+        add_buttons.addWidget(add_int, 1)
+
+        self.createButtons()
+
+        self.createEntries()
+
+    def add_item(self, item):
+        self._list_layout.addWidget(item)
+        self.connect(item, QtCore.SIGNAL('remove()'),
+                     lambda: item.deleteLater())
+        self.connect(item, QtCore.SIGNAL('changed()'),
+                     self.updateState)
+
+    def add_string(self):
+        self.add_item(StringMetadata(
+                "string%d" % (self._list_layout.count() + 1)))
+        self.updateState()
+
+    def add_int(self):
+        self.add_item(IntMetadata(
+                "int%d" % (self._list_layout.count() + 1)))
+        self.updateState()
+
+    def createButtons(self):
+        """ createButtons() -> None
+        Create and connect signals to Ok & Cancel button
+
+        """
+        buttonLayout = QtGui.QHBoxLayout()
+        buttonLayout.setMargin(5)
+        self.saveButton = QtGui.QPushButton("&Save", self)
+        self.saveButton.setFixedWidth(100)
+        self.saveButton.setEnabled(False)
+        buttonLayout.addWidget(self.saveButton)
+        self.resetButton = QtGui.QPushButton("&Reset", self)
+        self.resetButton.setFixedWidth(100)
+        self.resetButton.setEnabled(False)
+        buttonLayout.addWidget(self.resetButton)
+        self.layout().addLayout(buttonLayout)
+        self.connect(self.saveButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.saveTriggered)
+        self.connect(self.resetButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.resetTriggered)
+
+    def saveTriggered(self, checked = False):
+        """ saveTriggered(checked: bool) -> None
+        Update vistrail controller and module when the user click Ok
+
+        """
+        if self.updateVistrail():
+            self.saveButton.setEnabled(False)
+            self.resetButton.setEnabled(False)
+            self.state_changed = False
+            self.emit(QtCore.SIGNAL('stateChanged'))
+            self.emit(QtCore.SIGNAL('doneConfigure'), self.module.id)
+
+    def closeEvent(self, event):
+        self.askToSaveChanges()
+        event.accept()
+
+    def updateVistrail(self):
+        """ updateVistrail() -> None
+        Update functions on the metadata port of the module
+        """
+        # Remove the keys that we loaded
+        ops = [('delete', func) for func in self._loaded_keys]
+
+        # Add the metadata in the list
+        for i in xrange(self._list_layout.count()):
+            widget = self._list_layout.itemAt(i).widget()
+            ops.extend(self.controller.update_function_ops(
+                    self.module, 'metadata',
+                    [widget.to_string()]))
+
+        # This code should really be in VistrailController
+        self.controller.flush_delayed_actions()
+        action = create_action(ops)
+        self.controller.add_new_action(action,
+                                       "Updated PersistedPath metadata")
+        self.controller.perform_action(action)
+
+        return True
+
+    def getCurrentFunctions(self):
+        for i in xrange(self.module.getNumFunctions()):
+            func = self.module.functions[i]
+            if func.name == 'metadata':
+                yield func, func.params[0].strValue
+
+    def createEntries(self):
+        self._loaded_keys = set()
+        for func, metadata in self.getCurrentFunctions():
+            metadata = QueryCondition.translate_to_python(metadata)
+            save = True
+            if metadata is None:
+                save = False
+            elif isinstance(metadata, EqualString):
+                self.add_item(StringMetadata(metadata.key, metadata.value))
+            elif isinstance(metadata, EqualInt):
+                self.add_item(IntMetadata(metadata.key, metadata.value))
+            else:
+                save = False
+
+            if save:
+                self._loaded_keys.add(func)
+
+    def resetTriggered(self, checked = False):
+        for i in xrange(self._list_layout.count()):
+            self._list_layout.itemAt(i).widget().deleteLater()
+
+        self.createEntries()
+
+        self.saveButton.setEnabled(False)
+        self.resetButton.setEnabled(False)
+        self.state_changed = False
+        self.emit(QtCore.SIGNAL('stateChanged'))
+
+    def updateState(self):
+        self.saveButton.setEnabled(True)
+        self.resetButton.setEnabled(True)
+        if not self.state_changed:
+            self.state_changed = True
+            self.emit(QtCore.SIGNAL('stateChanged'))
+
+
+class MetadataConstantWidget(ConstantWidgetBase, QtGui.QWidget):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+
+    def __init__(self, param, parent=None):
+        QtGui.QWidget.__init__(self, parent)
+
+        self._key = QtGui.QLineEdit()
+        self.connect(self._key, QtCore.SIGNAL("returnPressed()"),
+                     self.update_parent)
+
+        self._type = QtGui.QComboBox()
+        self._type.addItems(['int', 'str'])
+        self.connect(self._type, QtCore.SIGNAL("currentIndexChanged()"),
+                     self.update_parent)
+
+        self._value = QtGui.QLineEdit()
+        self.connect(self._value, QtCore.SIGNAL("returnPressed()"),
+                     self.update_parent)
+
+        layout = QtGui.QHBoxLayout()
+        layout.addWidget(self._key)
+        layout.addWidget(self._type)
+        layout.addWidget(self._value)
+        self.setLayout(layout)
+
+        ConstantWidgetBase.__init__(self, param)
+        self.watchForFocusEvents(self._key)
+        self.watchForFocusEvents(self._type)
+        self.watchForFocusEvents(self._value)
+
+    def contents(self):
+        if self._type.currentText() == 'int':
+            return 'EqualInt(%s, %s)' % (str_repr(self._key.text()),
+                                         self._value.text())
+        else:  # self._type.currentText() == 'str':
+            return 'EqualString(%s, %s)' % (str_repr(self._key.text()),
+                                            str_repr(self._value.text()))
+
+    def setContents(self, value, silent=False):
+        cond = QueryCondition.translate_to_python(value, text_query=False)
+        self._key.setText(cond.key)
+        if isinstance(cond, EqualInt):
+            self._type.setCurrentIndex(0)
+            self._value.setText('%d' % cond.value)
+        elif isinstance(cond, EqualString):
+            self._type.setCurrentIndex(1)
+            self._value.setText(cond.value)
+        if not silent:
+            self.update_parent()
diff --git a/vistrails/packages/pipelineEdit/__init__.py b/vistrails/packages/pipelineEdit/__init__.py
index ce8f86c..519ed96 100644
--- a/vistrails/packages/pipelineEdit/__init__.py
+++ b/vistrails/packages/pipelineEdit/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,6 +37,8 @@
 pipeline, change its parameters based on aliases, and execute them on
 the spreadsheet."""
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.pipelineedit'
 name = 'Pipeline Editor'
 version = '0.0.2'
diff --git a/vistrails/packages/pipelineEdit/init.py b/vistrails/packages/pipelineEdit/init.py
index 61b4397..5bea2cf 100644
--- a/vistrails/packages/pipelineEdit/init.py
+++ b/vistrails/packages/pipelineEdit/init.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 import vistrails.api
 from vistrails.core.utils import DummyView
diff --git a/vistrails/packages/pythonCalc/__init__.py b/vistrails/packages/pythonCalc/__init__.py
index e2f845f..7f74f45 100644
--- a/vistrails/packages/pythonCalc/__init__.py
+++ b/vistrails/packages/pythonCalc/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -41,7 +42,9 @@ should also consult the documentation in the User's Guide and in
 core/modules/vistrails_module.py.
 """
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.pythoncalc'
 name = 'PythonCalc'
-version = '0.9.1'
+version = '0.9.2'
 old_identifiers = ['edu.utah.sci.vistrails.pythoncalc']
diff --git a/vistrails/packages/pythonCalc/init.py b/vistrails/packages/pythonCalc/init.py
index 32b73b6..1e076db 100644
--- a/vistrails/packages/pythonCalc/init.py
+++ b/vistrails/packages/pythonCalc/init.py
@@ -1,39 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-import vistrails.core.modules.module_registry
+
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module, ModuleError
+from vistrails.core.modules.config import IPort, OPort
 
 ###############################################################################
 # PythonCalc
@@ -49,7 +53,28 @@ from vistrails.core.modules.vistrails_module import Module, ModuleError
 
 class PythonCalc(Module):
     """PythonCalc is a module that performs simple arithmetic operations
-on its inputs."""
+    on its inputs.
+
+    """
+
+    # You need to report the ports the module wants to make
+    # available. This is done by creating _input_ports and
+    # _output_ports lists composed of InputPort (IPort) and OutputPort
+    # (OPort) objects. These are simple ports that take only one
+    # value. We'll see in later tutorials how to create compound ports
+    # which can take a tuple of values.  Each port must specify its
+    # name and signature.  The signature specifies the package
+    # (e.g. "basic" which is shorthand for
+    # "org.vistrails.vistrails.basic") and module (e.g. "Float").
+    # Note that the third input port (op) has two other arguments.
+    # The "enum" entry_type specifies that there are a set of options
+    # the user should choose from, and the values then specifies those
+    # options.
+    _input_ports = [IPort(name="value1", signature="basic:Float"),
+                    IPort(name="value2", signature="basic:Float"),
+                    IPort(name="op", signature="basic:String",
+                          entry_type="enum", values=["+", "-", "*", "/"])]
+    _output_ports = [OPort(name="value", signature="basic:Float")]
 
     # This constructor is strictly unnecessary. However, some modules
     # might want to initialize per-object data. When implementing your
@@ -62,22 +87,22 @@ on its inputs."""
     # will be executed directly. VisTrails does not use the return
     # value of this method.
     def compute(self):
-        # getInputFromPort is a method defined in Module that returns
+        # get_input is a method defined in Module that returns
         # the value stored at an input port. If there's no value
         # stored on the port, the method will return None.
-        v1 = self.getInputFromPort("value1")
-        v2 = self.getInputFromPort("value2")
+        v1 = self.get_input("value1")
+        v2 = self.get_input("value2")
 
-        # You should call setResult to store the appropriate results
+        # You should call set_output to store the appropriate results
         # on the ports.  In this case, we are only storing a
         # floating-point result, so we can use the number types
         # directly. For more complicated data, you should
         # return an instance of a VisTrails Module. This will be made
         # clear in further examples that use these more complicated data.
-        self.setResult("value", self.op(v1, v2))
+        self.set_output("value", self.op(v1, v2))
 
     def op(self, v1, v2):
-        op = self.getInputFromPort("op")
+        op = self.get_input("op")
         if op == '+':
             return v1 + v2
         elif op == '-':
@@ -92,36 +117,6 @@ on its inputs."""
         # function.
         raise ModuleError(self, "unrecognized operation: '%s'" % op)
 
-###############################################################################
-# the function initialize is called for each package, after all
-# packages have been loaded. It is used to register the module with
-# the VisTrails runtime.
-
-def initialize(*args, **keywords):
-
-    # We'll first create a local alias for the module_registry so that
-    # we can refer to it in a shorter way.
-    reg = vistrails.core.modules.module_registry.get_module_registry()
-
-    # VisTrails cannot currently automatically detect your derived
-    # classes, and the ports that they support as input and
-    # output. Because of this, you as a module developer need to let
-    # VisTrails know that you created a new module. This is done by calling
-    # function addModule:
-    reg.add_module(PythonCalc)
-
-    # In a similar way, you need to report the ports the module wants
-    # to make available. This is done by calling addInputPort and
-    # addOutputPort appropriately. These calls only show how to set up
-    # one-parameter ports. We'll see in later tutorials how to set up
-    # multiple-parameter plots.
-    reg.add_input_port(PythonCalc, "value1",
-                       (vistrails.core.modules.basic_modules.Float, 'the first argument'))
-    reg.add_input_port(PythonCalc, "value2",
-                       (vistrails.core.modules.basic_modules.Float, 'the second argument'))
-    reg.add_input_port(PythonCalc, "op",
-                       (vistrails.core.modules.basic_modules.String, 'the operation'),
-                       entry_types=['enum'], values=["['+', '-', '*', '/']"])
-    reg.add_output_port(PythonCalc, "value",
-                        (vistrails.core.modules.basic_modules.Float, 'the result'))
-
+# VisTrails will only load the modules specified in the _modules list.
+# This list contains all of the modules a package defines.
+_modules = [PythonCalc,]
diff --git a/vistrails/packages/pythonCalcQt/__init__.py b/vistrails/packages/pythonCalcQt/__init__.py
index de5584b..3b8b033 100644
--- a/vistrails/packages/pythonCalcQt/__init__.py
+++ b/vistrails/packages/pythonCalcQt/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -42,6 +43,8 @@ should also consult the documentation in the User's Guide and in
 core/modules/vistrails_module.py.
 """
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.pythoncalcqt'
 name = 'PythonCalcQt'
 version = '0.0.2'
diff --git a/vistrails/packages/pythonCalcQt/init.py b/vistrails/packages/pythonCalcQt/init.py
index 8d885b7..4dd278d 100644
--- a/vistrails/packages/pythonCalcQt/init.py
+++ b/vistrails/packages/pythonCalcQt/init.py
@@ -1,39 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import vistrails.core.modules.module_registry
 from vistrails.core.modules.vistrails_module import Module, ModuleError
+from ast import literal_eval
 from PyQt4 import QtCore, QtGui
 import vistrails.api
 
@@ -91,9 +95,9 @@ class QPythonCalc(QtGui.QWidget):
         similar to the PythonCalc module, but through the GUI.
 
         """
-        result = eval(str(self.value1Edit.text() +
-                          self.opCombo.currentText() +
-                          self.value2Edit.text()))
+        result = literal_eval(self.value1Edit.text() +
+                              self.opCombo.currentText() +
+                              self.value2Edit.text())
         self.resultLabel.setText(str(result))
 
     def createModule(self):
diff --git a/vistrails/packages/qgis/__init__.py b/vistrails/packages/qgis/__init__.py
index fd91230..373b92e 100644
--- a/vistrails/packages/qgis/__init__.py
+++ b/vistrails/packages/qgis/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import vistrails.core
 identifier = 'org.vistrails.vistrails.qgis'
 version = '0.0.2'
diff --git a/vistrails/packages/qgis/init.py b/vistrails/packages/qgis/init.py
index 636bb01..ee9c8fc 100644
--- a/vistrails/packages/qgis/init.py
+++ b/vistrails/packages/qgis/init.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 from vistrails.core.modules.vistrails_module import Module
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, CellLocation
-from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, QCellToolBar
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
+from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget
 
 import qgis.core
 import qgis.gui
@@ -53,13 +56,13 @@ class RasterLayer(Module):
         self.qgis_obj = None
 
     def compute(self):
-        fname = self.getInputFromPort('file').name
-        if self.hasInputFromPort('name'):
-            name = self.getInputFromPort('name')
+        fname = self.get_input('file').name
+        if self.has_input('name'):
+            name = self.get_input('name')
         else:
             name = os.path.splitext(os.path.basename(fname))[0]
         self.qgis_obj = qgis.core.QgsRasterLayer(fname, name)
-        self.setResult('self', self)
+        self.set_output('self', self)
 
 class VectorLayer(Module):
     _input_ports = [('file', '(basic:File)'), 
@@ -71,13 +74,13 @@ class VectorLayer(Module):
         self.qgis_obj = None
 
     def compute(self):
-        fname = self.getInputFromPort('file').name
-        if self.hasInputFromPort('name'):
-            name = self.getInputFromPort('name')
+        fname = self.get_input('file').name
+        if self.has_input('name'):
+            name = self.get_input('name')
         else:
             name = os.path.splitext(os.path.basename(fname))[0]
         self.qgis_obj = qgis.core.QgsVectorLayer(fname, name, "ogr")
-        self.setResult('self', self)
+        self.set_output('self', self)
 
 class QGISCell(SpreadsheetCell):
     """
@@ -91,8 +94,8 @@ class QGISCell(SpreadsheetCell):
         SpreadsheetCell.__init__(self)
     
     def compute(self):
-        rasterLayers = self.forceGetInputListFromPort('rasterLayers')
-        vectorLayers = self.forceGetInputListFromPort('vectorLayers')
+        rasterLayers = self.force_get_input_list('rasterLayers')
+        vectorLayers = self.force_get_input_list('vectorLayers')
         self.displayAndWait(QGISCellWidget, (rasterLayers, vectorLayers))
 
 class QGISCellWidget(QCellWidget):
diff --git a/vistrails/packages/rpy/__init__.py b/vistrails/packages/rpy/__init__.py
index b115553..3dfa0a1 100644
--- a/vistrails/packages/rpy/__init__.py
+++ b/vistrails/packages/rpy/__init__.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 name = "R"
 identifier = "org.vistrails.vistrails.rpy"
 version = "0.1.2"
diff --git a/vistrails/packages/rpy/init.py b/vistrails/packages/rpy/init.py
index c0920ee..8f103d9 100644
--- a/vistrails/packages/rpy/init.py
+++ b/vistrails/packages/rpy/init.py
@@ -1,51 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
+from ast import literal_eval
 import os
 import sys
-import tempfile
 import urllib
 import rpy2.robjects as robjects
 
-from vistrails.core.modules.basic_modules import File, Constant, \
-    new_constant
+from vistrails.core.modules.basic_modules import PathObject, new_constant
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+from .widgets import RSourceConfigurationWidget, RFigureConfigurationWidget
 
-from vistrails.core.modules.vistrails_module import Module, ModuleError, \
-    ModuleConnector, NotCacheable
-from vistrails.core.modules.basic_modules import new_constant
-import vistrails.core.modules.module_registry
-from widgets import RSourceConfigurationWidget, RFigureConfigurationWidget
 
 # FIXME when rpy2 is installed on the path, we won't need this
 old_sys_path = sys.path
@@ -96,7 +95,7 @@ def create_vector(v_list, desired_type=None):
     return robjects.RVector(v_list)
 
 def vector_conv(v, desired_type=None):
-    v_list = eval(v)
+    v_list = literal_eval(v)
     return create_vector(v_list, desired_type)
 
 RVector = new_constant('RVector', staticmethod(vector_conv),
@@ -159,14 +158,14 @@ def create_matrix(v_list):
     
 def matrix_conv(v):
     # should be a double list
-    v_list = eval(v)
+    v_list = literal_eval(v)
     create_matrix(v_list)
 
 def matrix_compute(self):
-    if self.hasInputFromPort('rvector'):
-        rvector = self.getInputFromPort('rvector')
-        nrows = self.getInputFromPort('nrows')
-        self.setResult('value', robjects.r.matrix(rvector, nrow=nrows))
+    if self.has_input('rvector'):
+        rvector = self.get_input('rvector')
+        nrows = self.get_input('nrows')
+        self.set_output('value', robjects.r.matrix(rvector, nrow=nrows))
     else:
         RArray.compute(self)
 
@@ -190,7 +189,7 @@ def create_list(v_dict):
     return robjects.r['list'](**data_dict)
 
 def list_conv(v):
-    v_dict = eval(v)
+    v_dict = literal_eval(v)
     return create_list(v_dict)
 
 RList = new_constant('RList', staticmethod(list_conv),
@@ -211,7 +210,7 @@ def create_data_frame(v_dict):
     return robjects.r['data.frame'](**data_dict)
 
 def data_frame_conv(v):
-    v_dict = eval(v)
+    v_dict = literal_eval(v)
     return create_data_frame(v_dict)
 
 RDataFrame = new_constant('RDataFrame', staticmethod(data_frame_conv),
@@ -224,63 +223,63 @@ class RVectorFromList(Module):
     _output_ports = [('rvector', '(Types|RVector)')]
 
     def compute(self):
-        ilist = self.getInputFromPort('list')
+        ilist = self.get_input('list')
         rvector = create_vector(ilist)
-        self.setResult('rvector', rvector)
+        self.set_output('rvector', rvector)
 
 class ListFromRVector(Module):
     _input_ports = [('rvector', '(Types|RVector)')]
     _output_ports = [('list', '(basic:List)')]
 
     def compute(self):
-        rvector = self.getInputFromPort('rvector')
+        rvector = self.get_input('rvector')
         olist = list(rvector)
-        self.setResult('list', olist)
+        self.set_output('list', olist)
 
 class RMatrixFromNestedList(Module):
     _input_ports = [('list', '(basic:List)')]
     _output_ports = [('rmatrix', '(Types|RMatrix)')]
 
     def compute(self):
-        ilist = self.getInputFromPort('list')
+        ilist = self.get_input('list')
         rmatrix = create_matrix(ilist)
-        self.setResult('rmatrix', rmatrix)
+        self.set_output('rmatrix', rmatrix)
 
 class NestedListFromRMatrix(Module):
     _input_ports = [('rmatrix', '(Types|RMatrix)')]
     _output_ports = [('list', '(basic:List)')]
     
     def compute(self):
-        rmatrix = self.getInputFromPort('rmatrix')
+        rmatrix = self.get_input('rmatrix')
         mlist = list(rmatrix)
         nrows = rmatrix.nrow
-        ncols = len(mlist) / nrows
+        ncols = len(mlist) // nrows
         olist = [] 
         for row in xrange(nrows):
             olist.append(mlist[row*ncols:(row+1)*ncols])
-        self.setResult('list', olist)
+        self.set_output('list', olist)
 
 class RDataFrameFromDict(Module):
     _input_ports = [('dict', '(basic:Dictionary)')]
     _output_ports = [('rdataframe', '(Types|RDataFrame)')]
     
     def compute(self):
-        idict = self.getInputFromPort('dict')
+        idict = self.get_input('dict')
         rdataframe = create_data_frame(idict)
-        self.setResult('rdataframe', rdataframe)
+        self.set_output('rdataframe', rdataframe)
 
 class DictFromRDataFrame(Module):
     _input_ports = [('rdataframe','(Types|RDataFrame)')]
     _output_ports = [('dict', '(basic:Dictionary)')]
 
     def compute(self):
-        rdataframe = self.getInputFromPort('rdataframe')
+        rdataframe = self.get_input('rdataframe')
         colnames = list(rdataframe.colnames())
         odict = {}
         for i in xrange(len(rdataframe)):
             # FIXME !!! just assume that each row can be converted to a list!!!
             odict[colnames[i]] = list(rdataframe[i])
-        self.setResult('dict', odict)
+        self.set_output('dict', odict)
 
 class RListFromDict(Module):
     # _input_ports = [('dict', '(basic:Dictionary)')]
@@ -288,9 +287,9 @@ class RListFromDict(Module):
     _output_ports = [('rlist', '(Types|RList)')]
     
     def compute(self):
-        idict = self.getInputFromPort('dict')
+        idict = self.get_input('dict')
         rlist = create_list(idict)
-        self.setResult('rlist', rlist)
+        self.set_output('rlist', rlist)
 
 class DictFromRList(Module):
     _input_ports = [('rlist', '(Types|RList)')]
@@ -298,14 +297,14 @@ class DictFromRList(Module):
     _output_ports = [('dict', '(basic:Module)')]
 
     def compute(self):
-        rlist = self.getInputFromPort('rlist')
+        rlist = self.get_input('rlist')
         colnames = list(rlist.names)
         odict = {}
         for i in xrange(len(rlist)):
             # FIXME !!! just assume that each row can be converted to a list!!!
             # FIXME this may need to be a list of lists
             odict[colnames[i]] = list(rlist[i])
-        self.setResult('dict', odict)
+        self.set_output('dict', odict)
 
 class RRead(Module):
     _input_ports = [('file', '(basic:File)'),
@@ -318,13 +317,13 @@ class RRead(Module):
     _output_ports = [('rdataframe', '(Types|RDataFrame)')]
 
     def do_read(self, read_cmd):
-        fname = self.getInputFromPort('file').name
+        fname = self.get_input('file').name
         options_dict = {}
         for port in RRead._input_ports:
-            if port[0] != 'file' and self.hasInputFromPort(port):
-                options_dict[port] = self.getInputFromPort(port)
+            if port[0] != 'file' and self.has_input(port):
+                options_dict[port] = self.get_input(port)
         rdataframe = robjects.r[read_cmd](fname, **options_dict)
-        self.setResult('rdataframe', rdataframe)
+        self.set_output('rdataframe', rdataframe)
 
 class RReadTable(RRead):
     def compute(self):
@@ -364,7 +363,7 @@ class RSource(Module):
         def cache_this():
             self.is_cacheable = lambda *args, **kwargs: True
         if use_input:
-            inputDict = dict([(k, self.getInputFromPort(k))
+            inputDict = dict([(k, self.get_input(k))
                               for k in self.inputPorts
                               if k not in excluded_inputs])
             for k,v in inputDict.iteritems():
@@ -373,7 +372,7 @@ class RSource(Module):
         if use_output:
             for k in self.outputPorts:
                 if k not in excluded_outputs and k in robjects.globalEnv:
-                    self.setResult(k, robjects.globalEnv[k])
+                    self.set_output(k, robjects.globalEnv[k])
 
     def run_file(self, fname, excluded_inputs=set(['source']), 
                  excluded_outputs=set()):
@@ -395,7 +394,7 @@ class RSource(Module):
         robjects.r('setwd("%s")' % dir)
 
     def compute(self):
-        code_str = urllib.unquote(str(self.forceGetInputFromPort('source', '')))
+        code_str = urllib.unquote(str(self.force_get_input('source', '')))
         self.run_code(code_str, use_input=True, use_output=True,
                       excluded_inputs=set(['source']))
 
@@ -409,10 +408,8 @@ class RFigure(RSource):
         self.run_code(code_str, use_input=True, 
                       excluded_inputs=excluded_inputs)
         robjects.r['dev.off']()
-        image_file = File()
-        image_file.name = fname
-        image_file.upToDate = True
-        self.setResult('imageFile', image_file)
+        image_file = PathObject(fname)
+        self.set_output('imageFile', image_file)
 
     def run_figure_file(self, fname, graphics_dev, width, height, 
                         excluded_inputs=set(['source'])):
@@ -424,19 +421,19 @@ class RFigure(RSource):
 class RSVGFigure(RFigure):
     def compute(self):
         code_str = \
-            urllib.unquote(str(self.forceGetInputFromPort('source', '')))
+            urllib.unquote(str(self.force_get_input('source', '')))
         RFigure.run_figure(self, code_str, 'svg', 4, 3)
 
 class RPNGFigure(RFigure):
     def compute(self):
         code_str = \
-            urllib.unquote(str(self.forceGetInputFromPort('source', '')))
+            urllib.unquote(str(self.force_get_input('source', '')))
         RFigure.run_figure(self, code_str, 'png', 640, 480)
 
 class RPDFFigure(RFigure):
     def compute(self):
         code_str = \
-            urllib.unquote(str(self.forceGetInputFromPort('source', '')))
+            urllib.unquote(str(self.force_get_input('source', '')))
         RFigure.run_figure(self, code_str, 'pdf', 4, 3)
 
 class RFactor(Module):
diff --git a/vistrails/packages/rpy/widgets.py b/vistrails/packages/rpy/widgets.py
index dc599b4..7f6940f 100644
--- a/vistrails/packages/rpy/widgets.py
+++ b/vistrails/packages/rpy/widgets.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 from vistrails.gui.modules.source_configure import SourceConfigurationWidget
 
 class RSourceConfigurationWidget(SourceConfigurationWidget):
diff --git a/vistrails/packages/sklearn/__init__.py b/vistrails/packages/sklearn/__init__.py
new file mode 100644
index 0000000..83aa42a
--- /dev/null
+++ b/vistrails/packages/sklearn/__init__.py
@@ -0,0 +1,48 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.requirements import require_python_module
+
+identifier = 'org.vistrails.vistrails.sklearn'
+name = 'sklearn'
+version = '0.15.2'
+
+
+def package_requirements():
+    require_python_module('sklearn', {
+                          'pip': 'scikit-learn',
+                          'linux-debian': 'python-sklearn',
+                          'linux-ubuntu': 'python-sklearn'})
diff --git a/vistrails/packages/sklearn/init.py b/vistrails/packages/sklearn/init.py
new file mode 100644
index 0000000..fb569c1
--- /dev/null
+++ b/vistrails/packages/sklearn/init.py
@@ -0,0 +1,423 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.modules.config import ModuleSettings
+from vistrails.core.modules.vistrails_module import Module
+
+import numpy as np
+from sklearn.base import ClassifierMixin
+from sklearn import datasets
+from sklearn.cross_validation import train_test_split, cross_val_score
+from sklearn.metrics import SCORERS, roc_curve
+from sklearn.grid_search import GridSearchCV as _GridSearchCV
+from sklearn.pipeline import make_pipeline
+from sklearn.utils.testing import all_estimators
+
+
+def try_convert(input_string):
+    if not isinstance(input_string, basestring):
+        # already converted
+        return input_string
+    if input_string.isdigit():
+        return int(input_string)
+    try:
+        return float(input_string)
+    except ValueError:
+        return input_string
+
+# backport of odd estimators that we don't want to include
+dont_test = ['SparseCoder', 'EllipticEnvelope', 'DictVectorizer',
+             'LabelBinarizer', 'LabelEncoder', 'MultiLabelBinarizer',
+             'TfidfTransformer', 'IsotonicRegression', 'OneHotEncoder',
+             'RandomTreesEmbedding', 'FeatureHasher', 'DummyClassifier',
+             'DummyRegressor', 'TruncatedSVD', 'PolynomialFeatures']
+
+
+###############################################################################
+# Example datasets
+
+class Digits(Module):
+    """Example dataset: digits.
+    """
+    _settings = ModuleSettings(namespace="datasets")
+    _output_ports = [("data", "basic:List", {'shape': 'circle'}),
+                     ("target", "basic:List", {'shape': 'circle'})]
+
+    def compute(self):
+        data = datasets.load_digits()
+        self.set_output("data", data.data)
+        self.set_output("target", data.target)
+
+
+class Iris(Module):
+    """Example dataset: iris.
+    """
+    _settings = ModuleSettings(namespace="datasets")
+    _output_ports = [("data", "basic:List", {'shape': 'circle'}),
+                     ("target", "basic:List", {'shape': 'circle'})]
+
+    def compute(self):
+        data = datasets.load_iris()
+        self.set_output("data", data.data)
+        self.set_output("target", data.target)
+
+
+###############################################################################
+# Base classes
+
+class Estimator(Module):
+    """Base class for all sklearn estimators.
+    """
+    _settings = ModuleSettings(abstract=True)
+    _output_ports = [("model", "Estimator", {'shape': 'diamond'})]
+
+
+class SupervisedEstimator(Estimator):
+    """Base class for all sklearn classifier modules."""
+    _settings = ModuleSettings(abstract=True)
+
+    def compute(self):
+        # get parameters, try to convert strings to float / int
+        params = dict([(p, try_convert(self.get_input(p))) for p in self.inputPorts
+                       if p not in ["training_data", "training_target"]])
+        clf = self._estimator_class(**params)
+        if "training_data" in self.inputPorts:
+            training_data = np.vstack(self.get_input("training_data"))
+            training_target = self.get_input("training_target")
+            clf.fit(training_data, training_target)
+        self.set_output("model", clf)
+
+
+class UnsupervisedEstimator(Estimator):
+    """Base class for all sklearn transformer modules."""
+    _settings = ModuleSettings(abstract=True)
+
+    def compute(self):
+        params = dict([(p, try_convert(self.get_input(p))) for p in self.inputPorts
+                       if p not in ["training_data", "training_target"]])
+        trans = self._estimator_class(**params)
+        if "training_data" in self.inputPorts:
+            training_data = np.vstack(self.get_input("training_data"))
+            trans.fit(training_data)
+        self.set_output("model", trans)
+
+
+class Predict(Module):
+    """Apply a learned scikit-learn classifier model to test data.
+    """
+    # TODO : data depth=1
+    _input_ports = [("model", "Estimator", {'shape': 'diamond'}),
+                    ("data", "basic:List", {'shape': 'circle'})]
+    _output_ports = [("prediction", "basic:List", {'shape': 'circle'}),
+                     ("decision_function", "basic:List")]
+
+    def compute(self):
+        clf = self.get_input("model")
+        data = self.get_input("data")
+        predictions = clf.predict(data)
+        decision_function = clf.decision_function(data)
+        self.set_output("prediction", predictions)
+        self.set_output("decision_function", decision_function)
+
+
+class Transform(Module):
+    """Apply a learned scikit-learn transformer to test data.
+    """
+    _input_ports = [("model", "Estimator", {'shape': 'diamond'}),
+                    ("data", "basic:List", {'shape': 'circle'})]
+    _output_ports = [("transformed_data", "basic:List", {'shape': 'circle'})]
+
+    def compute(self):
+        trans = self.get_input("model")
+        data = self.get_input("data")
+        transformed_data = trans.transform(data)
+        self.set_output("transformed_data", transformed_data)
+
+
+###############################################################################
+# Cross-validation
+
+
+class TrainTestSplit(Module):
+    """Split data into training and testing randomly."""
+    _settings = ModuleSettings(namespace="cross-validation")
+    _input_ports = [("data", "basic:List", {'shape': 'circle'}),
+                    ("target", "basic:List", {'shape': 'circle'}),
+                    ("test_size", "basic:Float", {"defaults": [.25]})]
+    _output_ports = [("training_data", "basic:List", {'shape': 'circle'}),
+                     ("training_target", "basic:List", {'shape': 'circle'}),
+                     ("test_data", "basic:List", {'shape': 'circle'}),
+                     ("test_target", "basic:List", {'shape': 'circle'})]
+
+    def compute(self):
+        X_train, X_test, y_train, y_test = \
+            train_test_split(self.get_input("data"), self.get_input("target"),
+                             test_size=try_convert(self.get_input("test_size")))
+        self.set_output("training_data", X_train)
+        self.set_output("training_target", y_train)
+        self.set_output("test_data", X_test)
+        self.set_output("test_target", y_test)
+
+
+class CrossValScore(Module):
+    """Split data into training and testing randomly."""
+    _settings = ModuleSettings(namespace="cross-validation")
+    _input_ports = [("model", "Estimator", {'shape': 'diamond'}),
+                    ("data", "basic:List", {'shape': 'circle'}),
+                    ("target", "basic:List", {'shape': 'circle'}),
+                    ("metric", "basic:String", {"defaults": ["accuracy"]}),
+                    ("folds", "basic:Integer", {"defaults": ["3"]})]
+    _output_ports = [("scores", "basic:List")]
+
+    def compute(self):
+        model = self.get_input("model")
+        data = self.get_input("data")
+        target = self.get_input("target")
+        metric = self.get_input("metric")
+        folds = self.get_input("folds")
+        scores = cross_val_score(model, data, target, scoring=metric, cv=folds)
+        self.set_output("scores", scores)
+
+###############################################################################
+# Meta Estimators
+
+
+class GridSearchCV(Estimator):
+    """Perform cross-validated grid-search over a parameter grid."""
+    _input_ports = [("model", "Estimator", {'shape': 'diamond'}),
+                    ("parameters", "basic:Dictionary"),
+                    ("data", "basic:List", {'shape': 'circle'}),
+                    ("target", "basic:List", {'shape': 'circle'}),
+                    ("metric", "basic:String", {"defaults": ["accuracy"]}),
+                    ("folds", "basic:Integer", {"defaults": ["3"]})]
+    _output_ports = [("scores", "basic:List"), ("model", "Estimator", {'shape': 'diamond'}),
+                     ("best_parameters", "basic:Dictionary"),
+                     ("best_score", "basic:Float")]
+
+    def compute(self):
+        base_model = self.get_input("model")
+        grid = _GridSearchCV(base_model,
+                             param_grid=self.get_input("parameters"),
+                             cv=self.get_input("folds"),
+                             scoring=self.get_input("metric"))
+        if "data" in self.inputPorts:
+            data = np.vstack(self.get_input("data"))
+            target = self.get_input("target")
+            grid.fit(data, target)
+            self.set_output("scores", grid.grid_scores_)
+            self.set_output("best_parameters", grid.best_params_)
+            self.set_output("best_score", grid.best_score_)
+        self.set_output("model", grid)
+
+
+class Pipeline(Estimator):
+    """Chain estimators to form a pipeline."""
+    _input_ports = [("training_data", "basic:List", {'shape': 'circle'}),
+                    ("training_target", "basic:List", {'shape': 'circle'}),("model1", "Estimator", {'shape': 'diamond'}),
+                    ("model2", "Estimator", {'optional': True, 'shape': 'diamond'}),
+                    ("model3", "Estimator", {'optional': True, 'shape': 'diamond'}),
+                    ("model4", "Estimator", {'optional': True, 'shape': 'diamond'})]
+
+    def compute(self):
+        models = ["model%d" % d for d in range(1, 5)]
+        steps = [self.get_input(model) for model in models if model in self.inputPorts]
+        pipeline = make_pipeline(*steps)
+        if "training_data" in self.inputPorts:
+            training_data = np.vstack(self.get_input("training_data"))
+            training_target = self.get_input("training_target")
+            pipeline.fit(training_data, training_target)
+        self.set_output("model", pipeline)
+
+###############################################################################
+# Metrics
+
+
+class Score(Module):
+    """Compute a model performance metric."""
+    _settings = ModuleSettings()
+    _input_ports = [("model", "Estimator", {'shape': 'diamond'}),
+                    ("data", "basic:List", {'shape': 'circle'}),
+                    ("target", "basic:List", {'shape': 'circle'}),
+                    ("metric", "basic:String", {"defaults": ["accuracy"]})]
+    _output_ports = [("score", "basic:Float")]
+
+    def compute(self):
+        scorer = SCORERS[self.get_input("metric")]
+        score = scorer(self.get_input("model"), self.get_input("data"), self.get_input("target"))
+        self.set_output("score", score)
+
+
+class ROCCurve(Module):
+    """Compute a ROC curve."""
+    _settings = ModuleSettings(namespace="metrics")
+    _input_ports = [("model", "Estimator", {'shape': 'diamond'}),
+                    ("data", "basic:List", {'shape': 'circle'}),
+                    ("target", "basic:List", {'shape': 'circle'})]
+    _output_ports = [("fpr", "basic:List"),
+                     ("tpr", "basic:List")]
+
+    def compute(self):
+        model = self.get_input("model")
+        data = self.get_input("data")
+        if hasattr(model, "decision_function"):
+            dec = model.decision_function(data)
+        else:
+            dec = model.predict_proba(data)[:, 1]
+        fpr, tpr, _ = roc_curve(self.get_input("target"), dec)
+        self.set_output("fpr", fpr)
+        self.set_output("tpr", tpr)
+
+
+###############################################################################<F2>
+# Classifiers and Regressors
+
+def make_module(name, Estimator, namespace, supervised=False, Base=None):
+    input_ports = [("training_data", "basic:List", {'shape': 'circle'})]
+    if supervised:
+        input_ports.append(("training_target", "basic:List", {'shape': 'circle'}))
+    est = Estimator()
+    input_ports.extend([(param, "basic:String", {'optional': True}) for param
+                        in est.get_params()])
+    _settings = ModuleSettings(namespace=namespace)
+    if Base is None:
+        if supervised:
+            Base = SupervisedEstimator
+        else:
+            Base = UnsupervisedEstimator
+    new_class = type(name, (Base,),
+                     {'_input_ports': input_ports, '_settings': _settings,
+                      '_estimator_class': Estimator, '__doc__':
+                      Estimator.__doc__})
+    return new_class
+
+
+def discover_supervised():
+    classifiers = all_estimators(type_filter="classifier")
+    regressors = all_estimators(type_filter="regressor")
+    classes = []
+    for name, Est in classifiers + regressors:
+        if issubclass(Est, ClassifierMixin):
+            namespace = "classifiers"
+        else:
+            namespace = "regressors"
+        classes.append(make_module(name, Est, namespace, supervised=True))
+    return classes
+
+
+###############################################################################<F2>
+# Clustering
+
+def discover_clustering():
+    return [make_module(name, Est, "clustering") for (name, Est) in
+            all_estimators(type_filter="cluster")]
+
+
+###############################################################################
+# Transformers
+
+def discover_unsupervised_transformers():
+    # also: random tree embedding
+    transformers = all_estimators(type_filter="transformer")
+    classes = []
+    for name, Est in transformers:
+        if name in dont_test:
+            continue
+        module = Est.__module__.split(".")[1]
+        if module not in ['decomposition', 'kernel_approximation',
+                          'neural_network', 'preprocessing', 'random_projection']:
+            # the manifold module does not really provide transformers and is
+            # handled elsewhere (there is usually no transform method).
+            continue
+        classes.append(make_module(name, Est, namespace=module))
+    return classes
+
+
+def discover_feature_selection():
+    # also: random tree embedding
+    transformers = all_estimators(type_filter="transformer")
+    classes = []
+    for name, Est in transformers:
+        if name in dont_test:
+            continue
+        module = Est.__module__.split(".")[1]
+        if module != "feature_selection" or name == "GenericUnivariateSelect":
+            continue
+        classes.append(make_module(name, Est, namespace=module, supervised=True))
+    return classes
+
+
+###############################################################################
+# Manifold learning
+# unfortunately this has a sightly different interface due to the fact that
+# most manifold algorithms can't generalize to new data.
+class ManifoldLearner(Module):
+    """Base class for all sklearn manifold modules.
+    """
+    _settings = ModuleSettings(abstract=True)
+    _output_ports = [("transformed_data", "basic:List", {'shape': 'circle'})]
+
+    def compute(self):
+        params = dict([(p, try_convert(self.get_input(p))) for p in self.inputPorts
+                       if p not in ["training_data"]])
+        trans = self._estimator_class(**params)
+        training_data = np.vstack(self.get_input("training_data"))
+        transformed_data = trans.fit_transform(training_data)
+        self.set_output("transformed_data", transformed_data)
+
+
+def discover_manifold_learning():
+    # also: random tree embedding
+    transformers = all_estimators()
+    classes = []
+    for name, Est in transformers:
+        if name in dont_test:
+            continue
+        module = Est.__module__.split(".")[1]
+        if module != "manifold":
+            continue
+        classes.append(make_module(name, Est, namespace=module, Base=ManifoldLearner))
+    return classes
+
+
+_modules = [Digits, Iris, Estimator, SupervisedEstimator,
+            UnsupervisedEstimator, ManifoldLearner, Predict, Transform,
+            TrainTestSplit, Score, ROCCurve, CrossValScore, GridSearchCV,
+            Pipeline]
+_modules.extend(discover_supervised())
+_modules.extend(discover_clustering())
+_modules.extend(discover_unsupervised_transformers())
+_modules.extend(discover_feature_selection())
+_modules.extend(discover_manifold_learning())
diff --git a/vistrails/packages/sklearn/tests.py b/vistrails/packages/sklearn/tests.py
new file mode 100644
index 0000000..13a16e6
--- /dev/null
+++ b/vistrails/packages/sklearn/tests.py
@@ -0,0 +1,300 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import numpy as np
+import unittest
+from vistrails.tests.utils import execute, intercept_results
+
+from vistrails.packages.sklearn.init import (Digits, Iris, TrainTestSplit,
+                                             Predict, Score, Transform,
+                                             CrossValScore, _modules,
+                                             GridSearchCV)
+from vistrails.packages.sklearn import identifier
+
+from sklearn.metrics import f1_score
+
+
+def class_by_name(name):
+    """Returns an autogenerated class from _modules from a string name."""
+    for module in _modules:
+        if module.__name__ == name:
+            return module
+
+
+class TestSklearn(unittest.TestCase):
+    def test_digits(self):
+        # check that the digits dataset can be loaded
+        with intercept_results(Digits, 'data', Digits, 'target') as (data, target):
+            self.assertFalse(execute([
+                ('datasets|Digits', identifier, [])
+            ]))
+        data = np.vstack(data)
+        target = np.hstack(target)
+        self.assertEqual(data.shape, (1797, 64))
+        self.assertEqual(target.shape, (1797,))
+
+    def test_iris(self):
+        # check that the iris dataset can be loaded
+        with intercept_results(Iris, 'data', Iris, 'target') as (data, target):
+            self.assertFalse(execute([
+                ('datasets|Iris', identifier, [])
+            ]))
+        data = np.vstack(data)
+        target = np.hstack(target)
+        self.assertEqual(data.shape, (150, 4))
+        self.assertEqual(target.shape, (150,))
+
+    def test_train_test_split(self):
+        # check that we can split the iris dataset
+        with intercept_results(TrainTestSplit, 'training_data', TrainTestSplit,
+                               'training_target', TrainTestSplit, 'test_data',
+                               TrainTestSplit, 'test_target') as results:
+            X_train, y_train, X_test, y_test = results
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('cross-validation|TrainTestSplit', identifier,
+                     [('test_size', [('Integer', '50')])])
+                ],
+                [
+                    (0, 'data', 1, 'data'),
+                    (0, 'target', 1, 'target')
+                ]
+            ))
+        X_train = np.vstack(X_train)
+        X_test = np.vstack(X_test)
+        y_train = np.hstack(y_train)
+        y_test = np.hstack(y_test)
+        self.assertEqual(X_train.shape, (100, 4))
+        self.assertEqual(X_test.shape, (50, 4))
+        self.assertEqual(y_train.shape, (100,))
+        self.assertEqual(y_test.shape, (50,))
+
+    def test_classifier_training_predict(self):
+        with intercept_results(Predict, 'prediction', Predict,
+                               'decision_function', TrainTestSplit, 'test_target',
+                               Score, 'score') as results:
+            y_pred, decision_function, y_test, score = results
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('cross-validation|TrainTestSplit', identifier,
+                     [('test_size', [('Integer', '50')])]),
+                    ('classifiers|LinearSVC', identifier, []),
+                    ('Predict', identifier, []),
+                    ('Score', identifier, []),
+                    # use custom metric
+                    ('Score', identifier,
+                     [('metric', [('String', 'f1')])]),
+
+                ],
+                [
+                    # train test split
+                    (0, 'data', 1, 'data'),
+                    (0, 'target', 1, 'target'),
+                    # fit LinearSVC on training data
+                    (1, 'training_data', 2, 'training_data'),
+                    (1, 'training_target', 2, 'training_target'),
+                    # predict on test data
+                    (2, 'model', 3, 'model'),
+                    (1, 'test_data', 3, 'data'),
+                    # score test data
+                    (2, 'model', 4, 'model'),
+                    (1, 'test_data', 4, 'data'),
+                    (1, 'test_target', 4, 'target'),
+                    # f1 scorer
+                    (2, 'model', 5, 'model'),
+                    (1, 'test_data', 5, 'data'),
+                    (1, 'test_target', 5, 'target')
+                ]
+            ))
+        y_pred = np.hstack(y_pred)
+        decision_function = np.vstack(decision_function)
+        y_test = np.hstack(y_test)
+        # unpack the results from the two scorers
+        score_acc, score_f1 = score
+        self.assertEqual(y_pred.shape, (50,))
+        self.assertTrue(np.all(np.unique(y_pred) == np.array([0, 1, 2])))
+        self.assertEqual(decision_function.shape, (50, 3))
+        # some accuracy
+        self.assertTrue(np.mean(y_test == y_pred) > .8)
+        # score is actually the accuracy
+        self.assertEqual(np.mean(y_test == y_pred), score_acc)
+        # f1 score is actually f1 score
+        self.assertEqual(f1_score(y_test, y_pred), score_f1)
+
+    def test_transformer_supervised_transform(self):
+        # test feature selection
+        with intercept_results(Transform, 'transformed_data') as (transformed_data,):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('feature_selection|SelectKBest', identifier,
+                        [('k', [('Integer', '2')])]),
+                    ('Transform', identifier, [])
+                ],
+                [
+                    (0, 'data', 1, 'training_data'),
+                    (0, 'target', 1, 'training_target'),
+                    (1, 'model', 2, 'model'),
+                    (0, 'data', 2, 'data')
+                ]
+            ))
+        transformed_data = np.vstack(transformed_data)
+        self.assertEqual(transformed_data.shape, (150, 2))
+
+    def test_transformer_unsupervised_transform(self):
+        # test PCA
+        with intercept_results(Transform, 'transformed_data') as (transformed_data,):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('decomposition|PCA', identifier,
+                        [('n_components', [('Integer', '2')])]),
+                    ('Transform', identifier, [])
+                ],
+                [
+                    (0, 'data', 1, 'training_data'),
+                    (1, 'model', 2, 'model'),
+                    (0, 'data', 2, 'data')
+                ]
+            ))
+        transformed_data = np.vstack(transformed_data)
+        self.assertEqual(transformed_data.shape, (150, 2))
+
+    def test_manifold_learning(self):
+        # test Isomap
+        with intercept_results(class_by_name("Isomap"), 'transformed_data') as (transformed_data,):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('manifold|Isomap', identifier, []),
+                ],
+                [
+                    (0, 'data', 1, 'training_data'),
+                ]
+            ))
+        transformed_data = np.vstack(transformed_data)
+        self.assertEqual(transformed_data.shape, (150, 2))
+
+    def test_cross_val_score(self):
+        # chech that cross_val score of LinearSVC has the right length
+        with intercept_results(CrossValScore, 'scores') as (scores,):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('classifiers|LinearSVC', identifier, []),
+                    ('cross-validation|CrossValScore', identifier, []),
+                ],
+                [
+                    (0, 'data', 2, 'data'),
+                    (0, 'target', 2, 'target'),
+                    (1, 'model', 2, 'model')
+                ]
+            ))
+        scores = np.hstack(scores)
+        self.assertEqual(scores.shape, (3,))
+        self.assertTrue(np.mean(scores) > .8)
+
+    def test_gridsearchcv(self):
+        # check that gridsearch on DecisionTreeClassifier does the right number of runs
+        # and gives the correct result.
+        with intercept_results(GridSearchCV, 'scores', GridSearchCV,
+                               'best_parameters') as (scores, parameters):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('classifiers|DecisionTreeClassifier', identifier, []),
+                    ('GridSearchCV', identifier,
+                     [('parameters', [('Dictionary', "{'max_depth': [1, 2, 3, 4]}")])]),
+                ],
+                [
+                    (0, 'data', 2, 'data'),
+                    (0, 'target', 2, 'target'),
+                    (1, 'model', 2, 'model')
+                ]
+            ))
+        self.assertEqual(len(scores[0]), 4)
+        self.assertTrue(parameters[0]['max_depth'], 2)
+
+    def test_pipeline(self):
+        with intercept_results(Iris, 'target', Predict, 'prediction') as (y_true, y_pred):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('preprocessing|StandardScaler', identifier, []),
+                    ('feature_selection|SelectKBest', identifier,
+                        [('k', [('Integer', '2')])]),
+                    ('classifiers|LinearSVC', identifier, []),
+                    ('Pipeline', identifier, []),
+                    ('Predict', identifier, [])
+                ],
+                [
+                    # feed data to pipeline
+                    (0, 'data', 4, 'training_data'),
+                    (0, 'target', 4, 'training_target'),
+                    # put models in pipeline
+                    (1, 'model', 4, 'model1'),
+                    (2, 'model', 4, 'model2'),
+                    (3, 'model', 4, 'model3'),
+                    # predict using pipeline
+                    (4, 'model', 5, 'model'),
+                    (0, 'data', 5, 'data')
+                ]
+            ))
+            y_true, y_pred = np.array(y_true[0]), np.array(y_pred[0])
+            self.assertEqual(y_true.shape, y_pred.shape)
+            self.assertTrue(np.mean(y_true == y_pred) > .8)
+
+    def test_nested_cross_validation(self):
+        with intercept_results(CrossValScore, 'scores') as (scores, ):
+            self.assertFalse(execute(
+                [
+                    ('datasets|Iris', identifier, []),
+                    ('classifiers|DecisionTreeClassifier', identifier, []),
+                    ('GridSearchCV', identifier,
+                     [('parameters', [('Dictionary', "{'max_depth': [1, 2, 3, 4]}")])]),
+                    ('cross-validation|CrossValScore', identifier, [])
+                ],
+                [
+                    (0, 'data', 3, 'data'),
+                    (0, 'target', 3, 'target'),
+                    (1, 'model', 2, 'model'),
+                    (2, 'model', 3, 'model')
+                ]
+            ))
+        self.assertEqual(len(scores[0]), 3)
+        self.assertTrue(np.mean(scores[0]) > .8)
diff --git a/vistrails/packages/spreadsheet/__init__.py b/vistrails/packages/spreadsheet/__init__.py
index 280fd6d..26ebb8e 100644
--- a/vistrails/packages/spreadsheet/__init__.py
+++ b/vistrails/packages/spreadsheet/__init__.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 from identifiers import *
 
 # This must be here because of VisTrails protocol
-from spreadsheet_config import configuration
+from .spreadsheet_config import configuration
diff --git a/vistrails/packages/spreadsheet/analogy_api.py b/vistrails/packages/spreadsheet/analogy_api.py
index 0562f3d..c394549 100644
--- a/vistrails/packages/spreadsheet/analogy_api.py
+++ b/vistrails/packages/spreadsheet/analogy_api.py
@@ -1,72 +1,75 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file describes the analogy structure the spreadsheet holding
-# and it should be reimplemented to integrate between the spreadsheet
-# and the analogy
-################################################################################
-import os
+
+"""This file describes the analogy structure the spreadsheet holding and it
+should be reimplemented to integrate between the spreadsheet and the analogy
+"""
+
+from __future__ import division
+
 import vistrails.core.analogy
 import vistrails.gui
 
+
 class SpreadsheetAnalogyObject(object):
     """
     SpreadsheetAnalogyObject provides a API functions to integrate
     between the spreadsheet and the analogy. There will be only one
     instance of the analogy object
-    
+
     """
     def __init__(self):
         """ SpreadsheetAnalogyObject() -> SpreadsheetAnalogyObject
         Initialize object properties
-        
+
         """
         pass
 
     def isValid(self):
-        """ isValid() -> bool        
+        """ isValid() -> bool
         Is the current analogy object is valid and can be applied to
         other pipeline
-        
+
         """
         return True
-        
+
     def createAnalogy(self, p1Info, p2Info):
-        """ createAnalogy(p1Info: tuple, p2Info) -> bool        
+        """ createAnalogy(p1Info: tuple, p2Info) -> bool
         p1Info, p2Info: (vistrailName, versionNumber, actions, pipeline)
-        
+
         Setup an analogy object from p1 to p2 given their info in
         p1Info and p2Info. CAUTION: sometimes the actual 'pipeline' on
         the spreadsheet is different than the one created from the
@@ -77,7 +80,7 @@ class SpreadsheetAnalogyObject(object):
 
         This function should return a boolean saying if the analogy
         has been successfully created or not.
-        
+
         """
 #         (p1_vistrail, p1_number, p1_actions, p1_pipeline) = p1Info
 #         (p2_vistrail, p2_number, p2_actions, p2_pipeline) = p2Info
@@ -94,7 +97,7 @@ class SpreadsheetAnalogyObject(object):
         the list of actions that has been applied. If no actions
         given (i.e. []), this can not be put back to the builder. If
         analogy is not applicable, this should return None
-        
+
         """
 
         (p1_locator, p1_number, p1_actions, p1_pipeline, p1_controller) = self._p1Info
@@ -115,10 +118,10 @@ class SpreadsheetAnalogyObject(object):
         if controller.current_version != p3_number:
             controller.change_selected_version(p3_number)
         action = perform( vt, p1_number, p2_number, p3_number)
-        
+
         controller.add_new_action(action)
         controller.perform_action(action)
-        
+
         new_version = controller.current_version
         new_pipeline = vt.getPipeline(new_version)
         return (controller.locator, new_version, [], new_pipeline, controller)
@@ -126,7 +129,7 @@ class SpreadsheetAnalogyObject(object):
     def __call__(self):
         """ __call__() -> SpreadsheetAnalogy
         Return self for calling method
-        
+
         """
         return self
 
diff --git a/vistrails/packages/spreadsheet/basic_widgets.py b/vistrails/packages/spreadsheet/basic_widgets.py
index f651d26..b5b4469 100644
--- a/vistrails/packages/spreadsheet/basic_widgets.py
+++ b/vistrails/packages/spreadsheet/basic_widgets.py
@@ -1,73 +1,83 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file describes basic VisTrails Modules of the Spreadsheet package:
-#   CellLocation
-#   SheetReference
-#   SingleCellSheetReference
-#   SpreadsheetCell
-################################################################################
-from vistrails.core.modules.vistrails_module import Module, NotCacheable, ModuleError
-from spreadsheet_base import (StandardSheetReference,
-                              StandardSingleCellSheetReference)
-from spreadsheet_controller import spreadsheetController
-from spreadsheet_event import DisplayCellEvent
+
+"""This file describes basic VisTrails Modules of the Spreadsheet package:
+  CellLocation
+  SheetReference
+  SingleCellSheetReference
+  SpreadsheetCell
+"""
+
+from __future__ import division
+
 from PyQt4 import QtCore
 
-################################################################################
+from vistrails.core.configuration import ConfigField, \
+    get_vistrails_configuration
+from vistrails.core.modules.output_modules import OutputMode, OutputModeConfig
+from vistrails.core.modules.vistrails_module import Module, NotCacheable, \
+    ModuleError
+
+from .spreadsheet_base import StandardSheetReference, \
+    StandardSingleCellSheetReference
+from .spreadsheet_controller import spreadsheetController
+from .spreadsheet_event import DisplayCellEvent
+
 
 def widgetName():
     """ widgetName() -> str
     Identify the name of the package
-    
+
     """
     return 'Basic Widgets'
 
+
 def registerWidget(reg, basicModules, basicWidgets):
     """ registerWidget(reg: module_registry, basicModules: package,
                        basicWidgets:package) -> None
     Register widgets with VisTrails registry
-    
+
     """
     reg.add_module(SheetReference)
     reg.add_input_port(SheetReference, "MinRowCount", basicModules.Integer, True)
     reg.add_input_port(SheetReference, "MinColumnCount",
                        basicModules.Integer, True)
     reg.add_input_port(SheetReference, "SheetName", basicModules.String, True)
-    reg.add_output_port(SheetReference, "self", SheetReference)
-     
+    reg.add_output_port(SheetReference, "value", SheetReference)
+
     reg.add_module(CellLocation)
     reg.add_input_port(CellLocation, "ColumnRowAddress",
                        basicModules.String, True)
@@ -76,7 +86,7 @@ def registerWidget(reg, basicModules, basicWidgets):
     reg.add_input_port(CellLocation, "RowSpan", basicModules.Integer, True)
     reg.add_input_port(CellLocation, "ColumnSpan", basicModules.Integer, True)
     reg.add_input_port(CellLocation, "SheetReference", SheetReference)
-    reg.add_output_port(CellLocation, "self", CellLocation)
+    reg.add_output_port(CellLocation, "value", CellLocation)
 
     reg.add_module(SpreadsheetCell)
     reg.add_input_port(SpreadsheetCell, "Location", CellLocation)
@@ -85,129 +95,117 @@ def registerWidget(reg, basicModules, basicWidgets):
     reg.add_module(SingleCellSheetReference)
     reg.add_input_port(SingleCellSheetReference, "SheetName",
                        basicModules.String, True)
-    reg.add_output_port(SingleCellSheetReference, "self",
+    reg.add_output_port(SingleCellSheetReference, "value",
                         SingleCellSheetReference)
-     
+
+
 class SheetReference(Module):
     """
     SheetReference is a VisTrail Module that allows users to specify
     which sheet (page) to put the visualiation on. This is as
     well a wrapper to simply contain real sheet reference classes
-    
-    """
-    def __init__(self):
-        """ SheetReference() -> SheetReference
-        Instantiate an empty SheetReference
-        
-        """
-        Module.__init__(self)
-        self.sheetReference = None
 
+    """
     def compute(self):
         """ compute() -> None
         Store information on input ports and ready to be passed on to whoever
         needs it
-        
-        """
-        if self.sheetReference==None:
-            self.sheetReference = StandardSheetReference()
-        ref = self.sheetReference
-        ref.minimumRowCount = self.forceGetInputFromPort("MinRowCount", 1)
-        ref.minimumColumnCount = self.forceGetInputFromPort("MinColumnCount", 1)
-        ref.sheetName = self.forceGetInputFromPort("SheetName")
-
-    def getSheetReference(self):
-        """ getSheetReference() -> subclass of StandardSheetReference
-        Return the actual information stored in the SheetReference
-        
+
         """
-        return self.sheetReference
+        ref = StandardSheetReference()
+        ref.minimumRowCount = self.force_get_input("MinRowCount", 1)
+        ref.minimumColumnCount = self.force_get_input("MinColumnCount", 1)
+        ref.sheetName = self.force_get_input("SheetName")
+
+        self.set_output('value', ref)
+
 
 class CellLocation(Module):
     """
     CellLocation is a Vistrail Module that allow users to specify
     where to put a visualization on a sheet, i.e. row, column
     location
-    
+
     """
-    def __init__(self):
-        """ CellLocation() -> CellLocation
-        Instantiate an empty cell location, i.e. any available cell
-        
-        """
-        Module.__init__(self)
-        self.row = -1
-        self.col = -1
-        self.rowSpan = -1
-        self.colSpan = -1
-        self.sheetReference = None
+    class Location(object):
+        def __init__(self):
+            self.row = -1
+            self.col = -1
+            self.rowSpan = -1
+            self.colSpan = -1
+            self.sheetReference = None
 
     def compute(self):
         """ compute() -> None
         Translate input ports into (row, column) location
-        
+
         """
+        loc = CellLocation.Location()
+
         def set_row_col(row, col):
             try:
-                self.col = ord(col)-ord('A')
-                self.row = int(row)-1
-            except:
+                loc.col = ord(col) - ord('A')
+                loc.row = int(row) - 1
+            except (TypeError, ValueError):
                 raise ModuleError(self, 'ColumnRowAddress format error')
-            
-        ref = self.forceGetInputFromPort("SheetReference")
+
+        ref = self.force_get_input("SheetReference")
         if ref:
-            self.sheetReference = ref.getSheetReference()
-
-        self.rowSpan = self.forceGetInputFromPort("RowSpan", -1)
-        self.colSpan = self.forceGetInputFromPort("ColumnSpan", -1)
-        if self.hasInputFromPort("Row") and self.hasInputFromPort("Column"):
-            self.row = self.getInputFromPort("Row")-1
-            self.col = self.getInputFromPort("Column")-1
-        elif self.hasInputFromPort("ColumnRowAddress"):
-            address = self.getInputFromPort("ColumnRowAddress")
+            loc.sheetReference = ref
+
+        loc.rowSpan = self.force_get_input("RowSpan", -1)
+        loc.colSpan = self.force_get_input("ColumnSpan", -1)
+        if self.has_input("Row") and self.has_input("Column"):
+            loc.row = self.get_input("Row")-1
+            loc.col = self.get_input("Column")-1
+        elif self.has_input("ColumnRowAddress"):
+            address = self.get_input("ColumnRowAddress")
             address = address.replace(' ', '').upper()
-            if len(address)>1:
+            if len(address) > 1:
                 if address[0] >= 'A' and address[0] <= 'Z':
                     set_row_col(address[1:], address[0])
                 else:
                     set_row_col(address[:-1], address[-1])
 
+        self.set_output('value', loc)
+
+
 class SpreadsheetCell(NotCacheable, Module):
     """
     SpreadsheetCell is a base class to other widget types. It provides
     a simple protocol to dispatch information to the spreadsheet
     cells. But it doesn't know how to display the information
     itself. That should be done by the specific widget type.
-    
+
     """
     def __init__(self):
         """ SpreadsheetCell() -> SpreadsheetCell
         Initialize attributes
-        
+
         """
         Module.__init__(self)
         self.location = None
-    
+
     def overrideLocation(self, location):
-        """ overrideLocation(location: CellLocation) -> None        
+        """ overrideLocation(location: CellLocation) -> None
         Make the cell always use this location instead of reading from
         the port
-        
+
         """
         self.location = location
 
     def createDisplayEvent(self, cellType, inputPorts):
-        """ display(cellType: python type, iputPorts: tuple) -> None        
+        """ display(cellType: python type, iputPorts: tuple) -> None
         Create a DisplayEvent with all the parameters from the cell
         locations and inputs
-        
+
         """
         e = DisplayCellEvent()
         e.vistrail = self.moduleInfo
         if self.location:
             location = self.location
         else:
-            location = self.forceGetInputFromPort("Location")
+            location = self.force_get_input("Location")
         if location:
             e.row = location.row
             e.col = location.col
@@ -226,7 +224,7 @@ class SpreadsheetCell(NotCacheable, Module):
         Keyword arguments:
         cellType   --- widget type, this is truely a python type
         inputPorts --- a tuple of input data that cellType() will understand
-        
+
         """
         e = self.createDisplayEvent(cellType, inputPorts)
         QtCore.QCoreApplication.processEvents()
@@ -234,24 +232,115 @@ class SpreadsheetCell(NotCacheable, Module):
         if spreadsheetWindow.echoMode == False:
             spreadsheetWindow.configShow(show=True)
         self.cellWidget = spreadsheetWindow.displayCellEvent(e)
-        self.setResult('Widget', self.cellWidget)
+        self.set_output('Widget', self.cellWidget)
         return self.cellWidget
 
     display = displayAndWait
 
+
+class SpreadsheetModeConfig(OutputModeConfig):
+    mode_type = "spreadsheet"
+    _fields = [ConfigField('row', None, int),
+               ConfigField('col', None, int),
+               ConfigField('sheetName', None, str),
+               ConfigField('sheetRowCount', None, int),
+               ConfigField('sheetColCount', None, int),
+               ConfigField('rowSpan', None, int),
+               ConfigField('colSpan', None, int)]
+
+
+class SpreadsheetMode(OutputMode):
+    mode_type = "spreadsheet"
+    priority = 500
+    config_cls = SpreadsheetModeConfig
+
+    @staticmethod
+    def can_compute():
+        if get_vistrails_configuration().batch:
+            return False
+        return True
+
+    def create_display_event(self, output_module, configuration,
+                             cell_cls, input_ports):
+        """create_display_event(output_module: Module,
+                                configuration: OutputModeConfig,
+                                cell_cls: class,
+                                input_ports: tuple) -> None
+        Create a DisplayEvent with all the parameters from the cell
+        locations and inputs
+
+        """
+        e = DisplayCellEvent()
+        if configuration is not None:
+            e.row = configuration['row']
+            e.col = configuration['col']
+            if (configuration['sheetName'] or configuration['sheetRowCount'] or
+                configuration['sheetColCount']):
+                ref = StandardSheetReference()
+                if configuration['sheetName']:
+                    ref.sheetName = configuration['sheetName']
+                if configuration['sheetRowCount']:
+                    ref.minimumRowCount = configuration['sheetRowCount']
+                if configuration['sheetColCount']:
+                    ref.minimumColumnCount = configuration['sheetColCount']
+                e.sheetReference = ref
+            e.rowSpan = configuration['rowSpan']
+            e.colSpan = configuration['colSpan']
+        e.vistrail = output_module.moduleInfo
+        e.cellType = cell_cls
+        e.inputPorts = input_ports
+        return e
+
+    def display(self, output_module, configuration, cell_type, input_ports):
+        """display(output_module: Module,
+                   configuration: OutputModeConfig,
+                   cell_cls: class,
+                   input_ports: tuple) -> None
+        Dispatch the cellType to the spreadsheet with appropriate input data
+        to display it
+
+        """
+        if spreadsheetController.echoMode():
+            return self.display_and_wait(output_module, configuration,
+                                         cell_type, input_ports)
+        e = self.create_display_event(cell_type, input_ports)
+        spreadsheetController.postEventToSpreadsheet(e)
+
+    def display_and_wait(self, output_module, configuration, cell_type,
+                         input_ports):
+        """display_and_wait(output_module: Module,
+                            configuration: OutputModeConfig,
+                            cell_cls: class,
+                            input_ports: tuple) -> None
+        Send the message and wait for the cell to complete its movement
+        constructed to return it
+
+        """
+        e = self.create_display_event(output_module, configuration,
+                                      cell_type, input_ports)
+        QtCore.QCoreApplication.processEvents()
+        spreadsheetWindow = spreadsheetController.findSpreadsheetWindow()
+        if spreadsheetWindow.echoMode == False:
+            spreadsheetWindow.configShow(show=True)
+        cell = spreadsheetWindow.displayCellEvent(e)
+        if cell is not None:
+            cell.set_output_module(output_module, configuration)
+        return cell
+
+
 class SingleCellSheetReference(SheetReference):
     """
     SingleCellSheetReference is a wrapper of StandardSingleCellSheetReference
     that will allow users to dedicate a whole sheet to view a single
     visualization by pass all other sheet control widgets.
-    
+
     """
     def compute(self):
         """ compute() -> None
         Store information from input ports into internal structure
-        
+
         """
-        if self.sheetReference==None:
-            self.sheetReference = StandardSingleCellSheetReference()
-        self.sheetReference.sheetName = self.forceGetInputFromPort("SheetName")
+        ref = StandardSingleCellSheetReference()
+        ref.sheetName = self.force_get_input("SheetName")
 
+        self.set_output('value', ref)
diff --git a/vistrails/packages/spreadsheet/cell.qrc b/vistrails/packages/spreadsheet/cell.qrc
new file mode 100644
index 0000000..677121d
--- /dev/null
+++ b/vistrails/packages/spreadsheet/cell.qrc
@@ -0,0 +1,10 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>images/copy_cell.png</file>
+    <file>images/move_cell.png</file>
+    <file>images/locate.png</file>
+    <file>images/update.png</file>
+    <file>images/create_analogy.png</file>
+    <file>images/apply_analogy.png</file>
+</qresource>
+</RCC>
diff --git a/vistrails/packages/spreadsheet/cell_rc.py b/vistrails/packages/spreadsheet/cell_rc.py
index 134c0aa..50a0211 100644
--- a/vistrails/packages/spreadsheet/cell_rc.py
+++ b/vistrails/packages/spreadsheet/cell_rc.py
@@ -1,46 +1,49 @@
+# -*- coding: utf-8 -*-
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-# -*- coding: utf-8 -*-
 
 # Resource object code
 #
-# Created: Fri Nov 30 16:53:17 2007
-#      by: The Resource Compiler for PyQt (Qt v4.2.2)
+# Created: Thu Mar 20 11:39:03 2014
+#      by: The Resource Compiler for PyQt (Qt v4.8.5)
 #
 # WARNING! All changes made in this file will be lost!
 
+from __future__ import division
+
 from PyQt4 import QtCore
 
 qt_resource_data = b"\
diff --git a/vistrails/packages/spreadsheet/celltoolbar.qrc b/vistrails/packages/spreadsheet/celltoolbar.qrc
new file mode 100644
index 0000000..eeaa812
--- /dev/null
+++ b/vistrails/packages/spreadsheet/celltoolbar.qrc
@@ -0,0 +1,11 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>images/player_pause.png</file>
+    <file>images/player_play.png</file>
+    <file>images/player_eject.png</file>
+    <file>images/noatunloopsong.png</file>
+    <file>images/camera_mount.png</file>
+    <file>images/camera.png</file>
+    <file>images/view-refresh.png</file>
+</qresource>
+</RCC>
diff --git a/vistrails/packages/spreadsheet/celltoolbar_rc.py b/vistrails/packages/spreadsheet/celltoolbar_rc.py
index 7bc26d6..c153d7c 100644
--- a/vistrails/packages/spreadsheet/celltoolbar_rc.py
+++ b/vistrails/packages/spreadsheet/celltoolbar_rc.py
@@ -1,46 +1,49 @@
+# -*- coding: utf-8 -*-
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-# -*- coding: utf-8 -*-
 
 # Resource object code
 #
-# Created: Mon Jul 19 16:02:46 2010
-#      by: The Resource Compiler for PyQt (Qt v4.6.3)
+# Created: Mon Dec 29 14:50:55 2014
+#      by: The Resource Compiler for PyQt (Qt v4.8.6)
 #
 # WARNING! All changes made in this file will be lost!
 
+from __future__ import division
+
 from PyQt4 import QtCore
 
 qt_resource_data = b"\
@@ -273,6 +276,132 @@ qt_resource_data = b"\
 \x89\x64\x3b\xb0\x7b\x1e\x0f\xe2\x02\x04\x18\x00\x0c\x5e\x57\xaa\
 \x57\xdc\x85\x99\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
 \
+\x00\x00\x07\xb6\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
+\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xaf\xc8\x37\x05\x8a\xe9\
+\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\
+\x00\x41\x64\x6f\x62\x65\x20\x49\x6d\x61\x67\x65\x52\x65\x61\x64\
+\x79\x71\xc9\x65\x3c\x00\x00\x07\x48\x49\x44\x41\x54\x78\xda\x62\
+\xfc\xff\xff\x3f\xc3\x40\x02\x80\x00\x62\x62\x18\x60\x00\x10\x40\
+\x03\xee\x00\x80\x00\x1a\x70\x07\x00\x04\xd0\x80\x3b\x00\x20\x80\
+\x58\x40\x84\xb1\x71\x2a\xc3\x8f\x1f\x3f\x99\x7e\xfe\xfc\xce\xfd\
+\xff\xff\xbf\xbf\x4a\x4a\xaa\x86\x52\x52\x02\x59\x3c\x3c\x8c\x66\
+\x7f\xfe\xfc\x61\x7e\xf2\xe4\xed\x8d\xd3\xa7\xf7\x2d\xfb\xf6\xed\
+\xdd\x76\x25\x25\xc7\x9f\x0c\x0c\xff\xa0\xda\x19\x21\xbe\x60\x82\
+\xf8\x83\x91\x91\x11\x8e\x99\x98\x18\x19\x40\xe9\x1b\xc4\x86\xc9\
+\x81\xc4\x98\x98\x98\x19\x7f\xff\xfe\xf4\xe5\xcc\x99\xa5\xe0\xd4\
+\x0f\x10\x40\x60\x07\xfc\xfb\xf7\xdf\x4e\x45\x45\xa6\x41\x50\x90\
+\x97\x07\x98\x2b\xfe\x72\x70\x70\x6a\x70\x71\x31\x0a\xb0\xb1\x31\
+\x81\x2d\xe1\xe5\xe5\x55\x94\x92\x8a\x75\xff\xf7\xef\xef\x65\x06\
+\x86\xff\x3f\x41\x86\xb0\xb3\xb3\x83\x03\x10\x64\xfe\xef\xdf\xbf\
+\x41\x06\x83\x2d\x01\x7a\x00\xcc\x06\x3b\xe0\xdf\x7f\x86\xff\x70\
+\x87\x81\x4c\x02\x3a\x80\x99\x99\xf1\xc5\x8b\x97\xaf\x1e\x3c\x50\
+\xa9\x7f\xf3\xe6\xce\x19\x80\x00\x02\x3b\x40\x4d\x4d\x76\x62\x6f\
+\x6f\x9a\x81\xa0\x20\x1f\xd8\xd5\x9f\x3f\x7f\x67\xf8\xf8\xf1\x2b\
+\xc3\xb7\x6f\xbf\xc1\x7c\x16\x16\x66\x06\x56\x56\x56\xa0\x47\x99\
+\xf4\x41\x86\xb1\xb1\x73\x30\x5c\xbf\x7c\x9c\xe1\xf1\x83\x3b\x0c\
+\x6a\xda\x46\x0c\xc2\x22\x62\x40\x75\x7f\x80\x1e\xf9\xc7\xc0\xcc\
+\xcc\xcc\xf0\xf7\x2f\x13\x03\x07\x07\x1f\x03\x3b\x3b\x50\x2d\x0b\
+\x23\x03\x33\x28\x10\x18\x99\x18\xbe\x7c\xfd\xc1\xf0\xfd\x27\x2b\
+\xd0\xfc\xbf\x0c\xf7\xef\x5f\x66\x02\x3a\x20\x09\x20\x80\xc0\x0e\
+\x10\x15\xe5\x96\x65\x61\xf9\xc7\xf0\xe5\xcb\x67\xb0\xeb\x3f\x7d\
+\xfa\xca\xf0\xf2\xe5\x7b\x86\x0f\x1f\xbe\x83\x83\x8f\x99\x99\x05\
+\x8c\x41\x72\x5c\x9c\x5c\x0c\x77\x6f\x9f\x60\x68\x59\x75\x9c\x41\
+\xc9\x3a\x80\xe1\x45\xd3\x74\x86\x25\xfd\xb9\x0c\x4b\x96\xaf\x66\
+\xf8\xf8\xe1\x03\x43\x45\x45\x25\xd8\xe7\x97\xaf\x5e\x64\x10\x91\
+\x92\x65\x10\x92\x94\x61\x78\xf1\x8d\x91\xe1\xf9\xd7\xff\x0c\xaf\
+\xdf\xfd\x64\xe0\x7a\x78\x83\x41\x54\x50\x11\xe8\x40\x0e\x05\xa0\
+\xd1\x0a\x00\x01\x04\x8e\xbc\x5f\xbf\x7e\xfd\xfd\xfd\xfb\x2f\x3c\
+\xbe\x50\xe3\x0c\x82\x41\x7c\x66\x66\x26\x70\xb4\xbf\x7c\x76\x93\
+\xe1\xfe\x27\x1e\x86\xdd\x8f\xa5\x18\x18\x39\x44\x19\x04\xf8\x78\
+\x18\x56\x2c\x5f\xc1\xb0\x60\xc1\x22\x86\xef\xdf\x7f\x30\x28\xab\
+\x28\x33\xd8\x58\x9b\x31\x3c\xff\xc6\xc4\x70\xe6\xfe\x67\x86\xcb\
+\xf7\xde\x30\x7c\xff\xf2\x9b\x81\xf9\xe7\x37\x06\x0e\x60\xd4\xfd\
+\xfe\xf5\x07\x18\x6d\x7f\x41\x96\xb1\x01\x04\x10\x0b\x2c\x31\x21\
+\xd9\x8d\x15\x40\x1c\xc7\xc8\xf0\xf8\xf1\x0d\x06\x77\x5f\x6f\x06\
+\x0e\xc1\x13\x0c\x07\x8f\x75\x31\x64\x97\x86\x30\xc8\x29\x6b\x31\
+\x2c\x5d\xba\x14\x68\xf9\x77\x06\x0d\x0d\x75\x60\x82\xfe\x0d\x8c\
+\x32\x76\x06\x0b\x25\x01\x86\x5f\x3f\x7e\x32\x5c\xb9\x72\x95\x41\
+\x98\x4b\x8d\x81\x55\x90\x9f\xe1\x1d\x23\x3b\x30\x7a\x7f\xc2\x3c\
+\xfb\x1f\x20\x80\x58\x88\xcd\x2e\x20\xdf\xbf\x7a\xf5\x88\x41\x4c\
+\x8c\x9f\x41\x52\x52\x9e\x21\x39\x5e\x99\x21\x3b\x25\x92\x81\x85\
+\x83\x07\x2c\x6f\x67\x67\x07\x57\xfb\xfb\x37\x24\x97\xf0\xf0\xf0\
+\x32\xfc\x66\xe7\x62\x30\x30\x34\x66\xb8\x78\xf1\x1a\x83\xa4\x94\
+\x38\x30\x3d\x81\x92\xe5\x0f\xb8\x87\x01\x02\x88\x05\xe1\xbb\xff\
+\x78\x7c\xcf\x04\xf4\xd5\x0f\xa0\xaf\xfe\x30\xc8\xc9\x29\x83\x83\
+\x99\x81\x81\x95\x81\x81\x9b\x93\x81\x0d\x18\x9c\x5f\xbe\x7c\x02\
+\x3a\xee\x05\x58\x0d\x1f\x1f\x3f\x30\x4d\x49\x80\x13\xee\xb7\x6f\
+\x3f\xc1\x39\x84\x99\x85\x1d\x68\xb9\x08\xc3\xa3\x47\x57\x18\x04\
+\x04\x54\x19\x90\xab\x1f\x80\x00\x22\x2a\x04\x40\x89\xef\xc3\x87\
+\x97\x0c\xb2\xb2\x52\xc0\x14\xfe\x1f\xec\x58\x90\xa3\x81\xd9\x92\
+\xe1\xde\xbd\x07\x0c\x2f\x5e\xbc\x06\x0a\xb1\x03\x2d\x62\x03\x26\
+\xde\x27\xc0\x68\x7a\xc2\xa0\xa2\xa2\xca\xc0\xc5\xc5\x0f\x4c\x5f\
+\xa0\xf8\xfe\xc3\x20\x2c\x2c\x0e\x4e\xd8\x3f\x7e\x7c\x87\x46\x39\
+\x24\x08\x00\x02\x88\x89\x50\x81\x08\x52\xf8\xf7\xef\x6f\xa0\x41\
+\x5f\x19\xd8\xd8\xb8\xc0\x96\x42\xa2\x84\x99\xe1\xcd\x9b\x97\x0c\
+\xaf\x5f\xbf\x63\xe0\xe1\x95\x64\x78\xfd\xe6\x23\xc3\xb9\x73\x67\
+\x19\x38\x38\x85\x80\x39\x8e\x87\xe1\xc6\x8d\x6b\x0c\xc0\x82\x0d\
+\x5a\x36\x00\xcb\x83\xff\x4c\x0c\xdc\xdc\xec\xc0\xd0\x7a\x0b\x0c\
+\x1d\x84\xbf\x01\x02\x88\x09\x62\x09\xde\xe4\x07\xf4\xc1\x2f\x06\
+\x4e\x4e\xa0\x0f\x99\x59\xc1\x86\xc1\x7c\xff\xfe\xfd\x7b\x06\x31\
+\x71\x39\x86\x53\xa7\x8e\x30\x24\xa7\x84\x30\x14\x15\xa5\x02\xb3\
+\x61\x16\xb0\xe0\xe2\x07\x46\x17\x17\xc3\xdb\xb7\xaf\x80\x96\x41\
+\x3c\xf7\xf7\xef\x5f\xb0\x19\x3f\x7e\x7c\x00\x47\x29\x0c\x00\x04\
+\x10\x11\x0e\x60\x00\x5b\x0a\x2a\xf9\x60\x6d\x07\x50\xd1\xfb\xf3\
+\xe7\x0f\x70\xaa\x11\x13\x17\x65\x58\xb8\x60\x26\xc3\xe7\x4f\x9f\
+\x40\x25\x2a\xc3\x89\xe3\x47\x18\xce\x9c\x39\xc6\x20\x2e\x21\x05\
+\x2c\x70\x3e\xc2\x2d\x83\x98\xc1\x01\xe4\xff\x03\xab\x83\x15\xe3\
+\x00\x01\xc4\x84\x5c\xa6\xe3\x03\x10\x4d\x08\x07\x81\x1c\xf1\x0f\
+\xe8\xab\xff\xc0\x7a\x41\x50\x48\x18\x45\x2d\xbf\x00\x3f\xc3\x1f\
+\x60\xb4\xfd\xfd\xfb\x0f\x29\x2a\x19\xc0\x25\xe5\xbf\x7f\xa8\xe6\
+\x02\x04\x10\x52\x2e\xc0\x57\x06\x30\x83\xf3\x38\xc2\x31\xff\x80\
+\xe9\x81\x13\x98\xe8\x58\x18\x5e\x3e\x7f\xca\x50\x5e\x51\xcd\xf0\
+\x13\x98\xb8\x5e\x3c\x7f\xce\xe0\xe1\xed\xc3\x60\x6e\x6e\xc9\x70\
+\xe3\xfa\x45\x06\x49\x09\x49\x68\x94\x41\xec\x00\x25\x40\x26\x26\
+\x56\xb0\xe3\x61\x76\x02\x04\x10\x0b\xa1\x28\x00\x19\xc0\xc6\xc6\
+\x06\xcc\x05\xff\x80\x3e\xfa\x05\x54\xcb\x0e\x97\x13\x03\xd6\x01\
+\xf7\xee\xdf\x65\x10\x11\x91\x60\x98\x39\x7b\x3e\x38\x7b\xf2\xf0\
+\x70\x33\xdc\xbd\x73\x1d\x58\xda\xfd\x64\x90\x90\x90\x02\xc7\x3d\
+\xac\x3e\xf9\xf1\xe3\x17\x50\x5e\x84\x01\x58\xc3\xc2\xed\x04\x08\
+\x20\x22\xb2\x21\x24\xb8\x39\x39\xf9\x19\xbe\x7e\xfd\xc4\xc0\xcf\
+\x2f\x08\x4f\x54\xc2\x22\xa2\x40\xd7\xff\x67\x78\xf2\xe4\x31\xc3\
+\xdb\x9f\x7f\x80\xc1\xfe\x87\xe1\xc5\xb3\x3f\xc0\xc4\xca\xc8\x60\
+\x6a\x6a\x01\x2e\x0d\x7f\xff\xfe\x01\xcd\x49\xbf\x80\x69\xe2\x27\
+\x30\x27\x08\x00\x13\xef\x57\x78\xb4\x03\x04\x10\x51\x51\x00\xb2\
+\x8c\x8f\x4f\x88\xe1\xd9\xb3\x7b\xc0\x52\x50\x12\xe8\x20\x48\x28\
+\x80\x7c\x22\x21\x21\x0d\x2c\x1d\x45\x81\x86\x7f\x01\xe7\x16\x16\
+\x16\x56\xa0\x2f\xf9\xc1\xf1\xff\xfd\xfb\x4f\xb0\x3a\x36\x36\x56\
+\x86\xdb\xb7\x6f\x03\x1d\x26\x08\xae\xd4\x90\x01\x40\x00\x11\x99\
+\x08\xff\x83\x35\x72\x72\x8a\x82\xf3\x37\x28\x38\x61\x8e\xfe\x0b\
+\xf4\x35\x0b\xb0\xa4\x13\x11\x11\x01\x3a\x4e\x0a\x48\x8b\x82\x83\
+\x17\xe4\x68\x10\x60\x65\x65\x01\x46\xdf\x6b\x60\xf9\xff\x97\x41\
+\x46\x46\x0d\xac\x1e\xb9\xee\x01\x08\x20\xa2\xb2\x21\x2c\x14\x84\
+\x84\x44\x81\x05\x12\x2b\xc3\xe5\xcb\xe7\xc0\x7a\x40\x69\x03\x51\
+\xd0\x20\xd4\x81\xf8\xa0\x82\x8a\x9d\x9d\x8d\xe1\xdd\xbb\xd7\x0c\
+\x77\xee\x3c\x06\x56\x52\xe6\xf0\x34\x85\x0c\x00\x02\x88\x09\x5a\
+\xaa\x31\x83\x2a\x1b\x6c\x55\x30\x72\x13\x0b\x54\xf8\x48\x4a\x2a\
+\x00\x83\x96\x95\xe1\xc8\x91\xa3\x0c\xcf\x9f\x3f\x01\xfa\x90\x19\
+\x5c\xd8\xc0\x13\x15\x30\x74\x40\x05\x0e\xa8\x14\xbc\x7a\xf5\x32\
+\x30\xe8\x9f\x31\xe8\xe8\x58\x03\x8b\x65\x0e\x70\x6b\x09\x62\x16\
+\x13\xb8\x69\x06\x52\x0f\x10\x40\xe0\x08\x79\xf2\xe4\xcd\xed\x87\
+\x0f\xdf\x09\x2b\x2a\x4a\x01\xe3\x15\x54\x9b\x81\xe2\x17\x98\xcf\
+\xff\x31\xc1\x2b\x23\x18\x06\xb5\x1b\x84\x85\xe5\x80\x29\xfa\x1b\
+\xb0\x04\xbc\x07\xac\x6a\xef\x01\x43\x86\x17\xe8\x30\x71\xb0\x8f\
+\x3f\x00\x1b\x25\xcf\x9e\x01\xeb\xff\xef\xff\x80\xe9\x46\x8a\x41\
+\x5b\x5b\x05\xec\xf8\x5f\xbf\x80\x25\xc6\x3f\x90\x67\x58\x80\x0d\
+\x9e\xcf\xa0\x68\x01\xd5\x68\xff\x01\x02\x88\x11\x14\x24\x52\x52\
+\x7a\x76\xe2\xe2\x72\xd5\xbc\xbc\xdc\xb2\xa0\xf8\x06\x66\xf3\xff\
+\xa0\x82\x07\x56\xec\x22\xb7\x07\x40\x86\xc1\x2a\x28\x50\xf9\x00\
+\xf2\xe9\xb7\x6f\x9f\x80\x21\xc1\x08\xf6\x3d\xa8\xf2\x01\x25\x52\
+\x7e\x7e\x21\x50\x33\x0e\x68\xd6\x1f\xa8\xc5\x90\xb4\x04\x64\x33\
+\x7e\xfc\xf8\xe6\xe7\xb5\x6b\x07\xf7\x7c\xff\xfe\x69\x0e\x40\x00\
+\x31\x42\x2d\x01\x49\x4b\x01\xb1\x1c\x28\x46\xe8\xd0\x1a\x07\x95\
+\x87\xc0\x2a\x94\xe1\x11\x40\x00\x31\x0e\x74\xdf\x10\x20\x80\x06\
+\xbc\x63\x02\x10\x40\x03\xee\x00\x80\x00\x1a\x70\x07\x00\x04\x18\
+\x00\x4e\x12\xc6\x99\x32\x89\xe5\xec\x00\x00\x00\x00\x49\x45\x4e\
+\x44\xae\x42\x60\x82\
 \x00\x00\x09\x8f\
 \x89\
 \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@@ -628,6 +757,135 @@ qt_resource_data = b"\
 \x85\x79\xce\xfe\x4d\x97\x02\x80\x35\xc9\x22\x06\x3e\xf6\x69\xc0\
 \x10\x79\xcd\x40\x07\x00\x10\x60\x00\x67\x40\x00\x61\x44\x18\x7f\
 \x31\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x07\xe8\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x07\x9f\x49\x44\x41\x54\x58\x85\xc5\x97\x69\x6c\x54\xd7\
+\x15\xc7\xff\xf7\xde\xb7\xcc\xe6\x19\x0f\xb6\xd9\x71\x0d\x69\x6a\
+\x84\xa1\x2c\x06\x5c\x35\xe4\x03\x28\x25\x25\x51\x8b\x42\x15\x5a\
+\xe3\x80\x9a\x14\xe3\xa6\x8a\x14\xb5\x52\x94\x96\xb6\x52\xfb\xa1\
+\xf9\x50\xa9\xad\xd4\x46\x45\xa1\x2c\x69\xb0\x49\x05\xa1\xca\xd2\
+\xaa\x09\x11\x71\x43\x09\x4d\x00\x63\x96\x1a\x12\x88\xb1\x0d\x78\
+\xb7\x67\xb3\x67\xe6\xad\xf7\xf4\xc3\xcc\xd0\xe7\x05\xdb\xdf\x7a\
+\xa4\xab\x37\xf7\xcd\xb9\xe7\xff\x3b\x77\xce\x3d\xef\x0d\xf0\x7f\
+\x36\x36\x13\xa7\xd5\x4f\x37\x2e\xf3\xf9\xd5\xef\x28\x1c\x8f\x3b\
+\x0e\x55\x38\xae\x5b\xc4\x39\x73\x18\x58\x96\x0b\xd6\x6e\xbb\xf2\
+\x23\xd7\x75\xde\x31\x93\xbe\x33\x6d\xc7\xb7\x5b\x53\xc5\x5a\x5b\
+\x7f\xe4\x5b\x17\xfe\xb4\xf3\xc4\x8c\x00\xd6\xd5\x1f\xad\xd2\x35\
+\x7e\x30\x12\xf2\x2d\xdd\xb0\xb2\x3c\x54\x3e\xaf\x58\x84\x83\x1a\
+\x74\x4d\x81\x23\x25\x4c\xc3\xc6\x70\xca\x40\xcf\x60\xca\xbd\x7c\
+\x73\x20\x7d\xb7\x3f\x45\x8c\xd3\x41\xd3\xa2\xdf\xb7\x1e\xac\xeb\
+\x1a\x1f\xaf\xfa\x99\xc6\xcd\xe0\x78\xaf\xe5\xc0\x53\xf7\x74\xef\
+\x0b\xb0\xae\xbe\xe9\xbb\x7e\x5d\xf9\xc3\xf6\xaf\x55\x05\x97\x2e\
+\x2e\x65\x44\x80\x24\x02\x49\x82\x4b\x04\x29\x73\x7e\x04\x80\x33\
+\x40\xe1\x0c\xa9\x8c\x8d\xd6\x1b\x7d\xf6\xe9\xf3\x9d\xb6\x43\x6e\
+\x93\x23\xb1\xb7\x65\xff\x8e\x21\x00\x58\xfb\xbd\xc6\x87\x14\x45\
+\x9c\xb4\x5d\x37\x30\x2d\xc0\xba\x86\xa6\x6d\x01\x5d\x3d\xf2\xfc\
+\xb7\x6b\x02\xc5\x61\x1f\x64\x5e\x90\x40\x20\x99\x03\x71\x24\x81\
+\x88\x20\x25\x41\x12\x20\x29\x07\xa2\xab\x1c\xae\x24\x7c\x74\xe9\
+\xb6\x7d\xba\xa5\xd3\x70\x80\x06\x26\xe9\xba\x10\xfc\x5f\x5b\x37\
+\x55\x85\xde\x38\x79\x05\x5e\x00\x65\xbc\xf8\xfa\x5d\x7f\x2e\xe1\
+\x8c\x1f\x6a\x78\xa2\x3a\x30\x2b\xe2\x83\x4b\x04\xc3\x72\x10\x4b\
+\x64\x61\x58\x0e\x14\x21\x50\x14\xd4\x10\x09\xe9\x20\x02\x6c\x57\
+\xc2\x72\x24\x48\x12\x6c\x49\x30\x6d\x17\x82\x33\x3c\xbc\xba\x42\
+\xad\xac\x28\x53\xff\x72\xf2\xca\x81\x78\x32\x1b\x78\x62\xd3\x32\
+\x5a\x38\x37\x3c\x21\xd9\x09\x00\x14\x50\xeb\xd7\x2f\x9f\xaf\xcf\
+\x2b\x2b\xc2\xd5\xf6\x01\x7a\xff\xe3\x5b\x72\x30\x91\xe1\x8c\x81\
+\x11\x51\xce\x87\x48\x0a\xce\xec\xc5\xf3\xa3\xe6\xaa\xa5\xf3\x43\
+\x95\x15\x25\xdc\xa7\x32\xa4\x4d\x17\x19\xd3\x46\x32\x63\x21\x95\
+\x49\x21\xa8\x2b\xd8\xb1\x65\x55\x20\x6b\xd8\xd0\x74\x95\xb9\x92\
+\xa6\x07\xd0\x05\xdf\x53\x53\xb5\xc0\x77\xe8\xed\x8b\xee\xad\xbb\
+\x09\x38\x92\x84\xe0\xdc\xb4\x2c\xa7\x9b\xb8\xbb\xa3\x65\xff\xae\
+\x4f\x00\xa0\x7a\xcf\xb1\xc8\xf5\x5b\x43\x35\xed\xdd\xf1\xdd\x80\
+\x7c\x7c\x4d\xe5\x02\xb6\xa2\x72\x9e\x1f\x5c\x20\x6d\xb8\x70\x25\
+\x10\x4f\xdb\x18\x35\x5d\xcc\x89\xe8\x68\xef\x1b\xc5\xb2\x85\x13\
+\x77\x60\x4c\x0d\x54\xef\x79\x25\xe0\x57\x8a\x07\x57\x56\xce\xd1\
+\x2e\x7e\xda\x87\x68\x38\xa8\x28\x0a\x47\xdf\x50\x22\x2e\x1c\xf5\
+\x8b\xff\x3e\xb8\x3d\x36\x59\xcd\xac\x78\xb6\x29\xea\x77\xf9\xb3\
+\x82\xb3\x9f\x7c\x65\xe5\x22\xdf\xca\xca\x79\xca\x60\xd2\x44\x3c\
+\x63\x43\x4a\x42\x21\xf3\xb5\x0f\x44\xf1\xeb\x57\xcf\x50\xcb\x81\
+\x3a\x5e\x58\xcb\xbd\x81\x38\x15\x2d\x26\x50\xe0\xd2\x67\xbd\xe2\
+\x0b\x0b\x4a\x58\x49\x34\x18\x13\x42\xf4\x83\x58\xdb\xfd\xc4\x01\
+\xe0\xea\xbe\xba\xf8\xb9\xfd\xb5\x2f\x19\x16\x55\x9e\xbd\xdc\x75\
+\xf2\xd5\x37\x2f\xa0\x24\xa4\xa0\xbc\x34\x00\xa2\x5c\xb1\x02\x00\
+\xe7\x0c\x9c\xc1\x1c\xa3\xe9\x9d\x48\x26\xb9\x61\x39\xd0\x7c\xbe\
+\xe1\x90\xdf\xf7\x41\x40\xd7\x3f\x70\x1c\xe7\x26\x91\x3b\xe1\x4c\
+\x4f\x66\xad\x87\x6a\x7b\x00\xfa\x58\x51\xb8\xa5\x28\x0a\xe2\xa3\
+\x16\x88\x00\x22\x80\x31\x80\xb3\x89\x87\x6e\x4c\x0d\x28\x36\x5c\
+\x47\x00\xb3\xa3\xa1\x7f\x04\x03\xfa\x35\xc6\x79\xb2\x38\x12\x0c\
+\x0c\x0d\x8f\xcc\xa8\x63\x56\xd7\x37\x7e\x3f\xec\xd7\x7f\x5c\xfb\
+\xd8\x2a\xad\x3f\x69\x20\x91\xb6\x20\x91\xeb\x15\x85\x1d\x98\x12\
+\x20\xeb\xc8\x2e\x55\x70\x8c\x66\xb2\x1f\xf6\x77\x3b\xed\xb6\x22\
+\x46\x93\xd9\x84\xe9\xba\xf6\xe8\x74\xe2\x35\x0d\x4d\x5b\x7d\xba\
+\xf6\xdb\x5d\xdf\x58\xed\xd7\x75\x15\x41\x9f\x86\xf2\xd2\x00\xc0\
+\x00\x06\x06\x55\x70\x08\x06\x0f\x4e\xce\x26\x20\xad\x7b\xfa\xf5\
+\x45\xe7\x0f\xd7\xde\x99\x49\xc6\x05\x5b\xb3\xfb\xb5\x4d\x0c\xfc\
+\xd4\x4c\xfd\xa7\xec\x84\xd5\xbb\x1b\x49\x70\x96\x2d\xcc\x25\x91\
+\x42\x04\x75\xb2\x40\xd2\xd5\x66\xb7\x1e\xde\x3e\x38\x53\xe1\x27\
+\x9f\x3c\x26\xba\x22\x46\xf9\xb9\x03\xbb\x3a\x0a\xf7\x26\xf4\x01\
+\x00\x78\xf9\x85\xaf\xfb\x81\x5c\xf1\x48\x22\xd8\xae\x84\x94\xb9\
+\x42\xea\xe8\x4d\x62\xdf\x89\xf3\x29\xdb\x72\xab\xa7\x13\x6f\x6e\
+\xee\xf0\x6d\xdc\xb8\xd8\x28\xcc\xdb\x8b\xad\x6f\x32\xe2\x7f\x85\
+\x27\x71\x3e\xd9\x42\x49\x84\xcb\x9d\x09\xb4\x76\xc4\x71\xb9\x33\
+\x81\x6b\x77\x52\x88\x8d\x9a\x18\x88\x67\x70\xe0\xcd\x96\xb4\xe3\
+\x3a\x9b\x2f\x1e\xdc\xf9\xf9\x94\xe9\x12\x31\x37\xaa\x96\x37\xb7\
+\x0d\xcc\xfd\x9f\x18\xb9\x40\xae\x89\x4d\x09\x30\xde\x66\x85\x34\
+\xa8\x82\xe1\x8f\xc7\xce\x49\xc3\x76\xeb\x0a\xdd\x70\x2a\xfb\xc5\
+\x2f\xc1\xae\xdf\xcd\x3e\x2c\x20\xab\x4e\x5d\xed\x7f\xa0\xb9\xb9\
+\x59\x51\x55\x6d\x6b\xee\x5b\x63\x1a\x00\x4f\xa1\x32\x06\x94\x14\
+\x69\xc8\x64\x6d\x00\xc4\x05\x78\x6d\xf5\x9e\xa3\xa5\xd3\x01\x74\
+\x46\x2e\x85\xe3\x69\xf7\xab\x00\x5f\xa6\x70\xaa\x6a\x8b\xcf\xd9\
+\x48\x24\x77\x30\x06\x58\x42\x8c\x4c\x09\xe0\x7d\x66\x10\x01\x37\
+\x7b\x47\x20\x39\xc7\x0f\x77\x3e\x84\x0d\x6b\xca\xb7\x09\x8e\xf6\
+\x75\xf5\x47\x9e\xaf\xa9\x6b\x9c\xd8\xdc\xf3\x96\x96\xf6\xa3\xaa\
+\xc2\xaa\x38\xa3\x65\x89\xb4\xb5\xf6\xf8\xe9\xeb\x4d\x45\xe1\x22\
+\xc1\x39\x1f\xb9\xba\xaf\x2e\x5e\xf0\x9b\xb4\x08\x25\x11\x38\x63\
+\x98\x5f\xea\x47\x4f\x2c\x0b\xdb\x25\xc4\x46\x2c\xc4\x46\x80\x25\
+\x8b\xca\xd4\x59\xd1\x22\xf5\xf2\xa7\xbd\x2f\x75\x76\x0f\xfd\x6a\
+\x7d\xc3\xd1\x13\xb6\x23\x5f\xd3\x0c\x9c\xff\xa4\xe9\xa9\x54\xf5\
+\x8b\xef\x47\x8a\x84\xef\xb9\xd1\xb4\xf3\xe2\xf2\x8a\x50\xea\xed\
+\xb3\x77\xe6\x9e\xb9\xd4\xb1\x20\x10\xf0\x91\x2f\xe0\x53\x13\x89\
+\xd4\x05\xaf\xd6\xa4\xc7\xf0\x77\x3f\xda\x8c\xac\xe5\x22\x91\xca\
+\x22\x1c\xf2\xa3\x2f\x91\x45\xf7\x70\x16\xfd\x09\x13\xae\x94\xd0\
+\x55\x81\x68\x50\x85\x94\x84\xae\x9e\x98\x7b\xb7\x27\x96\x8e\x8f\
+\x64\x74\x21\x14\x9d\x71\x05\x94\x7f\x76\x4b\xc7\x41\x20\xa8\xbb\
+\xd1\x68\x58\xd1\x03\x7e\xdc\xe9\xea\x19\xc9\x9a\xe6\x0f\x2e\xbe\
+\xb2\xa3\x71\xca\x1d\x20\x02\x6e\xde\x49\xc8\xc3\x6f\xb5\xf0\x07\
+\xcb\x4b\xb2\x5b\x36\x3c\xe8\x57\x04\x07\x63\x04\x02\x90\x31\x1d\
+\xa4\x0d\x07\x42\x30\x44\xa3\x61\x31\xbb\x2c\x12\x26\x09\x8c\xa4\
+\x0d\xa4\x0d\x1b\x8e\x4b\xe0\x9c\x31\xae\x68\x70\x49\x2a\x8e\x0b\
+\xa4\x92\x69\x58\x86\x31\x6a\xc6\xd5\x63\x5e\xad\xf1\x00\x0c\x00\
+\x6e\xf5\x26\xd0\xf8\xf7\xd6\x91\xe1\xdb\xe7\x1f\xb5\x53\x15\x9b\
+\x3a\x7a\x62\x3f\x5f\xb3\x74\xa1\xba\xa4\x62\xb6\x92\x4c\xdb\x88\
+\xa5\x2d\xd8\x0e\xc1\x72\x24\x4c\x5b\x42\x12\xdd\x5b\xce\x35\x1d\
+\x42\xe6\xfa\x86\xe5\xba\x00\x31\x64\x32\x59\x0c\xf6\xf5\x67\x8d\
+\x44\xcf\xae\xb6\xe3\x2f\x30\xe4\x6a\x4f\x02\x80\xf0\x88\x73\x00\
+\xfa\x82\xea\x6d\x3f\xbb\x72\xa3\x3f\x3d\x74\xfb\x52\xed\xad\x77\
+\x7f\x73\xab\xbf\xed\xbd\xcf\xcc\x6c\xf2\x6f\x23\x7c\xf6\xbc\xcf\
+\x6f\xc7\x17\xfa\x75\x05\x73\xa2\x21\xee\xd7\x15\x30\x86\xfc\x7b\
+\x21\x40\x32\x77\x95\x24\xf3\x79\xe4\x76\x2b\x3e\x9c\x94\x03\xbd\
+\x83\x99\xcc\x60\x7b\x43\xdb\x89\xbd\x67\xf3\x3a\x39\x07\x40\xb2\
+\x7b\xe8\x80\x06\x40\xab\xde\xdd\x98\xca\x26\x6e\x3f\x73\xed\x8d\
+\xbd\xcd\x85\x7b\x85\x51\x5a\xf5\xc8\x92\xf9\xcb\x1f\xab\xf5\x45\
+\x4a\x1f\x29\x0e\x07\x65\x69\x69\xd4\x1f\x0c\xf8\x98\xa6\xa9\x00\
+\x63\x70\x24\x60\x9a\x36\xd2\x86\x85\x64\x32\xed\x26\x63\x89\xac\
+\x6d\x66\xfe\xd3\x7d\xf1\xad\x9f\xf6\x5f\x79\xa7\x03\x80\x35\x6e\
+\x98\xcc\x93\xbd\x06\x40\xff\x72\xed\xcb\x7b\xae\xbc\xfe\xdc\x51\
+\x00\xfa\x38\x80\x7b\x73\xcd\x1f\x29\x2a\x5b\xbe\x65\x65\xf1\xc2\
+\x15\x35\x7a\x51\xd9\x97\xb8\xa6\x97\x81\xb8\x42\x8c\x09\x06\x39\
+\x2a\x1d\xb3\xd7\x88\xf7\x7d\x38\x74\xe3\x9f\xef\x0e\x5c\x3f\xd5\
+\x59\x10\xf3\x0a\xe7\xaf\x86\xf7\x14\x4c\x2a\x96\x1f\xea\xb8\xcf\
+\x6a\xbe\x7e\x84\x77\x3b\x01\x38\x00\x6c\xcf\x18\x9f\xf1\x98\xec\
+\x01\x98\xde\x22\xb4\x31\xf6\x58\x16\x82\xba\xf9\xc0\x4e\x7e\x61\
+\x41\x58\x60\x6c\x23\xa3\xbc\xaf\xd7\xdf\xf6\xac\xf3\x42\x19\xf9\
+\xeb\xa4\x7f\x4c\x0a\x3f\x87\x8a\xb1\xd9\x8e\x17\x2e\x14\x53\x21\
+\x46\x01\xb8\x00\x3d\x19\x48\x41\xf8\x5e\xaf\x9d\xee\x55\x4b\xe4\
+\x85\x0b\x10\xdc\x03\xe0\x15\x2f\x00\x78\x21\xbc\xc2\x4e\xfe\xde\
+\x04\x9b\xd1\xbb\xde\x24\x6b\xbc\xa3\x20\xee\x85\x98\xf8\x0f\xe4\
+\x3e\xf6\x5f\x84\x3d\xc2\x88\x6d\x32\x73\x76\x00\x00\x00\x00\x49\
+\x45\x4e\x44\xae\x42\x60\x82\
 "
 
 qt_resource_name = b"\
@@ -644,6 +902,10 @@ qt_resource_name = b"\
 \x03\x05\x50\x67\
 \x00\x70\
 \x00\x6c\x00\x61\x00\x79\x00\x65\x00\x72\x00\x5f\x00\x70\x00\x61\x00\x75\x00\x73\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x0a\
+\x0c\x91\x67\x27\
+\x00\x63\
+\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x70\x00\x6e\x00\x67\
 \x00\x10\
 \x05\x42\x7f\x67\
 \x00\x63\
@@ -656,15 +918,21 @@ qt_resource_name = b"\
 \x03\x75\x07\x07\
 \x00\x70\
 \x00\x6c\x00\x61\x00\x79\x00\x65\x00\x72\x00\x5f\x00\x70\x00\x6c\x00\x61\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x10\
+\x08\x15\x13\x67\
+\x00\x76\
+\x00\x69\x00\x65\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x70\x00\x6e\x00\x67\
 "
 
 qt_resource_struct = b"\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x02\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\
 \x00\x00\x00\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x09\x48\
-\x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x79\
-\x00\x00\x00\x88\x00\x00\x00\x00\x00\x01\x00\x00\x17\x90\
+\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x25\x33\
+\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x4a\
 \x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x01\x00\x00\x15\xb7\
+\x00\x00\x00\xec\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x85\
 \x00\x00\x00\x62\x00\x00\x00\x00\x00\x01\x00\x00\x0d\xfd\
 "
 
diff --git a/vistrails/packages/spreadsheet/identifiers.py b/vistrails/packages/spreadsheet/identifiers.py
index 1823bee..7c63559 100644
--- a/vistrails/packages/spreadsheet/identifiers.py
+++ b/vistrails/packages/spreadsheet/identifiers.py
@@ -1,39 +1,42 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.spreadsheet'
 name = 'VisTrails Spreadsheet'
-version = '0.9.2'
+version = '0.9.4'
 old_identifiers = ['edu.utah.sci.vistrails.spreadsheet']
diff --git a/vistrails/packages/spreadsheet/images/apply_analogy.png b/vistrails/packages/spreadsheet/images/apply_analogy.png
new file mode 100644
index 0000000..af17c1b
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/apply_analogy.png differ
diff --git a/vistrails/packages/spreadsheet/images/back.png b/vistrails/packages/spreadsheet/images/back.png
new file mode 100644
index 0000000..89e71fb
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/back.png differ
diff --git a/vistrails/gui/resources/images/camera.png b/vistrails/packages/spreadsheet/images/camera.png
similarity index 100%
rename from vistrails/gui/resources/images/camera.png
rename to vistrails/packages/spreadsheet/images/camera.png
diff --git a/vistrails/packages/spreadsheet/images/camera_mount.png b/vistrails/packages/spreadsheet/images/camera_mount.png
new file mode 100644
index 0000000..9197fe5
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/camera_mount.png differ
diff --git a/vistrails/packages/spreadsheet/images/copy_cell.png b/vistrails/packages/spreadsheet/images/copy_cell.png
new file mode 100644
index 0000000..3c0e1c9
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/copy_cell.png differ
diff --git a/vistrails/packages/spreadsheet/images/create_analogy.png b/vistrails/packages/spreadsheet/images/create_analogy.png
new file mode 100644
index 0000000..786796a
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/create_analogy.png differ
diff --git a/vistrails/packages/spreadsheet/images/delete.png b/vistrails/packages/spreadsheet/images/delete.png
new file mode 100644
index 0000000..ac9f30e
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/delete.png differ
diff --git a/vistrails/packages/spreadsheet/images/deletesheet.png b/vistrails/packages/spreadsheet/images/deletesheet.png
new file mode 100644
index 0000000..14d9dc7
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/deletesheet.png differ
diff --git a/vistrails/packages/spreadsheet/images/fittowindow.png b/vistrails/packages/spreadsheet/images/fittowindow.png
new file mode 100644
index 0000000..4972989
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/fittowindow.png differ
diff --git a/vistrails/packages/spreadsheet/images/forward.png b/vistrails/packages/spreadsheet/images/forward.png
new file mode 100644
index 0000000..1d096b1
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/forward.png differ
diff --git a/vistrails/packages/spreadsheet/images/locate.png b/vistrails/packages/spreadsheet/images/locate.png
new file mode 100644
index 0000000..bfc3963
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/locate.png differ
diff --git a/vistrails/packages/spreadsheet/images/move_cell.png b/vistrails/packages/spreadsheet/images/move_cell.png
new file mode 100644
index 0000000..990a50b
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/move_cell.png differ
diff --git a/vistrails/packages/spreadsheet/images/newsheet.png b/vistrails/packages/spreadsheet/images/newsheet.png
new file mode 100644
index 0000000..4816316
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/newsheet.png differ
diff --git a/vistrails/packages/spreadsheet/images/noatunloopsong.png b/vistrails/packages/spreadsheet/images/noatunloopsong.png
new file mode 100644
index 0000000..5d56f72
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/noatunloopsong.png differ
diff --git a/vistrails/packages/spreadsheet/images/ok.png b/vistrails/packages/spreadsheet/images/ok.png
new file mode 100644
index 0000000..3b40b9a
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/ok.png differ
diff --git a/vistrails/packages/spreadsheet/images/open.png b/vistrails/packages/spreadsheet/images/open.png
new file mode 100644
index 0000000..4052e04
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/open.png differ
diff --git a/vistrails/packages/spreadsheet/images/player_eject.png b/vistrails/packages/spreadsheet/images/player_eject.png
new file mode 100644
index 0000000..cd7d184
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/player_eject.png differ
diff --git a/vistrails/packages/spreadsheet/images/player_pause.png b/vistrails/packages/spreadsheet/images/player_pause.png
new file mode 100644
index 0000000..95fd2c2
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/player_pause.png differ
diff --git a/vistrails/packages/spreadsheet/images/player_play.png b/vistrails/packages/spreadsheet/images/player_play.png
new file mode 100644
index 0000000..1f7e5e3
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/player_play.png differ
diff --git a/vistrails/packages/spreadsheet/images/save.png b/vistrails/packages/spreadsheet/images/save.png
new file mode 100644
index 0000000..2cbccf7
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/save.png differ
diff --git a/vistrails/packages/spreadsheet/images/saveas.png b/vistrails/packages/spreadsheet/images/saveas.png
new file mode 100644
index 0000000..6190d91
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/saveas.png differ
diff --git a/vistrails/packages/spreadsheet/images/update.png b/vistrails/packages/spreadsheet/images/update.png
new file mode 100644
index 0000000..b52cd80
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/update.png differ
diff --git a/vistrails/packages/spreadsheet/images/view-refresh.png b/vistrails/packages/spreadsheet/images/view-refresh.png
new file mode 100644
index 0000000..606ea9e
Binary files /dev/null and b/vistrails/packages/spreadsheet/images/view-refresh.png differ
diff --git a/vistrails/packages/spreadsheet/init.py b/vistrails/packages/spreadsheet/init.py
index 1273905..a791de6 100644
--- a/vistrails/packages/spreadsheet/init.py
+++ b/vistrails/packages/spreadsheet/init.py
@@ -1,66 +1,71 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# Spreadsheet Package for VisTrails
-################################################################################
+
+"""Spreadsheet Package for VisTrails
+"""
+
+from __future__ import division
+
+import copy
+import os
 from PyQt4 import QtCore, QtGui
+import sys
+
 from vistrails.core import debug
 from vistrails.core.modules import basic_modules
 from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.modules.vistrails_module import Module
+from vistrails.core.modules.utils import create_descriptor_string
 from vistrails.core.system import vistrails_root_directory
-from spreadsheet_controller import spreadsheetController
-from spreadsheet_registry import spreadsheetRegistry
-from spreadsheet_window import SpreadsheetWindow
-import os
-import string
-import sys
-from spreadsheet_config import configuration
-import vistrails.core
+from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler, \
+    UpgradePackageRemap, UpgradeModuleRemap
 
-# This must be here because of VisTrails protocol
+from .spreadsheet_controller import spreadsheetController
+from .spreadsheet_registry import spreadsheetRegistry
 
-################################################################################
+
+# This must be here because of VisTrails protocol
 
 basicWidgets = None
 
+
 def importReturnLast(name):
     """ importReturnLast(name: str) -> package
     Import a package whose name is specified in name and return right-most
     package on the package name
-    
+
     """
     mod = __import__(name)
     components = name.split('.')
@@ -68,11 +73,12 @@ def importReturnLast(name):
         mod = getattr(mod, comp)
     return mod
 
+
 def addWidget(packagePath):
     """ addWidget(packagePath: str) -> package
     Add a new widget type to the spreadsheet registry supplying a
     basic set of spreadsheet widgets
-    
+
     """
     try:
         registry = get_module_registry()
@@ -84,20 +90,21 @@ def addWidget(packagePath):
         widget.registerWidget(registry, basic_modules, basicWidgets)
         spreadsheetRegistry.registerPackage(widget, packagePath)
         debug.log('  ==> Successfully import <%s>' % widgetName)
-    except:
-        debug.log('  ==> Ignored package <%s>' % packagePath)
+    except Exception, e:
+        debug.log('  ==> Ignored package <%s>' % packagePath, e)
         widget = None
     return widget
 
+
 def importWidgetModules(basicWidgets):
     """ importWidgetModules(basicWidgets: widget) -> None
     Find all widget package under ./widgets/* to add to the spreadsheet registry
-    
+
     """
     packageName = __name__.lower().endswith('.init') and \
         __name__[:-5] or __name__
     widgetDir = os.path.join(
-        os.path.join(os.path.dirname(vistrails_root_directory()), 
+        os.path.join(os.path.dirname(vistrails_root_directory()),
                      *packageName.split('.')),
         'widgets')
     candidates = os.listdir(widgetDir)
@@ -105,15 +112,16 @@ def importWidgetModules(basicWidgets):
         if os.path.isdir(os.path.join(widgetDir, folder)) and folder != '.svn':
             addWidget('.'.join([packageName, 'widgets', folder]))
 
+
 def initialize(*args, **keywords):
     """ initialize() -> None
     Package-entry to initialize the package
-    
+
     """
     import vistrails.core.application
     if not vistrails.core.application.is_running_gui():
         raise RuntimeError, "GUI is not running. The Spreadsheet package requires the GUI"
-    
+
     # initialize widgets
     debug.log('Loading Spreadsheet widgets...')
     global basicWidgets
@@ -127,14 +135,15 @@ def initialize(*args, **keywords):
     if app==None:
         app = QtGui.QApplication(sys.argv)
     if hasattr(app, 'builderWindow'):
-        global spreadsheetWindow        
+        global spreadsheetWindow
         spreadsheetWindow = spreadsheetController.findSpreadsheetWindow(show=False)
 
+
 def menu_items():
     """menu_items() -> tuple of (str,function)
     It returns a list of pairs containing text for the menu and a
     callback function that will be executed when that menu item is selected.
-    
+
     """
     def show_spreadsheet():
         spreadsheetWindow.show()
@@ -144,10 +153,90 @@ def menu_items():
     lst.append(("Show Spreadsheet", show_spreadsheet))
     return tuple(lst)
 
+
 def finalize():
     spreadsheetWindow = spreadsheetController.findSpreadsheetWindow()
     ### DO NOT ADD BACK spreadsheetWindow.destroy()
-    ### That will crash VisTrails on Mac. 
+    ### That will crash VisTrails on Mac.
     ### It is not supposed to be called directly
     spreadsheetWindow.cleanup()
     spreadsheetWindow.deleteLater()
+
+
+def upgrade_cell_to_output(module_remap, module_id, pipeline,
+                           old_name, new_module,
+                           end_version, input_port_name,
+                           start_version=None, output_version=None):
+    """This function upgrades a *Cell module to a *Output module.
+
+    The upgrade only happens if the original module doesn't have any connection
+    on the cell input ports that can't be translated.
+
+    This is to ease the transition to *Output modules, but we don't want (or
+    need) to break anything; the *Cell modules still exist, so they can stay.
+    """
+    if not isinstance(module_remap, UpgradePackageRemap):
+        module_remap = UpgradePackageRemap.from_dict(module_remap)
+
+    old_module = pipeline.modules[module_id]
+    old_module_name = create_descriptor_string(old_module.package,
+                                               old_module.name,
+                                               old_module.namespace,
+                                               False)
+    if old_module_name != old_name:
+        return module_remap
+
+    used_input_ports = set(old_module.connected_input_ports.keys())
+    for func in old_module.functions:
+        used_input_ports.add(func.name)
+
+    if used_input_ports != set([input_port_name]):
+        return module_remap
+
+    _old_remap = module_remap
+    module_remap = copy.copy(module_remap)
+    assert _old_remap.remaps is not module_remap.remaps
+    remap = UpgradeModuleRemap(start_version, end_version, output_version,
+                               module_name=old_name,
+                               new_module=new_module)
+    remap.add_remap('dst_port_remap', input_port_name, 'value')
+    remap.add_remap('function_remap', input_port_name, 'value')
+    module_remap.add_module_remap(remap)
+    return module_remap
+
+
+def handle_module_upgrade_request(controller, module_id, pipeline):
+    module_remap = {
+            'CellLocation': [
+                (None, '0.9.3', None, {
+                    'src_port_remap': {
+                        'self': 'value'},
+                }),
+            ],
+            'SheetReference': [
+                (None, '0.9.3', None, {
+                    'src_port_remap': {
+                        'self': 'value'},
+                }),
+            ],
+            'SingleCellSheetReference': [
+                (None, '0.9.3', None, {
+                    'src_port_remap': {
+                        'self': 'value'},
+                }),
+            ],
+        }
+
+    module_remap = upgrade_cell_to_output(
+            module_remap, module_id, pipeline,
+            'RichTextCell', 'org.vistrails.vistrails.basic:RichTextOutput',
+            '0.9.4', 'File')
+    module_remap = upgrade_cell_to_output(
+            module_remap, module_id, pipeline,
+            'ImageViewerCell', 'org.vistrails.vistrails.basic:ImageOutput',
+            '0.9.4', 'File')
+
+    return UpgradeWorkflowHandler.remap_module(controller,
+                                               module_id,
+                                               pipeline,
+                                               module_remap)
diff --git a/vistrails/packages/spreadsheet/spreadsheet.qrc b/vistrails/packages/spreadsheet/spreadsheet.qrc
new file mode 100644
index 0000000..6b3457c
--- /dev/null
+++ b/vistrails/packages/spreadsheet/spreadsheet.qrc
@@ -0,0 +1,14 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>images/newsheet.png</file>
+    <file>images/open.png</file>
+    <file>images/ok.png</file>
+    <file>images/back.png</file>
+    <file>images/forward.png</file>
+    <file>images/save.png</file>
+    <file>images/saveas.png</file>
+    <file>images/fittowindow.png</file>
+    <file>images/delete.png</file>
+    <file>images/deletesheet.png</file>
+</qresource>
+</RCC>
diff --git a/vistrails/packages/spreadsheet/spreadsheet_base.py b/vistrails/packages/spreadsheet/spreadsheet_base.py
index 983b705..448984c 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_base.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_base.py
@@ -1,51 +1,55 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains a set of internal Spreadsheet basic classes used
-# by others:
-#   StandardSheetReference
-#   StandardSingleCellSheetReference
-#   StandardSingleCellSheetTab
-################################################################################
-from PyQt4 import QtCore, QtGui
-from spreadsheet_helpers import CellHelpers
-from spreadsheet_registry import spreadsheetRegistry
-from spreadsheet_tab import (StandardWidgetSheetTab,
-                             StandardWidgetSheetTabInterface)
-
-################################################################################
+
+"""This file contains a set of internal Spreadsheet basic classes used by
+others:
+  StandardSheetReference
+  StandardSingleCellSheetReference
+  StandardSingleCellSheetTab
+"""
+
+from __future__ import division
+
+from PyQt4 import QtGui
+
+from .spreadsheet_helpers import CellHelpers
+from .spreadsheet_registry import spreadsheetRegistry
+from .spreadsheet_tab import StandardWidgetSheetTab, \
+    StandardWidgetSheetTabInterface
+
 
 class StandardSheetReference(object):
     """
@@ -57,7 +61,7 @@ class StandardSheetReference(object):
     def __init__(self):
         """ StandardSheetReference() -> StandardSheetReference
         Initialize to the current sheet with no minimum size
-        
+
         """
         self.sheetName = None
         self.minimumRowCount = 1
@@ -67,17 +71,17 @@ class StandardSheetReference(object):
     def isTabValid(self, tabWidget):
         """ isTabValid(tabWidget: QWidget) -> boolean
         Check to see if the tab is an acceptable type
-        
+
         """
         return issubclass(tabWidget.__class__, StandardWidgetSheetTab)
 
     def clearCandidate(self):
-        """ clearCandidate() -> None        
-        Begin the candidate searching process by clearing the previous        
+        """ clearCandidate() -> None
+        Begin the candidate searching process by clearing the previous
         candidate sheet. The searching process is done by looping
         through all available sheets and let the SheetReference decides
         and keep track of which one is the best appropriate
-        
+
         """
         self.candidate = None
 
@@ -85,7 +89,7 @@ class StandardSheetReference(object):
         """ checkCandidate(tabWidget: QWidget,
                            tabLabel: str,
                            tabIndex: int,
-                           curIndex: int) -> None                           
+                           curIndex: int) -> None
         Check to see if this new candidate is better than the one we
         have right now. If it is then use this one instead. The
         condition is very simple, sheet type comes first, then name
@@ -96,7 +100,7 @@ class StandardSheetReference(object):
         tabLabel  --- the display label of the sheet
         tabIndex  --- its index inside the tab controller
         curIndex  --- the current active index of the tab controller
-        
+
         """
         if self.isTabValid(tabWidget):
             if (self.sheetName!=None and
@@ -121,13 +125,13 @@ class StandardSheetReference(object):
                         if tabIndex!=curIndex:
                             return
             self.candidate = (tabWidget, tabLabel, tabIndex, curIndex)
-                
+
     def setupCandidate(self, tabController):
         """ setupCandidate(tabController: SpreadsheetTabController) -> None
         Setup the candidate we have to completely satisfy the reference,
         making ready to be displayed on, e.g. extend the number of row and
         column
-        
+
         """
         if self.candidate==None:
             candidate = StandardWidgetSheetTab(tabController,
@@ -145,19 +149,20 @@ class StandardSheetReference(object):
             tabController.setCurrentWidget(self.candidate[0])
             return self.candidate[0]
 
+
 class StandardSingleCellSheetTab(QtGui.QWidget,
                                  StandardWidgetSheetTabInterface):
     """
     StandardSingleCellSheetTab is a container of StandardWidgetSheet
     with only a single cell. This will be added directly to a
     QTabWidget on the spreadsheet as a sheet for displaying
-    
+
     """
     def __init__(self, tabWidget, row=1, col=1):
         """ StandardSingleCellSheetTab(row: int,
                                        col: int) -> StandardSingleCellSheetTab
         Initialize with the vertical layout containing only a single widget
-        
+
         """
         QtGui.QWidget.__init__(self, None)
         StandardWidgetSheetTabInterface.__init__(self)
@@ -175,25 +180,25 @@ class StandardSingleCellSheetTab(QtGui.QWidget,
         self.pipelineInfo = {}
 
     ### Belows are API Wrappers to connect to self.sheet
-            
+
     def getDimension(self):
         """ getDimension() -> tuple
         Get the sheet dimensions
-        
+
         """
         return (1,1)
-            
+
     def getCell(self, row, col):
         """ getCell(row: int, col: int) -> QWidget
         Get cell at a specific row and column.
-        
+
         """
         return self.cell
 
     def getCellToolBar(self, row, col):
         """ getCellToolBar(row: int, col: int) -> QWidget
         Return the toolbar widget at cell location (row, col)
-        
+
         """
         cell = self.getCell(row, col)
         if cell and hasattr(cell, 'toolBarType'):
@@ -202,13 +207,12 @@ class StandardSingleCellSheetTab(QtGui.QWidget,
             return self.toolBars[cell.toolBarType]
         else:
             return self.blankCellToolBar
-        return self.sheet.getCellToolBar(row, col)
 
     def getCellRect(self, row, col):
         """ getCellRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in parent coordinates
-        
+
         """
         return self.contentsRect()
 
@@ -216,7 +220,7 @@ class StandardSingleCellSheetTab(QtGui.QWidget,
         """ getCellGlobalRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in global coordinates
-        
+
         """
         rect = self.getCellRect(row, col)
         rect.moveTo(self.mapToGlobal(rect.topLeft()))
@@ -226,11 +230,11 @@ class StandardSingleCellSheetTab(QtGui.QWidget,
         """ setCellByType(row: int,
                           col: int,
                           cellType: a type inherits from QWidget,
-                          inpurPorts: tuple) -> None                          
+                          inpurPorts: tuple) -> None
         Replace the current location (row, col) with a cell of
         cellType. If the current type of that cell is the same as
         cellType, only the contents is updated with inputPorts.
-        
+
         """
         oldCell = self.getCell(row, col)
         if type(oldCell)!=cellType:
@@ -251,7 +255,7 @@ class StandardSingleCellSheetTab(QtGui.QWidget,
     def showHelpers(self, show, globalPos):
         """ showHelpers(show: boolean, globalPos: QPoint) -> None
         Show the helpers (toolbar, resizer) when show==True
-        
+
         """
         if show:
             self.helpers.snapTo(0,0)
@@ -263,20 +267,21 @@ class StandardSingleCellSheetTab(QtGui.QWidget,
     def getSelectedLocations(self):
         """ getSelectedLocations() -> tuple
         Return the selected locations (row, col) of the current sheet
-        
+
         """
         return [(0,0)]
 
+
 class StandardSingleCellSheetReference(StandardSheetReference):
     """
     StandardSingleCellSheetReference is a sheet reference that only
     accepts a single cell. This overrides the StandardSheetReference
-    
+
     """
     def isTabValid(self, tabWidget):
         """ isTabValid(tabWidget: QWidget) -> boolean
         Only accepts StandardSingleCellSheetTab
-        
+
         """
         return issubclass(tabWidget.__class__, StandardSingleCellSheetTab)
 
@@ -286,7 +291,7 @@ class StandardSingleCellSheetReference(StandardSheetReference):
                            tabIndex: int,
                            curIndex: int) -> None
         Better candidate is decided merely if it is the current index
-        
+
         """
         if self.isTabValid(tabWidget):
             better = False
@@ -297,11 +302,11 @@ class StandardSingleCellSheetReference(StandardSheetReference):
                 if self.candidate[2]==curIndex or tabIndex!=curIndex:
                     return
             self.candidate = (tabWidget, tabLabel, tabIndex, curIndex)
-                
+
     def setupCandidate(self, tabController):
         """ setupCandidate(tabController: SpreadsheetTabController) -> None
         Set up the sheet to be single-cell sheet
-        
+
         """
         if self.candidate==None:
             candidate = StandardSingleCellSheetTab(tabController)
@@ -311,6 +316,6 @@ class StandardSingleCellSheetReference(StandardSheetReference):
         else:
             return self.candidate[0]
 
+
 spreadsheetRegistry.registerSheet('StandardSingleCellSheetTab',
                                   StandardSingleCellSheetTab)
-
diff --git a/vistrails/packages/spreadsheet/spreadsheet_cell.py b/vistrails/packages/spreadsheet/spreadsheet_cell.py
index a2b8bef..2bfcfe4 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_cell.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_cell.py
@@ -1,67 +1,75 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains classes working with cell helper widgets, i.e. toolbar,
-# resizer, etc.:
-#   QCellWidget
-#   QCellToolBar
-################################################################################
-from PyQt4 import QtCore, QtGui
+
+"""This file contains classes working with cell helper widgets, i.e. toolbar,
+esizer, etc.:
+  QCellWidget
+  QCellToolBar
+"""
+
+from __future__ import division
+
 import datetime
 import os
+from PyQt4 import QtCore, QtGui
 import tempfile
+
 from vistrails.core import debug
+from vistrails.core.modules.output_modules import FileMode
+from vistrails.core.system import strftime
+
+from .analogy_api import SpreadsheetAnalogy
+from .spreadsheet_config import configuration
 import cell_rc
 import celltoolbar_rc
-import spreadsheet_controller
-import analogy_api
-from vistrails.core.configuration import get_vistrails_configuration
 
-################################################################################
 
 class QCellWidget(QtGui.QWidget):
     """
     QCellWidget is the base cell class. All types of spreadsheet cells
     should inherit from this.
-    
+
     """
+    save_formats = ["Images (*.png *.xpm *.jpg)",
+                    "Portable Document Format (*.pdf)"]
 
     def __init__(self, parent=None, flags=QtCore.Qt.WindowFlags()):
         """ QCellWidget(parent: QWidget) -> QCellWidget
         Instantiate the cell and helper properties
-        
+
         """
         QtGui.QWidget.__init__(self, parent, flags)
         self._historyImages = []
@@ -69,46 +77,48 @@ class QCellWidget(QtGui.QWidget):
         self._player.setAutoFillBackground(True)
         self._player.setFocusPolicy(QtCore.Qt.NoFocus)
         self._player.setScaledContents(True)
-        self._playerTimer = QtCore.QTimer()        
+        self._playerTimer = QtCore.QTimer()
         self._playerTimer.setSingleShot(True)
         self._currentFrame = 0
         self._playing = False
         # cell can be captured if it re-implements saveToPNG
         self._capturingEnabled = (not isinstance(self, QCellWidget) and
                                   hasattr(self, 'saveToPNG'))
+        self._output_module = None
+        self._output_configuration = None
         self.connect(self._playerTimer,
                      QtCore.SIGNAL('timeout()'),
                      self.playNextFrame)
-        if getattr(get_vistrails_configuration(),'fixedSpreadsheetCells',False):
+        if configuration.fixedCellSize:
             self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
             self.setFixedSize(200, 180)
 
     def setAnimationEnabled(self, enabled):
         """ setAnimationEnabled(enabled: bool) -> None
-        
+
         """
         self._capturingEnabled = enabled
         if not enabled:
             self.clearHistory()
-        
+
     def saveToPNG(self, filename):
-        """ saveToPNG(filename: str) -> Bool       
+        """ saveToPNG(filename: str) -> Bool
         Abtract function for saving the current widget contents to an
         image file
         Returns True when succesful
-        
+
         """
         debug.critical('saveToPNG() is unimplemented by the inherited cell')
 
     def saveToHistory(self):
         """ saveToHistory() -> None
         Save the current contents to the history
-        
+
         """
         # Generate filename
         current = datetime.datetime.now()
         tmpDir = tempfile.gettempdir()
-        fn = ( "hist_" + current.strftime("%Y_%m_%d__%H_%M_%S") +
+        fn = ( "hist_" + strftime(current, "%Y_%m_%d__%H_%M_%S") +
                "_" + str(current.microsecond)+".png")
         fn = os.path.join(tmpDir, fn)
         if self.saveToPNG(fn):
@@ -117,16 +127,16 @@ class QCellWidget(QtGui.QWidget):
     def clearHistory(self):
         """ clearHistory() -> None
         Clear all history files
-        
+
         """
         for fn in self._historyImages:
             os.remove(fn)
         self._historyImages = []
 
     def deleteLater(self):
-        """ deleteLater() -> None        
+        """ deleteLater() -> None
         Make sure to clear history and delete the widget
-        
+
         """
         self.clearHistory()
         QtGui.QWidget.deleteLater(self)
@@ -134,7 +144,7 @@ class QCellWidget(QtGui.QWidget):
     def updateContents(self, inputPorts):
         """ updateContents(inputPorts: tuple)
         Make sure to capture to history
-        
+
         """
         # Capture window into history for playback
         if self._capturingEnabled:
@@ -143,7 +153,7 @@ class QCellWidget(QtGui.QWidget):
     def resizeEvent(self, e):
         """ resizeEvent(e: QEvent) -> None
         Re-adjust the player widget
-        
+
         """
         QtGui.QWidget.resizeEvent(self, e)
 
@@ -153,7 +163,7 @@ class QCellWidget(QtGui.QWidget):
     def setPlayerFrame(self, frame):
         """ setPlayerFrame(frame: int) -> None
         Set the player to display a particular frame number
-        
+
         """
         if (len(self._historyImages)==0):
             return
@@ -166,7 +176,7 @@ class QCellWidget(QtGui.QWidget):
     def startPlayer(self):
         """ startPlayer() -> None
         Adjust the size of the player to the cell and show it
-        
+
         """
         if not self._capturingEnabled:
             return
@@ -178,11 +188,11 @@ class QCellWidget(QtGui.QWidget):
         self._player.show()
         self.hide()
         self._playing = True
-        
+
     def stopPlayer(self):
         """ startPlayer() -> None
         Adjust the size of the player to the cell and show it
-        
+
         """
         if not self._capturingEnabled:
             return
@@ -194,18 +204,18 @@ class QCellWidget(QtGui.QWidget):
     def showNextFrame(self):
         """ showNextFrame() -> None
         Display the next frame in the history
-        
+
         """
         self._currentFrame += 1
         if self._currentFrame>=len(self._historyImages):
             self._currentFrame = 0
         self.setPlayerFrame(self._currentFrame)
-        
+
     def playNextFrame(self):
-        """ playNextFrame() -> None        
+        """ playNextFrame() -> None
         Display the next frame in the history and start the timer for
         the frame after
-        
+
         """
         self.showNextFrame()
         self._playerTimer.start(100)
@@ -213,7 +223,7 @@ class QCellWidget(QtGui.QWidget):
     def grabWindowPixmap(self):
         """ grabWindowPixmap() -> QPixmap
         Widget special grabbing function
-        
+
         """
         return QtGui.QPixmap.grabWidget(self)
 
@@ -221,8 +231,14 @@ class QCellWidget(QtGui.QWidget):
         """ dumpToFile(filename: str, dump_as_pdf: bool) -> None
         Dumps itself as an image to a file, calling grabWindowPixmap """
         pixmap = self.grabWindowPixmap()
-        pixmap.save(filename,"PNG")
-            
+        ext = os.path.splitext(filename)[1].lower()
+        if not ext:
+            pixmap.save(filename, 'PNG')
+        elif ext == '.pdf':
+            self.saveToPDF(filename)
+        else:
+            pixmap.save(filename)
+
     def saveToPDF(self, filename):
         printer = QtGui.QPrinter()
 
@@ -240,21 +256,54 @@ class QCellWidget(QtGui.QWidget):
         painter.setWindow(pixmap.rect())
         painter.drawPixmap(0, 0, pixmap)
         painter.end()
-        
-        
-################################################################################
+
+    def set_output_module(self, output_module, configuration=None):
+        self._output_module = output_module
+        self._output_configuration = configuration
+
+    def has_file_output_mode(self):
+        # from vistrails.core.modules.output_modules import FileMode
+        if self._output_module is None:
+            return False
+        for mode in self._output_module.get_sorted_mode_list():
+            if issubclass(mode, FileMode):
+                return True
+        return False
+
+    def get_file_output_modes(self):
+        modes = []
+        if self._output_module is not None:
+            for mode_cls in self._output_module.get_sorted_mode_list():
+                if issubclass(mode_cls, FileMode):
+                    modes.append(mode_cls)
+        return modes
+
+    def get_conf_file_format(self):
+        if (self._output_configuration is not None and
+            'format' in self._output_configuration):
+            return self._output_configuration['format']
+        return None
+
+    def save_via_file_output(self, filename, mode_cls, save_format=None):
+        mode = mode_cls()
+        mode_config = self._output_module.get_mode_config(mode)
+        mode_config['file'] = filename
+        if save_format is not None:
+            mode_config['format'] = save_format
+        mode.compute_output(self._output_module, mode_config)
+
 
 class QCellToolBar(QtGui.QToolBar):
     """
     CellToolBar is inherited from QToolBar with some functionalities
     for interacting with CellHelpers
-    
+
     """
     def __init__(self, sheet):
         """ CellToolBar(sheet: SpreadsheetSheet) -> CellToolBar
         Initialize the cell toolbar by calling the user-defined
         toolbar construction function
-        
+
         """
         QtGui.QToolBar.__init__(self,sheet)
         self.setOrientation(QtCore.Qt.Horizontal)
@@ -264,42 +313,122 @@ class QCellToolBar(QtGui.QToolBar):
         self.layout().setMargin(0)
         self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
         pixmap = self.style().standardPixmap(QtGui.QStyle.SP_DialogCloseButton)
+        self.addSaveCellAction()
+        self.addExecuteCellAction()
         self.appendAction(QCellToolBarRemoveCell(QtGui.QIcon(pixmap), self))
         self.appendAction(QCellToolBarMergeCells(QtGui.QIcon(':celltoolbar/mergecells.png'), self))
         self.createToolBar()
 
     def addAnimationButtons(self):
         """ addAnimationButtons() -> None
-        
+
         """
         self.appendAction(QCellToolBarCaptureToHistory(self))
         self.appendAction(QCellToolBarPlayHistory(self))
         self.appendAction(QCellToolBarClearHistory(self))
 
+    def addSaveCellAction(self):
+        if not hasattr(self, 'saveActionVar'):
+            self.saveActionVar = QCellToolBarSelectedCell(
+                    QtGui.QIcon(":/images/camera.png"),
+                    "Save cell",
+                    self)
+            self.saveActionVar.setStatusTip("Export this cell only")
+
+            self.connect(self.saveActionVar, QtCore.SIGNAL('triggered(bool)'),
+                         self.exportCell)
+        self.appendAction(self.saveActionVar)
+
+    def exportCell(self, checked=False):
+        cell = self.sheet.getCell(self.row, self.col)
+        if cell.has_file_output_mode():
+            modes = cell.get_file_output_modes()
+            formats = []
+            format_map = {}
+            for mode in modes:
+                for m_format in mode.get_formats():
+                    if m_format not in format_map:
+                        formats.append(m_format)
+                        format_map[m_format] = mode
+            selected_filter = None
+            if cell.get_conf_file_format() is not None:
+                selected_filter = '(*.%s)' % cell.get_conf_file_format()
+            (filename, save_format) = \
+                    QtGui.QFileDialog.getSaveFileNameAndFilter(
+                        self, "Select a File to Export the Cell",
+                        ".", ';;'.join(['(*.%s)' % f for f in formats]),
+                        selected_filter)
+            if filename:
+                save_mode = format_map[save_format[3:-1]]
+                cell.save_via_file_output(filename, save_mode)
+        else:
+            if not cell.save_formats:
+                QtGui.QMessageBox.information(
+                        self, "Export cell",
+                        "This cell type doesn't provide any export option")
+                return
+            filename = QtGui.QFileDialog.getSaveFileName(
+                self, "Select a File to Export the Cell",
+                ".", ';;'.join(cell.save_formats))
+            if filename:
+                cell.dumpToFile(filename)
+
+    def addExecuteCellAction(self):
+        if not hasattr(self, 'executeActionVar'):
+            self.executeActionVar = QCellToolBarSelectedCell(
+                    QtGui.QIcon(":/images/view-refresh.png"),
+                    "Re-execute cell",
+                    self)
+            self.executeActionVar.setStatusTip("Re-execute this cell")
+
+            self.connect(self.executeActionVar, QtCore.SIGNAL('triggered(bool)'),
+                         self.executeCell)
+        self.appendAction(self.executeActionVar)
+
+    def executeCell(self, checked=False):
+        from spreadsheet_execute import executePipelineWithProgress
+        #cell = self.sheet.getCell(self.row, self.col)
+        info = self.sheet.getCellPipelineInfo(self.row, self.col)
+        if info:
+            info = info[0]
+            mId = info['moduleId']
+            pipeline = self.sheet.setPipelineToLocateAt(self.row, self.col,
+                                                        info['pipeline'],
+                                                        [mId])
+            executePipelineWithProgress(pipeline, 'Re-execute Cell',
+                                        current_version=info['version'],
+                                        actions=info['actions'],
+                                        reason=info['reason'],
+                                        locator=info['locator'],
+                                        controller=info['controller'],
+                                        sinks=[mId])
+
+
+
     def createToolBar(self):
-        """ createToolBar() -> None        
+        """ createToolBar() -> None
         A user-defined method for customizing the toolbar. This is
         going to be an empty method here for inherited classes to
         override.
-        
+
         """
         self.addAnimationButtons()
 
     def snapTo(self, row, col):
         """ snapTo(row, col) -> None
         Assign which row and column the toolbar should be snapped to
-        
+
         """
         self.row = row
         self.col = col
         self.updateToolBar()
 
     def updateToolBar(self):
-        """ updateToolBar() -> None        
+        """ updateToolBar() -> None
         This will get called when the toolbar widgets need to have
         their status updated. It sends out needUpdateStatus signal
         to let the widget have a change to update their own status
-        
+
         """
         cellWidget = self.sheet.getCell(self.row, self.col)
         for action in self.actions():
@@ -309,7 +438,7 @@ class QCellToolBar(QtGui.QToolBar):
     def connectAction(self, action, widget):
         """ connectAction(action: QAction, widget: QWidget) -> None
         Connect actions to special slots of a widget
-        
+
         """
         if hasattr(widget, 'updateStatus'):
             self.connect(action, QtCore.SIGNAL('needUpdateStatus'),
@@ -324,7 +453,7 @@ class QCellToolBar(QtGui.QToolBar):
     def appendAction(self, action):
         """ appendAction(action: QAction) -> QAction
         Setup and add action to the tool bar
-        
+
         """
         action.toolBar = self
         self.addAction(action)
@@ -345,14 +474,28 @@ class QCellToolBar(QtGui.QToolBar):
     def getSnappedWidget(self):
         """ getSnappedWidget() -> QWidget
         Return the widget being snapped by the toolbar
-        
+
         """
         if self.row>=0 and self.col>=0:
             return self.sheet.getCell(self.row, self.col)
         else:
             return None
 
-class QCellToolBarRemoveCell(QtGui.QAction):
+
+class QCellToolBarSelectedCell(QtGui.QAction):
+    """
+    QCellToolBarSelectedCell is an action only visible if the cell isn't empty.
+    """
+    def updateStatus(self, info):
+        """ updateStatus(info: tuple) -> None
+        Updates the status of the button based on the input info
+
+        """
+        (sheet, row, col, cellWidget) = info
+        self.setVisible(cellWidget is not None)
+
+
+class QCellToolBarRemoveCell(QCellToolBarSelectedCell):
     """
     QCellToolBarRemoveCell is the action to clear the current cell
 
@@ -361,18 +504,18 @@ class QCellToolBarRemoveCell(QtGui.QAction):
         """ QCellToolBarRemoveCell(icon: QIcon, parent: QWidget)
                                    -> QCellToolBarRemoveCell
         Setup the image, status tip, etc. of the action
-        
+
         """
-        QtGui.QAction.__init__(self,
-                               icon,
-                               "&Clear the current cell",
-                               parent)
+        QCellToolBarSelectedCell.__init__(self,
+                                          icon,
+                                          "&Clear the current cell",
+                                          parent)
         self.setStatusTip("Clear the current cell")
 
     def triggeredSlot(self, checked=False):
         """ toggledSlot(checked: boolean) -> None
         Execute the action when the button is clicked
-        
+
         """
         cellWidget = self.toolBar.getSnappedWidget()
         r = QtGui.QMessageBox.question(cellWidget, 'Clear cell',
@@ -383,14 +526,7 @@ class QCellToolBarRemoveCell(QtGui.QAction):
         if (r==QtGui.QMessageBox.Yes):
             self.toolBar.sheet.deleteCell(self.toolBar.row, self.toolBar.col)
 
-    def updateStatus(self, info):
-        """ updateStatus(info: tuple) -> None
-        Updates the status of the button based on the input info
-        
-        """
-        (sheet, row, col, cellWidget) = info
-        self.setVisible(cellWidget!=None)
-        
+
 class QCellToolBarMergeCells(QtGui.QAction):
     """
     QCellToolBarMergeCells is the action to merge selected cells to a
@@ -401,7 +537,7 @@ class QCellToolBarMergeCells(QtGui.QAction):
         """ QCellToolBarMergeCells(icon: QIcon, parent: QWidget)
                                    -> QCellToolBarMergeCells
         Setup the image, status tip, etc. of the action
-        
+
         """
         QtGui.QAction.__init__(self,
                                icon,
@@ -414,7 +550,7 @@ class QCellToolBarMergeCells(QtGui.QAction):
     def triggeredSlot(self):
         """ toggledSlot() -> None
         Execute the action when the button is clicked
-        
+
         """
         # Merge
         if self.isChecked():
@@ -436,15 +572,15 @@ class QCellToolBarMergeCells(QtGui.QAction):
     def updateStatus(self, info):
         """ updateStatus(info: tuple) -> None
         Updates the status of the button based on the input info
-        
+
         """
         (sheet, row, col, cellWidget) = info
         selectedCells = sorted(sheet.getSelectedLocations())
 
         # Will not show up if there is no cell selected
-        if len(selectedCells)==0:            
+        if len(selectedCells)==0:
             self.setVisible(False)
-            
+
         # If there is a single cell selected, only show up if it has
         # been merged before so that user can un-merge cells
         elif len(selectedCells)==1:
@@ -458,7 +594,7 @@ class QCellToolBarMergeCells(QtGui.QAction):
                 self.setVisible(True)
             else:
                 self.setVisible(False)
-                
+
         # If there are multiple cells selected, only show up if they
         # can be merged, i.e. cells are in consecutive position and
         # none of them is already merged
@@ -481,19 +617,20 @@ class QCellToolBarMergeCells(QtGui.QAction):
                 self.setVisible(True)
             else:
                 self.setVisible(False)
-            
+
+
 class QCellToolBarCaptureToHistory(QtGui.QAction):
     """
     QCellToolBarCaptureToHistory is the action to capture the
     underlying widget to history for play back. The cell type must
     support function saveToPNG(filename)
-    
+
     """
     def __init__(self, parent=None):
         """ QCellToolBarCaptureToHistory(parent: QWidget)
                                          -> QCellToolBarCaptureToHistory
         Setup the image, status tip, etc. of the action
-        
+
         """
         QtGui.QAction.__init__(self,
                                QtGui.QIcon(":/images/camera_mount.png"),
@@ -505,18 +642,18 @@ class QCellToolBarCaptureToHistory(QtGui.QAction):
     def triggeredSlot(self, checked=False):
         """ toggledSlot(checked: boolean) -> None
         Execute the action when the button is clicked
-        
+
         """
         cellWidget = self.toolBar.getSnappedWidget()
         self.toolBar.hide()
         cellWidget.saveToHistory()
         self.toolBar.updateToolBar()
         self.toolBar.show()
-        
+
     def updateStatus(self, info):
         """ updateStatus(info: tuple) -> None
         Updates the status of the button based on the input info
-        
+
         """
         (sheet, row, col, cellWidget) = info
         if cellWidget:
@@ -524,19 +661,18 @@ class QCellToolBarCaptureToHistory(QtGui.QAction):
         else:
             self.setVisible(False)
 
-################################################################################
-        
+
 class QCellToolBarPlayHistory(QtGui.QAction):
     """
     QCellToolBarPlayHistory is the action to play the history as an
     animation
-    
+
     """
     def __init__(self, parent=None):
         """ QCellToolBarPlayHistory(parent: QWidget)
                                     -> QCellToolBarPlayHistory
         Setup the image, status tip, etc. of the action
-        
+
         """
         self.icons = [QtGui.QIcon(":/images/player_play.png"),
                       QtGui.QIcon(":/images/player_pause.png")]
@@ -551,7 +687,7 @@ class QCellToolBarPlayHistory(QtGui.QAction):
     def triggeredSlot(self, checked=False):
         """ toggledSlot(checked: boolean) -> None
         Execute the action when the button is clicked
-        
+
         """
         cellWidget = self.toolBar.getSnappedWidget()
         if self.status==0:
@@ -563,7 +699,7 @@ class QCellToolBarPlayHistory(QtGui.QAction):
     def updateStatus(self, info):
         """ updateStatus(info: tuple) -> None
         Updates the status of the button based on the input info
-        
+
         """
         (sheet, row, col, cellWidget) = info
         if cellWidget:
@@ -578,39 +714,38 @@ class QCellToolBarPlayHistory(QtGui.QAction):
         else:
             self.setVisible(False)
 
-################################################################################
-            
+
 class QCellToolBarClearHistory(QtGui.QAction):
     """
     QCellToolBarClearHistory is the action to reset cell history
-    
+
     """
     def __init__(self, parent=None):
         """ QCellToolBarClearHistory(parent: QWidget)
                                      -> QCellToolBarClearHistory
         Setup the image, status tip, etc. of the action
-        
+
         """
         QtGui.QAction.__init__(self,
                                QtGui.QIcon(":/images/noatunloopsong.png"),
                                "&Clear this cell history",
                                parent)
         self.setStatusTip("Clear the cell history and its temporary "
-                          "image files on disk")        
-        
+                          "image files on disk")
+
     def triggeredSlot(self, checked=False):
         """ toggledSlot(checked: boolean) -> None
         Execute the action when the button is clicked
-        
+
         """
         cellWidget = self.toolBar.getSnappedWidget()
         cellWidget.clearHistory()
         self.toolBar.updateToolBar()
-        
+
     def updateStatus(self, info):
         """ updateStatus(info: tuple) -> None
         Updates the status of the button based on the input info
-        
+
         """
         (sheet, row, col, cellWidget) = info
         if cellWidget:
@@ -620,19 +755,18 @@ class QCellToolBarClearHistory(QtGui.QAction):
         else:
             self.setVisible(False)
 
-################################################################################
 
 class QCellContainer(QtGui.QWidget):
     """ QCellContainer is a simple QWidget containing the actual cell
     widget as a child. This also acts as a sentinel protecting the
     actual cell widget from being destroyed by sheet widgets
     (e.g. QTableWidget) where they take control of the cell widget.
-    
+
     """
     def __init__(self, widget=None, parent=None):
         """ QCellContainer(parent: QWidget) -> QCellContainer
         Create an empty container
-        
+
         """
         QtGui.QWidget.__init__(self, parent)
         layout = QtGui.QVBoxLayout()
@@ -646,7 +780,7 @@ class QCellContainer(QtGui.QWidget):
     def setWidget(self, widget):
         """ setWidget(widget: QWidget) -> None
         Set the contained widget of this container
-        
+
         """
         if widget!=self.containedWidget:
             if self.containedWidget:
@@ -662,14 +796,14 @@ class QCellContainer(QtGui.QWidget):
     def widget(self):
         """ widget() -> QWidget
         Return the contained widget
-        
+
         """
         return self.containedWidget
 
     def takeWidget(self):
         """ widget() -> QWidget
         Take the contained widget out without deleting
-        
+
         """
         widget = self.containedWidget
         if self.containedWidget:
@@ -679,20 +813,19 @@ class QCellContainer(QtGui.QWidget):
         self.toolBar = None
         return widget
 
-################################################################################
 
 class QCellPresenter(QtGui.QLabel):
     """
     QCellPresenter represents a cell in the Editing Mode. It has an
     info bar on top and control dragable icons on the bottom
-    
+
     """
     def __init__(self, parent=None):
         """ QCellPresenter(parent: QWidget) -> QCellPresenter
         Create the layout of the widget
-        
-        """        
-        QtGui.QLabel.__init__(self, parent)        
+
+        """
+        QtGui.QLabel.__init__(self, parent)
         self.setAutoFillBackground(True)
         self.setScaledContents(True)
         self.setMargin(0)
@@ -704,9 +837,9 @@ class QCellPresenter(QtGui.QLabel):
         layout.setMargin(self.margin())
         layout.setRowStretch(1, 1)
         self.setLayout(layout)
-        
+
         self.info = QPipelineInfo()
-        layout.addWidget(self.info, 0, 0, 1, 2)        
+        layout.addWidget(self.info, 0, 0, 1, 2)
 
         self.manipulator = QCellManipulator()
         layout.addWidget(self.manipulator, 1, 0, 1, 2)
@@ -714,7 +847,7 @@ class QCellPresenter(QtGui.QLabel):
     def assignCellWidget(self, cellWidget):
         """ updateFromCellWidget(cellWidget: QWidget) -> None
         Assign a cell widget to this presenter
-        
+
         """
         self.cellWidget = cellWidget
         if cellWidget:
@@ -736,17 +869,17 @@ class QCellPresenter(QtGui.QLabel):
     def assignCell(self, sheet, row, col):
         """ assignCell(sheet: Sheet, row: int, col: int) -> None
         Assign a sheet cell to the presenter
-        
+
         """
         self.manipulator.assignCell(sheet, row, col)
         self.assignCellWidget(sheet.getCell(row, col))
         info = sheet.getCellPipelineInfo(row, col)
         self.info.updateInfo(info)
-        
+
     def releaseCellWidget(self):
         """ releaseCellWidget() -> QWidget
         Return the ownership of self.cellWidget to the caller
-        
+
         """
         cellWidget = self.cellWidget
         self.assignCellWidget(None)
@@ -756,26 +889,25 @@ class QCellPresenter(QtGui.QLabel):
         return cellWidget
 
     def deleteLater(self):
-        """ deleteLater() -> None        
+        """ deleteLater() -> None
         Make sure to delete the cell widget if it exists
-        
+
         """
         if (self.cellWidget):
             self.cellWidget.deleteLater()
         QtGui.QLabel.deleteLater(self)
 
-################################################################################
 
 class QInfoLineEdit(QtGui.QLineEdit):
     """
     QInfoLineEdit is wrapper for a transparent, un-frame, read-only
     line edit
-    
+
     """
     def __init__(self, parent=None):
         """ QInfoLineEdit(parent: QWidget) -> QInfoLineEdit
         Initialize the line edit
-        
+
         """
         QtGui.QLineEdit.__init__(self, parent)
         self.setReadOnly(True)
@@ -789,31 +921,30 @@ class QInfoLineEdit(QtGui.QLineEdit):
 class QInfoLabel(QtGui.QLabel):
     """
     QInfoLabel is wrapper for a transparent, bolded label
-    
+
     """
     def __init__(self, text='', parent=None):
         """ QInfoLabel(text: str, parent: QWidget) -> QInfoLabel
         Initialize the line edit
-        
+
         """
         QtGui.QLabel.__init__(self, text, parent)
         font = QtGui.QFont(self.font())
         font.setBold(True)
         self.setFont(font)
 
-################################################################################
-    
+
 class QPipelineInfo(QtGui.QFrame):
     """
     QPipelineInfo displays information about the executed pipeline of
     a cell. It has 3 static lines: Vistrail name, (pipeline name,
     pipeline id) and the cell type
-    
+
     """
     def __init__(self, parent=None):
         """ QPipelineInfo(parent: QWidget) -> None
         Create the 3 information lines
-        
+
         """
         QtGui.QFrame.__init__(self, parent)
         self.setAutoFillBackground(True)
@@ -825,7 +956,7 @@ class QPipelineInfo(QtGui.QFrame):
         color.setAlpha(196)
         pal.setBrush(QtGui.QPalette.Base, QtGui.QBrush(color))
         self.setPalette(pal)
-        
+
         topLayout = QtGui.QVBoxLayout(self)
         topLayout.setSpacing(0)
         topLayout.setMargin(0)
@@ -859,7 +990,7 @@ class QPipelineInfo(QtGui.QFrame):
     def updateInfo(self, info):
         """ updateInfo(info: (dict, pid)) -> None
         Update the information of a pipeline info
-        
+
         """
         if info!=None and info[0]['locator']!=None:
             self.edits[0].setText(str(info[0]['locator'].name))
@@ -870,7 +1001,6 @@ class QPipelineInfo(QtGui.QFrame):
             for edit in self.edits:
                 edit.setText('N/A')
 
-################################################################################
 
 class QCellManipulator(QtGui.QFrame):
     """
@@ -879,18 +1009,18 @@ class QCellManipulator(QtGui.QFrame):
     another. It also inclues a button for update the pipeline under
     the cell to be a new version on the pipeline. It is useful for the
     parameter exploration talks back to the builder
-    
+
     """
     def __init__(self, parent=None):
         """ QPipelineInfo(parent: QWidget) -> None
         Create the 3 information lines
-        
+
         """
         QtGui.QFrame.__init__(self, parent)
         self.setAcceptDrops(True)
         self.setFrameStyle(QtGui.QFrame.NoFrame)
         self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
-        
+
         layout = QtGui.QVBoxLayout(self)
         layout.setSpacing(0)
         layout.setMargin(0)
@@ -899,7 +1029,7 @@ class QCellManipulator(QtGui.QFrame):
         layout.addStretch()
 
         bLayout = QtGui.QHBoxLayout()
-        layout.addLayout(bLayout)                
+        layout.addLayout(bLayout)
 
         bInfo = [(':/images/copy_cell.png',
                   'Drag to copy this cell to another place',
@@ -913,9 +1043,9 @@ class QCellManipulator(QtGui.QFrame):
                  (':/images/apply_analogy.png',
                   'Drag to apply the current analogy to this cell and put it '
                   'at another place', 'apply_analogy', 'Apply\nAnalogy')]
-        
+
         self.buttons = []
-        
+
         bLayout.addStretch()
         for b in bInfo:
             button = QCellDragLabel(QtGui.QPixmap(b[0]))
@@ -933,7 +1063,7 @@ class QCellManipulator(QtGui.QFrame):
 
         self.updateButton = QtGui.QToolButton()
         self.updateButton.setIconSize(QtCore.QSize(64, 64))
-        self.updateButton.setIcon(QtGui.QIcon(QtGui.QPixmap(            
+        self.updateButton.setIcon(QtGui.QIcon(QtGui.QPixmap(
             ':/images/update.png')))
         self.updateButton.setAutoRaise(True)
         self.updateButton.setToolTip('Add this cell as a new version')
@@ -946,7 +1076,7 @@ class QCellManipulator(QtGui.QFrame):
 
         self.locateButton = QtGui.QToolButton()
         self.locateButton.setIconSize(QtCore.QSize(64, 64))
-        self.locateButton.setIcon(QtGui.QIcon(QtGui.QPixmap(            
+        self.locateButton.setIcon(QtGui.QIcon(QtGui.QPixmap(
             ':/images/locate.png')))
         self.locateButton.setAutoRaise(True)
         self.locateButton.setToolTip('Select this pipeline in the version tree ')
@@ -957,26 +1087,26 @@ class QCellManipulator(QtGui.QFrame):
                      self.locateVersion)
         self.buttons.append(self.locateButton)
 
-        
+
         uLayout = QtGui.QHBoxLayout()
         uLayout.addStretch()
         uLayout.addWidget(self.locateButton)
         uLayout.addWidget(self.updateButton)
         uLayout.addStretch()
         layout.addLayout(uLayout)
-            
+
         bLayout.addStretch()
 
         layout.addStretch()
 
         self.innerRubberBand = QtGui.QRubberBand(QtGui.QRubberBand.Rectangle,
                                                  self)
-        
+
     def assignCell(self, sheet, row, col):
         """ assignCell(sheet: Sheet, row: int, col: int) -> None
         Assign a cell to the manipulator, so it knows where to drag
         and drop
-        
+
         """
         self.cellInfo = (sheet, row, col)
         for b in self.buttons:
@@ -997,7 +1127,7 @@ class QCellManipulator(QtGui.QFrame):
     def dragEnterEvent(self, event):
         """ dragEnterEvent(event: QDragEnterEvent) -> None
         Set to accept drops from the other cell info
-        
+
         """
         mimeData = event.mimeData()
         if hasattr(mimeData, 'cellInfo'):
@@ -1011,18 +1141,18 @@ class QCellManipulator(QtGui.QFrame):
                 self.highlight()
         else:
             event.ignore()
-            
+
     def dragLeaveEvent(self, event):
         """ dragLeaveEvent(event: QDragLeaveEvent) -> None
         Unhighlight when the cursor leaves
-        
+
         """
         self.highlight(False)
-        
+
     def dropEvent(self, event):
         """ dragLeaveEvent(event: QDragLeaveEvent) -> None
         Unhighlight when the cursor leaves
-        
+
         """
         self.highlight(False)
         mimeData = event.mimeData()
@@ -1032,29 +1162,29 @@ class QCellManipulator(QtGui.QFrame):
         if action in ['move', 'copy', 'create_analogy', 'apply_analogy']:
             event.setDropAction(QtCore.Qt.MoveAction)
             event.accept()
-            
+
             if action=='move':
                 self.cellInfo[0].swapCell(self.cellInfo[1], self.cellInfo[2],
                                           cellInfo[0], cellInfo[1], cellInfo[2])
                 manipulator.assignCell(*self.cellInfo)
                 self.assignCell(*cellInfo)
-                
+
             if action=='copy':
                 cellInfo[0].copyCell(cellInfo[1], cellInfo[2],
                                      self.cellInfo[0], self.cellInfo[1],
                                      self.cellInfo[2])
-                
+
             if action=='create_analogy':
                 p1Info = cellInfo[0].getPipelineInfo(cellInfo[1], cellInfo[2])
                 p2Info = self.cellInfo[0].getPipelineInfo(self.cellInfo[1],
                                                           self.cellInfo[2])
                 if p1Info!=None and p2Info!=None:
-                    analogy = analogy_api.SpreadsheetAnalogy()
+                    analogy = SpreadsheetAnalogy()
                     analogy.createAnalogy(p1Info, p2Info)
 
             if action=='apply_analogy':
                 p1Info = cellInfo[0].getPipelineInfo(cellInfo[1], cellInfo[2])
-                analogy = analogy_api.SpreadsheetAnalogy()
+                analogy = SpreadsheetAnalogy()
                 newPipeline = analogy.applyAnalogy(p1Info)
                 if newPipeline:
                     self.cellInfo[0].executePipelineToCell(newPipeline,
@@ -1064,12 +1194,12 @@ class QCellManipulator(QtGui.QFrame):
 
         else:
             event.ignore()
-                    
-        
+
+
     def highlight(self, on=True):
         """ highlight(on: bool) -> None
         Highlight the cell as if being selected
-        
+
         """
         if on:
             self.innerRubberBand.setGeometry(self.rect())
@@ -1078,12 +1208,12 @@ class QCellManipulator(QtGui.QFrame):
             self.innerRubberBand.hide()
 
     def updateVersion(self):
-        """ updateVersion() -> None        
+        """ updateVersion() -> None
         Use the performed action of this cell to add back a new
         version to the version tree
-        
+
         """
-        spreadsheetController = spreadsheet_controller.spreadsheetController
+        from .spreadsheet_controller import spreadsheetController
         builderWindow = spreadsheetController.getBuilderWindow()
         if builderWindow:
             info = self.cellInfo[0].getCellPipelineInfo(self.cellInfo[1],
@@ -1098,11 +1228,11 @@ class QCellManipulator(QtGui.QFrame):
                     # controller.performBulkActions(info['actions'])
 
     def locateVersion(self):
-        """ locateVersion() -> None        
+        """ locateVersion() -> None
         Select the version node on the version that has generated this cell
-        
+
         """
-        spreadsheetController = spreadsheet_controller.spreadsheetController
+        from .spreadsheet_controller import spreadsheetController
         builderWindow = spreadsheetController.getBuilderWindow()
         if builderWindow:
             info = self.cellInfo[0].getCellPipelineInfo(self.cellInfo[1],
@@ -1121,18 +1251,17 @@ class QCellManipulator(QtGui.QFrame):
                     view.history_selected()
                     view.activateWindow()
 
-################################################################################
 
 class QCellDragLabel(QtGui.QLabel):
     """
     QCellDragLabel is a pixmap label allowing users to drag it to
     another cell manipulator
-    
+
     """
     def __init__(self, pixmap, parent=None):
         """ QCellDragLabel(pixmap: QPixmap, parent: QWidget) -> QCellDragLabel
         Construct the pixmap label
-        
+
         """
         QtGui.QLabel.__init__(self, parent)
         self.setMargin(0)
@@ -1145,18 +1274,18 @@ class QCellDragLabel(QtGui.QLabel):
         self.startPos = None
         self.cellInfo = (None, -1, -1)
         self.action = None
-        
+
     def updateCellInfo(self, cellInfo):
         """ updateCellInfo(cellInfo: tuple) -> None
         Update cellInfo for mime data while dragging
-        
+
         """
         self.cellInfo = cellInfo
 
     def mousePressEvent(self, event):
         """ mousePressEvent(event: QMouseEvent) -> None
         Store the start position for drag event
-        
+
         """
         self.startPos = QtCore.QPoint(event.pos())
         QtGui.QLabel.mousePressEvent(self, event)
@@ -1164,7 +1293,7 @@ class QCellDragLabel(QtGui.QLabel):
     def mouseMoveEvent(self, event):
         """ mouseMoveEvent(event: QMouseEvent) -> None
         Prepare to drag
-        
+
         """
         p = event.pos() - self.startPos
         if p.manhattanLength()>=QtGui.QApplication.startDragDistance():
@@ -1175,5 +1304,5 @@ class QCellDragLabel(QtGui.QLabel):
             data.manipulator = self.parent()
             drag.setMimeData(data)
             drag.setHotSpot(self.cursorPixmap.rect().center())
-            drag.setPixmap(self.cursorPixmap)            
+            drag.setPixmap(self.cursorPixmap)
             drag.start(QtCore.Qt.MoveAction)
diff --git a/vistrails/packages/spreadsheet/spreadsheet_config.py b/vistrails/packages/spreadsheet/spreadsheet_config.py
index c75ccb2..183d9ab 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_config.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_config.py
@@ -1,39 +1,46 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
+from __future__ import division
+
 from vistrails.core.configuration import ConfigurationObject
+
+
 configuration = ConfigurationObject(rowCount=2,
                                     columnCount=3,
-                                    dumpfileType='PNG')
+                                    dumpfileType='PNG',
+                                    fixedCellSize=False)
 # other possible value for dumpfileType is PDF
diff --git a/vistrails/packages/spreadsheet/spreadsheet_controller.py b/vistrails/packages/spreadsheet/spreadsheet_controller.py
index 0d16f73..b4fc4d5 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_controller.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_controller.py
@@ -1,46 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains the spreadsheet controller to take care of
-# interactions to the spreadsheet:
-#   SpreadsheetController
-################################################################################
+
+"""This file contains the spreadsheet controller to take care of interactions
+to the spreadsheet:
+  SpreadsheetController
+"""
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
-from spreadsheet_window import SpreadsheetWindow
 
-################################################################################
+from .spreadsheet_window import SpreadsheetWindow
+
 
 class SpreadsheetController(object):
     """
@@ -52,14 +56,14 @@ class SpreadsheetController(object):
     def __init__(self):
         """ SpreadsheetController() -> SpreadsheetController
         This class is more like an interface where there is no data inside
-        
+
         """
         pass
 
     def findSpreadsheetWindow(self, show=True):
         """ findSpreadsheetWindow() -> QWidget
         Looking for the spreadsheet window
-        
+
         """
         wList = QtGui.QApplication.topLevelWidgets()
         for w in wList:
@@ -70,7 +74,7 @@ class SpreadsheetController(object):
         if show:
             spreadsheetWindow.configShow()
         return spreadsheetWindow
-        
+
     def postEventToSpreadsheet(self, event):
         """ postEventToSpreadsheet(event: QEvent) -> None
         Post an event to the spreadsheet to make thread-safe connection
@@ -81,10 +85,10 @@ class SpreadsheetController(object):
             QtCore.QCoreApplication.postEvent(spreadsheetWindow, event)
 
     def getBuilderWindow(self):
-        """ getBuilderWindow() -> QWidget        
+        """ getBuilderWindow() -> QWidget
         Return the builder window of the application, or None if
         couldn't fine one
-        
+
         """
         spreadsheetWindow = self.findSpreadsheetWindow()
         if hasattr(spreadsheetWindow.visApp, 'builderWindow'):
@@ -116,7 +120,7 @@ class SpreadsheetController(object):
         """ getEchoCellEvents() -> [DisplayCellEvent]
         Echo back the list of all cell events that have been captured
         earlier
-        
+
         """
         spreadsheetWindow = self.findSpreadsheetWindow(show=False)
         if spreadsheetWindow:
@@ -125,5 +129,6 @@ class SpreadsheetController(object):
             return events
         return None
 
+
 spreadsheetController = SpreadsheetController()
 registeredWidgets = {}
diff --git a/vistrails/packages/spreadsheet/spreadsheet_event.py b/vistrails/packages/spreadsheet/spreadsheet_event.py
index a86f697..7d1627c 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_event.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_event.py
@@ -1,61 +1,65 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains all Spreadsheet special Qt event classes
-################################################################################
-from PyQt4 import QtCore, QtGui
 
-################################################################################
+"""This file contains all Spreadsheet special Qt event classes
+"""
+
+from __future__ import division
+
+from PyQt4 import QtCore
+
 
 # A list of newly added events starting from QtCore.QEvent.User
 DisplayCellEventType = QtCore.QEvent.Type(QtCore.QEvent.User)
 BatchDisplayCellEventType = QtCore.QEvent.Type(QtCore.QEvent.User+1)
 RepaintCurrentSheetEventType = QtCore.QEvent.Type(QtCore.QEvent.User+2)
 
+
 class DisplayCellEvent(QtCore.QEvent):
     """
     DisplayCellEvent is an event to notify the spreadsheet that we want to
     display input data on a specific type of widget. This is more of a data
     container class
-    
+
     """
     def __init__(self):
         """ DisplayCellEvent() -> DisplayCellEvent
         Instantiate a display event with no location, cell type, input data nor
         an associated vistrail
-        
+
         """
         QtCore.QEvent.__init__(self, DisplayCellEventType)
         self.sheetReference = None
@@ -67,14 +71,15 @@ class DisplayCellEvent(QtCore.QEvent):
         self.inputPorts = None
         self.vistrail = None
 
+
 class BatchDisplayCellEvent(QtCore.QEvent):
     """
     BatchDisplayCellEvent is similar to DisplayCellEvent but it is holding a
     serie of DisplayCellEvent. This is very helpful since DisplayCellEvent
     requires a thread-safe procedure, thus, very slow/un-safe when displaying
     more than one cell with multiple events.
-    
-    """    
+
+    """
     def __init__(self):
         """ BatchDisplayCellEvent()
         Instantiate an empty BatchDisplayCellEvent
@@ -83,15 +88,16 @@ class BatchDisplayCellEvent(QtCore.QEvent):
         self.displayEvents = []
         self.vistrail = None
 
+
 class RepaintCurrentSheetEvent(QtCore.QEvent):
     """
     RepaintCurrentSheetEvent signal the spreadsheet to call repaint
     for all cells in the current sheet
-    
-    """    
+
+    """
     def __init__(self):
         """ RepaintCurrentSheetEvent() -> RepaintCurrentSheetEvent
         Initialize the event type
-        
+
         """
         QtCore.QEvent.__init__(self, RepaintCurrentSheetEventType)
diff --git a/vistrails/packages/spreadsheet/spreadsheet_execute.py b/vistrails/packages/spreadsheet/spreadsheet_execute.py
index 89b566e..7c7b766 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_execute.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_execute.py
@@ -1,67 +1,60 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains useful functions for executing pipelines on the spreadsheet
-# assignPipelineCellLocations
-# executePipelineWithProgress
-################################################################################
+
+"""This file contains useful functions for executing pipelines on the
+spreadsheet:
+  assignPipelineCellLocations
+  executePipelineWithProgress
+"""
+
+from __future__ import division
+
+import copy
 from PyQt4 import QtCore, QtGui
-from vistrails.core.vistrail.controller import VistrailController
-from vistrails.core.modules.module_registry import get_module_registry
+
 from vistrails.core.inspector import PipelineInspector
 from vistrails.core.interpreter.default import get_default_interpreter
+from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.vistrail.controller import VistrailController
 from vistrails.core.utils import DummyView
-from vistrails.core.vistrail.action import Action
-from vistrails.core.vistrail.module_function import ModuleFunction
-from vistrails.core.vistrail.module_param import ModuleParam
-from vistrails.core.vistrail.port import Port
-from vistrails.core.vistrail import module
-from vistrails.core.vistrail import connection
-import vistrails.db.services.action
-import copy
 
-from identifiers import identifier as spreadsheet_pkg
+from .identifiers import identifier as spreadsheet_pkg
 
-# FIXME broke this as Actions have been changed around
-#
-# from core.vistrail.action import AddModuleAction, AddConnectionAction, \
-#      DeleteConnectionAction, ChangeParameterAction
 
-################################################################################
-
-def assignPipelineCellLocations(pipeline, sheetName, 
+def assignPipelineCellLocations(pipeline, sheetName,
                                 row, col, cellIds=None,
                                 minRowCount=None, minColCount=None):
 
@@ -83,7 +76,7 @@ def assignPipelineCellLocations(pipeline, sheetName,
 
     for id_list in cellIds:
         # find at which depth we need to be working
-        try:                
+        try:
             id_iter = iter(id_list)
             m = pipeline.modules[id_iter.next()]
             for mId in id_iter:
@@ -93,7 +86,7 @@ def assignPipelineCellLocations(pipeline, sheetName,
             mId = id_list
 
         m = pipeline.modules[mId]
-        if not reg.is_descriptor_subclass(m.module_descriptor, 
+        if not reg.is_descriptor_subclass(m.module_descriptor,
                                           spreadsheet_cell_desc):
             continue
 
@@ -101,7 +94,7 @@ def assignPipelineCellLocations(pipeline, sheetName,
         # modules connected to this spreadsheet cell
         conns_to_delete = []
         for (cId,c) in pipeline.connections.iteritems():
-            if (c.destinationId==mId and 
+            if (c.destinationId==mId and
                 pipeline.modules[c.sourceId].name=="CellLocation"):
                 conns_to_delete.append(c.id)
         for c_id in conns_to_delete:
@@ -119,20 +112,20 @@ def assignPipelineCellLocations(pipeline, sheetName,
         # Add a sheet reference with a specific name
         sheetReference = create_module(id_scope, spreadsheet_pkg,
                                        "SheetReference")
-        sheetNameFunction = create_function(id_scope, sheetReference, 
+        sheetNameFunction = create_function(id_scope, sheetReference,
                                             "SheetName", [str(sheetName)])
             # ["%s %d" % (sheetPrefix, sheet)])
 
         sheetReference.add_function(sheetNameFunction)
 
         if minRowCount is not None:
-            minRowFunction = create_function(id_scope, sheetReference, 
+            minRowFunction = create_function(id_scope, sheetReference,
                                              "MinRowCount", [str(minRowCount)])
                                                    # [str(rowCount*vRCount)])
             sheetReference.add_function(minRowFunction)
         if minColCount is not None:
-            minColFunction = create_function(id_scope, sheetReference, 
-                                             "MinColumnCount", 
+            minColFunction = create_function(id_scope, sheetReference,
+                                             "MinColumnCount",
                                              [str(minColCount)])
                                                    # [str(colCount*vCCount)])
             sheetReference.add_function(minColFunction)
@@ -142,7 +135,7 @@ def assignPipelineCellLocations(pipeline, sheetName,
                                      "CellLocation")
         rowFunction = create_function(id_scope, cellLocation, "Row", [str(row)])
                                                  # [str(row*vRCount+vRow+1)])
-        colFunction = create_function(id_scope, cellLocation, "Column", 
+        colFunction = create_function(id_scope, cellLocation, "Column",
                                       [str(col)])
                                                  # [str(col*vCCount+vCol+1)])
 
@@ -150,12 +143,12 @@ def assignPipelineCellLocations(pipeline, sheetName,
         cellLocation.add_function(colFunction)
 
         # Then connect the SheetReference to the CellLocation
-        sheet_conn = create_connection(id_scope, sheetReference, "self",
+        sheet_conn = create_connection(id_scope, sheetReference, "value",
                                        cellLocation, "SheetReference")
 
         # Then connect the CellLocation to the spreadsheet cell
         cell_module = pipeline.get_module_by_id(mId)
-        cell_conn = create_connection(id_scope, cellLocation, "self",
+        cell_conn = create_connection(id_scope, cellLocation, "value",
                                       cell_module, "Location")
 
         pipeline.add_module(sheetReference)
@@ -167,12 +160,13 @@ def assignPipelineCellLocations(pipeline, sheetName,
 
     return root_pipeline
 
+
 def executePipelineWithProgress(pipeline,
                                 pTitle='Pipeline Execution',
                                 pCaption='Executing...',
                                 pCancel='&Cancel',
                                 **kwargs):
-    """ executePipelineWithProgress(pipeline: Pipeline,                                    
+    """ executePipelineWithProgress(pipeline: Pipeline,
                                     pTitle: str, pCaption: str, pCancel: str,
                                     kwargs: keyword arguments) -> bool
     Execute the pipeline while showing a progress dialog with title
@@ -180,7 +174,7 @@ def executePipelineWithProgress(pipeline,
     pCancel. kwargs is the keyword arguments that will be passed to
     the interpreter. A bool will be returned indicating if the
     execution was performed without cancel or not.
-    
+
     """
     withoutCancel = True
     totalProgress = len(pipeline.modules)
diff --git a/vistrails/packages/spreadsheet/spreadsheet_helpers.py b/vistrails/packages/spreadsheet/spreadsheet_helpers.py
index 4521fef..753607c 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_helpers.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_helpers.py
@@ -1,47 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains classes working with cell helper widgets, i.e. toolbar,
-# resizer, etc.:
-#   CellHelpers
-#   CellResizer
-#   CellResizerConfig
-################################################################################
+
+"""This file contains classes working with cell helper widgets, i.e. toolbar,
+resizer, etc.:
+  CellHelpers
+  CellResizer
+  CellResizerConfig
+"""
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
 
-################################################################################
 
 class CellResizerConfig(object):
     """
@@ -56,7 +59,7 @@ class CellResizerConfig(object):
         """ CellResizerConfig(size: int, color: QColor) -> CellResizerConfig
         Create mask and pixmap of a triangular shape with the specifc size
         and color
-        
+
         """
         self.size = size
         self.transparentColor = QtGui.QColor(QtCore.Qt.blue)
@@ -76,7 +79,7 @@ class CellResizerConfig(object):
     def pixmap(self):
         """ pixmap() -> QPixmap
         Return the pixmap of the resizer shape
-        
+
         """
         if not self.pixmapVar:
             self.pixmapVar = QtGui.QPixmap.fromImage(self.image)
@@ -85,7 +88,7 @@ class CellResizerConfig(object):
     def mask(self):
         """ mask() -> QRegion
         Return only the region of the resizer that will be shown on screen
-        
+
         """
         if not self.maskVar:
             mask = self.pixmap().createMaskFromColor(self.transparentColor)
@@ -95,10 +98,11 @@ class CellResizerConfig(object):
     def cursor(self):
         """ cursor() -> QCursor
         Return the cursor that will be shown inside the resizer
-        
+
         """
         return QtGui.QCursor(QtCore.Qt.SizeFDiagCursor)
 
+
 class CellResizer(QtGui.QLabel):
     """
     CellResizer is a customized shape SizeGrip that stays on top of
@@ -112,7 +116,7 @@ class CellResizer(QtGui.QLabel):
                         config: subclass of CellResizerConfig,
                         parent: QWidget) -> CellResizer
         Initialize the size grip with the default triangular shape
-        
+
         """
         QtGui.QLabel.__init__(self,sheet)
         self.setFixedSize(config.size, config.size)
@@ -131,17 +135,17 @@ class CellResizer(QtGui.QLabel):
         self.col = -1
         self.hide()
 
-    def setDragging(self,b):        
+    def setDragging(self,b):
         """ setDragging(b: boolean) -> None
         Set the resizer state to busy dragging
-        
+
         """
         self.dragging = b
 
     def snapTo(self,row,col):
         """ snapTo(row, col) -> None
         Assign which row and column the resizer should be controlling
-        
+
         """
         self.row = row
         self.col = col
@@ -149,17 +153,17 @@ class CellResizer(QtGui.QLabel):
     def adjustPosition(self, rect):
         """ adjustPosition(rect: QRect) -> None
         Adjust resizer position to be on the bottom-right corner of the cell
-        
+
         """
         p = self.parent().mapFromGlobal(rect.topLeft())
         self.move(p.x()+rect.width()-self.width(),
                   p.y()+rect.height()-self.height())
 
     def mousePressEvent(self,e):
-        """ mousePressEvent(e: QMouseEvent) -> None        
+        """ mousePressEvent(e: QMouseEvent) -> None
         Handle Qt mouse press event to track if we need to resize
         either left or right mouse button is clicked
-        
+
         """
         if self.col>=0:
             if e.button()==QtCore.Qt.LeftButton:
@@ -174,39 +178,39 @@ class CellResizer(QtGui.QLabel):
     def mouseReleaseEvent(self,e):
         """ mouseReleaseEvent(e: QMouseEvent) -> None
         Handle Qt mouse release event to clean up all state
-        
+
         """
         if (e.button()==QtCore.Qt.LeftButton or
             e.button()==QtCore.Qt.RightButton):
             self.dragging = False
 
     def mouseMoveEvent(self,e):
-        """ mouseMoveEvent(e: QMouseEvent) -> None        
+        """ mouseMoveEvent(e: QMouseEvent) -> None
         Interactively resize the corresponding column and row when the
         mouse moves
-        
+
         """
         if self.dragging:
             hSize = self.sheet.columnWidth(self.col)
             vSize = self.sheet.rowHeight(self.row)
             hd = e.globalX() - self.lastPos[0] - hSize
             vd = e.globalY() - self.lastPos[1] - vSize
-            
+
             # All sections should have the same size (Right-Click)
             if self.resizeAll:
                 # Resize the columns first
-                dS = int(hd / (self.col+1))
+                dS = int(hd // (self.col+1))
                 mS = hd % (self.col+1)
-                for i in xrange(self.sheet.columnCount()):                    
+                for i in xrange(self.sheet.columnCount()):
                     if i>self.col:
                         newValue = hSize+dS
                     else:
                         newValue = self.sheet.columnWidth(i)+dS+(i<mS)
                     self.sheet.setColumnWidth(i, newValue)
                 # Then resize the rows
-                dS = int(vd / (self.row+1))
+                dS = int(vd // (self.row+1))
                 mS = vd % (self.row+1)
-                for i in xrange(self.sheet.rowCount()):                    
+                for i in xrange(self.sheet.rowCount()):
                     if i>self.row:
                         newValue = vSize+dS
                     else:
@@ -221,6 +225,7 @@ class CellResizer(QtGui.QLabel):
             rect.moveTo(self.sheet.viewport().mapToGlobal(rect.topLeft()))
             self.adjustPosition(rect)
 
+
 class CellHelpers(object):
     """
     CellHelpers is a container include CellResizer that will shows up
@@ -231,17 +236,17 @@ class CellHelpers(object):
         """ CellHelpers(sheet: SpreadsheetSheet,
                         resizerInstance: CellResizer) -> CellHelpers
         Initialize with  a cell resizer
-        
+
         """
         self.sheet = sheet
         self.resizer = resizerInstance
         self.row = -1
         self.col = -1
-        
+
     def snapTo(self, row, col):
         """ snapTo(row: int, col: int) -> None
         Assign the resizer to the correct cell
-        
+
         """
         if row>=0 and ((row!=self.row) or (col!=self.col)):
             self.hide()
@@ -254,7 +259,7 @@ class CellHelpers(object):
     def adjustPosition(self):
         """ adjustPosition() -> None
         Adjust the resizer
-        
+
         """
         rect = self.sheet.getCellGlobalRect(self.row, self.col)
         if self.resizer:
@@ -263,14 +268,14 @@ class CellHelpers(object):
     def show(self):
         """ show() -> None
         An helper function derived from setVisible
-        
+
         """
         self.setVisible(True)
 
     def hide(self):
         """ hide() -> None
         An helper function derived from setVisible
-        
+
         """
         self.setVisible(False)
 
@@ -286,7 +291,7 @@ class CellHelpers(object):
     def isInteracting(self):
         """ isInteracting() -> boolean
         Check to see if the helper is in action with the resizer
-        
+
         """
         if self.resizer:
             return self.resizer.dragging
diff --git a/vistrails/packages/spreadsheet/spreadsheet_rc.py b/vistrails/packages/spreadsheet/spreadsheet_rc.py
index ca1f8d4..21aede9 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_rc.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_rc.py
@@ -1,44 +1,49 @@
+# -*- coding: utf-8 -*-
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
 # Resource object code
 #
-# Created: Fri Oct 6 13:32:35 2006
-#      by: The Resource Compiler for PyQt (Qt v4.1.3)
+# Created: Thu Mar 20 11:46:50 2014
+#      by: The Resource Compiler for PyQt (Qt v4.8.5)
 #
 # WARNING! All changes made in this file will be lost!
 
+from __future__ import division
+
 from PyQt4 import QtCore
 
 qt_resource_data = b"\
diff --git a/vistrails/packages/spreadsheet/spreadsheet_registry.py b/vistrails/packages/spreadsheet/spreadsheet_registry.py
index 03b9f80..ef85578 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_registry.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_registry.py
@@ -1,52 +1,54 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains the spreadsheet registry:
-#   SpreadsheetRegistry
-################################################################################
+
+"""This file contains the spreadsheet registry: SpreadsheetRegistry
+"""
+
+from __future__ import division
 
 class SpreadsheetRegistry(object):
     """
     SpreadsheetRegistry is the class holding information about cell and sheet
     types. Each sheet name will only have one sheet type associated with it
-    
+
     """
     def __init__(self):
         """ SpreadsheetRegistry() -> SpreadsheetRegistry
         Initialize the registry with no member
-        
+
         """
         self.packages = {}
         self.sheets = {}
@@ -54,14 +56,14 @@ class SpreadsheetRegistry(object):
     def registerPackage(self, package, name):
         """ registerPackage(package: python package, name: str) -> None
         Register a package containing spreadsheet widgets to the spreadsheet
-        
+
         """
         self.packages[package] = name
 
     def unregisterPackage(self, package):
         """ unregisterPackage(package: python package) -> None
         Unregister a package out of the spreadsheet
-        
+
         """
         if self.packages.has_key(package):
             del self.packages[package]
@@ -69,14 +71,14 @@ class SpreadsheetRegistry(object):
     def registerSheet(self, name, sheetType):
         """ registerSheet(name: str, sheetType: type) -> None
         Register a name for a sheet type
-        
+
         """
         self.sheets[name] = sheetType
-        
+
     def unregisterSheet(self, name):
         """ unregisterSheet(name: str) -> None
         Unregister a named sheet type
-        
+
         """
         if self.sheets.has_key(name):
             del self.sheets[name]
@@ -84,9 +86,9 @@ class SpreadsheetRegistry(object):
     def getSheet(self, name):
         """ getSheet(name: str) -> type
         Return the type of sheet with the corresponding name
-        
+
         """
-        if self.sheets.has_key(name):            
+        if self.sheets.has_key(name):
             return self.sheets[name]
         else:
             return None
@@ -94,11 +96,11 @@ class SpreadsheetRegistry(object):
     def getSheetByType(self, type):
         """ getSheetByType(type) -> name
         Return the name of sheet with the corresponding type
-        
+
         """
         for (n,t) in self.sheets.items():
             if t==type:
                 return n
         return None
-        
+
 spreadsheetRegistry = SpreadsheetRegistry()
diff --git a/vistrails/packages/spreadsheet/spreadsheet_sheet.py b/vistrails/packages/spreadsheet/spreadsheet_sheet.py
index 4c2e9d2..d2541c7 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_sheet.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_sheet.py
@@ -1,48 +1,52 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains a set of internal Spreadsheet basic classes used
-# by others:
-#   StandardWidgetHeaderView
-#   StandardWidgetItemDelegate
-#   StandardWidgetSheet
-################################################################################
+
+"""This file contains a set of internal Spreadsheet basic classes used by
+others:
+  StandardWidgetHeaderView
+  StandardWidgetItemDelegate
+  StandardWidgetSheet
+"""
+
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
-from spreadsheet_helpers import CellHelpers, CellResizer
 
-################################################################################
+from .spreadsheet_helpers import CellHelpers, CellResizer
+
 
 class StandardWidgetHeaderView(QtGui.QHeaderView):
     """
@@ -50,16 +54,19 @@ class StandardWidgetHeaderView(QtGui.QHeaderView):
     column/row labels) inheriting from QHeaderView. The main
     difference between this class and the original one is that it
     allows resizing and stretching at the same time
-    
+
     """
-    minimumSize = 50
+    THICKNESS = 30
+    MINIMUM_SIZE = 50
+
+    fitToWindow = True
 
     def __init__(self, orientation, parent=None):
         """ StandardWidgetHeaderView(orientation: QtCore.Qt.Align...,
                                      parent: QWidget)
                                      -> StandardWidgetHeaderView
         Initialize the header view to be like the one in the spreadsheet table
-        
+
         """
         QtGui.QHeaderView.__init__(self, orientation, parent)
         self.setMovable(True)
@@ -67,30 +74,118 @@ class StandardWidgetHeaderView(QtGui.QHeaderView):
         self.resizeSections(QtGui.QHeaderView.Stretch)
         self.setClickable(True)
         self.setHighlightSections(True)
-        self.fitToViewport = False
         if orientation==QtCore.Qt.Vertical:
             self.setDefaultAlignment(QtCore.Qt.AlignHCenter |
                                      QtCore.Qt.AlignVCenter)
 
-    def setFitToViewport(self, fit=True):
-        """ setFitToViewport(fit: boolean) -> None        
-        Set fit to viewport for have all the sections always stretch
-        to the whole viewport
+        self.connect(self, QtCore.SIGNAL('sectionResized(int, int, int)'),
+                     self.section_resized)
+        self._target_size = None
+
+    section_sizes = None
+    def read_section_sizes(self):
+        if (self.section_sizes is None or
+                len(self.section_sizes) != self.count()):
+            self.section_sizes = [float(self.sectionSize(self.logicalIndex(i)))
+                                  for i in xrange(self.count())]
 
+    _resizing = False
+
+    def section_resized(self, log_index, old_size, new_size):
+        if self._resizing:
+            return
+        else:
+            self._resizing = True
+            try:
+                self._section_resized(log_index, old_size, new_size)
+            finally:
+                self._resizing = False
+
+    def resize_right_rows(self, vis_index):
+        if self._resizing:
+            return
+        else:
+            self._resizing = True
+            try:
+                self._resize_right_rows(vis_index)
+            finally:
+                self._resizing = False
+
+    def _section_resized(self, log_index, old_size, new_size):
+        """ section_resized(horizontal: bool, log_index: int,
+                old_size: int, new_size: int) -> None
+        Called when a section of of the header is resized
         """
-        self.fitToViewport = fit
+        if not self.fitToWindow or self._target_size is None:
+            return
+
+        vis_index = self.visualIndex(log_index)
+        if vis_index == self.count() - 1:
+            self.resizeSection(log_index, old_size)
+            return
+
+        orig_new_size = new_size
+
+        # Can't shrink below minimum size
+        if new_size < old_size and new_size < self.MINIMUM_SIZE:
+            new_size = self.MINIMUM_SIZE
+
+        if self._target_size is None:
+            return
+
+        # Can't take other cells below minimum size
+        if new_size > old_size:
+            min_right = 0
+            for i in xrange(vis_index + 1, self.count()):
+                if not self.isSectionHidden(self.logicalIndex(i)):
+                    min_right += self.MINIMUM_SIZE
+            pos = self.sectionPosition(log_index)
+            total_right = self._target_size - pos - new_size
+            if total_right < min_right:
+                new_size = self._target_size - pos - min_right
+
+        if new_size != orig_new_size:
+            self.resizeSection(log_index, new_size)
+
+        # Resize the rows to the right
+        self.read_section_sizes()
+        self.section_sizes[vis_index] = float(new_size)
+        self._resize_right_rows(vis_index + 1)
+
+    def _resize_right_rows(self, vis_index):
+        self.read_section_sizes()
+
+        previous_space = sum(self.section_sizes[vis_index:])
+        new_space = self._target_size - sum(self.section_sizes[:vis_index])
+
+        # If we are growing the sections
+        if new_space > previous_space:
+            allocated_space = new_space - previous_space
+            for i, size in enumerate(self.section_sizes[vis_index:], vis_index):
+                size += allocated_space * (size / previous_space)
+                self.section_sizes[i] = size
+                self.resizeSection(self.logicalIndex(i), size)
+        # If we are shrinking the sections
+        else:
+            reclaimed_space = previous_space - new_space
+            for i, size in enumerate(self.section_sizes[vis_index:], vis_index):
+                size -= reclaimed_space * (
+                        (size - self.MINIMUM_SIZE)/previous_space)
+                self.section_sizes[i] = size
+                self.resizeSection(self.logicalIndex(i), size)
 
     def sizeHint(self):
         """ sizeHint() -> QSize
         Set a default thickness of the bar to 30
-        
+
         """
         size = QtGui.QHeaderView.sizeHint(self)
         if self.orientation()==QtCore.Qt.Vertical:
-            size.setWidth(30)
+            size.setWidth(self.THICKNESS)
         else:
-            size.setHeight(30)
-        return size        
+            size.setHeight(self.THICKNESS)
+        return size
+
 
 class StandardWidgetItemDelegate(QtGui.QItemDelegate):
     """
@@ -102,7 +197,7 @@ class StandardWidgetItemDelegate(QtGui.QItemDelegate):
         """ StandardWidgetItemDelegate(table: QTableWidget)
                                        -> StandardWidgetItemDelegate
         Initialize to store a table and padding
-        
+
         """
         self.table = table
         self.padding = 4
@@ -111,7 +206,7 @@ class StandardWidgetItemDelegate(QtGui.QItemDelegate):
     def setPadding(self, padding):
         """ setPadding(padding: int) -> None
         Re-set padding to a different value
-        
+
         """
         if self.padding!=padding:
             self.padding = padding
@@ -121,7 +216,7 @@ class StandardWidgetItemDelegate(QtGui.QItemDelegate):
                                  option: QStyleOptionViewItem,
                                  index: QModelIndex) -> None
         Make sure the widget only occupied inside the padded area
-    
+
         """
         rect = self.table.visualRect(index)
         rect.adjust(self.padding,self.padding,-self.padding,-self.padding)
@@ -130,9 +225,9 @@ class StandardWidgetItemDelegate(QtGui.QItemDelegate):
 
     def paint(self, painter, option, index):
         """ paint(painter: QPainter, option: QStyleOptionViewItem,
-                  index: QModelIndex) -> None                  
+                  index: QModelIndex) -> None
         Paint the current cell with a ring outside
-        
+
         """
         QtGui.QItemDelegate.paint(self, painter, option, index)
         if ((index.row(), index.column())==self.table.activeCell):
@@ -141,11 +236,12 @@ class StandardWidgetItemDelegate(QtGui.QItemDelegate):
                 QtGui.QColor(0.8549*255, 0.6971*255, 0.2255*255)), self.padding))
             r = self.table.visualRect(index)
             painter.setClipRegion(QtGui.QRegion(r))
-            r.adjust(self.padding/2,self.padding/2,-self.padding/2,-self.padding/2)
+            r.adjust(self.padding//2, self.padding//2,
+                     -self.padding//2, -self.padding//2)
             painter.drawRoundedRect(r, self.padding, self.padding)
             painter.restore()
-            
-            
+
+
 class StandardWidgetSheet(QtGui.QTableWidget):
     """
     StandardWidgetSheet is a standard sheet that can contain any type
@@ -159,7 +255,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         """ StandardWidgetSheet(rows: int, cols: int, parent: QWidget)
                                 -> StandardWidgetSheet
         Construct a sheet with rows x cols cells
-        
+
         """
         QtGui.QTableWidget.__init__(self, 0, 0, parent)
         self.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
@@ -176,7 +272,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
                      self.columnMoved)
         self.connect(self.horizontalHeader(),
                      QtCore.SIGNAL('sectionPressed(int)'),
-                     self.forceColumnMultiSelect) 
+                     self.forceColumnMultiSelect)
         self.setVerticalHeader(StandardWidgetHeaderView(QtCore.Qt.Vertical,
                                                         self))
         self.verticalHeader().setSelectionModel(self.selectionModel())
@@ -196,7 +292,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
             self.connect(cornerButton,
                          QtCore.SIGNAL('clicked()'),
                          self.forceSheetSelect)
-        
+
         self.delegate = StandardWidgetItemDelegate(self)
         self.setItemDelegate(self.delegate)
         self.helpers = CellHelpers(parent, CellResizer(self))
@@ -209,11 +305,11 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         self.activeCell = (-1,-1)
 
     def forceColumnMultiSelect(self, logicalIndex):
-        """ forceColumnMultiSelect(logicalIndex: int) -> None        
-        Make sure we always toggle the headerview in the right way        
+        """ forceColumnMultiSelect(logicalIndex: int) -> None
+        Make sure we always toggle the headerview in the right way
         NOTE: the MultiSelection type of SelectionMode does not work
         correctly for overlapping columns and rows selection
-        
+
         """
         if (self.selectionModel().isColumnSelected(logicalIndex, QtCore.QModelIndex())):
             self.selectionModel().select(self.model().index(0, logicalIndex),
@@ -225,11 +321,11 @@ class StandardWidgetSheet(QtGui.QTableWidget):
                                          QtGui.QItemSelectionModel.Columns)
 
     def forceRowMultiSelect(self, logicalIndex):
-        """ forceRowMultiSelect(logicalIndex: int) -> None        
-        Make sure we always toggle the headerview in the right way        
+        """ forceRowMultiSelect(logicalIndex: int) -> None
+        Make sure we always toggle the headerview in the right way
         NOTE: the MultiSelection type of SelectionMode does not work
         correctly for overlapping columns and rows selection
-        
+
         """
         if (self.selectionModel().isRowSelected(logicalIndex, QtCore.QModelIndex())):
             self.selectionModel().select(self.model().index(logicalIndex, 0),
@@ -241,16 +337,16 @@ class StandardWidgetSheet(QtGui.QTableWidget):
                                          QtGui.QItemSelectionModel.Rows)
 
     def forceSheetSelect(self):
-        """ forceSheetSelect() -> None        
+        """ forceSheetSelect() -> None
         Make sure we can toggle the whole sheet selection
-        
+
         """
         totalCells = self.rowCount()*self.columnCount()
         if (len(self.selectionModel().selectedIndexes())<totalCells):
             self.selectionModel().select(
                 QtGui.QItemSelection(self.model().index(0,0),
                                      self.model().index(self.rowCount()-1,
-                                                        self.columnCount()-1)),                
+                                                        self.columnCount()-1)),
                 QtGui.QItemSelectionModel.Select)
         else:
             self.selectionModel().clearSelection()
@@ -258,7 +354,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
     def updateHeaderStatus(self):
         """ updateHeaderStatus() -> None
         Update the visibility of the row and column header
-        
+
         """
         return
         self.horizontalHeader().setVisible(self.columnCount() > 1 or
@@ -269,7 +365,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
     def updateRowLabels(self, oldCount, newCount):
         """ updateRowLabels(oldCount: int, newCount: int) -> None
         Update vertical labels when the number of row changed
-        
+
         """
         vLabels = []
         vIdx = self.verticalHeader().visualIndex
@@ -281,14 +377,14 @@ class StandardWidgetSheet(QtGui.QTableWidget):
     def rowMoved(self, row, old, new):
         """ rowMove(row: int, old: int, new: int) -> None
         Renumber the vertical header labels when rows moved
-        
+
         """
         self.updateRowLabels(self.rowCount(), self.rowCount())
-        
+
     def updateColumnLabels(self, oldCount, newCount):
         """ updateColumnLabels(oldCount: int, newCount: int) -> None
         Update horizontal labels when the number of column changed
-        
+
         """
         hLabels = []
         vIdx = self.horizontalHeader().visualIndex
@@ -296,107 +392,60 @@ class StandardWidgetSheet(QtGui.QTableWidget):
             hLabels.append(chr(vIdx(i)+ord('A')))
         self.setHorizontalHeaderLabels(hLabels)
         self.updateHeaderStatus()
-        
+
     def columnMoved(self, row, old, new):
         """ columnMoved(row: int, old: int, new: int) -> None
         Renumber the horizontal header labels when columns moved
-        
+
         """
         self.updateColumnLabels(self.columnCount(), self.columnCount())
-        
+
     def setFitToWindow(self, fit=True):
         """ setFitToWindow(fit: boolean) -> None
         Force to fit all cells into the visible area. Set fit=False
         for the scroll mode where hidden cell can be viewed by scrolling
         the scrollbars.
-        
+
         """
         if fit!=self.fitToWindow:
             self.fitToWindow = fit
-            self.horizontalHeader().setFitToViewport(fit)
-            self.verticalHeader().setFitToViewport(fit)
+            self.horizontalHeader().fitToWindow = fit
+            self.horizontalHeader()._target_size = None
+            self.verticalHeader().fitToWindow = fit
+            self.verticalHeader()._target_size = None
             if not fit:
                 width = self.columnWidth(self.columnCount()-1)
                 height = self.rowHeight(self.rowCount()-1)
 
                 self.setColumnWidth(self.columnCount()-1, width)
                 self.setRowHeight(self.rowCount()-1, height)
-            self.horizontalHeader().setStretchLastSection(fit)
-            self.verticalHeader().setStretchLastSection(fit)
             self.stretchCells()
+            policy = (QtCore.Qt.ScrollBarAlwaysOff if fit
+                      else QtCore.Qt.ScrollBarAlwaysOn)
+            self.setHorizontalScrollBarPolicy(policy)
+            self.setVerticalScrollBarPolicy(policy)
 
     def showEvent(self, event):
         """ showEvent(event: QShowEvent) -> None
         Make sure to stretch the sheet on the first appearance
-        
+
         """
         self.stretchCells()
 
     def stretchCells(self):
         """ stretchCells() -> None
         Stretch all the cells with equally spaces to fit in the viewport
-        
+
         """
         if self.fitToWindow:
-            self.horizontalHeader().setFitToViewport(False)
             self.horizontalHeader().resizeSections(QtGui.QHeaderView.Stretch)
-            self.horizontalHeader().setFitToViewport(True)
-            self.verticalHeader().setFitToViewport(False)
             self.verticalHeader().resizeSections(QtGui.QHeaderView.Stretch)
-            self.verticalHeader().setFitToViewport(True)
-            
-    def resizeEvent(self, e):
-        """ resizeEvent(e: QResizeEvent) -> None
-        Resizes each row/column keeping the size ratios between them
-
-        """
-        if self.fitToWindow:
-            for min_size, getter, setter, count, final_size in [
-                    (self.horizontalHeader().minimumSize,
-                     self.columnWidth, self.setColumnWidth, self.columnCount(),
-                     e.size().width()),
-                    (self.verticalHeader().minimumSize,
-                     self.rowHeight, self.setRowHeight, self.rowCount(),
-                     e.size().height())]:
-                # Computes the total size of the columns
-                initial_size = 0
-                for i in xrange(count):
-                    size = getter(i)
-                    if size < min_size:
-                        initial_size += min_size
-                    else:
-                        initial_size += size
-
-                if initial_size == 0:
-                    continue
-
-                # Computes the resize ratio
-                ratio = float(final_size)/initial_size
-
-                i_total = 0
-                f_total = 0
-                for i in xrange(count - 1):
-                    initial = getter(i)
-                    if initial < min_size:
-                        initial = min_size
-                    final = int((initial + i_total) * ratio - f_total)
-                    if final < min_size:
-                        final = min_size
-                    setter(i, final)
-                    i_total += initial
-                    f_total += final
-                final = final_size - f_total
-                if final < min_size:
-                    final = min_size
-                setter(count - 1, final)
-
-        QtGui.QTableWidget.resizeEvent(self, e)
 
     def showHelpers(self, show, row, col):
-        """ showHelpers(show: boolean, row: int, col: int) -> None        
+        """ showHelpers(show: boolean, row: int, col: int) -> None
         Show/hide the helpers (resizer, toolbar) on the current cell
         depending on the value of show
-        
+
         """
         if self.helpers.isInteracting():
             return
@@ -410,10 +459,20 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         else:
             self.helpers.hide()
 
+    def resizeEvent(self, e):
+        if not self.fitToWindow:
+            return
+
+        thickness = StandardWidgetHeaderView.THICKNESS
+        self.horizontalHeader()._target_size = self.size().width() - thickness
+        self.horizontalHeader().resize_right_rows(0)
+        self.verticalHeader()._target_size = self.size().height() - thickness
+        self.verticalHeader().resize_right_rows(0)
+
     def getRealLocation(self, vRow, vCol, visual=False):
         """ getRealLocation(vRow: int, vCol: int, visual: bool) -> (int, int)
         Return the actual location even if there is spanning at (vRow, vCol)
-        
+
         """
         # Qt doesn't provide a mechanism to map from a cell to its
         # span region, so we have to scan the whole spreadsheet N^2
@@ -440,12 +499,12 @@ class StandardWidgetSheet(QtGui.QTableWidget):
                             return (r, c)
                         if (r+rs, c+cs) in cellSet:
                             cellSet.remove((r+rs, c+cs))
-        return (-1, -1)        
+        return (-1, -1)
 
     def getCell(self, row, col):
         """ getCell(row: int, col: int) -> QWidget
         Get cell at a specific row and column
-        
+
         """
         return self.cellWidget(*self.getRealLocation(row, col))
 
@@ -453,7 +512,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         """ getCellRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in parent coordinates
-        
+
         """
         idx = self.model().index(*self.getRealLocation(row, col))
         return self.visualRect(idx)
@@ -462,7 +521,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         """ getCellGlobalRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in global coordinates
-        
+
         """
         rect = self.getCellRect(row, col)
         rect.moveTo(self.viewport().mapToGlobal(rect.topLeft()))
@@ -470,10 +529,10 @@ class StandardWidgetSheet(QtGui.QTableWidget):
 
     def setCellByWidget(self, row, col, cellWidget):
         """ setCellByWidget(row: int,
-                            col: int,                            
+                            col: int,
                             cellWidget: QWidget) -> None
         Replace the current location (row, col) with a cell widget
-        
+
         """
         if cellWidget:
             # Relax the size constraint of the widget
@@ -489,7 +548,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
     def selectCell(self, row, col, toggling):
         """ selectCell(row: int, col: int, toggling: bool) -> None
         Select a cell based on its current selection
-        
+
         """
         (row, col) = self.getRealLocation(row, col, visual=True)
         if toggling:
@@ -520,7 +579,7 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         self.parent().toolBar.setCellToolBar(toolBar)
 
     def adjustWidgetGeometry(self, row, col):
-        """ setActiveCell(row: int, col: int) -> None        
+        """ setActiveCell(row: int, col: int) -> None
         Adjust the widget at cell (row, col) to fit inside the cell
 
         """
@@ -528,4 +587,3 @@ class StandardWidgetSheet(QtGui.QTableWidget):
         if cellWidget:
             index = self.model().index(*self.getRealLocation(row, col))
             self.delegate.updateEditorGeometry(cellWidget, None, index)
-        
diff --git a/vistrails/packages/spreadsheet/spreadsheet_tab.py b/vistrails/packages/spreadsheet/spreadsheet_tab.py
index c1d2096..a1e3087 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_tab.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_tab.py
@@ -1,70 +1,75 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file contains classes controlling tabs in the spreadsheets. A tab is
-# a container of a sheet:
-#   SizeSpinBox
-#   StandardTabDockWidget
-#   StandardWidgetSheetTab
-#   StandardWidgetTabBar
-#   StandardWidgetTabBarEditor
-#   StandardWidgetToolBar
-################################################################################
-from PyQt4 import QtCore, QtGui
+
+"""This file contains classes controlling tabs in the spreadsheets. A tab is
+a container of a sheet:
+  SizeSpinBox
+  StandardTabDockWidget
+  StandardWidgetSheetTab
+  StandardWidgetTabBar
+  StandardWidgetTabBarEditor
+  StandardWidgetToolBar
+"""
+
+from __future__ import division
+
 import os.path
-from spreadsheet_registry import spreadsheetRegistry
-from spreadsheet_sheet import StandardWidgetSheet
-from spreadsheet_cell import QCellPresenter, QCellContainer, QCellToolBar
-from spreadsheet_execute import assignPipelineCellLocations, \
-     executePipelineWithProgress
-from spreadsheet_config import configuration
+from PyQt4 import QtCore, QtGui
+
 from vistrails.core.inspector import PipelineInspector
+
+from .spreadsheet_registry import spreadsheetRegistry
+from .spreadsheet_sheet import StandardWidgetSheet
+from .spreadsheet_cell import QCellPresenter, QCellContainer, QCellToolBar
+from .spreadsheet_execute import assignPipelineCellLocations, \
+     executePipelineWithProgress
+from .spreadsheet_config import configuration
 import spreadsheet_rc
 
-################################################################################
 
 class SizeSpinBox(QtGui.QSpinBox):
     """
     SizeSpinBox is just an overrided spin box that will also emit
     'editingFinished()' signal when the user interact with mouse
-    
-    """    
+
+    """
     def __init__(self, initValue=0, parent=None):
         """ SizeSpinBox(initValue: int, parent: QWidget) -> SizeSpinBox
         Initialize with a default width of 50 and a value of 0
-        
+
         """
         QtGui.QSpinBox.__init__(self, parent)
         self.setMinimum(1)
@@ -75,22 +80,23 @@ class SizeSpinBox(QtGui.QSpinBox):
     def mouseReleaseEvent(self, event):
         """ mouseReleaseEvent(event: QMouseEvent) -> None
         Emit 'editingFinished()' signal when the user release a mouse button
-        
+
         """
         QtGui.QSpinBox.mouseReleaseEvent(self, event)
-        self.emit(QtCore.SIGNAL("editingFinished()"))        
+        self.emit(QtCore.SIGNAL("editingFinished()"))
+
 
 class StandardWidgetToolBar(QtGui.QToolBar):
     """
     StandardWidgetToolBar: The default toolbar for each sheet
     container. By default, only FitToWindow and Table resizing are
     included
-    
+
     """
     def __init__(self, parent=None):
         """ StandardWidgetToolBar(parent: QWidget) -> StandardWidgetToolBar
         Init the toolbar with default actions
-        
+
         """
         QtGui.QToolBar.__init__(self, parent)
         self.sheetTab = parent
@@ -103,11 +109,11 @@ class StandardWidgetToolBar(QtGui.QToolBar):
         self.addSeparator()
         self.layout().setSpacing(2)
         self.currentToolBarAction = None
-    
+
     def rowCountSpinBox(self):
         """ rowCountSpinBox() -> SizeSpinBox
         Return the row spin box widget:
-        
+
         """
         if not hasattr(self, 'rowSpinBox'):
             self.rowSpinBox = SizeSpinBox(self.sheetTab.sheet.rowCount())
@@ -122,7 +128,7 @@ class StandardWidgetToolBar(QtGui.QToolBar):
     def colCountSpinBox(self):
         """ colCountSpinBox() -> SizeSpinBox
         Return the column spin box widget:
-        
+
         """
         if not hasattr(self, 'colSpinBox'):
             self.colSpinBox = SizeSpinBox(self.sheetTab.sheet.columnCount())
@@ -138,7 +144,7 @@ class StandardWidgetToolBar(QtGui.QToolBar):
         """ setCellToolBar(cellToolBar: QToolBar) -> None
         Set the current cell toolbar on this toolbar. Use None to
         remove the cell toolbar
-        
+
         """
         if (not self.currentToolBarAction or
             self.widgetForAction(self.currentToolBarAction)!=cellToolBar):
@@ -151,11 +157,12 @@ class StandardWidgetToolBar(QtGui.QToolBar):
             else:
                 self.currentToolBarAction = None
 
+
 class StandardWidgetSheetTabInterface(object):
     """
     StandardWidgetSheetTabInterface is the interface for tab
     controller to call for manipulating a tab
-    
+
     """
     ### Belows are API Wrappers to connect to self.sheet
 
@@ -166,30 +173,30 @@ class StandardWidgetSheetTabInterface(object):
     def isSheetTabWidget(self):
         """ isSheetTabWidget() -> boolean
         Return True if this is a sheet tab widget
-        
+
         """
         return True
 
     def getDimension(self):
         """ getDimension() -> tuple
         Get the sheet dimensions
-        
+
         """
         return (0,0)
-            
+
     def setDimension(self, rc, cc):
         """ setDimension(rc: int, cc: int) -> None
         Set the sheet dimensions
-        
+
         """
         pass
-            
+
     def getCell(self, row, col):
-        """ getCell(row: int, col: int) -> QWidget        
+        """ getCell(row: int, col: int) -> QWidget
         Get cell at a specific row and column. In reality, this cell
         widget is inside a QCellContainer and the cell container is
         the actual widget under the cell
-        
+
         """
         cellWidget = self.getCellWidget(row, col)
         if isinstance(cellWidget, QCellContainer):
@@ -197,27 +204,27 @@ class StandardWidgetSheetTabInterface(object):
         return cellWidget
 
     def getCellWidget(self, row, col):
-        """ getCellWidget(row: int, col: int) -> QWidget        
+        """ getCellWidget(row: int, col: int) -> QWidget
         Get actual cell at a specific row and column. This will in
         fact return the container widget of a cell
-        
+
         """
         return None
 
     def setCellWidget(self, row, col, cellWidget):
         """ setCellWidget(row: int,
-                          col: int,                            
-                          cellWidget: QWidget) -> None                            
-        Replace the current location (row, col) with a 
+                          col: int,
+                          cellWidget: QWidget) -> None
+        Replace the current location (row, col) with a
         widget. The widget will be put into a container to be
         protected from being destroyed when taken out.
-        
+
         """
         pass
 
     def setCellByWidget(self, row, col, cellWidget):
         """ setCellByWidget(row: int,
-                            col: int,                            
+                            col: int,
                             cellWidget: QWidget) -> None
         Put the cellWidget inside a container and place it on the sheet
 
@@ -232,7 +239,7 @@ class StandardWidgetSheetTabInterface(object):
     def getCellToolBar(self, row, col):
         """ getCellToolBar(row: int, col: int) -> QWidget
         Return the toolbar widget at cell location (row, col)
-        
+
         """
         cell = self.getCell(row, col)
         if cell:
@@ -254,7 +261,7 @@ class StandardWidgetSheetTabInterface(object):
         """ getCellRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in parent coordinates
-        
+
         """
         return QtCore.QRect()
 
@@ -262,12 +269,12 @@ class StandardWidgetSheetTabInterface(object):
         """ getCellGlobalRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in global coordinates
-        
+
         """
         return QtCore.QRect()
 
     def getFreeCell(self):
-        """ getFreeCell() -> tuple        
+        """ getFreeCell() -> tuple
         Get a free cell location (row, col) on the spreadsheet
 
         """
@@ -280,17 +287,17 @@ class StandardWidgetSheetTabInterface(object):
         (r, c) = self.lastCellLocation
         (rs, cs) = self.getSpan(r, c)
         index = (colCount * r + c + cs) % (rowCount*colCount)
-        return (index/colCount, index%colCount)
+        return (index//colCount, index%colCount)
 
     def setCellByType(self, row, col, cellType, inputPorts):
         """ setCellByType(row: int,
                           col: int,
                           cellType: a type inherits from QWidget,
-                          inpurPorts: tuple) -> None                          
+                          inpurPorts: tuple) -> None
         Replace the current location (row, col) with a cell of
         cellType. If the current type of that cell is the same as
         cellType, only the contents is updated with inputPorts.
-        
+
         """
         oldCell = self.getCell(row, col)
         if cellType is None or not isinstance(oldCell, cellType):
@@ -308,29 +315,29 @@ class StandardWidgetSheetTabInterface(object):
         self.lastCellLocation = (row, col)
 
     def showHelpers(self, show, globalPos):
-        """ showHelpers(show: boolean, globalPos: QPoint) -> None    
+        """ showHelpers(show: boolean, globalPos: QPoint) -> None
         Show/hide the helpers (toolbar, resizer when the mouse is at
         globalPos
-        
+
         """
         pass
 
     def setCellPipelineInfo(self, row, col, info):
-        """ setCellPipelineInfo(row: int, col: int, info: any type) -> None        
+        """ setCellPipelineInfo(row: int, col: int, info: any type) -> None
         Provide a way for the spreadsheet to store vistrail
         information, info, for the cell (row, col)
-        
+
         """
         if not (row,col) in self.pipelineInfo:
             self.pipelineInfo[(row,col)] = {}
         self.pipelineInfo[(row,col)] = info
 
     def getCellPipelineInfo(self, row, col):
-        """ getCellPipelineInfo(row: int, col: int) -> any type        
+        """ getCellPipelineInfo(row: int, col: int) -> any type
         Provide a way for the spreadsheet to extract vistrail
         information, info, for the cell (row, col)
-        
-        """        
+
+        """
         if not (row,col) in self.pipelineInfo:
             return None
         return self.pipelineInfo[(row,col)]
@@ -338,29 +345,29 @@ class StandardWidgetSheetTabInterface(object):
     def getSelectedLocations(self):
         """ getSelectedLocations() -> list
         Return the selected locations (row, col) of the current sheet
-        
+
         """
         return []
 
     def clearSelection(self):
         """ clearSelection() -> None
         Clear all the selection in the current sheet
-        
+
         """
         pass
-    
+
     def deleteCell(self, row, col):
         """ deleteCell(row, col: int) -> None
         Delete a cell in the sheet
-        
+
         """
         self.setCellByType(row, col, None, None)
         self.setCellPipelineInfo(row, col, None)
-        
+
     def deleteAllCells(self):
         """ deleteAllCells() -> None
         Delete all cells in the sheet
-        
+
         """
         (rowCount, columnCount) = self.getDimension()
         for r in xrange(rowCount):
@@ -368,12 +375,12 @@ class StandardWidgetSheetTabInterface(object):
                 self.deleteCell(r, c)
 
     def takeCell(self, row, col):
-        """ takeCell(row, col) -> QWidget        
+        """ takeCell(row, col) -> QWidget
         Free the cell widget at (row, col) from the tab and return as
         the result of the function. If there is no widget at (row,
         col). This returns None. The ownership of the widget is passed
         to the caller.
-        
+
         """
         cell = self.getCellWidget(row, col)
         if isinstance(cell, QCellContainer):
@@ -386,7 +393,7 @@ class StandardWidgetSheetTabInterface(object):
     def setCellEditingMode(self, r, c, editing=True):
         """ setCellEditingMode(r: int, c: int, editing: bool) -> None
         Turn on/off the editing mode of a single cell
-        
+
         """
         if editing:
             cellWidget = self.getCell(r, c)
@@ -407,11 +414,11 @@ class StandardWidgetSheetTabInterface(object):
                 cellWidget = presenter.releaseCellWidget()
                 self.setCellByWidget(r, c, cellWidget)
                 presenter.hide()
-    
+
     def setEditingMode(self, editing=True):
         """ setEditingMode(editing: bool) -> None
         Turn on/off the editing mode of the tab
-        
+
         """
         # Turn off active cell selection
         self.sheet.clearSelection()
@@ -427,7 +434,7 @@ class StandardWidgetSheetTabInterface(object):
         """ swapCell(row, col: int, newSheet: Sheet,
                      newRow, newCol: int) -> None
         Swap the (row, col) of this sheet to (newRow, newCol) of newSheet
-        
+
         """
         myWidget = self.takeCell(row, col)
         theirWidget = newSheet.takeCell(newRow, newCol)
@@ -442,7 +449,7 @@ class StandardWidgetSheetTabInterface(object):
         """ copyCell(row, col: int, newSheet: Sheet,
                      newRow, newCol: int) -> None
         Copy the (row, col) of this sheet to (newRow, newCol) of newSheet
-        
+
         """
         info = self.getCellPipelineInfo(row, col)
         if info:
@@ -461,10 +468,10 @@ class StandardWidgetSheetTabInterface(object):
     def executePipelineToCell(self, pInfo, row, col, reason=''):
         """ executePipelineToCell(p: tuple, row: int, col: int) -> None
         p: (locator, version, actions, pipeline)
-        
+
         Execute a pipeline and put all of its cell to (row, col). This
         need to be fixed to layout all cells inside the pipeline
-        
+
         """
         pipeline = self.setPipelineToLocateAt(row, col, pInfo[3])
         executePipelineWithProgress(pipeline, 'Execute Cell',
@@ -476,10 +483,10 @@ class StandardWidgetSheetTabInterface(object):
 
     def setPipelineToLocateAt(self, row, col, inPipeline, cellIds=[]):
         """ setPipelineToLocateAt(row: int, col: int, inPipeline: Pipeline,
-                                  cellIds: [ids]) -> Pipeline                                  
+                                  cellIds: [ids]) -> Pipeline
         Modify the pipeline to have its cells (provided by cellIds) to
         be located at (row, col) of this sheet
-        
+
         """
         sheetName = str(self.tabWidget.tabText(self.tabWidget.indexOf(self)))
         # Note that we must increment row/col by 1 to match how the
@@ -490,7 +497,7 @@ class StandardWidgetSheetTabInterface(object):
     def getPipelineInfo(self, row, col):
         """ getPipelineInfo(row: int, col: int) -> tuple
         Return (locator, versionNumber, actions, pipeline, controller) for a cell
-        
+
         """
         info = self.getCellPipelineInfo(row, col)
         if info:
@@ -504,14 +511,14 @@ class StandardWidgetSheetTabInterface(object):
     def exportSheetToImage(self, fileName):
         """ exportSheetToImage() -> None
         Montage all the cell images and export to a file
-        
+
         """
         (rCount, cCount) = self.getDimension()
         if rCount<1 or cCount<1: return
         cellHeights = [self.getCellRect(r, 0).height()
                        for r in xrange(rCount)]
         cellWidths = [self.getCellRect(0, c).width()
-                      for c in xrange(cCount)] 
+                      for c in xrange(cCount)]
         finalImage = QtGui.QImage(sum(cellWidths), sum(cellHeights), QtGui.QImage.Format_ARGB32)
         finalImage.fill(0xFFFFFFFF)
         painter = QtGui.QPainter(finalImage)
@@ -522,14 +529,14 @@ class StandardWidgetSheetTabInterface(object):
                 widget = self.getCell(r, c)
                 if widget:
                     pix = widget.grabWindowPixmap()
-                    cx = (cellWidths[c]-pix.width())/2
-                    cy = (cellHeights[r]-pix.height())/2
+                    cx = (cellWidths[c]-pix.width())//2
+                    cy = (cellHeights[r]-pix.height())//2
                     painter.drawPixmap(x+cx, y+cy, widget.grabWindowPixmap())
                 x += cellWidths[c]
             y += cellHeights[r]
         painter.end()
-         
-        #forcing png format if no extension was provided 
+
+        #forcing png format if no extension was provided
         (_,ext) = os.path.splitext(fileName)
         if ext == '':
             finalImage.save(fileName, 'png')
@@ -540,7 +547,7 @@ class StandardWidgetSheetTabInterface(object):
     def exportSheetToImages(self, dirPath, format='png'):
         """ exportSheetToImage() -> None
         Montage all the cell images and export to a file
-        
+
         """
         (rCount, cCount) = self.getDimension()
         for r in xrange(rCount):
@@ -557,7 +564,7 @@ class StandardWidgetSheetTabInterface(object):
         Set the spanning at location (row, col). This is only a place
         holder. Subclasses should implement this and getSpan for a
         fully functioning spanning feature.
-        
+
         """
         pass
 
@@ -566,23 +573,24 @@ class StandardWidgetSheetTabInterface(object):
         Return the spanning at location (row, col). This is only a
         place holder. Subclasses should implement this and setSpan for
         a fully functioning spanning feature.
-        
+
         """
         return (1, 1)
 
+
 class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
     """
     StandardWidgetSheetTab is a container of StandardWidgetSheet with
     a toolbar on top. This will be added directly to a QTabWidget for
     displaying the spreadsheet.
-    
+
     """
     def __init__(self, tabWidget,row=None , col=None):
         """ StandardWidgetSheet(tabWidget: QTabWidget,
                                 row: int,
                                 col: int) -> StandardWidgetSheet
         Initialize with a toolbar and a sheet widget
-                                
+
         """
         QtGui.QWidget.__init__(self, None)
         StandardWidgetSheetTabInterface.__init__(self)
@@ -607,17 +615,17 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
     def rowSpinBoxChanged(self):
         """ rowSpinBoxChanged() -> None
         Handle the number of row changed
-        
+
         """
         if self.toolBar.rowSpinBox.value()!=self.sheet.rowCount():
             self.sheet.setRowCount(self.toolBar.rowSpinBox.value())
             self.sheet.stretchCells()
             self.setEditingMode(self.tabWidget.editingMode)
-        
+
     def colSpinBoxChanged(self):
         """ colSpinBoxChanged() -> None
         Handle the number of row changed
-        
+
         """
         if self.toolBar.colSpinBox.value()!=self.sheet.columnCount():
             self.sheet.setColumnCount(self.toolBar.colSpinBox.value())
@@ -629,22 +637,22 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
     def getDimension(self):
         """ getDimension() -> tuple
         Get the sheet dimensions
-        
+
         """
         return (self.sheet.rowCount(), self.sheet.columnCount())
-            
+
     def setDimension(self, rc, cc):
         """ setDimension(rc: int, cc: int) -> None
         Set the sheet dimensions
-        
+
         """
         self.toolBar.rowCountSpinBox().setValue(rc)
         self.toolBar.colCountSpinBox().setValue(cc)
-            
+
     def getCellWidget(self, row, col):
         """ getCellWidget(row: int, col: int) -> QWidget
         Get cell at a specific row and column.
-        
+
         """
         return self.sheet.getCell(row, col)
 
@@ -652,7 +660,7 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
         """ getCellRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in parent coordinates
-        
+
         """
         return self.sheet.getCellRect(row, col)
 
@@ -660,15 +668,15 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
         """ getCellGlobalRect(row: int, col: int) -> QRect
         Return the rectangle surrounding the cell at location (row, col)
         in global coordinates
-        
+
         """
         return self.sheet.getCellGlobalRect(row, col)
 
     def showHelpers(self, show, globalPos):
-        """ showHelpers(show: boolean, globalPos: QPoint) -> None        
+        """ showHelpers(show: boolean, globalPos: QPoint) -> None
         Show/hide the helpers (toolbar, resizer) depending on the
         status of show and the global position of the cursor
-        
+
         """
         localPos = self.sheet.viewport().mapFromGlobal(QtGui.QCursor.pos())
         row = self.sheet.rowAt(localPos.y())
@@ -677,11 +685,11 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
         show =  show and (rect.x()+rect.width()-localPos.x()<100 and
                           rect.y()+rect.height()-localPos.y()<100)
         self.sheet.showHelpers(show, row, col)
-        
+
     def getSelectedLocations(self):
         """ getSelectedLocations() -> list
         Return the selected locations (row, col) of the current sheet
-        
+
         """
         indexes = self.sheet.selectedIndexes()
         return [(idx.row(), idx.column()) for idx in indexes]
@@ -689,23 +697,23 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
     def clearSelection(self):
         """ clearSelection() -> None
         Clear all the selection in the current sheet
-        
+
         """
         self.sheet.clearSelection()
-    
+
     def setCellWidget(self, row, col, cellWidget):
         """ setCellWidget(row: int,
-                            col: int,                            
-                            cellWidget: QWidget) -> None                            
+                            col: int,
+                            cellWidget: QWidget) -> None
         Replace the current location (row, col) with a cell widget
-        
+
         """
         self.sheet.setCellByWidget(row, col, cellWidget)
 
     def dragEnterEvent(self, event):
         """ dragEnterEvent(event: QDragEnterEvent) -> None
         Set to accept drops from the version tree
-        
+
         """
         mimeData = event.mimeData()
         if hasattr(mimeData, 'versionId'):
@@ -716,7 +724,7 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
     def dragMoveEvent(self, event):
         """ dragEnterEvent(event: QDragEnterEvent) -> None
         Set to accept drops while moving from the version tree
-        
+
         """
         mimeData = event.mimeData()
         if (hasattr(mimeData, 'versionId') and
@@ -727,7 +735,7 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
 
     def dropEvent(self, event):
         """ Execute the pipeline at the particular location """
-        mimeData = event.mimeData()        
+        mimeData = event.mimeData()
         if (hasattr(mimeData, 'versionId') and
             hasattr(mimeData, 'controller')):
             event.accept()
@@ -755,7 +763,7 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
     def setSpan(self, row, col, rowSpan, colSpan):
         """ setSpan(row, col, rowSpan, colSpan: int) -> None
         Set the spanning at location (row, col).
-        
+
         """
         colSpan = max(colSpan, 1)
         rowSpan = max(rowSpan, 1)
@@ -766,7 +774,7 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
                 for c in xrange(colSpan):
                     if r!=0 or c!=0:
                         self.deleteCell(row+r, col+c)
-                        
+
             # Take the current widget out
             curWidget = self.takeCell(row, col)
 
@@ -782,22 +790,22 @@ class StandardWidgetSheetTab(QtGui.QWidget, StandardWidgetSheetTabInterface):
         Return the spanning at location (row, col). This is only a
         place holder. Subclasses should implement this and setSpan for
         a fully functioning spanning feature.
-        
+
         """
         return (self.sheet.rowSpan(row, col), self.sheet.columnSpan(row, col))
 
-    
-class StandardWidgetTabBarEditor(QtGui.QLineEdit):    
+
+class StandardWidgetTabBarEditor(QtGui.QLineEdit):
     """
     StandardWidgetTabBarEditor overrides QLineEdit to enable canceling
     edit when Esc is pressed
-    
+
     """
     def __init__(self, text='', parent=None):
         """ StandardWidgetTabBarEditor(text: str, parent: QWidget)
                                        -> StandardWidgetTabBarEditor
         Store the original text at during initialization
-        
+
         """
         QtGui.QLineEdit.__init__(self, text, parent)
         self.originalText = text
@@ -805,7 +813,7 @@ class StandardWidgetTabBarEditor(QtGui.QLineEdit):
     def keyPressEvent(self, e):
         """ keyPressEvent(e: QKeyEvent) -> None
         Override keyPressEvent to handle Esc key
-        
+
         """
         if e.key()==QtCore.Qt.Key_Escape:
             e.ignore()
@@ -814,16 +822,17 @@ class StandardWidgetTabBarEditor(QtGui.QLineEdit):
         else:
             QtGui.QLineEdit.keyPressEvent(self, e)
 
+
 class StandardWidgetTabBar(QtGui.QTabBar):
     """
     StandardWidgetTabBar: a customized QTabBar to allow double-click
     to change tab name
-    
+
     """
     def __init__(self, parent=None):
         """ StandardWidgetTabBar(parent: QWidget) -> StandardWidgetTabBar
         Initialize like the original QTabWidget TabBar
-        
+
         """
         QtGui.QTabBar.__init__(self, parent)
         self.setAcceptDrops(True)
@@ -831,7 +840,7 @@ class StandardWidgetTabBar(QtGui.QTabBar):
                           'by dragging the tabs')
         self.setDrawBase(False)
         self.editingIndex = -1
-        self.editor = None        
+        self.editor = None
         self.setFocusPolicy(QtCore.Qt.NoFocus)
         self.connect(self, QtCore.SIGNAL('currentChanged(int)'),
                      self.updateTabText)
@@ -846,18 +855,18 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def mouseDoubleClickEvent(self, e):
         """ mouseDoubleClickEvent(e: QMouseEvent) -> None
         Handle Double-Click event to start the editor
-        
+
         """
         if e.buttons()!=QtCore.Qt.LeftButton or self.editor: return
-        
+
         # Update the current editing tab widget
         self.editingIndex = self.currentIndex()
-        
+
         # A hack to capture the rect of the triangular tab from commonstyle.cpp
         rect = self.tabRect(self.editingIndex)
         h = rect.height()-2
-        dx = h/3 + 3
-        rect.adjust(dx+1,1,-dx,-1)
+        dx = h//3 + 3
+        rect.adjust(dx+1, 1, -dx, -1)
 
         # Display the editor inplace of the tab text
         text = self.tabText(self.editingIndex)
@@ -875,7 +884,7 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def updateTabText(self, idx=0):
         """ updateTabText(idx: int) -> None
         Update the tab text after editing has been finished
-        
+
         """
         if self.editingIndex>=0 and self.editor:
             self.setTabText(self.editingIndex, self.editor.text())
@@ -888,19 +897,19 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def indexAtPos(self, p):
         """ indexAtPos(p: QPoint) -> int Reimplement of the private
         indexAtPos to find the tab index under a point
-        
+
         """
         if self.tabRect(self.currentIndex()).contains(p):
             return self.currentIndex()
         for i in xrange(self.count()):
-            if self.isTabEnabled(i) and self.tabRect(i).contains(p):                
+            if self.isTabEnabled(i) and self.tabRect(i).contains(p):
                 return i
-        return -1;
+        return -1
 
     def mousePressEvent(self, e):
         """ mousePressEvent(e: QMouseEvent) -> None
         Handle mouse press event to see if we should start to drag tabs or not
-        
+
         """
         QtGui.QTabBar.mousePressEvent(self, e)
         if e.buttons()==QtCore.Qt.LeftButton and self.editor==None:
@@ -909,7 +918,7 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def getGlobalRect(self, index):
         """ getGlobalRect(self, index: int)
         Get the rectangle of a tab in global coordinates
-        
+
         """
         if index<0: return None
         rect = self.tabRect(index)
@@ -919,18 +928,18 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def highlightTab(self, index):
         """ highlightTab(index: int)
         Highlight the rubber band of a tab
-        
+
         """
         if index==-1:
             self.innerRubberBand.hide()
         else:
             self.innerRubberBand.setGeometry(self.tabRect(index))
             self.innerRubberBand.show()
-            
+
     def mouseMoveEvent(self, e):
         """ mouseMoveEvent(e: QMouseEvent) -> None
         Handle dragging tabs in and out or around
-        
+
         """
         QtGui.QTabBar.mouseMoveEvent(self, e)
         if self.startDragPos:
@@ -941,7 +950,7 @@ class StandardWidgetTabBar(QtGui.QTabBar):
         if self.dragging:
             t = self.indexAtPos(e.pos())
             if t!=-1:
-                if t!=self.targetTab:                    
+                if t!=self.targetTab:
                     self.targetTab = t
                     self.outerRubberBand.hide()
                     self.highlightTab(t)
@@ -961,7 +970,7 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def mouseReleaseEvent(self, e):
         """ mouseReleaseEvent(e: QMouseEvent) -> None
         Make sure the tab moved at the end
-        
+
         """
         QtGui.QTabBar.mouseReleaseEvent(self, e)
         if self.dragging:
@@ -977,26 +986,26 @@ class StandardWidgetTabBar(QtGui.QTabBar):
             self.targetTab = -1
             self.highlightTab(-1)
             self.outerRubberBand.hide()
-            
+
     def slotIndex(self, pos):
         """ slotIndex(pos: QPoint) -> int
         Return the slot index between the slots at the cursor pos
-        
+
         """
         p = self.mapFromGlobal(pos)
         for i in xrange(self.count()):
             r = self.tabRect(i)
             if self.isTabEnabled(i) and r.contains(p):
-                if p.x()<(r.x()+r.width()/2):
+                if p.x() < (r.x()+r.width()//2):
                     return i
                 else:
                     return i+1
         return -1
-        
+
     def slotGeometry(self, idx):
         """ slotGeometry(idx: int) -> QRect
         Return the geometry between the slots at cursor pos
-        
+
         """
         if idx<0 or self.count()==0: return None
         if idx<self.count():
@@ -1012,7 +1021,7 @@ class StandardWidgetTabBar(QtGui.QTabBar):
     def dragEnterEvent(self, event):
         """ dragEnterEvent(event: QDragEnterEvent) -> None
         Set to accept drops from the other cell info
-        
+
         """
         mimeData = event.mimeData()
         if hasattr(mimeData, 'cellInfo'):
@@ -1023,22 +1032,22 @@ class StandardWidgetTabBar(QtGui.QTabBar):
                 self.setCurrentIndex(idx)
         else:
             event.ignore()
-            
+
     def dragMoveEvent(self, event):
         """ dragMoveEvent(event: QDragMoveEvent) -> None
         Set to accept drops from the other cell info
-        
+
         """
         idx = self.indexAtPos(event.pos())
         if idx>=0:
             self.setCurrentIndex(idx)
-            
-            
+
+
 class StandardTabDockWidget(QtGui.QDockWidget):
     """
     StandardTabDockWidget inherits from QDockWidget to contain a sheet
     widget floating around that can be merge back to tab controller
-    
+
     """
     def __init__(self, title, tabWidget, tabBar, tabController):
         """ StandardTabDockWidget(title: str,
@@ -1047,7 +1056,7 @@ class StandardTabDockWidget(QtGui.QDockWidget):
                                   tabController: StandardWidgetTabController)
                                   -> StandardTabDockWidget
         Initialize the dock widget to override the floating button
-        
+
         """
         QtGui.QDockWidget.__init__(self, title, None,
                                    QtCore.Qt.FramelessWindowHint)
@@ -1071,10 +1080,10 @@ class StandardTabDockWidget(QtGui.QDockWidget):
         self.resize(tabWidget.size())
 
     def findFloatingButton(self):
-        """ findFloatingButton() -> QAbstractButton        
+        """ findFloatingButton() -> QAbstractButton
         Hack to find the private Floating Button. Since there is only
         one button exists, we just need to find QAbstractButton
-        
+
         """
         for c in self.children():
             if isinstance(c, QtGui.QAbstractButton):
@@ -1084,7 +1093,7 @@ class StandardTabDockWidget(QtGui.QDockWidget):
     def eventFilter(self, q, e):
         """ eventFilter(q: QObject, e: QEvent) -> depends on event type
         Event filter the floating button to makes it merge to the tab controller
-        
+
         """
         if q and q==self.floatingButton:
             if (e.type()==QtCore.QEvent.MouseButtonRelease and
@@ -1096,7 +1105,7 @@ class StandardTabDockWidget(QtGui.QDockWidget):
                 return False
         return QtGui.QDockWidget.eventFilter(self, q, e)
 
-    def isTabControllerUnderMouse(self, tb):        
+    def isTabControllerUnderMouse(self, tb):
         """ Check if any of common parent of the tab controller and tb
         is under the mouse """
         tbp = []
@@ -1113,7 +1122,7 @@ class StandardTabDockWidget(QtGui.QDockWidget):
     def event(self, e):
         """ event(e: QEvent) -> depends on event type
         Handle movement of the dock widget to snap to the tab controller
-        
+
         """
         # MOUSE PRESS (QtCore.QEvent.NonClientAreaMouseButtonPress=174)
         if e.type() in [QtCore.QEvent.MouseButtonPress,174]:
@@ -1191,7 +1200,7 @@ class StandardTabDockWidget(QtGui.QDockWidget):
                 self.hide()
                 self.tabController.mergeTab(self, self.tabController.count())
                 return True
-            
+
         return QtGui.QDockWidget.event(self, e)
 
     def closeEvent(self, event):
@@ -1199,5 +1208,6 @@ class StandardTabDockWidget(QtGui.QDockWidget):
         self.tabController.mergeTab(self, self.tabController.count())
         event.accept()
 
+
 spreadsheetRegistry.registerSheet('StandardWidgetSheetTab',
                                   StandardWidgetSheetTab)
diff --git a/vistrails/packages/spreadsheet/spreadsheet_tabcontroller.py b/vistrails/packages/spreadsheet/spreadsheet_tabcontroller.py
index 17725ab..fe10531 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_tabcontroller.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_tabcontroller.py
@@ -1,58 +1,63 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file implements the Spreadsheet Tab Controller, to manages tabs
-#   StandardWidgetTabController
-################################################################################
+
+"""This file implements the Spreadsheet Tab Controller, to manages tabs:
+StandardWidgetTabController
+"""
+
+from __future__ import division
+
+from ast import literal_eval
+import copy
+import gc
 import os.path
 from PyQt4 import QtCore, QtGui
+
 from vistrails.core.db.locator import FileLocator, _DBLocator as DBLocator
 from vistrails.core.interpreter.default import get_default_interpreter
-from vistrails.db.services.io import SaveBundle
-from spreadsheet_registry import spreadsheetRegistry
-from spreadsheet_tab import (StandardWidgetTabBar,
-                             StandardWidgetSheetTab, StandardTabDockWidget)
-from spreadsheet_registry import spreadsheetRegistry
 from vistrails.core.utils import DummyView
 from vistrails.core.utils.uxml import XMLWrapper, named_elements
-import copy
-import gc
+from vistrails.db.services.io import SaveBundle
 from vistrails.gui.theme import CurrentTheme
 from vistrails.gui.utils import show_warning
 
-################################################################################
+from .spreadsheet_registry import spreadsheetRegistry
+from .spreadsheet_tab import StandardWidgetTabBar, StandardWidgetSheetTab, \
+    StandardTabDockWidget
+
 
 class StandardWidgetTabController(QtGui.QTabWidget):
     """
@@ -65,9 +70,9 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         """ StandardWidgetTabController(parent: QWidget)
                                         -> StandardWidgetTabController
         Initialize signals/slots and widgets for the tab bar
-        
+
         """
-        
+
         QtGui.QTabWidget.__init__(self, parent)
         self.operatingWidget = self
         self.setTabBar(StandardWidgetTabBar(self))
@@ -98,18 +103,18 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         self.setCornerWidget(self.closeButton)
         self.connect(self.closeButton, QtCore.SIGNAL('clicked()'),
                      self.deleteSheetAction().trigger)
-        
+
     def isLoadingMode(self):
         """ isLoadingMode() -> boolean
         Checking if the controller is in loading mode
-        
+
         """
         return self.loadingMode
 
     def getMonitoredLocations(self, spec):
         """ getMonitoredLocations(spec: tuple) -> location
         Return the monitored location associated with spec
-        
+
         """
         key = ((spec[0]['locator'], spec[0]['version']), spec[1], spec[2])
         if key in self.monitoredPipelines:
@@ -120,18 +125,18 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def appendMonitoredLocations(self, spec, value):
         """ getMonitoredLocations(spec: tuple, value: location) -> None
         Return the monitored location associated with spec
-        
+
         """
         key = ((spec[0]['locator'], spec[0]['version']), spec[1], spec[2])
         if key in self.monitoredPipelines:
             self.monitoredPipelines[key].append(value)
         else:
             self.monitoredPipelines[key] = [value]
-         
+
     def newSheetAction(self):
         """ newSheetAction() -> QAction
         Return the 'New Sheet' action
-        
+
         """
         if not hasattr(self, 'newSheetActionVar'):
             icon = QtGui.QIcon(':/images/newsheet.png')
@@ -147,7 +152,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def deleteSheetAction(self):
         """ deleteSheetAction() -> QAction
         Return the 'Delete Sheet' action:
-        
+
         """
         if not hasattr(self, 'deleteSheetActionVar'):
             icon = QtGui.QIcon(':/images/deletesheet.png')
@@ -166,7 +171,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def showNextTabAction(self):
         """ showNextTabAction() -> QAction
         Return the 'Next Sheet' action
-        
+
         """
         if not hasattr(self, 'showNextTabActionVar'):
             icon = QtGui.QIcon(':/images/forward.png')
@@ -184,7 +189,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def showPrevTabAction(self):
         """ showPrevTabAction() -> QAction
         Return the 'Prev Sheet' action
-        
+
         """
         if not hasattr(self, 'showPrevTabActionVar'):
             icon = QtGui.QIcon(':/images/back.png')
@@ -201,7 +206,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def saveAction(self):
         """ saveAction() -> QAction
         Return the 'Save' action
-        
+
         """
         if not hasattr(self, 'saveActionVar'):
             self.saveActionVar = QtGui.QAction(QtGui.QIcon(':/images/save.png'),
@@ -216,7 +221,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def saveAsAction(self):
         """ saveAsAction() -> QAction
         Return the 'Save As...' action
-        
+
         """
         if not hasattr(self, 'saveAsActionVar'):
             icon = QtGui.QIcon(':/images/saveas.png')
@@ -231,7 +236,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def openAction(self):
         """ openAction() -> QAction
         Return the 'Open...' action
-        
+
         """
         if not hasattr(self, 'openActionVar'):
             self.openActionVar = QtGui.QAction(QtGui.QIcon(':/images/open.png'),
@@ -246,10 +251,10 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def exportSheetToImageAction(self):
         """ exportSheetToImageAction() -> QAction
         Export the current sheet to an image
-        
+
         """
         if not hasattr(self, 'exportSheetToImageVar'):
-            self.exportSheetToImageVar = QtGui.QAction('Export', self)
+            self.exportSheetToImageVar = QtGui.QAction('Export Sheet', self)
             self.exportSheetToImageVar.setStatusTip(
                 'Export all cells in the spreadsheet to a montaged image')
 
@@ -257,43 +262,48 @@ class StandardWidgetTabController(QtGui.QTabWidget):
             singleAction = exportMenu.addAction('As a Single Image')
             multiAction = exportMenu.addAction('Separately')
             self.exportSheetToImageVar.setMenu(exportMenu)
-            
+
             self.connect(self.exportSheetToImageVar,
                          QtCore.SIGNAL('triggered(bool)'),
-                         self.exportSheetToImageActionTriggered)
-            
-            self.connect(exportMenu,
-                         QtCore.SIGNAL('triggered(QAction*)'),
-                         self.exportSheetToImageActionTriggered)
+                         self.exportSheetToSingleImageActionTriggered)
+
+            self.connect(singleAction,
+                         QtCore.SIGNAL('triggered()'),
+                         self.exportSheetToSingleImageActionTriggered)
+            self.connect(multiAction,
+                         QtCore.SIGNAL('triggered()'),
+                         self.exportSheetToSeparateImagesActionTriggered)
         return self.exportSheetToImageVar
 
-    def exportSheetToImageActionTriggered(self, action=None):
-        """ exportSheetToImageActionTriggered(checked: boolean) -> None
-        Actual code to create export an image
-        
-        """
-        if not isinstance(action, bool) and action.text() == 'Separately':
-            dir = QtGui.QFileDialog.getExistingDirectory(
-                self, 'Select a Directory to Export Images', ".",
-                QtGui.QFileDialog.ShowDirsOnly)
-            if dir:
-                self.currentWidget().exportSheetToImages(dir)
-        else:
-            file = QtGui.QFileDialog.getSaveFileName(
-                self, "Select a File to Export the Sheet",
-                ".", "Images (*.png *.xpm *.jpg)")
-            if file:
-                self.currentWidget().exportSheetToImage(str(file))
-        
+    def exportSheetToSingleImageActionTriggered(self, action=None):
+        """ exportSheetToSingleImageActionTriggered() -> None
+        Exports the sheet as a big image
+        """
+        filename = QtGui.QFileDialog.getSaveFileName(
+            self, "Select a File to Export the Sheet",
+            ".", "Images (*.png *.xpm *.jpg)")
+        if filename:
+            self.currentWidget().exportSheetToImage(filename)
+
+    def exportSheetToSeparateImagesActionTriggered(self, action=None):
+        """ exportSheetToSeparateImagesActionTriggered() -> None
+        Exports the cells as separate images
+        """
+        dirname = QtGui.QFileDialog.getExistingDirectory(
+            self, 'Select a Directory to Export Images', ".",
+            QtGui.QFileDialog.ShowDirsOnly)
+        if dirname:
+            self.currentWidget().exportSheetToImages(dirname)
+
     def newSheetActionTriggered(self, checked=False):
         """ newSheetActionTriggered(checked: boolean) -> None
         Actual code to create a new sheet
-        
+
         """
         self.setCurrentIndex(self.addTabWidget(StandardWidgetSheetTab(self),
                                                'Sheet %d' % (self.count()+1)))
         self.currentWidget().sheet.stretchCells()
-        
+
     def tabInserted(self, index):
         """tabInserted(index: int) -> None
         event handler to get when sheets are inserted """
@@ -316,12 +326,12 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         for (code, locations) in self.monitoredPipelines.iteritems():
             for lid in reversed(xrange(len(locations))):
                 if sheet==locations[lid][0]:
-                    del locations[lid]                        
+                    del locations[lid]
 
     def deleteSheetActionTriggered(self, checked=False):
         """ deleteSheetActionTriggered(checked: boolean) -> None
         Actual code to delete the current sheet
-        
+
         """
         if self.count()>0:
             widget = self.currentWidget()
@@ -332,11 +342,11 @@ class StandardWidgetTabController(QtGui.QTabWidget):
             widget.deleteLater()
             QtCore.QCoreApplication.processEvents()
             gc.collect()
-            
+
     def clearTabs(self):
         """ clearTabs() -> None
         Clear and reset the controller
-        
+
         """
         self.executedPipelines = [[], {}, {}]
         while self.count()>0:
@@ -353,7 +363,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
                       -> QTabWidget
         Redirect insertTab command to operatingWidget, this can either be a
         QTabWidget or a QStackedWidget
-        
+
         """
         if self.operatingWidget!=self:
             ret = self.operatingWidget.insertWidget(idx, tabWidget)
@@ -365,7 +375,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def findSheet(self, sheetReference):
         """ findSheet(sheetReference: subclass(SheetReference)) -> Sheet widget
         Find/Create a sheet that meets a certen sheet reference
-        
+
         """
         if not sheetReference:
             return None
@@ -381,14 +391,14 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         """ changeTabText(tabIdx: int, newTabText: str) -> None
         Update window title on the operating widget when the tab text
         has changed
-        
+
         """
         self.operatingWidget.widget(tabIdx).setWindowTitle(newTabText)
 
     def moveTab(self, tabIdx, destination):
         """ moveTab(tabIdx: int, destination: int) -> None
         Move a tab at tabIdx to a different position at destination
-        
+
         """
         if (tabIdx<0 or tabIdx>self.count() or
             destination<0 or destination>self.count()):
@@ -402,25 +412,25 @@ class StandardWidgetTabController(QtGui.QTabWidget):
 
     def splitTab(self, tabIdx, pos=None):
         """ splitTab(tabIdx: int, pos: QPoint) -> None
-        Split a tab to be  a stand alone window and move to position pos        
-        
+        Split a tab to be  a stand alone window and move to position pos
+
         """
         if tabIdx<0 or tabIdx>self.count() or self.count()==0:
             return
         tabWidget = self.widget(tabIdx)
         self.removeTab(tabIdx)
-        
+
         frame = StandardTabDockWidget(tabWidget.windowTitle(), tabWidget,
                                       self.tabBar(), self)
         if pos:
             frame.move(pos)
-        frame.show()        
+        frame.show()
         self.floatingTabWidgets.append(frame)
 
     def mergeTab(self, frame, tabIdx):
         """ mergeTab(frame: StandardTabDockWidget, tabIdx: int) -> None
         Merge a tab dock widget back to the controller at position tabIdx
-        
+
         """
         if tabIdx<0 or tabIdx>self.count():
             return
@@ -437,7 +447,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def addTabWidget(self, tabWidget, sheetLabel):
         """ addTabWidget(tabWidget: QWidget, sheetLabel: str) -> int
         Add a new tab widget to the controller
-        
+
         """
         return self.insertTabWidget(-1, tabWidget, sheetLabel)
 
@@ -445,7 +455,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         """ insertTabWidget(index: int, tabWidget: QWidget, sheetLabel: str)
                             -> int
         Insert a tab widget to the controller at some location
-        
+
         """
         if sheetLabel==None:
             sheetLabel = 'Sheet %d' % (len(self.tabWidgets)+1)
@@ -457,7 +467,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def tabWidgetUnderMouse(self):
         """ tabWidgetUnderMouse() -> QWidget
         Return the tab widget that is under mouse, hide helpers for the rest
-        
+
         """
         result = None
         for t in self.tabWidgets:
@@ -471,7 +481,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         """ setupFullScreenWidget(fs: boolean, stackedWidget: QStackedWidget)
                                   -> None
         Prepare(fs=True)/Clean(fs=False) up full screen mode
-                                  
+
         """
         if fs:
             idx = self.currentIndex()
@@ -496,7 +506,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def showNextTab(self):
         """ showNextTab() -> None
         Bring the next tab up
-        
+
         """
         if self.operatingWidget.currentIndex()<self.operatingWidget.count()-1:
             index = self.operatingWidget.currentIndex()+1
@@ -505,7 +515,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def showPrevTab(self):
         """ showPrevTab() -> None
         Bring the previous tab up
-        
+
         """
         if self.operatingWidget.currentIndex()>0:
             index = self.operatingWidget.currentIndex()-1
@@ -514,9 +524,9 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def tabPopupMenu(self):
         """ tabPopupMenu() -> QMenu
         Return a menu containing a list of all tabs
-        
+
         """
-        menu = QtGui.QMenu(self)        
+        menu = QtGui.QMenu(self)
         en = self.operatingWidget.currentIndex()<self.operatingWidget.count()-1
         self.showNextTabAction().setEnabled(en)
         menu.addAction(self.showNextTabAction())
@@ -536,7 +546,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def showPopupMenu(self):
         """ showPopupMenu() -> None
         Activate the tab list and show the popup menu
-        
+
         """
         menu = self.tabPopupMenu()
         action = menu.exec_(QtGui.QCursor.pos())
@@ -548,10 +558,10 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         menu.deleteLater()
 
     def changeSpreadsheetFileName(self, fileName):
-        """ changeSpreadsheetFileName(fileName: str) -> None        
+        """ changeSpreadsheetFileName(fileName: str) -> None
         Change the current spreadsheet filename and reflect it on the
         window title
-        
+
         """
         self.spreadsheetFileName = fileName
         if self.spreadsheetFileName:
@@ -567,7 +577,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def addPipeline(self, pipelineInfo):
         """ addPipeline(pipelineInfo: dict) -> None
         Add vistrail pipeline executions to history
-        
+
         """
         vistrail = self.pipelineId(pipelineInfo)
         self.executedPipelines[0].append(vistrail)
@@ -580,7 +590,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def getCurrentPipelineId(self, pipelineInfo):
         """ getCurrentPipelineId(pipelineInfo: dict) -> Int
         Get the current pipeline id
-        
+
         """
         vistrail = self.pipelineId(pipelineInfo)
         return self.executedPipelines[1][vistrail]
@@ -588,25 +598,25 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def increasePipelineCellId(self, pipelineInfo):
         """ increasePipelineCellId(pipelineInfo: dict) -> int
         Increase the current cell pipeline id
-        
+
         """
         vistrail = self.pipelineId(pipelineInfo)
         cid = self.executedPipelines[2][vistrail]
         self.executedPipelines[2][vistrail] += 1
         return cid
-        
+
     def getCurrentPipelineCellId(self, pipelineInfo):
         """ getCurrentPipelineCellId(pipelineInfo: dict) -> int
         Get current pipeline cell id
-        
+
         """
         vistrail = self.pipelineId(pipelineInfo)
         return self.executedPipelines[2][vistrail]
-        
+
     def addPipelineCell(self, pipelineInfo):
         """ addPipelineCell(pipelineInfo: dict) -> None
         Add vistrail pipeline executions to history
-        
+
         """
         vistrail = self.pipelineId(pipelineInfo)
         self.executedPipelines[0].append(vistrail)
@@ -617,10 +627,10 @@ class StandardWidgetTabController(QtGui.QTabWidget):
 
 
     def saveSpreadsheet(self, fileName=None):
-        """ saveSpreadsheet(fileName: str) -> None        
+        """ saveSpreadsheet(fileName: str) -> None
         Save the current spreadsheet to a file if fileName is not
         None. Else, pop up a dialog to ask for a file name.
-        
+
         """
         def serialize_locator(locator):
             wrapper = XMLWrapper()
@@ -629,7 +639,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
             root.setAttribute("version", "1.0")
             locator.serialize(dom,root)
             return dom.toxml()
-        
+
         def need_save():
             from vistrails.gui.vistrails_window import _app
             need_save_vt = False
@@ -646,11 +656,11 @@ class StandardWidgetTabController(QtGui.QTabWidget):
                                 if controller.changed:
                                     need_save_vt = True
             return need_save_vt
-        
+
         if need_save():
             show_warning('Save Spreadsheet', 'Please save your vistrails and try again.')
             return
-        
+
         if fileName==None:
             fileName = self.spreadsheetFileName
         if fileName:
@@ -685,11 +695,11 @@ class StandardWidgetTabController(QtGui.QTabWidget):
             indexFile.close()
         else:
             self.saveSpreadsheetAs()
-        
+
     def saveSpreadsheetAs(self):
         """ saveSpreadsheetAs() -> None
         Asking a file name before saving the spreadsheet
-        
+
         """
         fileName = QtGui.QFileDialog.getSaveFileName(self,
                                                      'Choose a spreadsheet '
@@ -702,12 +712,12 @@ class StandardWidgetTabController(QtGui.QTabWidget):
             if ext=='':
                 fileName += '.vss'
             self.saveSpreadsheet(fileName)
-        
+
     def openSpreadsheet(self, fileName):
         """ openSpreadsheet(fileName: str) -> None
         Open a saved spreadsheet assuming that all VTK files must exist and have
         all the version using the saved spreadsheet
-        
+
         """
         def parse_locator(text):
             locator = None
@@ -733,13 +743,13 @@ class StandardWidgetTabController(QtGui.QTabWidget):
         lidx += 1
         for tabIdx in xrange(tabCount):
             # FIXME: eval should pretty much never be used
-            tabInfo = eval(lines[lidx])
+            tabInfo = literal_eval(lines[lidx])
             lidx += 1
             sheet = spreadsheetRegistry.getSheet(tabInfo[1])(self)
             sheet.setDimension(tabInfo[2], tabInfo[3])
             self.addTabWidget(sheet, tabInfo[0])
             while lines[lidx]!='---':
-                (r, c, vistrail, pid, cid) = eval(lines[lidx])
+                (r, c, vistrail, pid, cid) = literal_eval(lines[lidx])
                 locator = vistrail['locator']
                 if locators.has_key(locator):
                     vistrail['locator'] = locators[locator]
@@ -757,11 +767,11 @@ class StandardWidgetTabController(QtGui.QTabWidget):
                                          "&Cancel", 0, pipelineCount,
                                          self,
                                          QtCore.Qt.WindowStaysOnTopHint
-                                         );
+                                         )
         progress.show()
         for pipelineIdx in xrange(pipelineCount):
             # FIXME: eval should pretty much never be used
-            (serializedLocator, version) = eval(lines[lidx])
+            (serializedLocator, version) = literal_eval(lines[lidx])
             try:
                 locator = locators[serializedLocator]
             except KeyError:
@@ -794,7 +804,7 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def openSpreadsheetAs(self):
         """ openSpreadsheetAs() -> None
         Open a saved spreadsheet and set its filename in the dialog box
-        
+
         """
         fileName = QtGui.QFileDialog.getOpenFileName(self,
                                                      'Choose a spreadsheet',
@@ -808,14 +818,14 @@ class StandardWidgetTabController(QtGui.QTabWidget):
     def cleanup(self):
         """ cleanup() -> None
         Clear reference of non-collectable objects/temp files for gc
-        
+
         """
         self.clearTabs()
 
     def setEditingMode(self, editing=True):
         """ setEditingMode(editing: bool) -> None
         Turn on/off the editing mode of the whole spreadsheet
-        
+
         """
         self.editingMode = editing
         for w in self.tabWidgets:
diff --git a/vistrails/packages/spreadsheet/spreadsheet_window.py b/vistrails/packages/spreadsheet/spreadsheet_window.py
index 51cc4c4..807434b 100644
--- a/vistrails/packages/spreadsheet/spreadsheet_window.py
+++ b/vistrails/packages/spreadsheet/spreadsheet_window.py
@@ -1,69 +1,72 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# This file implements the main spreadsheet window:
-#   SpreadsheetWindow
-################################################################################
-from PyQt4 import QtCore, QtGui
-from spreadsheet_base import StandardSheetReference
-from spreadsheet_event import BatchDisplayCellEventType, DisplayCellEventType, \
-     RepaintCurrentSheetEventType
-from spreadsheet_tabcontroller import StandardWidgetTabController
-from spreadsheet_sheet import StandardWidgetSheet
-from spreadsheet_cell import QCellContainer
-from spreadsheet_config import configuration
-from vistrails.core.modules import module_utils
-from vistrails.core.utils import trace_method
+
+"""This file implements the main spreadsheet window: SpreadsheetWindow
+"""
+
+from __future__ import division
+
 import ctypes
 import os.path
-import sys
+from PyQt4 import QtCore, QtGui
 import tempfile
 
-################################################################################
+from vistrails.core.modules import module_utils
+
+from .spreadsheet_base import StandardSheetReference
+from .spreadsheet_cell import QCellContainer
+from .spreadsheet_config import configuration
+from .spreadsheet_event import BatchDisplayCellEventType, \
+    DisplayCellEventType, RepaintCurrentSheetEventType
+from .spreadsheet_sheet import StandardWidgetSheet
+from .spreadsheet_tabcontroller import StandardWidgetTabController
+
+
 class SpreadsheetWindow(QtGui.QMainWindow):
     """
     SpreadsheetWindow is the top-level main window containing a
     stacked widget of QTabWidget and its stacked widget for slideshow
     mode
-    
+
     """
     def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
         """ SpreadsheetWindow(parent: QWidget, f: WindowFlags)
                               -> SpreadsheetWindow
         Layout menu, status bar and tab widget
-        
+
         """
         QtGui.QMainWindow.__init__(self, parent, f)
         self.createEventMap()
@@ -79,12 +82,12 @@ class SpreadsheetWindow(QtGui.QMainWindow):
         self.setCentralWidget(self.stackedCentralWidget)
         self.setStatusBar(QtGui.QStatusBar(self))
         self.modeActionGroup = QtGui.QActionGroup(self)
-        
+
         self.visApp = QtCore.QCoreApplication.instance()
         self.visApp.installEventFilter(self)
-        
+
         self.setupMenu()
-        
+
         self.connect(self.tabController,
                      QtCore.SIGNAL('needChangeTitle'),
                      self.setWindowTitle)
@@ -110,7 +113,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
            self.visApp.builderWindow.isVisible():
             self.visApp.builderWindow.quit()
 
-    
+
     def cleanup(self):
         if self.visApp!=None:
             self.visApp.removeEventFilter(self)
@@ -153,7 +156,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def fitToWindowAction(self):
         """ fitToWindowAction() -> QAction
         Return the fit to window action
-        
+
         """
         if not hasattr(self, 'fitAction'):
             self.fitAction = QtGui.QAction('Fit to window', self)
@@ -170,14 +173,14 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def fitActionToggled(self, checked):
         """ fitActionToggled(checked: boolean) -> None
         Handle fitToWindow Action toggled
-        
+
         """
         self.tabController.currentWidget().sheet.setFitToWindow(checked)
-        
+
     def fullScreenAction(self):
         """ fullScreenAction() -> QAction
         Return the fullscreen action
-        
+
         """
         if not hasattr(self, 'fullScreenActionVar'):
             self.fullScreenActionVar = QtGui.QAction('&Full Screen', self)
@@ -202,7 +205,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def fullScreenActivated(self, full=None):
         """ fullScreenActivated(full: bool) -> None
         if fullScreen has been requested has pressed, then go to fullscreen now
-        
+
         """
         if full==None:
             fs = self.isFullScreen()
@@ -219,12 +222,12 @@ class SpreadsheetWindow(QtGui.QMainWindow):
         self.tabController.setupFullScreenWidget(fs,
                                                  self.fullScreenStackedWidget)
         self.stackedCentralWidget.setCurrentIndex(int(fs))
-        
+
     def interactiveModeAction(self):
         """ interactiveModeAction() -> QAction
         Return the interactive mode action, this is the mode where users can
         interact with the content of the cells
-        
+
         """
         if not hasattr(self, 'interactiveModeActionVar'):
             self.interactiveModeActionVar = QtGui.QAction('&Interactive Mode',
@@ -241,7 +244,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
         """ editingModeAction() -> QAction
         Return the editing mode action, this is the mode where users can
         interact with the content of the cells
-        
+
         """
         if not hasattr(self, 'editingModeActionVar'):
             self.editingModeActionVar = QtGui.QAction('&Editing Mode',
@@ -258,7 +261,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
         """ showBuilderWindowAction() -> QAction
         Return the show builder action, this is used to show the builder window
         when only the spreadsheet window is visible.
-        
+
         """
         if not hasattr(self, 'showBuilderWindowActionVar'):
             self.showBuilderWindowActionVar = \
@@ -271,26 +274,26 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                 self.showBuilderWindowActionVar.setEnabled(True)
             else:
                 self.showBuilderWindowActionVar.setEnabled(False)
-                
+
             self.connect(self.showBuilderWindowActionVar,
                          QtCore.SIGNAL('triggered()'),
                          self.showBuilderWindowActionTriggered)
-            
+
         return self.showBuilderWindowActionVar
-    
+
     def modeChanged(self, action):
-        """ modeChanged(action: QAction) -> None        
+        """ modeChanged(action: QAction) -> None
         Handle the new mode (interactive or editing) based on the
         triggered action
-        
+
         """
         editing = self.editingModeAction().isChecked()
         self.tabController.setEditingMode(editing)
-    
+
     def configShow(self, show=False):
         """ configShow() -> None
         Read VisTrails setting and show the spreadsheet window accordingly
-        
+
         """
         if hasattr(self.visApp, 'configuration'):
             if self.shownConfig:
@@ -304,8 +307,8 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                 self.visApp.builderWindow.updateGeometry()
                 frame = self.visApp.builderWindow.frameGeometry()
                 rect = self.visApp.builderWindow.rect()
-                frameDiff = QtCore.QPoint((frame.width()-rect.width())/2,
-                                          (frame.height()-rect.height())/2)
+                frameDiff = QtCore.QPoint((frame.width()-rect.width())//2,
+                                          (frame.height()-rect.height())//2)
                 self.visApp.builderWindow.move(
                     frame.topLeft()+r.center()-frame.center())
                 for i in xrange(desktop.numScreens()):
@@ -314,7 +317,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                         self.adjustSize()
                         self.move(r.center()-self.rect().center()-frameDiff)
                         break
-            if not self.visApp.temp_configuration.interactiveMode:
+            if self.visApp.temp_configuration.batch:
                 self.shownConfig = True
                 if show:
                     self.show()
@@ -324,23 +327,23 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                 self.showMaximized()
                 ### When the builder is hidden, the spreadsheet window does
                 ### not have focus. We have to force it
-                if self.visApp.temp_configuration.showSpreadsheetOnly:
+                if not self.visApp.temp_configuration.showWindow:
                     self.raise_()
             else:
                 self.show()
                 ### When the builder is hidden, the spreadsheet window does
                 ### not have focus. We have to force it to have the focus
-                if self.visApp.temp_configuration.showSpreadsheetOnly:
-                    self.raise_()                
+                if not self.visApp.temp_configuration.showWindow:
+                    self.raise_()
         else:
             self.show()
-            
+
         self.shownConfig = True
 
     def showEvent(self, e):
         """ showEvent(e: QShowEvent) -> None
         Make sure we show ourself for show event
-        
+
         """
         self.show()
         # Without this Ubuntu Unity will not show the menu bar
@@ -349,7 +352,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def closeEvent(self, e):
         """ closeEvent(e: QCloseEvent) -> None
         When close, just hide instead
-        
+
         """
         if hasattr(self.visApp, 'builderWindow'):
             if self.visApp.builderWindow.isVisible():
@@ -364,14 +367,14 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def sizeHint(self):
         """ sizeHint() -> QSize
         Return a default size of the window
-        
+
         """
         return QtCore.QSize(1024, 768)
 
     def eventFilter(self,q,e):
         """ eventFilter(q: QObject, e: QEvent) -> depends on event type
         An application-wide eventfilter to capture mouse/keyboard events
-        
+
         """
         eType = e.type()
         # Handle Show/Hide cell resizer on MouseMove
@@ -386,7 +389,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
             e.buttons()&QtCore.Qt.RightButton):
             self.tabController.showPopupMenu()
             return True
-                
+
         # Handle slideshow shortcuts
         if (eType==QtCore.QEvent.KeyPress and
             self.isFullScreen()):
@@ -421,7 +424,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def event(self, e):
         """ event(e: QEvent) -> depends on event type
         Handle all special events from spreadsheet controller
-        
+
         """
         if self.eventMap.has_key(e.type()):
             self.eventMap[e.type()](e)
@@ -429,10 +432,10 @@ class SpreadsheetWindow(QtGui.QMainWindow):
         return QtGui.QMainWindow.event(self, e)
 
     def createEventMap(self):
-        """ createEventMap() -> None        
+        """ createEventMap() -> None
         Create the event map to call inside the event(). This must be
         called before anything else
-        
+
         """
         self.eventMap = {
             DisplayCellEventType : self.displayCellEvent,
@@ -443,11 +446,11 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def displayCellEvent(self, e):
         """ displayCellEvent(e: DisplayCellEvent) -> None
         Display a cell when receive this event
-        
+
         """
         if self.echoMode:
             self.echoCellEvents.append(e)
-            return None 
+            return None
         self.tabController.addPipeline(e.vistrail)
         cid = self.tabController.increasePipelineCellId(e.vistrail)
         pid = self.tabController.getCurrentPipelineId(e.vistrail)
@@ -478,7 +481,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
             else:
                 sheet.setCellByWidget(row, col, e.cellType)
             QtCore.QCoreApplication.processEvents()
-            cell = sheet.getCell(row, col) 
+            cell = sheet.getCell(row, col)
             if self.editingModeAction().isChecked():
                 sheet.setCellEditingMode(row, col, True)
             #If a cell has to dump its contents to a file, it will be in the
@@ -508,15 +511,15 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                         dump_as_pdf = False
                     elif configuration.dumpfileType == 'PDF':
                         dump_as_pdf = True
-                        
-                    #extra_info configuration overwrites global configuration    
+
+                    #extra_info configuration overwrites global configuration
                     if extra_info.has_key('pdf'):
                         dump_as_pdf = extra_info['pdf']
-                    
+
                     file_extension = '.png'
                     if dump_as_pdf == True:
                         file_extension = '.pdf'
-                            
+
                     # add cell location by default
                     if not extra_info.has_key('nameDumpCells'):
                         base_fname = base_fname + "_%d_%d" % (row, col)
@@ -531,17 +534,17 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                         cell.dumpToFile(filename)
                     else:
                         cell.saveToPDF(filename)
-            #if the cell was already selected, then we need to update 
+            #if the cell was already selected, then we need to update
             #the toolbar with this new cell
             if hasattr(sheet, 'sheet'):
                 if sheet.sheet.activeCell == (row,col):
                     sheet.sheet.setActiveCell(row,col)
-            return cell 
+            return cell
 
     def batchDisplayCellEvent(self, batchEvent):
         """ batchDisplayCellEvent(batchEvent: BatchDisplayCellEvent) -> None
         Handle event where a series of cells are arrived
-        
+
         """
         self.tabController.addPipeline(batchEvent.vistrail)
         for e in batchEvent.displayEvents:
@@ -551,7 +554,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def repaintCurrentSheetEvent(self, e):
         """ repaintCurrentSheetEvent(e: RepaintCurrentSheetEvent) -> None
         Repaint the current sheet
-        
+
         """
         currentTab = self.tabController.currentWidget()
         if currentTab:
@@ -561,7 +564,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
                     widget = currentTab.getCell(r, c)
                     if widget:
                         widget.repaint()
-    
+
     def showBuilderWindowActionTriggered(self):
         """showBuilderWindowActionTriggered() -> None
         This will show the builder window """
@@ -581,7 +584,7 @@ class SpreadsheetWindow(QtGui.QMainWindow):
     def startReviewingMode(self):
         """ startReviewingMode()
         Reorganize the spreadsheet to contain only cells executed from locator:version
-        
+
         """
         currentTab = self.tabController.currentWidget()
         if currentTab:
@@ -654,15 +657,13 @@ class SpreadsheetWindow(QtGui.QMainWindow):
         """ getEchoCellEvents() -> [DisplayCellEvent]
         Echo back the list of all cell events that have been captured
         earlier
-        
+
         """
         return self.echoCellEvents
 
     def clearEchoCellEvents(self):
         """ clearEchoCellEvents()
-        Erase the list of echoed events 
+        Erase the list of echoed events
 
         """
         self.echoCellEvents = []
-
-    
diff --git a/vistrails/packages/spreadsheet/widgets/__init__.py b/vistrails/packages/spreadsheet/widgets/__init__.py
index cdc9214..d1486d2 100644
--- a/vistrails/packages/spreadsheet/widgets/__init__.py
+++ b/vistrails/packages/spreadsheet/widgets/__init__.py
@@ -1,36 +1,39 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 # Nothing here on purpose
+from __future__ import division
+
 pass
diff --git a/vistrails/packages/spreadsheet/widgets/iebrowser/__init__.py b/vistrails/packages/spreadsheet/widgets/iebrowser/__init__.py
index dc0cdd5..20256b8 100644
--- a/vistrails/packages/spreadsheet/widgets/iebrowser/__init__.py
+++ b/vistrails/packages/spreadsheet/widgets/iebrowser/__init__.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # Internet Explorer plugin for VisTrails Spreadsheet
 ################################################################################
+from __future__ import division
+
 from iecell import IECell
 
 ################################################################################
diff --git a/vistrails/packages/spreadsheet/widgets/iebrowser/iecell.py b/vistrails/packages/spreadsheet/widgets/iebrowser/iecell.py
index 0a41462..f8e5b1b 100644
--- a/vistrails/packages/spreadsheet/widgets/iebrowser/iecell.py
+++ b/vistrails/packages/spreadsheet/widgets/iebrowser/iecell.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,10 +37,13 @@
 ############################################################################
 # web browser view implementation
 ############################################################################
-from vistrails.core.modules.vistrails_module import Module
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui, QAxContainer
 from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
-from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget
+from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, \
+    QCellToolBar
+import os
 import shutil
 ############################################################################
 
@@ -52,11 +56,11 @@ class IECell(SpreadsheetCell):
         """ compute() -> None
         Dispatch the URL to the spreadsheet
         """
-        if self.hasInputFromPort("url"):
-            urlValue = self.getInputFromPort("url")
+        if self.has_input("url"):
+            urlValue = self.get_input("url")
             fileValue = None
-        elif self.hasInputFromPort("file"):
-            fileValue = self.getInputFromPort("file")
+        elif self.has_input("file"):
+            fileValue = self.get_input("file")
             urlValue = None
         else:
             fileValue = None
@@ -68,6 +72,8 @@ class IECellWidget(QCellWidget):
     IECellWidget has a QAxContainer to display supported documents
     
     """
+    save_formats = QCellWidget.save_formats + ["HTML files (*.html)"]
+
     def __init__(self, parent=None):
         """ IECellWidget(parent: QWidget) -> IECellWidget
         Create a ActiveX Container pointing to the IE Cell
@@ -100,9 +106,12 @@ class IECellWidget(QCellWidget):
             self.browser.dynamicCall('Navigate(const QString&)', 'about:blank')
 
     def dumpToFile(self, filename):
-        if self.urlSrc is not None:
-            shutil.copyfile(str(self.urlSrc.toLocalFile()), filename)
-            
+        if os.path.splitext(filename)[1].lower() in ('.html', '.htm'):
+            if self.urlSrc is not None:
+                shutil.copyfile(str(self.urlSrc.toLocalFile()), filename)
+        else:
+            super(IECellWidget, self).dumpToFile(filename)
+
     def saveToPDF(self, filename):
         printer = QtGui.QPrinter()
         printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/__init__.py b/vistrails/packages/spreadsheet/widgets/imageviewer/__init__.py
index 38432e2..26032b0 100644
--- a/vistrails/packages/spreadsheet/widgets/imageviewer/__init__.py
+++ b/vistrails/packages/spreadsheet/widgets/imageviewer/__init__.py
@@ -1,44 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # ImageViewer plugin for VisTrails Spreadsheet
 ################################################################################
-from imageviewer import ImageViewerCell
+from __future__ import division
+
+from vistrails.core.modules.output_modules import ImageOutput
+
+from imageviewer import ImageViewerCell, ImageFileToSpreadsheet
 
 ################################################################################
 
+
 def widgetName():
     """ widgetName() -> str
     Return the name of this widget plugin
@@ -56,3 +62,5 @@ def registerWidget(reg, basicModules, basicWidgets):
     reg.add_module(ImageViewerCell)
     reg.add_input_port(ImageViewerCell, "Location", basicWidgets.CellLocation)
     reg.add_input_port(ImageViewerCell, "File", basicModules.File)    
+
+    ImageOutput.register_output_mode(ImageFileToSpreadsheet)
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/images/fittocell.png b/vistrails/packages/spreadsheet/widgets/imageviewer/images/fittocell.png
new file mode 100644
index 0000000..2abf3eb
Binary files /dev/null and b/vistrails/packages/spreadsheet/widgets/imageviewer/images/fittocell.png differ
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/images/flip.png b/vistrails/packages/spreadsheet/widgets/imageviewer/images/flip.png
new file mode 100644
index 0000000..40fec6a
Binary files /dev/null and b/vistrails/packages/spreadsheet/widgets/imageviewer/images/flip.png differ
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/images/rotate.png b/vistrails/packages/spreadsheet/widgets/imageviewer/images/rotate.png
new file mode 100644
index 0000000..ff4689b
Binary files /dev/null and b/vistrails/packages/spreadsheet/widgets/imageviewer/images/rotate.png differ
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/images/save.png b/vistrails/packages/spreadsheet/widgets/imageviewer/images/save.png
new file mode 100644
index 0000000..6190d91
Binary files /dev/null and b/vistrails/packages/spreadsheet/widgets/imageviewer/images/save.png differ
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.py b/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.py
index 7e927a1..402b53b 100644
--- a/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.py
+++ b/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.py
@@ -1,49 +1,60 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # ImageViewer widgets/toolbar implementation
 ################################################################################
+from __future__ import division
+
+import os
 from PyQt4 import QtCore, QtGui
-from vistrails.core.modules.vistrails_module import Module
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, SpreadsheetMode
 from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, QCellToolBar
 from vistrails.packages.spreadsheet.spreadsheet_controller import spreadsheetController
 import imageviewer_rc
 
 ################################################################################
 
+class ImageFileToSpreadsheet(SpreadsheetMode):
+    def compute_output(self, output_module, configuration=None):
+        fname = output_module.get_input('value').name
+        window = spreadsheetController.findSpreadsheetWindow()
+        local_file = window.file_pool.make_local_copy(fname)
+        self.display_and_wait(output_module, configuration,
+                              ImageViewerCellWidget, (local_file,))
+
 class ImageViewerCell(SpreadsheetCell):
     """
     ImageViewerCell is a custom Module to display labels, images, etc.
@@ -54,9 +65,9 @@ class ImageViewerCell(SpreadsheetCell):
         Dispatch the display event to the spreadsheet with images and labels
         
         """
-        if self.hasInputFromPort("File"):
+        if self.has_input("File"):
             window = spreadsheetController.findSpreadsheetWindow()
-            file_to_display = self.getInputFromPort("File")
+            file_to_display = self.get_input("File")
             fileValue = window.file_pool.make_local_copy(file_to_display.name)
         else:
             fileValue = None
@@ -116,7 +127,19 @@ class ImageViewerCellWidget(QCellWidget):
         if pixmap and (not pixmap.isNull()):
             return pixmap.save(filename)
         return False
-    
+
+    def dumpToFile(self, filename):
+        """ dumpToFile(filename: str) -> None
+        Dumps the cell as an image file
+
+        """
+        pixmap = self.label.pixmap()
+        if pixmap and (not pixmap.isNull()):
+            if not os.path.splitext(filename)[1]:
+                pixmap.save(filename, 'PNG')
+            else:
+                pixmap.save(filename)
+
     def saveToPDF(self, filename):
         """ saveToPDF(filename: str) -> bool
         Save the current widget contents to a pdf file
@@ -183,39 +206,6 @@ class ImageViewerFitToCellAction(QtGui.QAction):
         (sheet, row, col, cellWidget) = info
         self.setChecked(cellWidget.label.hasScaledContents())
 
-class ImageViewerSaveAction(QtGui.QAction):
-    """
-    ImageViewerSaveAction is the action to save the image to file
-    
-    """
-    def __init__(self, parent=None):
-        """ ImageViewerSaveAction(parent: QWidget) -> ImageViewerSaveAction
-        Setup the image, status tip, etc. of the action
-        
-        """
-        QtGui.QAction.__init__(self,
-                               QtGui.QIcon(":/images/save.png"),
-                               "&Save image as...",
-                               parent)
-        self.setStatusTip("Save image to file")
-        
-    def triggeredSlot(self, checked=False):
-        """ toggledSlot(checked: boolean) -> None
-        Execute the action when the button is clicked
-        
-        """
-        cellWidget = self.toolBar.getSnappedWidget()
-        if not cellWidget.label.pixmap() or cellWidget.label.pixmap().isNull():
-            return
-        fn = QtGui.QFileDialog.getSaveFileName(None, "Save image as...",
-                                               "screenshot.png",
-                                               "Images (*.png);;PDF files (*.pdf)")
-        if fn:
-            if fn.lower().endswith("png"):
-                cellWidget.label.pixmap().toImage().save(fn, "png")
-            elif fn.lower().endswith("pdf"):
-                cellWidget.saveToPDF(fn)
-        
 
 class ImageViewerZoomSlider(QtGui.QSlider):
     """
@@ -246,7 +236,7 @@ class ImageViewerZoomSlider(QtGui.QSlider):
         if self.toolBar:
             cellWidget = self.toolBar.getSnappedWidget()
             if not cellWidget.label.hasScaledContents():
-                newWidth = cellWidget.originalPix.width()*value/100
+                newWidth = cellWidget.originalPix.width()*value//100
                 pixmap = cellWidget.originalPix.scaledToWidth(newWidth)
                 cellWidget.label.setPixmap(pixmap)
 
@@ -261,7 +251,7 @@ class ImageViewerZoomSlider(QtGui.QSlider):
                 not cellWidget._playing):
                 self.setEnabled(True)
                 originalWidth = cellWidget.originalPix.width()
-                self.setValue(cellWidget.label.pixmap().width()*100/originalWidth)
+                self.setValue(cellWidget.label.pixmap().width()*100//originalWidth)
             else:
                 self.setEnabled(False)
                 self.setValue(100)
@@ -358,7 +348,6 @@ class ImageViewerToolBar(QCellToolBar):
         
         """
         self.appendAction(ImageViewerFitToCellAction(self))
-        self.appendAction(ImageViewerSaveAction(self))
         self.appendAction(ImageViewerRotateAction(self))
         self.appendAction(ImageViewerFlipAction(self))
         self.slider = ImageViewerZoomSlider(self)
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.qrc b/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.qrc
new file mode 100644
index 0000000..69e9a37
--- /dev/null
+++ b/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>images/fittocell.png</file>
+    <file>images/flip.png</file>
+    <file>images/rotate.png</file>
+    <file>images/save.png</file>
+</qresource>
+</RCC>
diff --git a/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer_rc.py b/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer_rc.py
index 9412c41..ff1bca1 100644
--- a/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer_rc.py
+++ b/vistrails/packages/spreadsheet/widgets/imageviewer/imageviewer_rc.py
@@ -1,44 +1,49 @@
+# -*- coding: utf-8 -*-
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+
 # Resource object code
 #
-# Created: Thu Sep 21 00:22:30 2006
-#      by: The Resource Compiler for PyQt (Qt v4.1.3)
+# Created: Thu Mar 20 11:57:15 2014
+#      by: The Resource Compiler for PyQt (Qt v4.8.5)
 #
 # WARNING! All changes made in this file will be lost!
 
+from __future__ import division
+
 from PyQt4 import QtCore
 
 qt_resource_data = b"\
diff --git a/vistrails/packages/spreadsheet/widgets/richtext/__init__.py b/vistrails/packages/spreadsheet/widgets/richtext/__init__.py
index 564257c..987d097 100644
--- a/vistrails/packages/spreadsheet/widgets/richtext/__init__.py
+++ b/vistrails/packages/spreadsheet/widgets/richtext/__init__.py
@@ -1,41 +1,46 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # RichText plugin for VisTrails Spreadsheet
 ################################################################################
-from richtext import RichTextCell, XSLCell
+from __future__ import division
+
+from vistrails.core.modules.output_modules import RichTextOutput
+
+from richtext import RichTextCell, XSLCell, RichTextToSpreadsheet
 
 ################################################################################
 
@@ -46,7 +51,7 @@ def widgetName():
     """
     return 'HTML Viewer'
 
-def registerWidget(reg, basicModules, basicWidgets):    
+def registerWidget(reg, basicModules, basicWidgets):
     """ registerWidget(reg: module_registry,
                        basicModules: python package,
                        basicWidgets: python package) -> None
@@ -64,3 +69,5 @@ def registerWidget(reg, basicModules, basicWidgets):
     reg.add_input_port(XSLCell, "Location", basicWidgets.CellLocation)
     reg.add_input_port(XSLCell, "XML", basicModules.File)
     reg.add_input_port(XSLCell, "XSL", basicModules.File)
+
+    RichTextOutput.register_output_mode(RichTextToSpreadsheet)
diff --git a/vistrails/packages/spreadsheet/widgets/richtext/richtext.py b/vistrails/packages/spreadsheet/widgets/richtext/richtext.py
index b26b7b5..3e3fe24 100644
--- a/vistrails/packages/spreadsheet/widgets/richtext/richtext.py
+++ b/vistrails/packages/spreadsheet/widgets/richtext/richtext.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # Richtext widgets implementation
 ################################################################################
+from __future__ import division
+
 import os
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtCore import QUrl
@@ -42,10 +45,22 @@ from PyQt4.QtXmlPatterns import QXmlQuery
 
 from vistrails.core.bundles.pyimport import py_import
 from vistrails.core.modules.vistrails_module import ModuleError
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, \
+    SpreadsheetMode
 from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget
 ################################################################################
 
+
+class RichTextToSpreadsheet(SpreadsheetMode):
+    def compute_output(self, output_module, configuration=None):
+        filename = output_module.get_input('value').name
+
+        with open(filename, 'rb') as fp:
+            html = fp.read()
+
+        self.display_and_wait(output_module, configuration,
+                              RichTextCellWidget, (html,))
+
 class RichTextCell(SpreadsheetCell):
     """
     RichTextCell is a custom Module to view HTML files
@@ -55,9 +70,9 @@ class RichTextCell(SpreadsheetCell):
         """ compute() -> None
         Dispatch the HTML contents to the spreadsheet
         """
-        filename = self.getInputFromPort("File").name
+        filename = self.get_input("File").name
 
-        text_format = self.getInputFromPort("Format")
+        text_format = self.get_input("Format")
         with open(filename, 'rb') as fp:
             if text_format == 'html':
                 html = fp.read() # reads bytes
@@ -77,7 +92,6 @@ class RichTextCell(SpreadsheetCell):
 
         self.displayAndWait(RichTextCellWidget, (html,))
 
-
 class XSLCell(SpreadsheetCell):
     """
     XSLCell is a custom Module to render an XML file via an XSL stylesheet
@@ -87,8 +101,8 @@ class XSLCell(SpreadsheetCell):
         """ compute() -> None
         Render the XML tree and display it on the spreadsheet
         """
-        xml = self.getInputFromPort('XML').name
-        xsl = self.getInputFromPort('XSL').name
+        xml = self.get_input('XML').name
+        xsl = self.get_input('XSL').name
 
         query = QXmlQuery(QXmlQuery.XSLT20)
         query.setFocus(QUrl.fromLocalFile(os.path.join(os.getcwd(), xml)))
@@ -99,12 +113,13 @@ class XSLCell(SpreadsheetCell):
 
         self.displayAndWait(RichTextCellWidget, (html,))
 
-
 class RichTextCellWidget(QCellWidget):
     """
     RichTextCellWidget has a QTextBrowser to display HTML files
 
     """
+    save_formats = QCellWidget.save_formats + ["HTML files (*.html)"]
+
     def __init__(self, parent=None):
         """ RichTextCellWidget(parent: QWidget) -> RichTextCellWidget
         Create a rich text cell without a toolbar
@@ -133,21 +148,21 @@ class RichTextCellWidget(QCellWidget):
 
     def dumpToFile(self, filename):
         """ dumpToFile(filename) -> None
-        It will generate a screenshot of the cell contents and dump to filename.
-        It will also create a copy of the original text file used with
-        filename's basename and the original extension.
+        It will generate a screenshot of the cell contents, or a copy of the
+        original document, depending on the given filename.
         """
         if self.html is not None:
-            basename, ext = os.path.splitext(filename)
-            with open(basename + '.html', 'wb') as fp:
-                if isinstance(self.html, bytes):
-                    fp.write(self.html)
-                else:
-                    codec = QtCore.QTextCodec.codecForHtml(
-                            self.html.encode('utf-8'),
-                            QtCore.QTextCodec.codecForName('UTF-8'))
-                    fp.write(codec.fromUnicode(self.html))
-        QCellWidget.dumpToFile(self,filename)
+            if os.path.splitext(filename)[1].lower() in ('.html', '.html'):
+                with open(filename, 'wb') as fp:
+                    if isinstance(self.html, bytes):
+                        fp.write(self.html)
+                    else:
+                        codec = QtCore.QTextCodec.codecForHtml(
+                                self.html.encode('utf-8'),
+                                QtCore.QTextCodec.codecForName('UTF-8'))
+                        fp.write(codec.fromUnicode(self.html))
+            else:
+                super(RichTextCellWidget, self).dumpToFile(filename)
 
     def saveToPDF(self, filename):
         printer = QtGui.QPrinter()
diff --git a/vistrails/packages/spreadsheet/widgets/svg/__init__.py b/vistrails/packages/spreadsheet/widgets/svg/__init__.py
index 203aebf..f9fb2d3 100644
--- a/vistrails/packages/spreadsheet/widgets/svg/__init__.py
+++ b/vistrails/packages/spreadsheet/widgets/svg/__init__.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # SVG plugin for VisTrails Spreadsheet
 ################################################################################
+from __future__ import division
+
 from svg import SVGCell, SVGSplitter
 
 ################################################################################
diff --git a/vistrails/packages/spreadsheet/widgets/svg/svg.py b/vistrails/packages/spreadsheet/widgets/svg/svg.py
index e231f42..b6267b4 100644
--- a/vistrails/packages/spreadsheet/widgets/svg/svg.py
+++ b/vistrails/packages/spreadsheet/widgets/svg/svg.py
@@ -1,41 +1,44 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # SVG widgets implementation
 ################################################################################
-from vistrails.core.modules.basic_modules import File
+from __future__ import division
+
+from vistrails.core.modules.basic_modules import PathObject
 from vistrails.core.modules.vistrails_module import Module
 from PyQt4 import QtCore, QtGui, QtSvg
 from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
@@ -44,6 +47,7 @@ from vistrails.packages.spreadsheet.spreadsheet_controller import spreadsheetCon
 from vistrails.packages.spreadsheet.spreadsheet_event import (DisplayCellEvent,
                                                     BatchDisplayCellEvent)
 from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, QCellToolBar
+import os
 import shutil
 ################################################################################
 
@@ -56,9 +60,9 @@ class SVGCell(SpreadsheetCell):
         """ compute() -> None
         Dispatch SVG file into the spreadshet for display
         """
-        if self.hasInputFromPort("File"):
+        if self.has_input("File"):
             window = spreadsheetController.findSpreadsheetWindow()
-            file_to_display = self.getInputFromPort("File")
+            file_to_display = self.get_input("File")
             fileValue = window.file_pool.make_local_copy(file_to_display.name)
         else:
             fileValue = None
@@ -71,6 +75,9 @@ class SVGCellWidget(QCellWidget):
     received SVG file from the SVGCell
     
     """
+    save_formats = (QCellWidget.save_formats +
+                    ["Scalable Vector Graphics (*.svg)"])
+
     def __init__(self, parent=None):
         """ SVGCellWidget(parent: QWidget) -> SVGCellWidget
         Create a SVGCellWidget without any toolbar
@@ -92,10 +99,14 @@ class SVGCellWidget(QCellWidget):
         (fileValue,) = inputPorts
         self.svgWidget.load(fileValue.name)
         self.fileSrc = fileValue.name
-        
+
     def dumpToFile(self, filename):
-        if self.fileSrc is not None:
-            shutil.copyfile(self.fileSrc, filename)
+        ext = os.path.splitext(filename)[1].lower()
+        if ext == '.svg':
+            if self.fileSrc is not None:
+                shutil.copyfile(self.fileSrc, filename)
+        else:
+            super(SVGCellWidget, self).dumpToFile(filename)
 
     def saveToPDF(self, filename):
         printer = QtGui.QPrinter()
@@ -120,8 +131,8 @@ class SVGSplitter(Module):
         Use BatchDisplayCellEvent to display a serie of SVG files
         
         """
-        if self.hasInputFromPort("File"):
-            fileValue = self.getInputFromPort("File")
+        if self.has_input("File"):
+            fileValue = self.get_input("File")
         else:
             fileValue = None
         if fileValue:
@@ -137,58 +148,12 @@ class SVGSplitter(Module):
                 if len(comps)==2:
                     e = DisplayCellEvent()        
                     e.sheetReference = StandardSingleCellSheetReference()
-                    e.sheetReference.sheetName = comps[1]                    
+                    e.sheetReference.sheetName = comps[1]
                     e.cellType = SVGCellWidget
-                    F = File()
-                    from os.path import abspath, basename, dirname
-                    F.name = (dirname(abspath(fileValue.name))+
-                              '/'+basename(comps[0]))
+                    from os.path import abspath, basename, dirname, join
+                    F = PathObject(join(dirname(abspath(fileValue.name)),
+                                        basename(comps[0])))
                     e.inputPorts = (F,)
                     batchDisplayEvent.displayEvents.append(e)
             f.close()
             spreadsheetController.postEventToSpreadsheet(batchDisplayEvent)
-                    
-class SVGSaveAction(QtGui.QAction):
-    """
-    ImageViewerSaveAction is the action to save the image to file
-    
-    """
-    def __init__(self, parent=None):
-        """ ImageViewerSaveAction(parent: QWidget) -> ImageViewerSaveAction
-        Setup the image, status tip, etc. of the action
-        
-        """
-        QtGui.QAction.__init__(self,
-                               QtGui.QIcon(":/images/save.png"),
-                               "&Save svg as...",
-                               parent)
-        self.setStatusTip("Save svg to file")
-        
-    def triggeredSlot(self, checked=False):
-        """ toggledSlot(checked: boolean) -> None
-        Execute the action when the button is clicked
-        
-        """
-        cellWidget = self.toolBar.getSnappedWidget()
-        
-        fn = QtGui.QFileDialog.getSaveFileName(None, "Save svg as...",
-                                               "screenshot.png",
-                                               "SVG (*.svg);;PDF files (*.pdf)")
-        if fn:
-            if fn.lower().endswith("svg"):
-                cellWidget.dumpToFile(fn)
-            elif fn.lower().endswith("pdf"):
-                cellWidget.saveToPDF(fn)
-        
-class SVGToolBar(QCellToolBar):
-    """
-    ImageViewerToolBar derives from CellToolBar to give the ImageViewerCellWidget
-    a customizable toolbar
-    
-    """
-    def createToolBar(self):
-        """ createToolBar() -> None
-        This will get call initiallly to add customizable widgets
-        
-        """
-        self.appendAction(SVGSaveAction(self))
diff --git a/vistrails/packages/spreadsheet/widgets/webview/__init__.py b/vistrails/packages/spreadsheet/widgets/webview/__init__.py
index 58d4880..8a3830d 100644
--- a/vistrails/packages/spreadsheet/widgets/webview/__init__.py
+++ b/vistrails/packages/spreadsheet/widgets/webview/__init__.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 ################################################################################
 # WebView plugin for VisTrails Spreadsheet
 ################################################################################
+from __future__ import division
+
 from webview import WebViewCell
 
 ################################################################################
diff --git a/vistrails/packages/spreadsheet/widgets/webview/webview.py b/vistrails/packages/spreadsheet/widgets/webview/webview.py
index da77d24..5ac61e0 100644
--- a/vistrails/packages/spreadsheet/widgets/webview/webview.py
+++ b/vistrails/packages/spreadsheet/widgets/webview/webview.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -36,10 +37,13 @@
 ############################################################################
 # web browser view implementation
 ############################################################################
-from vistrails.core.modules.vistrails_module import Module
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui, QtWebKit
 from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
-from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget
+from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, \
+    QCellToolBar
+import os
 import shutil
 ############################################################################
 
@@ -52,11 +56,11 @@ class WebViewCell(SpreadsheetCell):
         """ compute() -> None
         Dispatch the URL to the spreadsheet
         """
-        if self.hasInputFromPort("url"):
-            urlValue = self.getInputFromPort("url")
+        if self.has_input("url"):
+            urlValue = self.get_input("url")
             fileValue = None
-        elif self.hasInputFromPort("file"):
-            fileValue = self.getInputFromPort("file")
+        elif self.has_input("file"):
+            fileValue = self.get_input("file")
             urlValue = None
         else:
             fileValue = None
@@ -68,6 +72,8 @@ class WebViewCellWidget(QCellWidget):
     WebViewCellWidget has a QTextBrowser to display HTML files
     
     """
+    save_formats = QCellWidget.save_formats + ["HTML files (*.html)"]
+
     def __init__(self, parent=None):
         """ WebViewCellWidget(parent: QWidget) -> WebViewCellWidget
         Create a rich text cell without a toolbar
@@ -75,11 +81,12 @@ class WebViewCellWidget(QCellWidget):
         """
         QCellWidget.__init__(self, parent)
         self.setLayout(QtGui.QVBoxLayout(self))
+        QtWebKit.QWebSettings.globalSettings().setAttribute(
+            QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
         self.browser = QtWebKit.QWebView()
         self.layout().addWidget(self.browser)
         self.browser.setMouseTracking(True)
         self.urlSrc = None
-        # self.browser.controlBarType = None
 
     def updateContents(self, inputPorts):
         """ updateContents(inputPorts: tuple) -> None
@@ -100,11 +107,14 @@ class WebViewCellWidget(QCellWidget):
             self.browser.setHtml("No HTML file is specified!")
 
     def dumpToFile(self, filename):
-        if self.urlSrc is not None:
-            shutil.copyfile(str(self.urlSrc.toLocalFile()), filename)
-            
+        if os.path.splitext(filename)[1].lower() in ('.html', '.htm'):
+            with open(filename, 'wb') as fp:
+                fp.write(self.browser.page().mainFrame().toHtml())
+        else:
+            super(WebViewCellWidget, self).dumpToFile(filename)
+
     def saveToPDF(self, filename):
         printer = QtGui.QPrinter()
         printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
         printer.setOutputFileName(filename)
-        self.browser.print_(printer)
\ No newline at end of file
+        self.browser.print_(printer)
diff --git a/vistrails/packages/sql/__init__.py b/vistrails/packages/sql/__init__.py
index ae81603..e1e8e14 100644
--- a/vistrails/packages/sql/__init__.py
+++ b/vistrails/packages/sql/__init__.py
@@ -1,47 +1,58 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """
-SQL Scripting package. It supports MySQL and PostgreSQL.
-
-Preliminary work at adding DBConnection and SQLSource modules.
-Interfaces may change so don't write any critical code using this
-package!
+SQL Scripting package.
 
+Uses SQLAlchemy to access a variety of database software.
 """
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.sql'
 name = 'SQL'
-version = '0.0.4'
+version = '0.1.0'
 old_identifiers = ['edu.utah.sci.vistrails.sql']
+
+def package_dependencies():
+    return ['org.vistrails.vistrails.tabledata']
+
+def package_requirements():
+    from vistrails.core.requirements import require_python_module
+    require_python_module('sqlalchemy', {
+            'pip': 'SQLAlchemy',
+            'linux-debian': 'python-sqlalchemy',
+            'linux-ubuntu': 'python-sqlalchemy',
+            'linux-fedora': 'python-sqlalchemy'})
diff --git a/vistrails/packages/sql/init.py b/vistrails/packages/sql/init.py
index e6420bc..a0c309f 100644
--- a/vistrails/packages/sql/init.py
+++ b/vistrails/packages/sql/init.py
@@ -1,225 +1,335 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-from vistrails.core.bundles import py_import
-from PyQt4 import QtCore, QtGui
+
+from __future__ import division
+
+from sqlalchemy.engine import create_engine
+from sqlalchemy.engine.url import URL
+from sqlalchemy.exc import SQLAlchemyError
 import urllib
 
+from vistrails.core.db.action import create_action
+from vistrails.core.bundles.installbundle import install
 from vistrails.core import debug
-from vistrails.core.modules.vistrails_module import Module, ModuleError, NotCacheable
-from vistrails.gui.modules.source_configure import SourceConfigurationWidget
+from vistrails.core.modules.config import ModuleSettings
+from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.modules.vistrails_module import Module, ModuleError
 from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
-from vistrails.core.utils import PortAlreadyExists
-from vistrails.gui.theme import CurrentTheme
-
-MySQLdb = py_import('MySQLdb', {
-        'pip': 'mysql-python',
-        'linux-debian': 'python-mysqldb',
-        'linux-ubuntu': 'python-mysqldb',
-        'linux-fedora': 'MySQL-python'})
-
-psycopg2 = py_import('psycopg2', {
-        'pip': 'psycopg2',
-        'linux-debian':'python-psycopg2',
-        'linux-ubuntu':'python-psycopg2',
-        'linux-fedora':'python-psycopg2'})
-
-
-class QPasswordEntry(QtGui.QDialog):
-    def __init__(self, parent=None):
-        QtGui.QWidget.__init__(self, parent)
-        self.setModal(True)
-        self.setWindowTitle("Enter Password:")
-        self.setLayout(QtGui.QVBoxLayout())
-        hbox = QtGui.QHBoxLayout()
-        hbox.addWidget(QtGui.QLabel("Password:"))
-        self.line_edit = QtGui.QLineEdit()
-        self.line_edit.setEchoMode(QtGui.QLineEdit.Password)
-        hbox.addWidget(self.line_edit)
-        self.layout().addLayout(hbox)
-
-        bbox = QtGui.QHBoxLayout()
-        cancel = QtGui.QPushButton("Cancel")
-        ok = QtGui.QPushButton("OK")
-        ok.setDefault(True)
-        bbox.addWidget(cancel, 1, QtCore.Qt.AlignRight)
-        bbox.addWidget(ok, 0, QtCore.Qt.AlignRight)
-        self.layout().addLayout(bbox)
-        self.connect(ok, QtCore.SIGNAL("clicked(bool)"), self.accept)
-        self.connect(cancel, QtCore.SIGNAL("clicked(bool)"), self.reject)
-
-    def get_password(self):
-        return str(self.line_edit.text())
+from vistrails.core.utils import versions_increasing
+
+from vistrails.packages.tabledata.common import TableObject
+
 
 class DBConnection(Module):
-    def __init__(self):
-         Module.__init__(self)
-         self.conn = None
-         self.protocol = 'mysql'
-    
-    def get_db_lib(self):
-        if self.protocol == 'mysql':
-            return MySQLdb
-        elif self.protocol == 'postgresql':
-            return psycopg2
-        else:
-            raise ModuleError(self, "Currently no support for '%s'" % protocol)
-        
-    def ping(self):
-        """ping() -> boolean 
-        It will ping the database to check if the connection is alive.
-        It returns True if it is, False otherwise. 
-        This can be used for preventing the "MySQL Server has gone away" error. 
-        """
-        result = False
-        if self.conn:
-            try:
-                self.conn.ping()
-                result = True
-            except self.get_db_lib().OperationalError, e:
-                result = False
-            except AttributeError, e:
-                #psycopg2 connections don't have a ping method
-                try:
-                    if self.conn.status == 1:
-                        result = True
-                except Exception, e:
-                    result = False
-        return result
-    
-    def open(self):        
-        retry = True
-        while retry:
-            config = {'host': self.host,
-                      'port': self.port,
-                      'user': self.user}
-            
-            # unfortunately keywords are not standard across libraries
-            if self.protocol == 'mysql':    
-                config['db'] = self.db_name
-                if self.password is not None:
-                    config['passwd'] = self.password
-            elif self.protocol == 'postgresql':
-                config['database'] = self.db_name
-                if self.password is not None:
-                    config['password'] = self.password
-            try:
-                self.conn = self.get_db_lib().connect(**config)
-                break
-            except self.get_db_lib().Error, e:
-                debug.warning(str(e))
-                if (e[0] == 1045 or self.get_db_lib().OperationalError 
-                    and self.password is None):
-                    passwd_dlg = QPasswordEntry()
-                    if passwd_dlg.exec_():
-                        self.password = passwd_dlg.get_password()
-                    else:
-                        retry = False
-                else:
-                    raise ModuleError(self, str(e))
-             
+    """Connects to a database.
+
+    If the URI you enter uses a driver which is not currently installed,
+    VisTrails will try to set it up.
+    """
+    _input_ports = [('protocol', '(basic:String)'),
+                    ('user', '(basic:String)',
+                     {'optional': True}),
+                    ('password', '(basic:String)',
+                     {'optional': True}),
+                    ('host', '(basic:String)',
+                     {'optional': True}),
+                    ('port', '(basic:Integer)',
+                     {'optional': True}),
+                    ('db_name', '(basic:String)')]
+    _output_ports = [('connection', '(DBConnection)')]
+
     def compute(self):
-        self.checkInputPort('db_name')
-        self.host = self.forceGetInputFromPort('host', 'localhost')
-        self.port = self.forceGetInputFromPort('port', 3306)
-        self.user = self.forceGetInputFromPort('user', None)
-        self.db_name = self.getInputFromPort('db_name')
-        self.protocol = self.forceGetInputFromPort('protocol', 'mysql')
-        if self.hasInputFromPort('password'):
-            self.password = self.getInputFromPort('password')
-        else:
-            self.password = None
-
-        self.open()
-
-    # nice to have enumeration constant type
-    _input_ports = [('host', '(basic:String)'),
-                    ('port', '(basic:Integer)'),
-                    ('user', '(basic:String)'),
-                    ('db_name', '(basic:String)'),
-                    ('protocol', '(basic:String)')]
-    _output_ports = [('self', '(DBConnection)')]
+        url = URL(drivername=self.get_input('protocol'),
+                  username=self.force_get_input('user', None),
+                  password=self.force_get_input('password', None),
+                  host=self.force_get_input('host', None),
+                  port=self.force_get_input('port', None),
+                  database=self.get_input('db_name'))
+
+        try:
+            engine = create_engine(url)
+        except ImportError, e:
+            driver = url.drivername
+            installed = False
+            if driver == 'sqlite':
+                raise ModuleError(self,
+                                  "Python was built without sqlite3 support")
+            elif (driver == 'mysql' or
+                    driver == 'drizzle'): # drizzle is a variant of MySQL
+                installed = install({
+                        'pip': 'mysql-python',
+                        'linux-debian': 'python-mysqldb',
+                        'linux-ubuntu': 'python-mysqldb',
+                        'linux-fedora': 'MySQL-python'})
+            elif (driver == 'postgresql' or
+                    driver == 'postgre'):   # deprecated alias
+                installed = install({
+                        'pip': 'psycopg2',
+                        'linux-debian':'python-psycopg2',
+                        'linux-ubuntu':'python-psycopg2',
+                        'linux-fedora':'python-psycopg2'})
+            elif driver == 'firebird':
+                installed = install({
+                        'pip': 'fdb',
+                        'linux-fedora':'python-fdb'})
+            elif driver == 'mssql' or driver == 'sybase':
+                installed = install({
+                        'pip': 'pyodbc',
+                        'linux-debian':'python-pyodbc',
+                        'linux-ubuntu':'python-pyodbc',
+                        'linux-fedora':'pyodbc'})
+            elif driver == 'oracle':
+                installed = install({
+                        'pip': 'cx_Oracle'})
+            else:
+                raise ModuleError(self,
+                                  "SQLAlchemy couldn't connect: %s" %
+                                  debug.format_exception(e))
+            if not installed:
+                raise ModuleError(self,
+                                  "Failed to install required driver")
+            try:
+                engine = create_engine(url)
+            except Exception, e:
+                raise ModuleError(self,
+                                  "Couldn't connect to the database: %s" %
+                                  debug.format_exception(e))
+        except SQLAlchemyError:
+            # This is NoSuchModuleError in newer versions of SQLAlchemy but we
+            # want compatibility here
+            raise ModuleError(
+                    self,
+                    "SQLAlchemy has no support for protocol %r -- are you "
+                    "sure you spelled that correctly?" % url.drivername)
+
+        self.set_output('connection', engine.connect())
+
 
 class SQLSource(Module):
-    def __init__(self):
-        Module.__init__(self)
-        self.is_cacheable = self.cachedOff
-        
-    def compute(self):
-        cached = False
-        if self.hasInputFromPort('cacheResults'):
-            cached = self.getInputFromPort('cacheResults')
-        self.checkInputPort('connection')
-        connection = self.getInputFromPort('connection')
-        inputs = [self.getInputFromPort(k) for k in self.inputPorts
-                  if k != 'source' and k != 'connection' and k!= 'cacheResults']
-        #print 'inputs:', inputs
-        s = urllib.unquote(str(self.forceGetInputFromPort('source', '')))
-        if not connection.ping():
-            connection.open()
-        cur = connection.conn.cursor()
-        cur.execute(s, inputs)
-    
-        if cached:
-            self.is_cacheable = self.cachedOn
-        else:
-            self.is_cacheable = self.cachedOff
-            
-        self.setResult('resultSet', cur.fetchall())
-
-    def cachedOn(self):
-        return True
-    
-    def cachedOff(self):
-        return False
-    
+    _settings = ModuleSettings(configure_widget=
+            'vistrails.packages.sql.widgets:SQLSourceConfigurationWidget')
     _input_ports = [('connection', '(DBConnection)'),
-                    ('cacheResults', '(basic:Boolean)'),    
+                    ('cacheResults', '(basic:Boolean)'),
                     ('source', '(basic:String)')]
-    _output_ports = \
-        [('resultSet', '(basic:List)')]
+    _output_ports = [('result', '(org.vistrails.vistrails.tabledata:Table)'),
+                     ('resultSet', '(basic:List)')]
+
+    def is_cacheable(self):
+        return False
+
+    def compute(self):
+        cached = False
+        if self.has_input('cacheResults'):
+            cached = self.get_input('cacheResults')
+            self.is_cacheable = lambda: cached
+        connection = self.get_input('connection')
+        inputs = dict((k, self.get_input(k)) for k in self.inputPorts.iterkeys()
+                  if k not in ('source', 'connection', 'cacheResults'))
+        s = urllib.unquote(str(self.get_input('source')))
+
+        try:
+            transaction = connection.begin()
+            results = connection.execute(s, inputs)
+            try:
+                rows = results.fetchall()
+            except Exception:
+                self.set_output('result', None)
+                self.set_output('resultSet', None)
+            else:
+                # results.returns_rows is True
+                # We don't use 'if return_rows' because this attribute didn't
+                # use to exist
+                table = TableObject.from_dicts(rows, results.keys())
+                self.set_output('result', table)
+                self.set_output('resultSet', rows)
+            transaction.commit()
+        except SQLAlchemyError, e:
+            raise ModuleError(self, debug.format_exception(e))
+
+
+_modules = [DBConnection, SQLSource]
 
-class SQLSourceConfigurationWidget(SourceConfigurationWidget):
-    def __init__(self, module, controller, parent=None):
-        SourceConfigurationWidget.__init__(self, module, controller, None,
-                                           True, False, parent)
-        
-_modules = [DBConnection,
-            (SQLSource, {'configureWidgetType': SQLSourceConfigurationWidget})]
 
 def handle_module_upgrade_request(controller, module_id, pipeline):
-    module_remap = {'SQLSource': [(None, '0.0.3', None, {})]}
+    # Before 0.0.3, SQLSource's resultSet output was type ListOfElements (which
+    #   doesn't exist anymore)
+    # In 0.0.3, SQLSource's resultSet output was type List
+    # In 0.1.0, SQLSource's output was renamed to result and is now a Table;
+    #   this is totally incompatible and no upgrade code is possible
+    #   the resultSet is kept for now for compatibility
+
+    # Up to 0.0.4, DBConnection would ask for a password if one was necessary;
+    #   this behavior has not been kept. There is now a password input port, to
+    #   which you can connect a PasswordDialog from package dialogs if needed
+
+    old_module = pipeline.modules[module_id]
+    # DBConnection module from before 0.1.0: automatically add the password
+    # prompt module
+    if (old_module.name == 'DBConnection' and
+            versions_increasing(old_module.version, '0.1.0')):
+        reg = get_module_registry()
+        # Creates the new module
+        new_module = controller.create_module_from_descriptor(
+                reg.get_descriptor(DBConnection))
+        # Create the password module
+        mod_desc = reg.get_descriptor_by_name(
+                'org.vistrails.vistrails.dialogs', 'PasswordDialog')
+        mod = controller.create_module_from_descriptor(mod_desc)
+        # Adds a 'label' function to the password module
+        ops = [('add', mod)]
+        ops.extend(controller.update_function_ops(mod,
+                                                  'label', ['Server password']))
+        # Connects the password module to the new module
+        conn = controller.create_connection(mod, 'result',
+                                            new_module, 'password')
+        ops.append(('add', conn))
+        # Replaces the old module with the new one
+        upgrade_actions = UpgradeWorkflowHandler.replace_generic(
+                controller, pipeline,
+                old_module, new_module,
+                src_port_remap={'self': 'connection'})
+        password_fix_action = create_action(ops)
+        return upgrade_actions + [password_fix_action]
+
+    return UpgradeWorkflowHandler.attempt_automatic_upgrade(
+            controller, pipeline,
+            module_id)
+
+
+###############################################################################
+
+import unittest
 
-    return UpgradeWorkflowHandler.remap_module(controller, module_id, pipeline,
-                                               module_remap)
+
+class TestSQL(unittest.TestCase):
+    def test_query_sqlite3(self):
+        """Queries a SQLite3 database.
+        """
+        import os
+        import sqlite3
+        import tempfile
+        import urllib2
+        from vistrails.tests.utils import execute, intercept_results
+        identifier = 'org.vistrails.vistrails.sql'
+
+        test_db_fd, test_db = tempfile.mkstemp(suffix='.sqlite3')
+        os.close(test_db_fd)
+        try:
+            conn = sqlite3.connect(test_db)
+            cur = conn.cursor()
+            cur.execute('''
+                    CREATE TABLE test(name VARCHAR(24) PRIMARY KEY,
+                                      lastname VARCHAR(32) NOT NULL,
+                                      age INTEGER NOT NULL)
+                    ''')
+            cur.executemany('''
+                    INSERT INTO test(name, lastname, age)
+                    VALUES(:name, :lastname, :age)
+                    ''',
+                    [{'name': 'John', 'lastname': 'Smith', 'age': 25},
+                     {'name': 'Lara', 'lastname': 'Croft', 'age': 21}])
+            conn.commit()
+            conn.close()
+
+            source = ('''
+                    INSERT INTO test(name, lastname, age)
+                    VALUES(:name, :lastname, :age)
+                    ''')
+
+            with intercept_results(DBConnection, 'connection', SQLSource, 'result') as (connection, table):
+                self.assertFalse(execute([
+                        ('DBConnection', identifier, [
+                            ('protocol', [('String', 'sqlite')]),
+                            ('db_name', [('String', test_db)]),
+                        ]),
+                        ('SQLSource', identifier, [
+                            ('source', [('String', urllib2.quote(source))]),
+                            ('name', [('String', 'Michael')]),
+                            ('lastname', [('String', 'Buck')]),
+                            ('age', [('Integer', '78')]),
+                        ]),
+                    ],
+                    [
+                        (0, 'connection', 1, 'connection'),
+                    ],
+                    add_port_specs=[
+                        (1, 'input', 'name',
+                         'org.vistrails.vistrails.basic:String'),
+                        (1, 'input', 'lastname',
+                         'org.vistrails.vistrails.basic:String'),
+                        (1, 'input', 'age',
+                         'org.vistrails.vistrails.basic:Integer'),
+                    ]))
+
+            self.assertEqual(len(connection), 1)
+            connection[0].close()
+            self.assertEqual(len(table), 1)
+            self.assertIsNone(table[0])
+
+            source = "SELECT name, lastname, age FROM test WHERE age > :age"
+
+            with intercept_results(DBConnection, 'connection', SQLSource, 'result') as (connection, table):
+                self.assertFalse(execute([
+                        ('DBConnection', identifier, [
+                            ('protocol', [('String', 'sqlite')]),
+                            ('db_name', [('String', test_db)]),
+                        ]),
+                        ('SQLSource', identifier, [
+                            ('source', [('String', urllib2.quote(source))]),
+                            ('age', [('Integer', '22')]),
+                        ]),
+                    ],
+                    [
+                        (0, 'connection', 1, 'connection'),
+                    ],
+                    add_port_specs=[
+                        (1, 'input', 'age',
+                         'org.vistrails.vistrails.basic:Integer'),
+                    ]))
+
+            self.assertEqual(len(connection), 1)
+            connection[0].close()
+            self.assertEqual(len(table), 1)
+            table, = table
+            self.assertEqual(table.names, ['name', 'lastname', 'age'])
+            self.assertEqual((table.rows, table.columns), (2, 3))
+            self.assertEqual(set(table.get_column(1)),
+                             set(['Smith', 'Buck']))
+        finally:
+            try:
+                os.remove(test_db)
+            except OSError:
+                pass # Oops, we are leaking the file here...
diff --git a/vistrails/packages/sql/widgets.py b/vistrails/packages/sql/widgets.py
new file mode 100644
index 0000000..23f6eac
--- /dev/null
+++ b/vistrails/packages/sql/widgets.py
@@ -0,0 +1,51 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.gui.modules.source_configure import SourceConfigurationWidget
+
+
+class SQLSourceConfigurationWidget(SourceConfigurationWidget):
+    def __init__(self, module, controller, parent=None):
+        SourceConfigurationWidget.__init__(
+                self,
+                module,
+                controller,
+                None,       # editor_class
+                True,       # has_inputs
+                False,      # has_outputs
+                parent)
diff --git a/vistrails/packages/tabledata/__init__.py b/vistrails/packages/tabledata/__init__.py
index 6b7d29f..2e00d63 100644
--- a/vistrails/packages/tabledata/__init__.py
+++ b/vistrails/packages/tabledata/__init__.py
@@ -6,24 +6,37 @@ extraction and conversion routines.
 
 """
 
+# ChangeLog:
+# 2014-05-29 -- 0.1.5
+#   * Updates JSON readers
+# 2014-02-03 -- 0.1.4
+#   * Merges some tabdata functionality (improve CSV)
+# 2014-01-14 -- 0.1.3
+#   * Adds writer modules
+# 2013-12-09 -- 0.1.2
+#   * No longer use 'self' ports to output tables
+# 2013-10-04 -- 0.1.1
+#   * Moves reading modules out of specific namespaces
+#     (read|csv|CSVFile -> read|CSVFile)
+# 2013-05-16 -- 0.1.0
+#   * Package created (for DAT project)
+
+from __future__ import division
+
 from vistrails.core.packagemanager import get_package_manager
 
-from identifiers import *
+from .identifiers import *
 
 
 def package_dependencies():
     pm = get_package_manager()
-    if pm.has_package('org.vistrails.vistrails.spreadsheet'):
-        return ['org.vistrails.vistrails.spreadsheet']
-    else:
+    spreadsheet_identifier = 'org.vistrails.vistrails.spreadsheet'
+    if pm.has_package(spreadsheet_identifier):
+        return [spreadsheet_identifier]
+    else: # pragma: no cover
         return []
 
 
 def package_requirements():
     from vistrails.core.requirements import require_python_module
-    require_python_module('numpy', {
-            'pip': 'numpy',
-            'linux-debian': 'python-numpy',
-            'linux-ubuntu': 'python-numpy',
-            'linux-fedora': 'numpy'})
     require_python_module('csv')
diff --git a/vistrails/packages/tabledata/common.py b/vistrails/packages/tabledata/common.py
index 0f5be29..2195796 100644
--- a/vistrails/packages/tabledata/common.py
+++ b/vistrails/packages/tabledata/common.py
@@ -1,17 +1,181 @@
-from vistrails.core.modules.vistrails_module import Module, ModuleError
+from __future__ import division
+
+try:
+    import numpy
+except ImportError: # pragma: no cover
+    numpy = None
+
+from vistrails.core.modules.basic_modules import List, ListType
+from vistrails.core.modules.config import ModuleSettings
+from vistrails.core.modules.output_modules import OutputModule, FileMode, \
+    IPythonMode
+from vistrails.core.modules.vistrails_module import Module, ModuleError, \
+    Converter
+
+
+class InternalModuleError(Exception):
+    """Track ModuleError in subclasses."""
+
+    def raise_module_error(self, module_obj):
+        raise ModuleError(module_obj, self.message)
+
+
+class TableObject(object):
+    columns = None # the number of columns in the table
+    rows = None # the number of rows in the table
+    names = None # the names of the columns
+    name = None # a name for the table (useful for joins, etc.)
+
+    def __init__(self, columns, nb_rows, names):
+        self.columns = len(columns)
+        self.rows = nb_rows
+        self.names = names
+
+        self._columns = columns
+
+    def get_column(self, i, numeric=False): # pragma: no cover
+        """Gets a column from the table as a list or numpy array.
+
+        If numeric=False (the default), the data is returned 'as-is'. It might
+        either be bytes (=str), unicode or number (int, long, float).
+
+        If numeric=True, the data is returned as a numpy array if numpy is
+        available, or as a list of floats.
+        """
+        if numeric and numpy is not None:
+            return numpy.array(self._columns[i], dtype=numpy.float32)
+        else:
+            return self._columns[i]
+
+    def get_column_by_name(self, name, numeric=False):
+        """Gets a column from its name.
+
+        This convenience methods looks up the right column index if names are
+        available and calls get_column().
+
+        You shouldn't need to override this method, get_column() should be
+        sufficient.
+        """
+        try:
+            col = self.names.index(name)
+        except ValueError:
+            raise KeyError(name)
+        else:
+            return self.get_column(col, numeric)
+
+    @classmethod
+    def from_dicts(cls, dicts, keys=None):
+        iterator = iter(dicts)
+        try:
+            first = next(iterator)
+        except StopIteration:
+            if keys is None:
+                raise ValueError("No entry in sequence")
+            return cls([[]] * len(keys), 0, list(keys))
+        if keys is None:
+            keys = first.keys()
+        columns = [[first[key]] for key in keys]
+        count = 1
+        for dct in iterator:
+            for i, key in enumerate(keys):
+                try:
+                    v = dct[key]
+                except KeyError:
+                    raise ValueError("Entry %d has no key %r" % (count, key))
+                else:
+                    columns[i].append(v)
+            count += 1
+        return cls(columns, count, keys)
 
 
 class Table(Module):
-    columns = None
-    rows = None
+    _input_ports = [('name', '(org.vistrails.vistrails.basic:String)')]
+    _output_ports = [('value', 'Table')]
+
+    def set_output(self, port_name, value):
+        if self.list_depth == 0 and value is not None and port_name == 'value':
+            if value.name is None:
+                value.name = self.force_get_input('name', None)
+        Module.set_output(self, port_name, value)
+
+
+def choose_column(nb_columns, column_names=None, name=None, index=None):
+    """Selects a column in a table either by name or index.
+
+    If both are specified, the function will make sure that they represent the
+    same column.
+    """
+    if name is not None:
+        if isinstance(name, unicode):
+            name = name.encode('utf-8')
+        if column_names is None:
+            raise ValueError("Unable to get column by name: table doesn't "
+                             "have column names")
+        try:
+            name_index = column_names.index(name)
+        except ValueError:
+            try:
+                name_index = column_names.index(name.strip())
+            except ValueError:
+                raise ValueError("Column name was not found: %r" % name)
+        if index is not None:
+            if name_index != index:
+                raise ValueError("Both a column name and index were "
+                                 "specified, and they don't agree")
+        return name_index
+    elif index is not None:
+        if index < 0 or index >= nb_columns:
+            raise ValueError("No column %d, table only has %d columns" % (
+                             index, nb_columns))
+        return index
+    else:
+        raise ValueError("No column name nor index specified")
+
 
-    names = None
+def choose_columns(nb_columns, column_names=None, names=None, indexes=None):
+    """Selects a list of columns from a table.
 
-    def get_column(self, i):
-        raise NotImplementedError
+    If both the names and indexes lists are specified, the function will make
+    sure that they represent the same list of columns.
+    Columns may appear more than once.
+    """
+    if names is not None:
+        if column_names is None:
+            raise ValueError("Unable to get column by names: table "
+                             "doesn't have column names")
+        result = []
+        for name in names:
+            if isinstance(name, unicode):
+                name = name.encode('utf-8')
+            try:
+                idx = column_names.index(name)
+            except ValueError:
+                try:
+                    idx = column_names.index(name.strip())
+                except ValueError:
+                    raise ValueError("Column name was not found: %r" % name)
+            result.append(idx)
+        if indexes is not None:
+            if result != indexes:
+                raise ValueError("Both column names and indexes were "
+                                 "specified, and they don't agree")
+        return result
+    elif indexes is not None:
+        for index in indexes:
+            if index < 0 or index >= nb_columns:
+                raise ValueError("No column %d, table only has %d columns" % (
+                                 index, nb_columns))
+        return indexes
+    else:
+        raise ValueError("No column names nor indexes specified")
 
 
 class ExtractColumn(Module):
+    """Gets a single column from a table, as a list.
+
+    Specifying one of 'column_name' or 'column_index' is sufficient; if you
+    provide both, the module will check that the column has the expected name.
+    """
     _input_ports = [
             ('table', Table),
             ('column_name', '(org.vistrails.vistrails.basic:String)',
@@ -24,41 +188,174 @@ class ExtractColumn(Module):
             ('value', '(org.vistrails.vistrails.basic:List)')]
 
     def compute(self):
-        table = self.getInputFromPort('table')
-        if self.hasInputFromPort('column_index'):
-            column_index = self.getInputFromPort('column_index')
-        if self.hasInputFromPort('column_name'):
-            name = self.getInputFromPort('column_name')
-            if isinstance(name, unicode):
-                name = name.encode('utf-8')
-            if table.names is None:
-                raise ModuleError("Unable to get column by names: table "
-                                  "doesn't have column names")
-            try:
-                index = table.names.index(name)
-            except ValueError:
-                try:
-                    name = name.strip()
-                    index = table.column_names.index(name)
-                except:
-                    raise ModuleError(self, "Column name was not found")
-            if self.hasInputFromPort('column_index'):
-                if column_index != index:
-                    raise ModuleError(self,
-                                      "Both column_name and column_index were "
-                                      "specified, and they don't agree")
-        elif self.hasInputFromPort('column_index'):
-            index = column_index
+        table = self.get_input('table')
+        try:
+            column_idx = choose_column(
+                    table.columns,
+                    column_names=table.names,
+                    name=self.force_get_input('column_name', None),
+                    index=self.force_get_input('column_index', None))
+
+            self.set_output('value', table.get_column(
+                    column_idx,
+                    self.get_input('numeric', allow_default=True)))
+        except ValueError, e:
+            raise ModuleError(self, e.message)
+
+
+class BuildTable(Module):
+    """Builds a table by putting together columns from multiple sources.
+
+    Input can be a mix of lists, which will be used as single columns, and
+    whole tables, whose column names will be mangled.
+    """
+    _settings = ModuleSettings(configure_widget=
+            'vistrails.packages.tabledata.widgets:BuildTableWidget')
+    _output_ports = [('value', Table)]
+
+    def __init__(self):
+        Module.__init__(self)
+        self.input_ports_order = []
+
+    def transfer_attrs(self, module):
+        Module.transfer_attrs(self, module)
+        self.input_ports_order = [p.name for p in module.input_port_specs]
+
+    def compute(self):
+        items = None
+        if self.input_ports_order: # pragma: no branch
+            items = [(p, self.get_input(p))
+                     for p in self.input_ports_order]
+        if not items:
+            raise ModuleError(self, "No inputs were provided")
+
+        nb_rows = None
+        cols = []
+        names = []
+        for portname, item in items:
+            if isinstance(item, TableObject):
+                if nb_rows is not None:
+                    if item.rows != nb_rows:
+                        raise ModuleError(
+                                self,
+                                "Different row counts: %d != %d" % (
+                                item.rows, nb_rows))
+                else:
+                    nb_rows = item.rows
+                cols.extend(item.get_column(c)
+                            for c in xrange(item.columns))
+                if item.names is not None:
+                    names.extend(item.names)
+                else:
+                    names.extend("%s col %d" % (portname, i)
+                                 for i in xrange(len(cols) - len(names)))
+            else:
+                if nb_rows is not None:
+                    if len(item) != nb_rows:
+                        raise ModuleError(
+                                self,
+                                "Different row counts: %d != %d" % (
+                                len(item), nb_rows))
+                else:
+                    nb_rows = len(item)
+                cols.append(item)
+                names.append(portname)
+
+        self.set_output('value', TableObject(cols, nb_rows, names))
+
+
+class SingleColumnTable(Converter):
+    """Automatic Converter module from List to Table.
+    """
+    _input_ports = [('in_value', List)]
+    _output_ports = [('out_value', Table)]
+
+    def compute(self):
+        column = self.get_input('in_value')
+        if not isinstance(column, ListType):
+            column = list(column)
+        self.set_output('out_value', TableObject(
+                [column],               # columns
+                len(column),            # nb_rows
+                ['converted_list']))    # names
+
+
+class HtmlRendererMixin(object):
+    @staticmethod
+    def make_html(table):
+        document = ['<!DOCTYPE html>\n'
+                    '<html>\n  <head>\n'
+                    '    <meta http-equiv="Content-type" content="text/html; '
+                            'charset=utf-8" />\n'
+                    '    <title>Exported table</title>\n'
+                    '    <style type="text/css">\n'
+                    'table { border-collapse: collapse; }\n'
+                    'td, th { border: 1px solid black; }\n'
+                    '    </style>\n'
+                    '  </head>\n  <body>\n    <table>\n']
+        if table.names is not None:
+            names = table.names
+        else:
+            names = ['col %d' % n for n in xrange(table.columns)]
+        document.append('<tr>\n')
+        document.extend('  <th>%s</th>\n' % name for name in names)
+        document.append('</tr>\n')
+        columns = [table.get_column(col) for col in xrange(table.columns)]
+        for row in xrange(table.rows):
+            document.append('<tr>\n')
+            for col in xrange(table.columns):
+                elem = columns[col][row]
+                if isinstance(elem, bytes):
+                    elem = elem.decode('utf-8', 'replace')
+                elif not isinstance(elem, unicode):
+                    elem = unicode(elem)
+                document.append('  <td>%s</td>\n' % elem)
+            document.append('</tr>\n')
+        document.append('    </table>\n  </body>\n</html>\n')
+
+        return ''.join(document)
+
+
+class TableToFileMode(FileMode, HtmlRendererMixin):
+    formats = ['html', 'csv']
+
+    def write_html(self, table, configuration):
+        filename = self.get_filename(configuration, suffix='.html')
+        with open(filename, 'wb') as fp:
+            fp.write(self.make_html(table))
+
+    def write_csv(self, table, configuration):
+        from .write.write_csv import WriteCSV
+
+        filename = self.get_filename(configuration, suffix='.csv')
+        WriteCSV.write(filename, table)
+
+    def compute_output(self, output_module, configuration=None):
+        value = output_module.get_input("value")
+        format = configuration.get('format', 'html').lower()
+        try:
+            func = getattr(self, 'write_%s' % format)
+        except AttributeError:
+            raise AttributeError("TableToFileMode: unknown format %s" % format)
         else:
-            raise ModuleError(self,
-                              "You must set one of column_name or "
-                              "column_index")
+            func(value, configuration)
+
+
+class TableToIPythonMode(IPythonMode, HtmlRendererMixin):
+    def compute_output(self, output_module, configuration=None):
+        from IPython.core.display import display, HTML
+
+        table = output_module.get_input('value')
+        html = self.make_html(table)
+        display(HTML(data=html))
 
-        result = table.get_column(
-                index,
-                numeric=self.getInputFromPort('numeric', allowDefault=True))
 
-        self.setResult('value', result)
+class TableOutput(OutputModule):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules.output_configuration:OutputModuleConfigurationWidget")
+    _input_ports = [('value', 'Table')]
+    _output_modes = [TableToFileMode, TableToIPythonMode]
 
 
-_modules = [(Table, {'abstract': True}), ExtractColumn]
+_modules = [(Table, {'abstract': True}), ExtractColumn, BuildTable,
+            (SingleColumnTable, {'hide_descriptor': True}),
+            TableOutput]
diff --git a/vistrails/packages/tabledata/convert/__init__.py b/vistrails/packages/tabledata/convert/__init__.py
index d369879..2cfce3d 100644
--- a/vistrails/packages/tabledata/convert/__init__.py
+++ b/vistrails/packages/tabledata/convert/__init__.py
@@ -1,3 +1,40 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from vistrails.core.modules.utils import make_modules_dict
 
 from convert_dates import _modules as dates_modules
diff --git a/vistrails/packages/tabledata/convert/convert_dates.py b/vistrails/packages/tabledata/convert/convert_dates.py
index 25161ae..0e8af62 100644
--- a/vistrails/packages/tabledata/convert/convert_dates.py
+++ b/vistrails/packages/tabledata/convert/convert_dates.py
@@ -1,3 +1,40 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import datetime
 from distutils.version import LooseVersion
 import re
@@ -6,6 +43,10 @@ import warnings
 
 from vistrails.core.modules.vistrails_module import Module, ModuleError
 from vistrails.core.bundles import py_import
+from vistrails.core.utils import VistrailsWarning
+
+
+PYTZ_MIN_VER = LooseVersion('2012')
 
 
 class UTC(datetime.tzinfo):
@@ -99,17 +140,17 @@ def make_timezone(s):
                 'linux-debian': 'python-tz',
                 'linux-ubuntu': 'python-tz',
                 'linux-fedora': 'pytz'})
-    except ImportError:
+    except ImportError: # pragma: no cover
         raise ValueError("can't understand timezone %r (maybe you should "
                          "install pytz?)" % s)
     else:
         ver = LooseVersion(pytz.__version__)
-        if ver < LooseVersion('2012'):
+        if ver < PYTZ_MIN_VER: # pragma: no cover
             warnings.warn(
                     "You are using an old version of pytz (%s). You might "
                     "run into some issues with daylight saving handling." %
                     pytz.__version__,
-                    category=UserWarning)
+                    category=VistrailsWarning)
         try:
             return pytz.timezone(s)
         except KeyError:
@@ -136,10 +177,10 @@ class TimestampsToDates(Module):
         return [datetime.datetime.fromtimestamp(t, utc) for t in timestamps]
 
     def compute(self):
-        timestamps = self.getInputFromPort('timestamps')
+        timestamps = self.get_input('timestamps')
 
         result = self.convert(timestamps)
-        self.setResult('dates', result)
+        self.set_output('dates', result)
 
 
 class StringsToDates(Module):
@@ -185,7 +226,7 @@ class StringsToDates(Module):
                     'linux-debian': 'python-dateutil',
                     'linux-ubuntu': 'python-dateutil',
                     'linux-fedora': 'python-dateutil'})
-            except ImportError:
+            except ImportError: # pragma: no cover
                 raise ValueError("can't read dates without a format without "
                                  "the dateutil package")
             from dateutil import parser
@@ -223,16 +264,16 @@ class StringsToDates(Module):
         return result
 
     def compute(self):
-        tz = self.getInputFromPort('timezone')
+        tz = self.get_input('timezone')
 
-        strings = self.getInputFromPort('strings')
-        fmt = self.getInputFromPort('format')
+        strings = self.get_input('strings')
+        fmt = self.get_input('format')
 
         try:
             result = self.convert(strings, fmt, tz)
         except ValueError, e:
             raise ModuleError(self, e.message)
-        self.setResult('dates', result)
+        self.set_output('dates', result)
 
 
 class DatesToMatplotlib(Module):
@@ -254,12 +295,12 @@ class DatesToMatplotlib(Module):
                     'linux-debian': 'python-matplotlib',
                     'linux-ubuntu': 'python-matplotlib',
                     'linux-fedora': 'python-matplotlib'})
-        except ImportError:
+        except ImportError: # pragma: no cover
             raise ModuleError(self, "matplotlib is not available")
 
-        datetimes = self.getInputFromPort('datetimes')
+        datetimes = self.get_input('datetimes')
         result = self.convert(datetimes)
-        self.setResult('dates', result)
+        self.set_output('dates', result)
 
 
 class TimestampsToMatplotlib(Module):
@@ -284,12 +325,12 @@ class TimestampsToMatplotlib(Module):
                     'linux-debian': 'python-matplotlib',
                     'linux-ubuntu': 'python-matplotlib',
                     'linux-fedora': 'python-matplotlib'})
-        except ImportError:
+        except ImportError: # pragma: no cover
             raise ModuleError(self, "matplotlib is not available")
 
-        timestamps = self.getInputFromPort('timestamps')
+        timestamps = self.get_input('timestamps')
         result = self.convert(timestamps)
-        self.setResult('dates', result)
+        self.set_output('dates', result)
 
 
 class StringsToMatplotlib(Module):
@@ -318,19 +359,19 @@ class StringsToMatplotlib(Module):
                     'linux-debian': 'python-matplotlib',
                     'linux-ubuntu': 'python-matplotlib',
                     'linux-fedora': 'python-matplotlib'})
-        except ImportError:
+        except ImportError: # pragma: no cover
             raise ModuleError(self, "matplotlib is not available")
 
-        tz = self.getInputFromPort('timezone')
+        tz = self.get_input('timezone')
 
-        strings = self.getInputFromPort('strings')
-        fmt = self.getInputFromPort('format')
+        strings = self.get_input('strings')
+        fmt = self.get_input('format')
 
         try:
             result = self.convert(strings, fmt, tz)
         except ValueError, e:
             raise ModuleError(self, e.message)
-        self.setResult('dates', result)
+        self.set_output('dates', result)
 
 
 _modules = {'dates': [
@@ -367,7 +408,7 @@ class TestTimestampToDates(unittest.TestCase):
                  '2013-01-02 19:05:00 UTC +0000'])
         try:
             import pytz
-        except ImportError:
+        except ImportError: # pragma: no cover
             pass
         else:
             self.assertEqual(
@@ -408,7 +449,7 @@ class TestStringsToDates(unittest.TestCase):
         """
         try:
             import dateutil
-        except ImportError:
+        except ImportError: # pragma: no cover
             self.skipTest("dateutil is not available")
 
         dates = ['2013-05-20 9:25',
@@ -457,9 +498,9 @@ class TestStringsToDates(unittest.TestCase):
         """
         try:
             import pytz
-        except ImportError:
+        except ImportError: # pragma: no cover
             self.skipTest("pytz is not available")
-        if LooseVersion(pytz.__version__) < LooseVersion('2012'):
+        if LooseVersion(pytz.__version__) < PYTZ_MIN_VER: # pragma: no cover
             self.skipTest("pytz version is known to cause issues (%s)" %
                           pytz.__version__)
 
@@ -492,7 +533,7 @@ class TestDatesToMatplotlib(unittest.TestCase):
         """
         try:
             import matplotlib
-        except ImportError:
+        except ImportError: # pragma: no cover
             self.skipTest("matplotlib is not available")
 
         from matplotlib.dates import date2num
@@ -535,7 +576,7 @@ class TestTimestampsToMatplotlib(unittest.TestCase):
         """
         try:
             import matplotlib
-        except ImportError:
+        except ImportError: # pragma: no cover
             self.skipTest("matplotlib is not available")
 
         from matplotlib.dates import date2num
@@ -559,7 +600,7 @@ class TestStringsToMatplotlib(unittest.TestCase):
         """
         try:
             import matplotlib
-        except ImportError:
+        except ImportError: # pragma: no cover
             self.skipTest("matplotlib is not available")
 
         from matplotlib.dates import date2num
diff --git a/vistrails/packages/tabledata/identifiers.py b/vistrails/packages/tabledata/identifiers.py
index 81fb4b9..edda4d5 100644
--- a/vistrails/packages/tabledata/identifiers.py
+++ b/vistrails/packages/tabledata/identifiers.py
@@ -1,3 +1,5 @@
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.tabledata'
 name = 'tabledata'
-version = '0.1.0'
+version = '0.1.6'
diff --git a/vistrails/packages/tabledata/init.py b/vistrails/packages/tabledata/init.py
index cf1df2d..4c8ab1b 100644
--- a/vistrails/packages/tabledata/init.py
+++ b/vistrails/packages/tabledata/init.py
@@ -1,17 +1,100 @@
+from __future__ import division
+
+from vistrails.core.bundles.pyimport import py_import
 from vistrails.core.modules.utils import make_modules_dict
 from vistrails.core.packagemanager import get_package_manager
+from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
+
+try:
+    py_import('numpy', {
+            'pip': 'numpy',
+            'linux-debian': 'python-numpy',
+            'linux-ubuntu': 'python-numpy',
+            'linux-fedora': 'numpy'})
+except ImportError: # pragma: no cover
+    pass
 
-from .common import _modules as common_modules
+from .common import _modules as common_modules, TableOutput
 from .convert import _modules as convert_modules
+from .operations import _modules as operation_modules
 from .read import _modules as read_modules
+from .write import _modules as write_modules
 
 
 _modules = [common_modules,
             convert_modules,
-            read_modules]
+            operation_modules,
+            read_modules,
+            write_modules]
 
-if get_package_manager().has_package('org.vistrails.vistrails.spreadsheet'):
-    from .viewer import _modules as viewer_modules
+if get_package_manager().has_package( # pragma: no branch
+        'org.vistrails.vistrails.spreadsheet'):
+    from .viewer import _modules as viewer_modules, TableToSpreadsheetMode
     _modules.append(viewer_modules)
+    TableOutput.register_output_mode(TableToSpreadsheetMode)
 
 _modules = make_modules_dict(*_modules)
+
+
+def handle_module_upgrade_request(controller, module_id, pipeline):
+    def add_keyname(fname, module):
+        new_function = controller.create_function(module,
+                                                  "key_name",
+                                                  ["_key"])
+        return [('add', new_function, 'module', module.id)]
+
+    module_remap = {
+            'read|csv|CSVFile': [
+                (None, '0.1.1', 'read|CSVFile', {
+                    'src_port_remap': {
+                        'self': 'value'},
+                })
+            ],
+            'read|numpy|NumPyArray': [
+                (None, '0.1.1', 'read|NumPyArray', {
+                    'src_port_remap': {
+                        'self': 'value'},
+                })
+            ],
+            'read|CSVFile': [
+                ('0.1.1', '0.1.2', None, {
+                    'src_port_remap': {
+                        'self': 'value'},
+                }),
+                ('0.1.3', '0.1.5', None, {})
+            ],
+            'read|NumPyArray': [
+                ('0.1.1', '0.1.2', None, {
+                    'src_port_remap': {
+                        'self': 'value'},
+                })
+            ],
+            'read|ExcelSpreadsheet': [
+                ('0.1.1', '0.1.2', None, {
+                    'src_port_remap': {
+                        'self': 'value'},
+                }),
+                ('0.1.3', '0.1.4', None, {})
+            ],
+            'read|JSONFile': [
+                (None, '0.1.5', 'read|JSONObject', {
+                    'function_remap': {
+                        None: add_keyname},
+                })
+            ],
+        }
+
+    try:
+        from vistrails.packages.spreadsheet.init import upgrade_cell_to_output
+    except ImportError:
+        pass
+    else:
+        module_remap = upgrade_cell_to_output(
+                module_remap, module_id, pipeline,
+                'TableCell', 'TableOutput',
+                '0.1.6', 'table')
+
+    return UpgradeWorkflowHandler.remap_module(controller,
+                                               module_id,
+                                               pipeline,
+                                               module_remap)
diff --git a/vistrails/packages/tabledata/operations.py b/vistrails/packages/tabledata/operations.py
new file mode 100644
index 0000000..77b338c
--- /dev/null
+++ b/vistrails/packages/tabledata/operations.py
@@ -0,0 +1,699 @@
+from __future__ import division
+
+try:
+    import numpy
+except ImportError: # pragma: no cover
+    numpy = None
+import re
+
+from vistrails.core.modules.vistrails_module import ModuleError
+
+from .common import TableObject, Table, choose_column, choose_columns
+
+# FIXME use pandas?
+
+
+def utf8(obj):
+    if isinstance(obj, bytes):
+        return obj
+    elif isinstance(obj, unicode):
+        return obj.encode('utf-8')
+    else:
+        return bytes(obj)
+
+
+class JoinedTables(TableObject):
+    def __init__(self, left_t, right_t, left_key_col, right_key_col,
+                 case_sensitive=False, always_prefix=False):
+        self.left_t = left_t
+        self.right_t = right_t
+        self.left_key_col = left_key_col
+        self.right_key_col = right_key_col
+        self.case_sensitive = case_sensitive
+        self.always_prefix = always_prefix
+
+        self.build_column_names()
+        self.compute_row_map()
+        self.column_cache = {}
+        self.rows = len(self.row_map)
+
+    def build_column_names(self):
+        left_name = self.left_t.name
+        if left_name is None:
+            left_name = "left"
+        right_name = self.right_t.name
+        if right_name is None:
+            right_name = "right"
+
+        def get_col_names(table, other, prefix):
+            names = []
+            for i in xrange(table.columns):
+                should_prefix = self.always_prefix
+                if table.names is not None:
+                    n = table.names[i]
+                else:
+                    n = "col %d" % i
+                    should_prefix = True
+                if not should_prefix and other.names is not None:
+                    if n in other.names:
+                        should_prefix = True
+                names.append("%s%s" % (prefix + "." if should_prefix else "",
+                                       n))
+            return names
+
+        self.names = (get_col_names(self.left_t, self.right_t, left_name) +
+                      get_col_names(self.right_t, self.left_t, right_name))
+        self.columns = len(self.names)
+
+    def get_column(self, index, numeric=False):
+        if (index, numeric) in self.column_cache:
+            return self.column_cache[(index, numeric)]
+
+        result = []
+        if index < self.left_t.columns:
+            column = self.left_t.get_column(index, numeric)
+            for i in xrange(self.left_t.rows):
+                if i in self.row_map:
+                    result.append(column[i])
+        else:
+            column = self.right_t.get_column(index - self.left_t.columns,
+                                             numeric)
+            for i in xrange(self.left_t.rows):
+                if i in self.row_map:
+                    j = self.row_map[i]
+                    result.append(column[j])
+
+        if numeric and numpy is not None:
+            result = numpy.array(result, dtype=numpy.float32)
+        self.column_cache[(index, numeric)] = result
+        return result
+
+    def compute_row_map(self):
+        def build_key_dict(table, key_col):
+            column = table.get_column(key_col)
+            if self.case_sensitive:
+                key_dict = dict((utf8(val).strip(), i)
+                                for i, val in enumerate(column))
+            else:
+                key_dict = dict((utf8(val).strip().upper(), i)
+                                for i, val in enumerate(column))
+            return key_dict
+
+        right_keys = build_key_dict(self.right_t, self.right_key_col)
+
+        self.row_map = {}
+        for left_row_idx, key in enumerate(
+                self.left_t.get_column(self.left_key_col)):
+            key = utf8(key).strip()
+            if not self.case_sensitive:
+                key = key.upper()
+            if key in right_keys:
+                self.row_map[left_row_idx] = right_keys[key]
+
+
+class JoinTables(Table):
+    """Joins data from two tables using equality of a pair of columns.
+
+    This creates a table by combining the fields from the two tables. It will
+    match the values in the two selected columns (one from each table). If a
+    row from one of the table has a value for the selected field that doesn't
+    exist in the other table, that row will not appear in the result
+    (INNER JOIN semantics).
+    """
+    _input_ports = [('left_table', 'Table'),
+                    ('right_table', 'Table'),
+                    ('left_column_idx', 'basic:Integer'),
+                    ('left_column_name', 'basic:String'),
+                    ('right_column_idx', 'basic:Integer'),
+                    ('right_column_name', 'basic:String'),
+                    ('case_sensitive', 'basic:Boolean',
+                     {"optional": True, "defaults": str(["False"])}),
+                    ('always_prefix', 'basic:Boolean',
+                     {"optional": True, "defaults": str(["False"])})]
+    _output_ports = [('value', Table)]
+
+    def compute(self):
+        left_t = self.get_input('left_table')
+        right_t = self.get_input('right_table')
+        case_sensitive = self.get_input('case_sensitive')
+        always_prefix = self.get_input('always_prefix')
+
+        def get_column_idx(table, prefix):
+            col_name_port = "%s_column_name" % prefix
+            col_idx_port = '%s_column_idx' % prefix
+            try:
+                col_idx = choose_column(
+                        table.columns,
+                        column_names=table.names,
+                        name=self.force_get_input(col_name_port, None),
+                        index=self.force_get_input(col_idx_port, None))
+            except ValueError, e:
+                raise ModuleError(self, e.message)
+
+            return col_idx
+
+        left_key_col = get_column_idx(left_t, "left")
+        right_key_col = get_column_idx(right_t, "right")
+
+        table = JoinedTables(left_t, right_t, left_key_col, right_key_col,
+                             case_sensitive, always_prefix)
+        self.set_output('value', table)
+
+
+class ProjectedTable(TableObject):
+    def __init__(self, table, col_idxs, col_names):
+        self.table = table
+        self.col_map = dict(enumerate(col_idxs))
+        self.columns = len(self.col_map)
+        self.names = col_names
+
+    def get_column(self, index, numeric=False):
+        mapped_idx = self.col_map[index]
+        return self.table.get_column(mapped_idx, numeric)
+
+    @property
+    def rows(self):
+        return self.table.rows
+
+
+class ProjectTable(Table):
+    """Build a table from the columns of another table.
+
+    This allows you to restrict, reorder or rename the columns of a table. You
+    can also duplicate columns by mentioning them several times.
+    """
+    _input_ports = [("table", "Table"),
+                    ("column_names", "basic:List"),
+                    ("column_indexes", "basic:List"),
+                    ("new_column_names", "basic:List",
+                     {"optional": True})]
+    _output_ports = [("value", Table)]
+
+    def compute(self):
+        table = self.get_input("table")
+        try:
+            indexes = choose_columns(
+                    table.columns,
+                    column_names=table.names,
+                    names=self.force_get_input('column_names', None),
+                    indexes=self.force_get_input('column_indexes', None))
+        except ValueError, e:
+            raise ModuleError(self, e.message)
+        if self.has_input('new_column_names'):
+            column_names = self.get_input('new_column_names')
+            if len(column_names) != len(indexes):
+                raise ModuleError(self,
+                                  "new_column_names was specified but doesn't "
+                                  "have the right number of names")
+        else:
+            column_names = []
+            names = {}
+            for i in indexes:
+                name = table.names[i]
+                if name in names:
+                    nb = names[name]
+                    names[name] += 1
+                    name = '%s_%d' % (name, nb)
+                else:
+                    names[name] = 1
+                column_names.append(name)
+
+        projected_table = ProjectedTable(table, indexes, column_names)
+        self.set_output("value", projected_table)
+
+
+class SelectFromTable(Table):
+    """Builds a table from the rows of another table.
+
+    This allows you to filter the records in a table according to a condition
+    on a specific field.
+    """
+    _input_ports = [('table', 'Table'),
+                    ('str_expr', 'basic:String,basic:String,basic:String',
+                     {'entry_types': "['default','enum','default']",
+                      'values': "[[], ['==', '!=', '=~'], []]"}),
+                    ('float_expr', 'basic:String,basic:String,basic:Float',
+                     {'entry_types': "['default','enum','default']",
+                      'values': "[[], ['==', '!=', '<', '>', '<=', '>='], []]"})]
+    _output_ports = [('value', Table)]
+
+    @staticmethod
+    def make_condition(comparand, comparer):
+        if isinstance(comparand, float):
+            with_cast = lambda f: lambda v: f(float(v))
+        else:
+            with_cast = lambda f: f
+        if comparer == '==':
+            return with_cast(lambda v: v == comparand)
+        elif comparer == '!=':
+            return with_cast(lambda v: v != comparand)
+        elif comparer == '<':
+            return with_cast(lambda v: v < comparand)
+        elif comparer == '>':
+            return with_cast(lambda v: v > comparand)
+        elif comparer == '<=':
+            return with_cast(lambda v: v <= comparand)
+        elif comparer == '>=':
+            return with_cast(lambda v: v >= comparand)
+        elif comparer == '=~':
+            regex = re.compile(comparand)
+            return regex.search
+        else:
+            raise ValueError("Invalid comparison operator %r" % comparer)
+
+    def compute(self):
+        table = self.get_input('table')
+
+        if self.has_input('str_expr'):
+            (col, comparer, comparand) = self.get_input('str_expr')
+        elif self.has_input('float_expr'):
+            (col, comparer, comparand) = self.get_input('float_expr')
+        else:
+            raise ModuleError(self, "Must have some expression")
+
+        try:
+            idx = int(col)
+        except ValueError:
+            try:
+                idx = table.names.index(col)
+            except ValueError:
+                raise ModuleError(self, "No column %r" % col)
+        else:
+            if idx < 0 or idx >= table.columns:
+                raise ModuleError(self,
+                                  "No column %d, table only has %d columns" % (
+                                  idx, table.columns))
+
+        condition = self.make_condition(comparand, comparer)
+        numeric = isinstance(comparand, float)
+        column = table.get_column(idx, numeric)
+        matched_rows = [i
+                        for i, col_val in enumerate(column)
+                        if condition(col_val)]
+        columns = []
+        for col in xrange(table.columns):
+            column = table.get_column(col)
+            columns.append([column[row] for row in matched_rows])
+        selected_table = TableObject(columns, len(matched_rows), table.names)
+        self.set_output('value', selected_table)
+
+
+class AggregatedTable(TableObject):
+    def __init__(self, table, op, col, group_col):
+        self.table = table
+        self.op = op
+        self.col = col
+        self.group_col = group_col
+
+        self.build_map()
+
+    def build_map(self):
+        agg_map = {}
+        for i, val in enumerate(self.table.get_column(self.group_col)):
+            if val in agg_map:
+                agg_map[val].append(i)
+            else:
+                agg_map[val] = [i]
+        self.agg_rows = [(min(rows), rows) for rows in agg_map.itervalues()]
+        self.agg_rows.sort()
+        self.rows = len(self.agg_rows)
+        self.columns = 2
+        if self.table.names is not None:
+            self.names = [self.table.names[self.group_col],
+                          self.table.names[self.col]]
+
+    def get_column(self, index, numeric=False):
+        def average(value_iter):
+            # value_iter can only be used once
+            sum = 0
+            count = 0
+            for count, v in enumerate(value_iter):
+                sum += v
+            return sum / (count+1)
+        op_map = {'sum': sum,
+                  'average': average,
+                  'min': min,
+                  'max': max}
+        if index == 0:
+            col = self.table.get_column(self.group_col, numeric)
+            return [col[x[0]] for x in self.agg_rows]
+        else:
+            if self.op == 'count':
+                return [len(x[1]) for x in self.agg_rows]
+            elif self.op in op_map:
+                col = self.table.get_column(self.col, True)
+                return [op_map[self.op](col[idx] for idx in x[1])
+                        for x in self.agg_rows]
+            else:
+                raise ValueError('Unknown operation: "%s"' % self.op)
+
+
+class AggregateColumn(Table):
+    _input_ports = [('table', 'Table'),
+                    ('op', 'basic:String',
+                     {'entry_types': "['enum']",
+                      'values': "[['sum', 'count', 'average', 'min', 'max']]"}),
+                    ('column_name', 'basic:String'),
+                    ('column_index', 'basic:Integer'),
+                    ('group_by_name', 'basic:String'),
+                    ('group_by_index', 'basic:Integer')]
+    _output_ports = [('value', 'Table')]
+
+    def compute(self):
+        table = self.get_input('table')
+        op = self.get_input('op')
+        column_name = self.force_get_input('column_name', None)
+        column_index = self.force_get_input('column_index', None)
+        col_idx = choose_column(table.columns,
+                                column_names=table.names,
+                                name=column_name,
+                                index=column_index)
+        group_by_name = self.force_get_input('group_by_name', None)
+        group_by_index = self.force_get_input('group_by_index', None)
+        gb_idx = choose_column(table.columns,
+                               column_names=table.names,
+                               name=group_by_name,
+                               index=group_by_index)
+
+        res_table = AggregatedTable(table, op, col_idx, gb_idx)
+        self.set_output('value', res_table)
+
+_modules = [JoinTables, ProjectTable, SelectFromTable, AggregateColumn]
+
+
+###############################################################################
+
+import unittest
+from vistrails.tests.utils import execute, intercept_result
+from .identifiers import identifier
+
+
+class TestJoin(unittest.TestCase):
+    def test_join(self):
+        """Test joining tables that have column names.
+        """
+        with intercept_result(JoinTables, 'value') as results:
+            self.assertFalse(execute([
+                    ('BuildTable', identifier, [
+                        ('id', [('List', repr([1, '2', 4, 5]))]),
+                        ('A_name', [('List',
+                            repr(['one', 2, 'four', 'five'])),
+                        ]),
+                    ]),
+                    ('BuildTable', identifier, [
+                        ('B_age', [('List',
+                            repr([14, 50, '12', 22])),
+                        ]),
+                        ('id', [('List', repr(['1', 2, 3, 5]))]),
+                    ]),
+                    ('JoinTables', identifier, [
+                        ('left_column_idx', [('Integer', '0')]),
+                        ('right_column_name', [('String', 'id')]),
+                        ('right_column_idx', [('Integer', '1')]),
+                    ]),
+                ],
+                [
+                    (0, 'value', 2, 'left_table'),
+                    (1, 'value', 2, 'right_table'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'id',
+                     'org.vistrails.vistrails.basic:List'),
+                    (0, 'input', 'A_name',
+                     'org.vistrails.vistrails.basic:List'),
+                    (1, 'input', 'B_age',
+                     'org.vistrails.vistrails.basic:List'),
+                    (1, 'input', 'id',
+                     'org.vistrails.vistrails.basic:List'),
+                ]))
+        self.assertEqual(len(results), 1)
+        table, = results
+
+        self.assertEqual(table.names, ['left.id', 'A_name',
+                                       'B_age', 'right.id'])
+
+        self.assertEqual(table.get_column(0, False), [1, '2', 5])
+        l = table.get_column(0, True)
+        self.assertIsInstance(l, numpy.ndarray)
+        self.assertEqual(list(l), [1, 2, 5])
+        self.assertEqual(table.get_column(3, False), ['1', 2, 5])
+        l = table.get_column(3, True)
+        self.assertIsInstance(l, numpy.ndarray)
+        self.assertEqual(list(l), [1, 2, 5])
+
+        self.assertEqual(table.get_column(1, False), ['one', 2, 'five'])
+        self.assertEqual(list(table.get_column(2, True)), [14, 50, 22])
+
+    def test_noname(self):
+        """Tests joining tables that have no column names.
+        """
+        with intercept_result(JoinTables, 'value') as results:
+            self.assertFalse(execute([
+                    ('WriteFile', 'org.vistrails.vistrails.basic', [
+                        ('in_value', [('String', '1;one\n2;2\n4;four\n'
+                                                 '5;five')]),
+                    ]),
+                    ('read|CSVFile', identifier, [
+                        ('delimiter', [('String', ';')]),
+                        ('header_present', [('Boolean', 'False')]),
+                        ('sniff_header', [('Boolean', 'False')]),
+                    ]),
+                    ('WriteFile', 'org.vistrails.vistrails.basic', [
+                        ('in_value', [('String', '14;1\n50;2\n12;3\n22;5\n')]),
+                    ]),
+                    ('read|CSVFile', identifier, [
+                        ('delimiter', [('String', ';')]),
+                        ('header_present', [('Boolean', 'False')]),
+                        ('sniff_header', [('Boolean', 'False')]),
+                    ]),
+                    ('JoinTables', identifier, [
+                        ('left_column_idx', [('Integer', '0')]),
+                        ('right_column_idx', [('Integer', '1')]),
+                    ]),
+                ],
+                [
+                    (0, 'out_value', 1, 'file'),
+                    (2, 'out_value', 3, 'file'),
+                    (1, 'value', 4, 'left_table'),
+                    (3, 'value', 4, 'right_table'),
+                ]))
+        self.assertEqual(len(results), 1)
+        table, = results
+
+        self.assertEqual(table.names, ['left.col 0', 'left.col 1',
+                                       'right.col 0', 'right.col 1'])
+        self.assertEqual(table.get_column(0, False), ['1', '2', '5'])
+        self.assertEqual(table.get_column(1, False), ['one', '2', 'five'])
+
+
+class TestProjection(unittest.TestCase):
+    def do_project(self, project_functions, error=None):
+        with intercept_result(ProjectTable, 'value') as results:
+            errors = execute([
+                    ('BuildTable', identifier, [
+                        ('letters', [('List', repr(['a', 'b', 'c', 'd']))]),
+                        ('numbers', [('List', repr([1, 2, 3, '4']))]),
+                        ('cardinals', [('List', repr(['one', 'two',
+                                                      'three', 'four']))]),
+                        ('ordinals', [('List', repr(['first', 'second',
+                                                     'third', 'fourth']))])
+                    ]),
+                    ('ProjectTable', identifier, project_functions),
+                ],
+                [
+                    (0, 'value', 1, 'table'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'letters',
+                     'org.vistrails.vistrails.basic:List'),
+                    (0, 'input', 'numbers',
+                     'org.vistrails.vistrails.basic:List'),
+                    (0, 'input', 'cardinals',
+                     'org.vistrails.vistrails.basic:List'),
+                    (0, 'input', 'ordinals',
+                     'org.vistrails.vistrails.basic:List'),
+                ])
+        if error is not None:
+            self.assertEqual([1], errors.keys())
+            self.assertIn(error, errors[1].message)
+            return None
+        else:
+            self.assertFalse(errors)
+            self.assertEqual(len(results), 1)
+            return results[0]
+
+    def test_column_numbers(self):
+        """Projects using column numbers.
+        """
+        self.do_project([
+                ('column_indexes', [('List', '[0, 4, 1, 0]')]),
+            ],
+            'table only has 4 columns')
+        result = self.do_project([
+                ('column_indexes', [('List', '[0, 3, 1, 0]')]),
+            ])
+        self.assertEqual(result.names, ['letters', 'ordinals',
+                                        'numbers', 'letters_1'])
+        self.assertEqual(result.get_column(0, False),
+                         ['a', 'b', 'c', 'd'])
+        self.assertEqual(list(result.get_column(2, True)),
+                         [1, 2, 3, 4])
+        self.assertEqual(result.get_column(3, False),
+                         ['a', 'b', 'c', 'd'])
+
+    def test_column_numbers_rename(self):
+        """Projects and rename columns, using column numbers.
+        """
+        self.do_project([
+                ('column_indexes', [('List', '[0, 3, 1, 0]')]),
+                ('new_column_names', [('List', '["a", "b", "c"]')])
+            ],
+            "doesn't have the right number of names")
+        result = self.do_project([
+                ('column_indexes', [('List', '[0, 3, 1, 0]')]),
+                ('new_column_names', [('List', '["a", "b", "c", "d"]')]),
+            ])
+        self.assertEqual(result.names, ['a', 'b', 'c', 'd'])
+
+    def test_column_names(self):
+        """Projects using column names.
+        """
+        self.do_project([
+                ('column_names', [('List', repr(['letters', 'crackers']))]),
+            ],
+            "not found: 'crackers'")
+        self.do_project([
+                ('column_names', [('List', repr(['letters', 'ordinals']))]),
+                ('column_indexes', [('List', '[0, 2]')]),
+            ],
+            "they don't agree")
+        self.do_project([
+                ('column_names', [('List', repr(['letters', 'ordinals']))]),
+                ('column_indexes', [('List', '[0, 3]')]),
+            ])
+        result = self.do_project([
+                ('column_names', [('List', repr(['letters', 'ordinals',
+                                                 'letters']))]),
+            ])
+        self.assertEqual(result.names, ['letters', 'ordinals', 'letters_1'])
+
+
+class TestSelect(unittest.TestCase):
+    def do_select(self, select_functions, error=None):
+        with intercept_result(SelectFromTable, 'value') as results:
+            errors = execute([
+                    ('WriteFile', 'org.vistrails.vistrails.basic', [
+                        ('in_value', [('String', '22;a;T;abaab\n'
+                                                 '43;b;F;aabab\n'
+                                                 '-7;d;T;abbababb\n'
+                                                 '500;e;F;aba abacc')]),
+                    ]),
+                    ('read|CSVFile', identifier, [
+                        ('delimiter', [('String', ';')]),
+                        ('header_present', [('Boolean', 'False')]),
+                        ('sniff_header', [('Boolean', 'False')]),
+                    ]),
+                    ('SelectFromTable', identifier, select_functions),
+                ],
+                [
+                    (0, 'out_value', 1, 'file'),
+                    (1, 'value', 2, 'table'),
+                ])
+        if error is not None:
+            self.assertEqual([2], errors.keys())
+            self.assertIn(error, errors[2].message)
+            return None
+        else:
+            self.assertFalse(errors)
+            self.assertEqual(len(results), 1)
+            return results[0]
+
+    def test_numeric(self):
+        """Selects using the 'less-than' condition.
+        """
+        self.do_select([
+                ('float_expr', [('String', '6'),
+                                ('String', '<='),
+                                ('Float', '42.0')]),
+            ],
+            "table only has 4 columns")
+        table = self.do_select([
+                ('float_expr', [('String', '0'),
+                                ('String', '<='),
+                                ('Float', '42.0')]),
+            ])
+        l = table.get_column(0, True)
+        self.assertIsInstance(l, numpy.ndarray)
+        self.assertEqual(list(l), [22, -7])
+        self.assertEqual(table.get_column(1, False), ['a', 'd'])
+
+    def test_text(self):
+        """Selects using the 'equal' condition.
+        """
+        table = self.do_select([
+                ('str_expr', [('String', '2'),
+                              ('String', '=='),
+                              ('String', 'T')])
+            ])
+        self.assertEqual(table.get_column(0, False), ['22', '-7'])
+
+    def test_regex(self):
+        """Selects using the 'regex-match' condition.
+        """
+        table = self.do_select([
+                ('str_expr', [('String', '3'),
+                              ('String', '=~'),
+                              ('String', r'([ab])\1')]),
+            ])
+        self.assertEqual(table.get_column(0, False), ['22', '43', '-7'])
+
+class TestAggregate(unittest.TestCase):
+    def do_aggregate(self, agg_functions):
+        with intercept_result(AggregateColumn, 'value') as results:
+            errors = execute([
+                    ('WriteFile', 'org.vistrails.vistrails.basic', [
+                        ('in_value', [('String', '22;a;T;100\n'
+                                                 '43;b;F;3\n'
+                                                 '-7;d;T;41\n'
+                                                 '500;e;F;21\n'
+                                                 '20;a;T;1\n'
+                                                 '43;b;F;23\n'
+                                                 '21;a;F;41\n')]),
+                    ]),
+                    ('read|CSVFile', identifier, [
+                        ('delimiter', [('String', ';')]),
+                        ('header_present', [('Boolean', 'False')]),
+                        ('sniff_header', [('Boolean', 'False')]),
+                    ]),
+                    ('AggregateColumn', identifier, agg_functions),
+                ],
+                [
+                    (0, 'out_value', 1, 'file'),
+                    (1, 'value', 2, 'table'),
+                ])
+        self.assertFalse(errors)
+        self.assertEqual(len(results), 1)
+        return results[0]
+
+    def test_aggregate_sum(self):
+        table = self.do_aggregate([('op', [('String', 'sum')]),
+                                   ('column_index', [('Integer', '0')]),
+                                   ('group_by_index', [('Integer', '1')])])
+        self.assertEqual(table.get_column(0, False), ['a', 'b', 'd', 'e'])
+        self.assertEqual(table.get_column(1, True), [63, 86, -7, 500])
+
+    def test_aggregate_avg(self):
+        table = self.do_aggregate([('op', [('String', 'average')]),
+                                   ('column_index', [('Integer', '3')]),
+                                   ('group_by_index', [('Integer', '2')])])
+        self.assertEqual(table.get_column(0, False), ['T', 'F'])
+        second_col = list(table.get_column(1, True))
+        self.assertAlmostEqual(second_col[0], 47.3333333333333)
+        self.assertAlmostEqual(second_col[1], 22.0)
+
+    def test_aggregate_min(self):
+        table = self.do_aggregate([('op', [('String', 'min')]),
+                                   ('column_index', [('Integer', '0')]),
+                                   ('group_by_index', [('Integer', '2')])])
+        self.assertEqual(table.get_column(0, False), ['T', 'F'])
+        self.assertEqual(table.get_column(1, True), [-7, 21])
diff --git a/vistrails/packages/tabledata/read/__init__.py b/vistrails/packages/tabledata/read/__init__.py
index ae083df..d35a48e 100644
--- a/vistrails/packages/tabledata/read/__init__.py
+++ b/vistrails/packages/tabledata/read/__init__.py
@@ -1,7 +1,59 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 from vistrails.core.modules.utils import make_modules_dict
 
-from read_numpy import _modules as numpy_modules
-from read_csv import _modules as csv_modules
+try:
+    # read_numpy requires numpy
+    import numpy
+except ImportError: # pragma: no cover
+    numpy_modules = []
+else:
+    from .read_numpy import _modules as numpy_modules
+
+from .read_excel import get_xlrd
+if get_xlrd():
+    from .read_excel import _modules as excel_modules
+else: # pragma: no cover
+    excel_modules = []
 
+from .read_csv import _modules as csv_modules
+from .read_json import _modules as json_modules
 
-_modules = make_modules_dict(numpy_modules, csv_modules, namespace='read')
+_modules = make_modules_dict(numpy_modules, csv_modules, excel_modules,
+                             json_modules,
+                             namespace='read')
diff --git a/vistrails/packages/tabledata/read/read_csv.py b/vistrails/packages/tabledata/read/read_csv.py
index c69859d..7509636 100644
--- a/vistrails/packages/tabledata/read/read_csv.py
+++ b/vistrails/packages/tabledata/read/read_csv.py
@@ -1,9 +1,48 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import csv
-from itertools import izip
-import numpy
+import operator
+try:
+    import numpy
+except ImportError: # pragma: no cover
+    numpy = None
 
-from vistrails.core.modules.vistrails_module import ModuleError
-from ..common import Table
+from ..common import TableObject, Table, InternalModuleError
 
 
 def count_lines(fp):
@@ -13,104 +52,115 @@ def count_lines(fp):
     return lines
 
 
-class ReadError(Exception):
-    pass
-
+# FIXME : test coverage for CSVTable
+class CSVTable(TableObject):
+    def __init__(self, csv_file, header_present, delimiter,
+                 skip_lines=0, dialect=None, use_sniffer=True):
+        self._rows = None
 
-class CSVFile(Table):
-    _input_ports = [
-            ('file', '(org.vistrails.vistrails.basic:File)'),
-            ('delimiter', '(org.vistrails.vistrails.basic:String)',
-             {'optional': True}),
-            ('header_present', '(org.vistrails.vistrails.basic:Boolean)',
-             {'optional': True, 'defaults': "['True']"})]
-    _output_ports = [
-            ('column_count', '(org.vistrails.vistrails.basic:Integer)'),
-            ('column_names', '(org.vistrails.vistrails.basic:List)'),
-            ('self', '(org.vistrails.vistrails.tabledata:read|csv|CSVFile)')]
+        self.header_present = header_present
+        self.delimiter = delimiter
+        self.filename = csv_file
+        self.skip_lines = skip_lines
+        self.dialect = dialect
 
-    _STANDARD_DELIMITERS = [';', ',', '\t', '|']
+        (self.columns, self.names, self.delimiter,
+         self.header_present, self.dialect) = \
+            self.read_file(csv_file, delimiter, header_present, skip_lines,
+                           dialect, use_sniffer)
+        if self.header_present:
+            self.skip_lines += 1
 
-    def __init__(self):
-        Table.__init__(self)
-        self._rows = None
+        self.column_cache = {}
 
     @staticmethod
-    def read_file(filename, delimiter=None, header_present=True):
+    def read_file(filename, delimiter=None, header_present=True,
+                  skip_lines=0, dialect=None, use_sniffer=True):
+        if delimiter is None and use_sniffer is False:
+            raise InternalModuleError("Must set delimiter if not using sniffer")
+
         try:
             with open(filename, 'rb') as fp:
-                first_line = fp.readline()
-            if delimiter is None:
-                counts = [first_line.count(d)
-                          for d in CSVFile._STANDARD_DELIMITERS]
-                read_delimiter, count = max(
-                        izip(CSVFile._STANDARD_DELIMITERS, counts),
-                        key=lambda (delim, count): count)
-                if count == 0:
-                    raise ReadError("Couldn't guess the field delimiter")
+                if use_sniffer:
+                    first_lines = ""
+                    line = fp.readline()
+                    for i in xrange(skip_lines):
+                        if not line:
+                            break
+                        line = fp.readline()
+                    for i in xrange(5):
+                        if not line:
+                            break
+                        first_lines += line
+                        line = fp.readline()
+                    sniffer = csv.Sniffer()
+                    fp.seek(0)
+                    if delimiter is None:
+                        dialect = sniffer.sniff(first_lines)
+                        delimiter = dialect.delimiter
+                        # cannot determine header without sniffing delimiter
+                        if header_present is None:
+                            header_present = sniffer.has_header(first_lines)
+
+                for i in xrange(skip_lines):
+                    line = fp.readline()
+                    if not line:
+                        raise InternalModuleError("skip_lines greater than "
+                                                  "the number of lines in the "
+                                                  "file")
+
+                if dialect is not None:
+                    reader = csv.reader(fp, dialect=dialect)
                 else:
-                    delimiter = read_delimiter
-            else:
-                count = first_line.count(delimiter)
-
-            column_count = count + 1
-
-            if header_present:
-                column_names = [
-                        name.strip()
-                        for name in first_line.split(delimiter)]
-            else:
-                column_names = None
-        except IOError:
-            raise ReadError("File does not exist")
-
-        return column_count, column_names, delimiter
-
-    def compute(self):
-        csv_file = self.getInputFromPort('file').name
-        self.header_present = self.getInputFromPort('header_present',
-                                                    allowDefault=True)
-        if self.hasInputFromPort('delimiter'):
-            self.delimiter = self.getInputFromPort('delimiter')
-        else:
-            self.delimiter = None
+                    reader = csv.reader(fp, delimiter=delimiter)
+                result = reader.next()
+                column_count = len(result)
 
-        self.filename = csv_file
-
-        try:
-            self.columns, self.names, self.delimiter = self.read_file(
-                    csv_file,
-                    self.delimiter,
-                    self.header_present)
-        except ReadError, e:
-            raise ModuleError(self, *e.args)
-
-        self.column_cache = {}
+                if header_present:
+                    column_names = [name.strip() for name in result]
+                else:
+                    column_names = None
+        except IOError:
+            raise InternalModuleError("File does not exist")
 
-        self.setResult('column_count', self.columns)
-        self.setResult('column_names', self.names)
+        return column_count, column_names, delimiter, header_present, dialect
 
     def get_column(self, index, numeric=False):
-        if index in self.column_cache:
-            return self.column_cache[index]
+        if (index, numeric) in self.column_cache:
+            return self.column_cache[(index, numeric)]
 
-        if numeric:
+        if numeric and numpy is not None:
             result = numpy.loadtxt(
                     self.filename,
                     dtype=numpy.float32,
                     delimiter=self.delimiter,
-                    skiprows=1 if self.header_present else 0,
+                    skiprows=self.skip_lines,
                     usecols=[index])
         else:
             with open(self.filename, 'rb') as fp:
-                if self.header_present:
-                    fp.readline()
-                reader = csv.reader(
-                        fp,
-                        delimiter=self.delimiter)
-                result = [row[index] for row in reader]
-
-        self.column_cache[index] = result
+                for i in xrange(self.skip_lines):
+                    line = fp.readline()
+                    if not line:
+                        raise ValueError("skip_lines greater than the number "
+                                         "of lines in the file")
+                if self.dialect is not None:
+                    reader = csv.reader(fp, dialect=self.dialect)
+                else:
+                    reader = csv.reader(fp, delimiter=self.delimiter)
+
+                getter = operator.itemgetter(index)
+                try:
+                    result = []
+                    for rownb, row in enumerate(reader, 1):
+                        result.append(getter(row))
+                except IndexError:
+                    raise ValueError("Invalid CSV file: only %d fields on "
+                                     "line %d (column %d requested)" % (
+                                         len(row), rownb, index))
+            if numeric:
+                result = [float(e) for e in result]
+
+        self.column_cache[(index, numeric)] = result
         return result
 
     @property
@@ -119,12 +169,55 @@ class CSVFile(Table):
             return self._rows
         with open(self.filename, 'rb') as fp:
             self._rows = count_lines(fp)
-        if self.header_present:
-            self._rows -= 1
+        self._rows -= self.skip_lines
         return self._rows
 
 
-_modules = {'csv': [CSVFile]}
+class CSVFile(Table):
+    """Reads a table from a CSV file.
+
+    This module uses Python's csv module to read a table from a file. It is
+    able to guess the actual format of the file in most cases, or you can use
+    the 'delimiter', 'header_present' and 'skip_lines' ports to force how the
+    file will be read.
+    """
+    _input_ports = [
+            ('file', '(org.vistrails.vistrails.basic:File)'),
+            ('delimiter', '(org.vistrails.vistrails.basic:String)',
+             {'optional': True}),
+            ('header_present', '(org.vistrails.vistrails.basic:Boolean)',
+             {'optional': True, 'defaults': "['True']"}),
+            ('sniff_header', '(org.vistrails.vistrails.basic:Boolean)',
+             {'optional': True, 'defaults': "['True']"}),
+            ('skip_lines', '(org.vistrails.vistrails.basic:Integer)',
+             {'optional': True, 'defaults': "['0']"}),
+            ('dialect', '(org.vistrails.vistrails.basic:String)',
+             {'optional': True})]
+    _output_ports = [
+            ('column_count', '(org.vistrails.vistrails.basic:Integer)'),
+            ('column_names', '(org.vistrails.vistrails.basic:List)'),
+            ('value', Table)]
+
+    def compute(self):
+        csv_file = self.get_input('file').name
+        header_present = self.force_get_input('header_present', None)
+        delimiter = self.force_get_input('delimiter', None)
+        skip_lines = self.get_input('skip_lines')
+        dialect = self.force_get_input('dialect', None)
+        sniff_header = self.get_input('sniff_header')
+
+        try:
+            table = CSVTable(csv_file, header_present, delimiter, skip_lines,
+                             dialect, sniff_header)
+        except InternalModuleError, e:
+            e.raise_module_error(self)
+
+        self.set_output('column_count', table.columns)
+        self.set_output('column_names', table.names)
+        self.set_output('value', table)
+
+
+_modules = [CSVFile]
 
 
 ###############################################################################
@@ -151,7 +244,7 @@ class CSVTestCase(unittest.TestCase):
         with intercept_result(ExtractColumn, 'value') as results:
             with intercept_result(CSVFile, 'column_count') as columns:
                 self.assertFalse(execute([
-                        ('read|csv|CSVFile', identifier, [
+                        ('read|CSVFile', identifier, [
                             ('file', [('File', self._test_dir + '/test.csv')]),
                         ]),
                         ('ExtractColumn', identifier, [
@@ -164,7 +257,7 @@ class CSVTestCase(unittest.TestCase):
                         ]),
                     ],
                     [
-                        (0, 'self', 1, 'table'),
+                        (0, 'value', 1, 'table'),
                         (1, 'value', 2, 'l'),
                     ],
                     add_port_specs=[
@@ -181,7 +274,7 @@ class CSVTestCase(unittest.TestCase):
         """Uses CSVFile and ExtractColumn with mismatching columns.
         """
         self.assertTrue(execute([
-                ('read|csv|CSVFile', identifier, [
+                ('read|CSVFile', identifier, [
                     ('file', [('File', self._test_dir + '/test.csv')]),
                 ]),
                 ('ExtractColumn', identifier, [
@@ -190,14 +283,14 @@ class CSVTestCase(unittest.TestCase):
                 ]),
             ],
             [
-                (0, 'self', 1, 'table'),
+                (0, 'value', 1, 'table'),
             ]))
 
     def test_csv_missing(self):
         """Uses CSVFile and ExtractColumn with a nonexisting column.
         """
         self.assertTrue(execute([
-                ('read|csv|CSVFile', identifier, [
+                ('read|CSVFile', identifier, [
                     ('file', [('File', self._test_dir + '/test.csv')]),
                 ]),
                 ('ExtractColumn', identifier, [
@@ -205,7 +298,7 @@ class CSVTestCase(unittest.TestCase):
                 ]),
             ],
             [
-                (0, 'self', 1, 'table'),
+                (0, 'value', 1, 'table'),
             ]))
 
     def test_csv_nonnumeric(self):
@@ -213,7 +306,7 @@ class CSVTestCase(unittest.TestCase):
         """
         with intercept_result(ExtractColumn, 'value') as results:
             self.assertFalse(execute([
-                    ('read|csv|CSVFile', identifier, [
+                    ('read|CSVFile', identifier, [
                         ('file', [('File', self._test_dir + '/test.csv')]),
                         ('header_present', [('Boolean', 'False')]),
                     ]),
@@ -223,7 +316,7 @@ class CSVTestCase(unittest.TestCase):
                     ]),
                 ],
                 [
-                    (0, 'self', 1, 'table'),
+                    (0, 'value', 1, 'table'),
                 ]))
         self.assertEqual(len(results), 1)
         self.assertEqual(results[0],
diff --git a/vistrails/packages/tabledata/read/read_excel.py b/vistrails/packages/tabledata/read/read_excel.py
new file mode 100644
index 0000000..03a3a38
--- /dev/null
+++ b/vistrails/packages/tabledata/read/read_excel.py
@@ -0,0 +1,271 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+try:
+    import numpy
+except ImportError: # pragma: no cover
+    numpy = None
+
+from vistrails.core.bundles.pyimport import py_import
+from vistrails.core.modules.vistrails_module import ModuleError
+
+from ..common import TableObject, Table
+
+
+def get_xlrd():
+    try:
+        return py_import('xlrd', {
+                             'pip': 'xlrd',
+                             'linux-debian': 'python-xlrd',
+                             'linux-ubuntu': 'python-xlrd',
+                             'linux-fedora': 'python-xlrd'},
+                         True)
+    except ImportError: # pragma: no cover
+        return None
+
+
+class ExcelTable(TableObject):
+    def __init__(self, sheet, header_present):
+        self.sheet = sheet
+
+        self.header_present = header_present
+        if self.header_present:
+            self.names = [c.value for c in self.sheet.row(0)]
+        else:
+            self.names = None
+
+        self.rows = self.sheet.nrows
+        if self.header_present:
+            self.rows -= 1
+
+        self.columns = self.sheet.ncols
+
+        self.column_cache = {}
+
+    def get_column(self, index, numeric=False):
+        if (index, numeric) in self.column_cache:
+            return self.column_cache[(index, numeric)]
+
+        result = [c.value for c in self.sheet.col(index)]
+        if self.header_present:
+            result = result[1:]
+        if numeric and numpy is not None:
+            result = numpy.array(result, dtype=numpy.float32)
+        elif numeric:
+            result = [float(e) for e in result]
+
+        self.column_cache[(index, numeric)] = result
+        return result
+
+
+class ExcelSpreadsheet(Table):
+    """Reads a table from a Microsoft Excel file.
+
+    This module uses xlrd from the python-excel.org project to read a XLS or
+    XLSX file.
+    """
+    _input_ports = [
+            ('file', '(org.vistrails.vistrails.basic:File)'),
+            ('sheet_name', '(org.vistrails.vistrails.basic:String)',
+             {'optional': True}),
+            ('sheet_index', '(org.vistrails.vistrails.basic:Integer)',
+             {'optional': True}),
+            ('header_present', '(org.vistrails.vistrails.basic:Boolean)',
+             {'optional': True, 'defaults': "['False']"})]
+    _output_ports = [
+            ('column_count', '(org.vistrails.vistrails.basic:Integer)'),
+            ('column_names', '(org.vistrails.vistrails.basic:String)'),
+            ('value', Table)]
+
+    def compute(self):
+        xlrd = get_xlrd()
+        if xlrd is None: # pragma: no cover
+            raise ModuleError(self, "xlrd is not available")
+
+        workbook = self.get_input('file')
+        workbook = xlrd.open_workbook(workbook.name)
+
+        if self.has_input('sheet_index'):
+            sheet_index = self.get_input('sheet_index')
+        if self.has_input('sheet_name'):
+            name = self.get_input('sheet_name')
+            try:
+                index = workbook.sheet_names().index(name)
+            except Exception:
+                raise ModuleError(self, "Sheet name not found")
+            if self.has_input('sheet_index'):
+                if sheet_index != index:
+                    raise ModuleError(self,
+                                      "Both sheet_name and sheet_index were "
+                                      "specified, and they don't agree")
+        elif self.has_input('sheet_index'):
+            index = sheet_index
+        else:
+            index = 0
+        sheet = workbook.sheet_by_index(index)
+        header_present = self.get_input('header_present')
+        table = ExcelTable(sheet, header_present)
+        self.set_output('value', table)
+
+        if table.names is not None:
+            self.set_output('column_names', table.names)
+        self.set_output('column_count', table.columns)
+
+
+_modules = [ExcelSpreadsheet]
+
+
+###############################################################################
+
+import itertools
+import unittest
+from vistrails.tests.utils import execute, intercept_result
+from ..identifiers import identifier
+from ..common import ExtractColumn
+
+ at unittest.skipIf(get_xlrd() is None, "xlrd not available")
+class ExcelTestCase(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        import os
+        cls._test_dir = os.path.join(
+                os.path.dirname(__file__),
+                os.pardir,
+                'test_files')
+
+    def assertAlmostEqual_lists(self, a, b):
+        for i, j in itertools.izip(a, b):
+            self.assertAlmostEqual(i, j, places=5)
+
+    def test_xls_numeric(self):
+        """Uses ExcelSpreadsheet to load a numeric array.
+        """
+        with intercept_result(ExtractColumn, 'value') as results:
+            with intercept_result(ExcelSpreadsheet, 'column_count') as cols:
+                self.assertFalse(execute([
+                        ('read|ExcelSpreadsheet', identifier, [
+                            ('file', [('File', self._test_dir + '/xl.xls')]),
+                            ('sheet_index', [('Integer', '1')]),
+                            ('sheet_name', [('String', 'Feuil2')]),
+                            ('header_present', [('Boolean', 'False')])
+                        ]),
+                        ('ExtractColumn', identifier, [
+                            ('column_index', [('Integer', '0')]),
+                            ('numeric', [('Boolean', 'True')]),
+                        ]),
+                    ],
+                    [
+                        (0, 'value', 1, 'table'),
+                    ]))
+        self.assertEqual(cols, [1])
+        self.assertEqual(len(results), 1)
+        self.assertAlmostEqual_lists(list(results[0]), [1, 2, 2, 3, -7.6])
+
+    def test_xls_sheet_mismatch(self):
+        """Uses ExcelSpreadsheet with mismatching sheets.
+        """
+        err = execute([
+                ('read|ExcelSpreadsheet', identifier, [
+                    ('file', [('File', self._test_dir + '/xl.xls')]),
+                    ('sheet_index', [('Integer', '0')]),
+                    ('sheet_name', [('String', 'Feuil2')]),
+                ]),
+            ])
+        self.assertEqual(list(err.keys()), [0])
+        self.assertEqual(
+                err[0].msg,
+                "Both sheet_name and sheet_index were specified, and they "
+                "don't agree")
+
+    def test_xls_sheetname_missing(self):
+        """Uses ExcelSpreadsheet with a missing sheet.
+        """
+        err = execute([
+                ('read|ExcelSpreadsheet', identifier, [
+                    ('file', [('File', self._test_dir + '/xl.xls')]),
+                    ('sheet_name', [('String', 'Sheet12')]),
+                ]),
+            ])
+        self.assertEqual(list(err.keys()), [0])
+        self.assertEqual(err[0].msg, "Sheet name not found")
+
+    def test_xls_header_nonnumeric(self):
+        """Uses ExcelSpreadsheet to load data.
+        """
+        with intercept_result(ExtractColumn, 'value') as results:
+            with intercept_result(ExcelSpreadsheet, 'column_count') as cols:
+                self.assertFalse(execute([
+                        ('read|ExcelSpreadsheet', identifier, [
+                            ('file', [('File', self._test_dir + '/xl.xls')]),
+                            ('sheet_name', [('String', 'Feuil1')]),
+                            ('header_present', [('Boolean', 'True')])
+                        ]),
+                        ('ExtractColumn', identifier, [
+                            ('column_index', [('Integer', '0')]),
+                            ('column_name', [('String', 'data1')]),
+                            ('numeric', [('Boolean', 'False')]),
+                        ]),
+                    ],
+                    [
+                        (0, 'value', 1, 'table'),
+                    ]))
+        self.assertEqual(cols, [2])
+        self.assertEqual(len(results), 1)
+        self.assertEqual(list(results[0]), ['here', 'is', 'some', 'text'])
+
+    def test_xls_header_numeric(self):
+        """Uses ExcelSpreadsheet to load a numeric array.
+        """
+        with intercept_result(ExtractColumn, 'value') as results:
+            with intercept_result(ExcelSpreadsheet, 'column_count') as cols:
+                self.assertFalse(execute([
+                        ('read|ExcelSpreadsheet', identifier, [
+                            ('file', [('File', self._test_dir + '/xl.xls')]),
+                            # Will default to first sheet
+                            ('header_present', [('Boolean', 'True')])
+                        ]),
+                        ('ExtractColumn', identifier, [
+                            ('column_name', [('String', 'data2')]),
+                            ('numeric', [('Boolean', 'True')]),
+                        ]),
+                    ],
+                    [
+                        (0, 'value', 1, 'table'),
+                    ]))
+        self.assertEqual(cols, [2])
+        self.assertEqual(len(results), 1)
+        self.assertAlmostEqual_lists(list(results[0]), [1, -2.8, 3.4, 3.3])
diff --git a/vistrails/packages/tabledata/read/read_json.py b/vistrails/packages/tabledata/read/read_json.py
new file mode 100644
index 0000000..c19e110
--- /dev/null
+++ b/vistrails/packages/tabledata/read/read_json.py
@@ -0,0 +1,325 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+from vistrails.core.modules.vistrails_module import ModuleError
+
+from ..common import TableObject, Table, InternalModuleError
+
+
+class JSONTable(Table):
+    _input_ports = [('file', '(org.vistrails.vistrails.basic:File)')]
+    _output_ports = [
+            ('column_count', '(org.vistrails.vistrails.basic:Integer)'),
+            ('column_names', '(org.vistrails.vistrails.basic:List)'),
+            ('value', Table)]
+
+    def compute(self):
+        json_file = self.get_input('file').name
+        with open(json_file, 'rb') as fp:
+            obj = json.load(fp)
+        try:
+            table = self.make_table(obj)
+        except InternalModuleError, e:
+            e.raise_module_error(self)
+        self.set_output('column_count', table.columns)
+        if table.names is not None:
+            self.set_output('column_names', table.names)
+        self.set_output('value', table)
+
+    @staticmethod
+    def add_list(columns, key, value):
+        if not isinstance(value, list):
+            raise InternalModuleError("Entry for key %r is not a list" % key)
+        if key is not None:
+            value = [key] + value
+        for i, v in enumerate(value):
+            columns[i].append(v)
+
+    @staticmethod
+    def add_dict(columns, keys, key_set, key, value):
+        if not isinstance(value, dict):
+            raise InternalModuleError(
+                    "Entry for key %r is not an object" % key)
+        value_keys = set(value.keys())
+        m = key_set - value_keys
+        if m:
+            raise InternalModuleError(
+                    "Entry for key %r is missing field %r" % (
+                    key,
+                    next(iter(m))))
+        m = value_keys - key_set
+        if m:
+            raise InternalModuleError(
+                    "Entry for key %r has unexpected field %r" % (
+                    key,
+                    next(iter(m))))
+        if key is None:
+            for i, k in enumerate(keys):
+                columns[i].append(value[k])
+        else:
+            columns[0].append(key)
+            for i, k in enumerate(keys):
+                columns[i + 1].append(value[k])
+
+
+class JSONObject(JSONTable):
+    """Loads a JSON file and build a table from an object.
+
+    In JSON, an object is written with {}. It is essentially an associative
+    array. A column will contain the keys in this array.
+
+    Example:
+        {
+            "John": {"lastname": "Smith", "age": 25, "city": "New York"},
+            "Ashley": {"lastname": "Crofts", "age": 21, "city": "Fort Worth"},
+            "Michael": {"lastname": "Buck", "age": 78, "city": "Goodman"}
+        }
+
+        key    | lastname | age |    city
+        -------+----------+-----+-----------
+        John   |  Smith   |  25 | New York
+        Ashley |  Crofts  |  21 | Fort Worth
+        Michal |  Buck    |  78 | Goodman
+
+    Rows can also be lists (but they still all have to be in the same format).
+    In this case, columns will not be named.
+
+    To read a list of rows, use the JSONList module instead.
+    """
+    _input_ports = [('key_name', '(org.vistrails.vistrails.basic:String)',
+                     {'optional': True, 'defaults': repr(["key"])})]
+
+    def make_table(self, obj):
+        if not isinstance(obj, dict):
+            raise ModuleError(self, "JSON file is not an object")
+        key_name = self.get_input('key_name', True)
+        iterator = obj.iteritems()
+        try:
+            first_key, first_value = next(iterator)
+        except StopIteration:
+            raise ModuleError(self, "No entry in JSON object")
+        count = 1
+        if isinstance(first_value, list):
+            keys = None
+            columns = [[] for i in xrange(1 + len(first_value))]
+            self.add_list(columns, first_key, first_value)
+            for key, value in iterator:
+                self.add_list(columns, key, value)
+                count += 1
+        elif isinstance(first_value, dict):
+            keys = first_value.keys()
+            key_set = set(keys)
+            columns = [[] for i in xrange(1 + len(keys))]
+            self.add_dict(columns, keys, key_set, first_key, first_value)
+            for key, value in iterator:
+                self.add_dict(columns, keys, key_set, key, value)
+                count += 1
+        else:
+            raise ModuleError(self, "Values should be lists or objects")
+
+        if keys is not None:
+            names = [key_name] + keys
+        else:
+            names = None
+        return TableObject(columns, count, names)
+
+
+class JSONList(JSONTable):
+    """Loads a JSON file and build a table from a list.
+
+    In JSON, a list is written with [].
+
+    Example:
+        [[ 4, 14, 15,  1],
+         [ 9,  7,  6, 12],
+         [ 5, 11, 10,  8],
+         [16,  2,  3, 13]]
+
+        gives a 4x4 unnamed table.
+    """
+    def make_table(self, obj):
+        if not isinstance(obj, list):
+            raise ModuleError(self, "JSON file is not a list")
+        iterator = iter(obj)
+        try:
+            first = next(iterator)
+        except StopIteration:
+            raise ModuleError(self, "No element in JSON list")
+        count = 1
+        if isinstance(first, list):
+            keys = None
+            columns = [[] for i in xrange(len(first))]
+            self.add_list(columns, None, first)
+            for value in iterator:
+                self.add_list(columns, None, value)
+                count += 1
+        elif isinstance(first, dict):
+            keys = first.keys()
+            key_set = set(keys)
+            columns = [[] for i in xrange(len(keys))]
+            self.add_dict(columns, keys, key_set, None, first)
+            for value in iterator:
+                self.add_dict(columns, keys, key_set, None, value)
+                count += 1
+        else:
+            raise ModuleError(self, "Values should be lists or objects")
+
+        return TableObject(columns, count, keys)
+
+
+_modules = [(JSONTable, {'abstract': True}), JSONObject, JSONList]
+
+
+###############################################################################
+
+import unittest
+from vistrails.tests.utils import execute, intercept_results
+from ..identifiers import identifier
+
+
+class TestJSON(unittest.TestCase):
+    def test_object(self):
+        """Reads an object with object or list rows.
+        """
+        json_files = [
+            ("""
+            {
+                "John": {"lastname": "Smith", "age": 25, "city": "New York"},
+                "Lara": {"lastname": "Croft", "age": 21, "city": "Nashville"},
+                "Michael": {"lastname": "Buck", "age": 78, "city": "Goodman"}
+            }
+            """, True),
+            ("""
+            {
+                "John": ["Smith", 25, "New York"],
+                "Lara": ["Croft", 21, "Nashville"],
+                "Michael": ["Buck", 78, "Goodman"]
+            }
+            """, False),
+            ]
+
+        for json_file, has_names in json_files:
+            with intercept_results(JSONObject, 'value', 'column_count',
+                                   'column_names') as results:
+                self.assertFalse(execute([
+                        ('WriteFile', 'org.vistrails.vistrails.basic', [
+                            ('in_value', [('String', json_file)]),
+                        ]),
+                        ('read|JSONObject', identifier, []),
+                    ],
+                    [
+                        (0, 'out_value', 1, 'file'),
+                    ]))
+            self.assertTrue(all((len(r) == 1) for r in results[:2]))
+            (table,), (count,), names = results
+            self.assertEqual(count, 4)
+
+            import numpy
+            if has_names:
+                self.assertEqual(names, [table.names])
+                self.assertEqual(table.names[0], 'key')
+                self.assertEqual(set(table.names[1:]),
+                                 set(['lastname', 'age', 'city']))
+                f_city = table.names.index('city')
+                f_age = table.names.index('age')
+            else:
+                self.assertEqual(names, [])
+                self.assertIsNone(table.names)
+                f_city = 3
+                f_age = 2
+            self.assertEqual(set(table.get_column(f_city)),
+                             set(["New York", "Nashville", "Goodman"]))
+            l = table.get_column(f_age, True)
+            self.assertIsInstance(l, numpy.ndarray)
+            self.assertEqual(set(l), set([21, 25, 78]))
+
+    def test_list(self):
+        """Reads a list of object or list rows.
+        """
+        json_files = [
+            """
+            [
+                {"firstname": "John", "lastname": "Smith", "age": 25},
+                {"firstname": "Lara", "lastname": "Croft", "age": 21},
+                {"firstname": "Michael", "lastname": "Buck", "age": 78}
+            ]
+            """,
+            """
+            [[2, 7, 6],
+             [9, 5, 1],
+             [4, 3, 8]]
+            """,
+            ]
+
+        for nb, json_file in enumerate(json_files):
+            with intercept_results(JSONList, 'value', 'column_count',
+                                   'column_names') as results:
+                self.assertFalse(execute([
+                        ('WriteFile', 'org.vistrails.vistrails.basic', [
+                            ('in_value', [('String', json_file)]),
+                        ]),
+                        ('read|JSONList', identifier, []),
+                    ],
+                    [
+                        (0, 'out_value', 1, 'file'),
+                    ]))
+            self.assertTrue(all((len(r) == 1) for r in results[:2]))
+            (table,), (count,), names = results
+            self.assertEqual(count, 3)
+
+            import numpy
+            if nb == 0:
+                self.assertEqual(names, [table.names])
+                self.assertEqual(set(table.names),
+                                 set(['firstname', 'lastname', 'age']))
+                self.assertEqual(set(table.get_column_by_name('firstname')),
+                                 set(["John", "Lara", "Michael"]))
+                l = table.get_column_by_name('age', True)
+                self.assertIsInstance(l, numpy.ndarray)
+                self.assertEqual(set(l), set([21, 25, 78]))
+            else:
+                self.assertEqual(names, [])
+                self.assertIsNone(table.names)
+                self.assertEqual([table.get_column(col) for col in xrange(3)],
+                                 [[2, 9, 4],
+                                  [7, 5, 3],
+                                  [6, 1, 8]])
diff --git a/vistrails/packages/tabledata/read/read_numpy.py b/vistrails/packages/tabledata/read/read_numpy.py
index 8f251f4..b60c884 100644
--- a/vistrails/packages/tabledata/read/read_numpy.py
+++ b/vistrails/packages/tabledata/read/read_numpy.py
@@ -1,21 +1,58 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import numpy
 
 from vistrails.core.modules.vistrails_module import Module
 
 
 class NumPyArray(Module):
-    """
-    A Numpy Array, that can be loaded from a file.
+    """Reads a Numpy Array that has been written to a file.
 
     Declared as returning a List, but returns a Numpy array instead!
-    """
-    _input_ports = [
-            ('file', '(org.vistrails.vistrails.basic:File)'),
-            ('datatype', '(org.vistrails.vistrails.basic:String)'),
-            ('shape', '(org.vistrails.vistrails.basic:List)')]
-    _output_ports = [
-            ('value', '(org.vistrails.vistrails.basic:List)')]
 
+    NumPy can use one of two schemes: either 'plain' binary arrays, i.e. just
+    the binary representation of the data format (in this case you must specify
+    the exact format to get the original data back), or the NPY format, i.e.
+    .npy files that know what the actual structure of the array is.
+
+    If the array you are reading is not a simple one-dimensional array, you can
+    use the shape port to indicate its expected structure.
+    """
     NPY_FMT = object()
 
     FORMAT_MAP = dict(
@@ -37,10 +74,18 @@ class NumPyArray(Module):
         complex128 = numpy.complex128,
     )
 
+    _input_ports = [
+            ('file', '(org.vistrails.vistrails.basic:File)'),
+            ('datatype', '(org.vistrails.vistrails.basic:String)',
+             {'entry_types': "['enum']", 'values': "[%r]" % FORMAT_MAP.keys()}),
+            ('shape', '(org.vistrails.vistrails.basic:List)')]
+    _output_ports = [
+            ('value', '(org.vistrails.vistrails.basic:List)')]
+
     def compute(self):
-        filename = self.getInputFromPort('file').name
-        if self.hasInputFromPort('datatype'):
-            dtype = NumPyArray.FORMAT_MAP[self.getInputFromPort('datatype')]
+        filename = self.get_input('file').name
+        if self.has_input('datatype'):
+            dtype = NumPyArray.FORMAT_MAP[self.get_input('datatype')]
         else:
             if filename[-4:].lower() == '.npy':
                 dtype = self.NPY_FMT
@@ -54,12 +99,12 @@ class NumPyArray(Module):
             # Numpy's plain binary format
             # Written with: array.tofile('xxx.dat')
             array = numpy.fromfile(filename, dtype)
-        if self.hasInputFromPort('shape'):
-            array.shape = tuple(self.getInputFromPort('shape'))
-        self.setResult('value', array)
+        if self.has_input('shape'):
+            array.shape = tuple(self.get_input('shape'))
+        self.set_output('value', array)
 
 
-_modules = {'numpy': [NumPyArray]}
+_modules = [NumPyArray]
 
 
 ###############################################################################
@@ -84,7 +129,7 @@ class NumpyTestCase(unittest.TestCase):
 
         with intercept_result(NumPyArray, 'value') as results:
             self.assertFalse(execute([
-                    ('read|numpy|NumPyArray', identifier, [
+                    ('read|NumPyArray', identifier, [
                         ('datatype', [('String', 'float32')]),
                         ('shape', [('List', '[2, 3]')]),
                         ('file', [('File', self._test_dir + '/random.dat')]),
@@ -102,7 +147,7 @@ class NumpyTestCase(unittest.TestCase):
 
         with intercept_result(NumPyArray, 'value') as results:
             self.assertFalse(execute([
-                    ('read|numpy|NumPyArray', identifier, [
+                    ('read|NumPyArray', identifier, [
                         ('datatype', [('String', 'npy')]),
                         ('file', [('File', self._test_dir + '/random.npy')]),
                     ]),
@@ -128,7 +173,7 @@ class NumpyTestCase(unittest.TestCase):
 
         with intercept_result(NumPyArray, 'value') as results:
             self.assertFalse(execute([
-                    ('read|numpy|NumPyArray', identifier, [
+                    ('read|NumPyArray', identifier, [
                         ('file', [('File', self._test_dir + '/random.npy')]),
                     ]),
                 ]))
diff --git a/vistrails/packages/tabledata/test_files/xl.xls b/vistrails/packages/tabledata/test_files/xl.xls
new file mode 100644
index 0000000..49121f7
Binary files /dev/null and b/vistrails/packages/tabledata/test_files/xl.xls differ
diff --git a/vistrails/packages/tabledata/viewer.py b/vistrails/packages/tabledata/viewer.py
index fbc67b3..c7a8508 100644
--- a/vistrails/packages/tabledata/viewer.py
+++ b/vistrails/packages/tabledata/viewer.py
@@ -1,8 +1,17 @@
+from __future__ import division
+
+import os
 from PyQt4 import QtCore, QtGui
 
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, \
+    SpreadsheetMode
 from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget
 
+class TableToSpreadsheetMode(SpreadsheetMode):
+    def compute_output(self, output_module, configuration=None):
+        table = output_module.get_input('value')
+        self.display_and_wait(output_module, configuration,
+                              TableCellWidget, (table,))
 
 class TableCell(SpreadsheetCell):
     """Shows a table in a spreadsheet cell.
@@ -10,15 +19,18 @@ class TableCell(SpreadsheetCell):
     _input_ports = [('table', '(org.vistrails.vistrails.tabledata:Table)')]
 
     def compute(self):
-        table = self.getInputFromPort('table')
+        table = self.get_input('table')
         self.displayAndWait(TableCellWidget, (table,))
 
 
 class TableCellWidget(QCellWidget):
+    save_formats = QCellWidget.save_formats + ["HTML files (*.html)"]
+
     def __init__(self, parent=None):
         QCellWidget.__init__(self, parent)
 
         layout = QtGui.QVBoxLayout()
+        layout.setContentsMargins(0,0,0,0)
 
         self.table = QtGui.QTableWidget()
 
@@ -31,25 +43,94 @@ class TableCellWidget(QCellWidget):
 
     def updateContents(self, inputPorts):
         table, = inputPorts
+        self.orig_table = table
 
-        self.table.setColumnCount(table.columns)
+        self.table.setSortingEnabled(False)
+        self.table.clear()
+        self.table.setColumnCount(table.columns + 1)
         self.table.setRowCount(table.rows)
 
-        for col in xrange(table.columns):
-            column = table.get_column(col)
-            for row in xrange(table.rows):
-                elem = column[row]
+        for row in xrange(table.rows):
+            item = QtGui.QTableWidgetItem()
+            item.setData(QtCore.Qt.EditRole, row)
+            item.setFlags(QtCore.Qt.NoItemFlags)
+            self.table.setItem(row, 0, item)
+
+        try:
+            for col in xrange(table.columns):
+                column = table.get_column(col)
+                for row in xrange(table.rows):
+                    elem = column[row]
+                    if isinstance(elem, bytes):
+                        elem = elem.decode('utf-8', 'replace')
+                    elif not isinstance(elem, unicode):
+                        elem = unicode(elem)
+                    item = QtGui.QTableWidgetItem(elem)
+                    item.setFlags(QtCore.Qt.ItemIsEnabled |
+                                  QtCore.Qt.ItemIsSelectable)
+                    self.table.setItem(row, col + 1, item)
+        except:
+            self.table.setColumnCount(1)
+            raise
+
+        if table.names is not None:
+            names = table.names
+        else:
+            names = ['col %d' % n for n in xrange(table.columns)]
+        self.table.setHorizontalHeaderLabels(['row' ] + names)
+        self.table.setSortingEnabled(True)
+        self.table.sortByColumn(0, QtCore.Qt.AscendingOrder)
+        self.table.resizeColumnsToContents()
+
+    def write_html(self):
+        document = ['<!DOCTYPE html>\n'
+                    '<html>\n  <head>\n'
+                    '    <meta http-equiv="Content-type" content="text/html; '
+                            'charset=utf-8" />\n'
+                    '    <title>Exported table</title>\n'
+                    '    <style type="text/css">\n'
+                    'table { border-collapse: collapse; }\n'
+                    'td, th { border: 1px solid black; }\n'
+                    '    </style>\n'
+                    '  </head>\n  <body>\n    <table>\n']
+        table = self.orig_table
+        if table.names is not None:
+            names = table.names
+        else:
+            names = ['col %d' % n for n in xrange(table.columns)]
+        document.append('<tr>\n')
+        document.extend('  <th>%s</th>\n' % name for name in names)
+        document.append('</tr>\n')
+        columns = [table.get_column(col) for col in xrange(table.columns)]
+        for row in xrange(table.rows):
+            document.append('<tr>\n')
+            for col in xrange(table.columns):
+                elem = columns[col][row]
                 if isinstance(elem, bytes):
                     elem = elem.decode('utf-8', 'replace')
                 elif not isinstance(elem, unicode):
                     elem = unicode(elem)
-                item = QtGui.QTableWidgetItem(elem)
-                item.setFlags(QtCore.Qt.ItemIsEnabled |
-                              QtCore.Qt.ItemIsSelectable)
-                self.table.setItem(row, col, item)
-
-        if table.names is not None:
-            self.table.setHorizontalHeaderLabels(table.names)
+                document.append('  <td>%s</td>\n' % elem)
+            document.append('</tr>\n')
+        document.append('    </table>\n  </body>\n</html>\n')
+
+        return ''.join(document)
+
+    def dumpToFile(self, filename):
+        ext = os.path.splitext(filename)[1].lower()
+        if ext in ('.html', '.htm'):
+            with open(filename, 'wb') as fp:
+                fp.write(self.write_html())
+        else:
+            super(TableCellWidget, self).dumpToFile(filename)
+
+    def saveToPDF(self, filename):
+        document = QtGui.QTextDocument()
+        document.setHtml(self.write_html())
+        printer = QtGui.QPrinter()
+        printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
+        printer.setOutputFileName(filename)
+        document.print_(printer)
 
 
 _modules = [TableCell]
diff --git a/vistrails/packages/tabledata/widgets.py b/vistrails/packages/tabledata/widgets.py
new file mode 100644
index 0000000..2853929
--- /dev/null
+++ b/vistrails/packages/tabledata/widgets.py
@@ -0,0 +1,217 @@
+from __future__ import division
+
+from PyQt4 import QtCore, QtGui
+
+from vistrails.core.system import get_vistrails_basic_pkg_id
+from vistrails.gui.modules.module_configure import \
+    StandardModuleConfigurationWidget
+
+from .identifiers import identifier
+from vistrails.core.modules.basic_modules import List
+
+
+class Entry(QtGui.QWidget):
+    remove = QtCore.pyqtSignal()
+    changed = QtCore.pyqtSignal()
+
+    def __init__(self, name):
+        QtGui.QWidget.__init__(self)
+        layout = QtGui.QHBoxLayout()
+        self.setLayout(layout)
+        self.lineedit = QtGui.QLineEdit(name)
+        layout.addWidget(QtGui.QLabel(self.prefix))
+        layout.addWidget(self.lineedit)
+        layout.addStretch()
+        remove_button = QtGui.QPushButton("Remove port")
+        remove_button.setSizePolicy(QtGui.QSizePolicy.Fixed,
+                                    QtGui.QSizePolicy.Fixed)
+        layout.addWidget(remove_button)
+
+        self.connect(remove_button, QtCore.SIGNAL('clicked()'),
+                     self.remove)
+        self.connect(self.lineedit, QtCore.SIGNAL('textEdited(const QString &)'),
+                     self.changed)
+
+    @property
+    def name(self):
+        return self.lineedit.text()
+
+
+class TableEntry(Entry):
+    prefix = "Table input"
+
+
+class ColumnEntry(Entry):
+    prefix = "Single column entry"
+
+
+class BuildTableWidget(StandardModuleConfigurationWidget):
+    """
+    Configuration widget allowing to create the ports of the BuildTable module.
+    """
+    def __init__(self, module, controller, parent=None):
+        StandardModuleConfigurationWidget.__init__(self, module,
+                                                   controller, parent)
+
+        # Window title
+        self.setWindowTitle("Build table configuration")
+
+        central_layout = QtGui.QVBoxLayout()
+        central_layout.setMargin(0)
+        central_layout.setSpacing(0)
+        self.setLayout(central_layout)
+
+        self._scroll_area = QtGui.QScrollArea()
+        inner_widget = QtGui.QWidget()
+        self._list_layout = QtGui.QVBoxLayout()
+        scroll_layout = QtGui.QVBoxLayout()
+        scroll_layout.addLayout(self._list_layout)
+        scroll_layout.addStretch()
+        inner_widget.setLayout(scroll_layout)
+        self._scroll_area.setVerticalScrollBarPolicy(
+                QtCore.Qt.ScrollBarAlwaysOn)
+        self._scroll_area.setWidget(inner_widget)
+        self._scroll_area.setWidgetResizable(True)
+        central_layout.addWidget(self._scroll_area)
+
+        add_buttons = QtGui.QHBoxLayout()
+        central_layout.addLayout(add_buttons)
+        add_table = QtGui.QPushButton("Add a whole table")
+        self.connect(add_table, QtCore.SIGNAL('clicked()'),
+                     self.add_table)
+        add_buttons.addWidget(add_table)
+        add_column = QtGui.QPushButton("Add a list as a single column")
+        self.connect(add_column, QtCore.SIGNAL('clicked()'),
+                     self.add_column)
+        add_buttons.addWidget(add_column)
+
+        self.createButtons()
+
+        self.createEntries()
+
+    def add_item(self, item):
+        self._list_layout.addWidget(item)
+        self.connect(item, QtCore.SIGNAL('remove()'),
+                     lambda: item.deleteLater())
+        self.connect(item, QtCore.SIGNAL('changed()'),
+                     self.updateState)
+
+    def add_table(self):
+        self.add_item(TableEntry(
+                "Table #%d" % (self._list_layout.count() + 1)))
+        self.updateState()
+
+    def add_column(self):
+        self.add_item(ColumnEntry(
+                "Column #%d" % (self._list_layout.count() + 1)))
+        self.updateState()
+
+    def createButtons(self):
+        """ createButtons() -> None
+        Create and connect signals to Ok & Cancel button
+
+        """
+        buttonLayout = QtGui.QHBoxLayout()
+        buttonLayout.setMargin(5)
+        self.saveButton = QtGui.QPushButton("&Save", self)
+        self.saveButton.setFixedWidth(100)
+        self.saveButton.setEnabled(False)
+        buttonLayout.addWidget(self.saveButton)
+        self.resetButton = QtGui.QPushButton("&Reset", self)
+        self.resetButton.setFixedWidth(100)
+        self.resetButton.setEnabled(False)
+        buttonLayout.addWidget(self.resetButton)
+        self.layout().addLayout(buttonLayout)
+        self.connect(self.saveButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.saveTriggered)
+        self.connect(self.resetButton, QtCore.SIGNAL('clicked(bool)'),
+                     self.resetTriggered)
+
+    def saveTriggered(self, checked = False):
+        """ saveTriggered(checked: bool) -> None
+        Update vistrail controller and module when the user click Ok
+
+        """
+        if self.updateVistrail():
+            self.saveButton.setEnabled(False)
+            self.resetButton.setEnabled(False)
+            self.state_changed = False
+            self.emit(QtCore.SIGNAL('stateChanged'))
+            self.emit(QtCore.SIGNAL('doneConfigure'), self.module.id)
+
+    def closeEvent(self, event):
+        self.askToSaveChanges()
+        event.accept()
+
+    def getCurrentPorts(self):
+        current_ports = []
+        for port_spec in self.module.input_port_specs:
+            is_table = port_spec.signature[0][0] is not List
+            current_ports.append((port_spec.name, is_table))
+        return current_ports
+
+    def updateVistrail(self):
+        """ updateVistrail() -> None
+        Update Vistrail to contain changes in the port table
+
+        """
+        table_sig = '(%s:Table)' % identifier
+        list_sig = '(%s:List)' % get_vistrails_basic_pkg_id()
+        seen_new_ports = set()
+        current_ports = dict(self.getCurrentPorts())
+        add_ports = []
+        delete_ports = []
+        for i in xrange(self._list_layout.count()):
+            widget = self._list_layout.itemAt(i).widget()
+            is_table = isinstance(widget, TableEntry)
+            name = widget.name
+
+            if name in seen_new_ports:
+                QtGui.QMessageBox.critical(
+                        self,
+                        "Duplicated port name",
+                        "There is several input ports with name %r" % name)
+                return
+            seen_new_ports.add(name)
+
+            if name in current_ports:
+                old_is_table = current_ports.pop(name)
+                if is_table == old_is_table:
+                    continue
+                delete_ports.append(('input', name))
+
+            sigstring = table_sig if is_table else list_sig
+            add_ports.append(('input', name,
+                              sigstring, -1))
+
+        delete_ports.extend(('input', unseen_port)
+                            for unseen_port in current_ports.iterkeys())
+
+        self.controller.update_ports(self.module.id, delete_ports, add_ports)
+
+        return True
+
+    def createEntries(self):
+        for name, is_table in self.getCurrentPorts():
+            if is_table:
+                self.add_item(TableEntry(name))
+            else:
+                self.add_item(ColumnEntry(name))
+
+    def resetTriggered(self, checked = False):
+        for i in xrange(self._list_layout.count()):
+            self._list_layout.itemAt(i).widget().deleteLater()
+
+        self.createEntries()
+
+        self.saveButton.setEnabled(False)
+        self.resetButton.setEnabled(False)
+        self.state_changed = False
+        self.emit(QtCore.SIGNAL('stateChanged'))
+
+    def updateState(self):
+        self.saveButton.setEnabled(True)
+        self.resetButton.setEnabled(True)
+        if not self.state_changed:
+            self.state_changed = True
+            self.emit(QtCore.SIGNAL('stateChanged'))
diff --git a/vistrails/packages/tabledata/write/__init__.py b/vistrails/packages/tabledata/write/__init__.py
new file mode 100644
index 0000000..4fb6cf0
--- /dev/null
+++ b/vistrails/packages/tabledata/write/__init__.py
@@ -0,0 +1,136 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.modules.utils import make_modules_dict
+
+try:
+    # write_numpy requires numpy
+    import numpy
+except ImportError: # pragma: no cover
+    numpy_modules = []
+else:
+    from .write_numpy import _modules as numpy_modules
+
+from .write_excel import get_xlwt
+if get_xlwt():
+    from .write_excel import _modules as excel_modules
+else: # pragma: no cover
+    excel_modules = []
+
+from .write_csv import _modules as csv_modules
+
+
+_modules = make_modules_dict(numpy_modules, csv_modules, excel_modules,
+                             namespace='write')
+
+
+###############################################################################
+
+import unittest
+
+
+class BaseWriteTestCase(object):
+    def test_numeric(self):
+        from vistrails.tests.utils import execute, intercept_result
+        from ..common import ExtractColumn
+        from ..identifiers import identifier
+        with intercept_result(ExtractColumn, 'value') as results:
+            self.assertFalse(execute([
+                    ('BuildTable', identifier, [
+                        ('a', [('List', '[1, 2, 3]')]),
+                        ('b', [('List', '[4, 5, 6]')]),
+                    ]),
+                    (self.WRITER_MODULE, identifier, []),
+                    (self.READER_MODULE, identifier, []),
+                    ('ExtractColumn', identifier, [
+                        ('column_index', [('Integer', '1')]),
+                        ('numeric', [('Boolean', 'True')]),
+                    ]),
+                ], [
+                    (0, 'value', 1, 'table'),
+                    (1, 'file', 2, 'file'),
+                    (2, 'value', 3, 'table'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'a',
+                     'org.vistrails.vistrails.basic:List'),
+                    (0, 'input', 'b',
+                     'org.vistrails.vistrails.basic:List'),
+                ]))
+        self.assertEqual(len(results), 1)
+        self.assertEqual(list(results[0]), [4, 5, 6])
+
+    def test_strings(self):
+        from vistrails.tests.utils import execute, intercept_result
+        from ..common import ExtractColumn
+        from ..identifiers import identifier
+        with intercept_result(ExtractColumn, 'value') as results:
+            self.assertFalse(execute([
+                    ('BuildTable', identifier, [
+                        ('a', [('List', "['a', '2', 'c']")]),
+                        ('b', [('List', "[4, 5, 6]")]),
+                    ]),
+                    (self.WRITER_MODULE, identifier, []),
+                    (self.READER_MODULE, identifier, []),
+                    ('ExtractColumn', identifier, [
+                        ('column_index', [('Integer', '0')]),
+                        ('numeric', [('Boolean', 'False')]),
+                    ]),
+                ], [
+                    (0, 'value', 1, 'table'),
+                    (1, 'file', 2, 'file'),
+                    (2, 'value', 3, 'table'),
+                ],
+                add_port_specs=[
+                    (0, 'input', 'a',
+                     '(org.vistrails.vistrails.basic:List)'),
+                    (0, 'input', 'b',
+                     '(org.vistrails.vistrails.basic:List)'),
+                ]))
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0], ['a', '2', 'c'])
+
+
+ at unittest.skipIf(get_xlwt() is None, "xlwt not available")
+class ExcelWriteTestCase(unittest.TestCase, BaseWriteTestCase):
+    WRITER_MODULE = 'write|WriteExcelSpreadsheet'
+    READER_MODULE = 'read|ExcelSpreadsheet'
+
+
+class CSVWriteTestCase(unittest.TestCase, BaseWriteTestCase):
+    WRITER_MODULE = 'write|WriteCSV'
+    READER_MODULE = 'read|CSVFile'
diff --git a/vistrails/packages/tabledata/write/write_csv.py b/vistrails/packages/tabledata/write/write_csv.py
new file mode 100644
index 0000000..8ab8cf5
--- /dev/null
+++ b/vistrails/packages/tabledata/write/write_csv.py
@@ -0,0 +1,108 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from itertools import izip
+
+from vistrails.core import debug
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+from ..common import Table
+
+
+class WriteCSV(Module):
+    """Writes a table to a CSV file.
+
+    You can use the 'delimiter' and 'write_header' ports to choose the format
+    you want. By default, the file will include a single-line header if the
+    table has column names, and will use semicolon separators (';').
+    """
+    _input_ports = [
+            ('table', Table),
+            ('delimiter', '(org.vistrails.vistrails.basic:String',
+             {'optional': True, 'defaults': "[';']"}),
+            ('write_header', '(org.vistrails.vistrails.basic:Boolean)',
+             {'optional': True})]
+    _output_ports = [('file', '(org.vistrails.vistrails.basic:File)')]
+
+    @staticmethod
+    def write(fname, table, delimiter=';', write_header=True):
+        cols = [table.get_column(i) for i in xrange(table.columns)]
+
+        with open(fname, 'w') as fp:
+            if write_header and table.names is not None:
+                fp.write(delimiter.join(table.names) + '\n')
+
+            line = 0
+            for l in izip(*cols):
+                fp.write(delimiter.join(str(e) for e in l) + '\n')
+                line += 1
+
+        return line
+
+    def compute(self):
+        table = self.get_input('table')
+        delimiter = self.get_input('delimiter')
+        fileobj = self.interpreter.filePool.create_file(suffix='.csv')
+        fname = fileobj.name
+
+        with open(fname, 'w') as fp:
+            write_header = self.force_get_input('write_header')
+            if write_header is not False:
+                if table.names is None:
+                    if write_header is True:  # pragma: no cover
+                        raise ModuleError(
+                                self,
+                                "write_header is set but the table doesn't "
+                                "have column names")
+
+            if not table.columns:
+                raise ModuleError(
+                        self,
+                        "Table has no columns")
+
+            nb_lines = self.write(fname, table, delimiter,
+                                  write_header is not False)
+
+            rows = table.rows
+            if nb_lines != rows:  # pragma: no cover
+                debug.warning("WriteCSV wrote %d lines instead of expected "
+                              "%d" % (nb_lines, rows))
+
+        self.set_output('file', fileobj)
+
+
+_modules = [WriteCSV]
diff --git a/vistrails/packages/tabledata/write/write_excel.py b/vistrails/packages/tabledata/write/write_excel.py
new file mode 100644
index 0000000..52b20f8
--- /dev/null
+++ b/vistrails/packages/tabledata/write/write_excel.py
@@ -0,0 +1,89 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2013-2014, NYU-Poly.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.bundles.pyimport import py_import
+from vistrails.core import debug
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+
+from ..common import Table
+
+
+def get_xlwt():
+    try:
+        return py_import('xlwt', {
+                             'pip': 'xlwt',
+                             'linux-debian': 'python-xlwt',
+                             'linux-ubuntu': 'python-xlwt',
+                             'linux-fedora': 'python-xlwt'},
+                         True)
+    except ImportError: # pragma: no cover
+        return None
+
+
+class WriteExcelSpreadsheet(Module):
+    """Writes a table to an Excel spreadsheet file.
+    """
+    _input_ports = [('table', Table)]
+    _output_ports = [('file', '(org.vistrails.vistrails.basic:File)')]
+
+    def compute(self):
+        table = self.get_input('table')
+        rows = table.rows
+
+        xlwt = get_xlwt()
+        if xlwt is None: # pragma: no cover
+            raise ModuleError(self, "xlwt is not available")
+
+        workbook = xlwt.Workbook()
+        sheet = workbook.add_sheet('Sheet1')
+
+        fileobj = self.interpreter.filePool.create_file(suffix='.xls')
+        fname = fileobj.name
+
+        for c in xrange(table.columns):
+            column = table.get_column(c)
+            for r, e in enumerate(column):
+                sheet.write(r, c, e)
+            if r+1 != rows: # pragma: no cover
+                debug.warning("WriteExcelSpreadsheet wrote %d lines instead "
+                              "of expected %d" % (r, rows))
+
+        workbook.save(fname)
+        self.set_output('file', fileobj)
+
+
+_modules = [WriteExcelSpreadsheet]
diff --git a/vistrails/packages/tabledata/write/write_numpy.py b/vistrails/packages/tabledata/write/write_numpy.py
new file mode 100644
index 0000000..186f7be
--- /dev/null
+++ b/vistrails/packages/tabledata/write/write_numpy.py
@@ -0,0 +1,112 @@
+from __future__ import division
+
+import numpy
+
+from vistrails.core.modules.vistrails_module import Module
+
+from ..read.read_numpy import NumPyArray
+
+
+class WriteNumPy(Module):
+    """Writes a list as a Numpy file.
+
+    NumPy can use one of two schemes: either 'plain' binary arrays, i.e. just
+    the binary representation of the data format (in this case you must specify
+    the exact format to get the original data back), or the NPY format, i.e.
+    .npy files that know what the actual structure of the array is.
+    """
+    _input_ports = [
+            ('array', '(org.vistrails.vistrails.basic:List)'),
+            ('datatype', '(org.vistrails.vistrails.basic:String)',
+             {'entry_types': "['enum']",
+              'values': "[%r]" % NumPyArray.FORMAT_MAP.keys()})]
+    _output_ports = [('file', '(org.vistrails.vistrails.basic:File)')]
+
+    def compute(self):
+        array = self.get_input('array')
+        if not isinstance(array, numpy.ndarray):
+            array = numpy.array(array)
+        dtype = NumPyArray.FORMAT_MAP[self.get_input('datatype')]
+
+        if dtype is NumPyArray.NPY_FMT:
+            fileobj = self.interpreter.filePool.create_file(suffix='.npy')
+            fname = fileobj.name
+
+            # Numpy's ".NPY" format
+            numpy.save(fname, array)
+        else:
+            fileobj = self.interpreter.filePool.create_file(suffix='.dat')
+            fname = fileobj.name
+
+            # Numpy's plain binary format
+            array.astype(dtype).tofile(fname)
+
+        self.set_output('file', fileobj)
+
+
+_modules = [WriteNumPy]
+
+
+###############################################################################
+
+import unittest
+
+
+class WriteNumpyTestCase(unittest.TestCase):
+    def test_raw_numpy(self):
+        """Uses WriteNumPy to write an array in raw format.
+        """
+        import array
+        from vistrails.tests.utils import execute, intercept_result
+        from ..identifiers import identifier
+        with intercept_result(WriteNumPy, 'file') as results:
+            self.assertFalse(execute([
+                    ('write|WriteNumPy', identifier, [
+                        ('array', [('List', '[0, 1, 258, 6758]')]),
+                        ('datatype', [('String', 'uint32')]),
+                    ]),
+                ]))
+        self.assertEqual(len(results), 1)
+        expected_bytes = [0, 0, 0, 0,
+                          1, 0, 0, 0,
+                          2, 1, 0, 0,
+                          102, 26, 0, 0]
+        with open(results[0].name, 'rb') as fp:
+            self.assertEqual(fp.read(),
+                             array.array('B', expected_bytes).tostring())
+
+    def test_npy_numpy(self):
+        """Uses WriteNumPy to write an array in .NPY format.
+        """
+        from vistrails.tests.utils import execute, intercept_result
+        from ..identifiers import identifier
+        with intercept_result(WriteNumPy, 'file') as results:
+            self.assertFalse(execute([
+                    ('write|WriteNumPy', identifier, [
+                        ('array', [('List', '[0, 1, 258, 6758]')]),
+                        ('datatype', [('String', 'npy')]),
+                    ]),
+                ]))
+        self.assertEqual(len(results), 1)
+        self.assertEqual(list(numpy.load(results[0].name)), [0, 1, 258, 6758])
+
+    def test_write_read(self):
+        """Uses WriteNumPy and NumPyArray to write then read an array.
+        """
+        from vistrails.tests.utils import execute, intercept_result
+        from ..identifiers import identifier
+        for dtype in ('npy', 'uint32'):
+            with intercept_result(NumPyArray, 'value') as results:
+                self.assertFalse(execute([
+                        ('write|WriteNumPy', identifier, [
+                            ('array', [('List', '[0, 1, 258, 6758]')]),
+                            ('datatype', [('String', dtype)]),
+                        ]),
+                        ('read|NumPyArray', identifier, [
+                            ('datatype', [('String', dtype)]),
+                        ]),
+                    ], [
+                        (0, 'file', 1, 'file'),
+                    ]))
+            self.assertEqual(len(results), 1)
+            self.assertEqual(list(results[0]), [0, 1, 258, 6758])
diff --git a/vistrails/packages/tej/__init__.py b/vistrails/packages/tej/__init__.py
new file mode 100644
index 0000000..1039245
--- /dev/null
+++ b/vistrails/packages/tej/__init__.py
@@ -0,0 +1,3 @@
+identifier = 'org.vistrails.extra.tej'
+name = 'tej'
+version = '0.2'
diff --git a/vistrails/packages/tej/init.py b/vistrails/packages/tej/init.py
new file mode 100644
index 0000000..40c535c
--- /dev/null
+++ b/vistrails/packages/tej/init.py
@@ -0,0 +1,386 @@
+from __future__ import absolute_import, division
+
+import contextlib
+import io
+import logging
+import os
+import urllib
+
+from vistrails.core import debug
+from vistrails.core.bundles import py_import
+from vistrails.core.modules.basic_modules import PathObject
+from vistrails.core.modules.config import ModuleSettings
+from vistrails.core.modules.vistrails_module import Module, ModuleError, \
+    ModuleSuspended
+from vistrails.core.vistrail.job import JobMixin
+
+
+tej = py_import('tej', {'pip': 'tej'})
+
+
+assert __name__.endswith('.init')
+this_pkg = __name__[:-5]
+
+
+class ServerLogger(tej.ServerLogger):
+    def __init__(self):
+        self.hidden = False
+        tej.ServerLogger.__init__(self)
+
+    @contextlib.contextmanager
+    def hide_output(self):
+        self.hidden = True
+        try:
+            yield
+        finally:
+            self.hidden = False
+
+    def message(self, data):
+        if self.hidden:
+            debug.debug("tej server: %s" % data)
+        else:
+            debug.warning("tej server: %s" % data)
+
+ServerLogger = ServerLogger()
+
+
+class RemoteQueue(tej.RemoteQueue):
+    def server_logger(self):
+        return ServerLogger
+
+
+class QueueCache(object):
+    """A global cache of RemoteQueue objects.
+    """
+    def __init__(self):
+        self._cache = {}
+
+    def get(self, destination, queue):
+        key = destination, queue
+        if key in self._cache:
+            return self._cache[key]
+        else:
+            queue = RemoteQueue(destination, queue)
+            self._cache[key] = queue
+            return queue
+
+QueueCache = QueueCache()
+
+
+class Queue(Module):
+    """A connection to a queue on a remote server.
+
+    `hostname` can be a hostname or a full destination in the format:
+    ``[ssh://][user@]server[:port]``, e.g. ``vistrails at nyu.edu``.
+    """
+    _input_ports = [('hostname', '(basic:String)'),
+                    ('username', '(basic:String)',
+                     {'optional': True}),
+                    ('port', '(basic:Integer)',
+                     {'optional': True, 'defaults': "['22']"}),
+                    ('queue', '(basic:String)',
+                     {'optional': True, 'defaults': "['~/.tej']"})]
+    _output_ports = [('queue', '(org.vistrails.extra.tej:Queue)')]
+
+    def compute(self):
+        destination_str = self.get_input('hostname')
+        if self.has_input('username') or self.has_input('port'):
+            destination = {'hostname': destination_str,
+                           'username': self.get_input('username'),
+                           'port': self.get_input('port')}
+            destination_str = tej.destination_as_string(destination)
+
+        queue = self.get_input('queue')
+        self.set_output('queue', QueueCache.get(destination_str, queue))
+
+
+class RemoteJob(object):
+    def __init__(self, queue, job_id):
+        self.queue = queue
+        self.job_id = job_id
+
+    def finished(self):
+        try:
+            with ServerLogger.hide_output():
+                status, target, arg = self.queue.status(self.job_id)
+        except tej.JobNotFound:
+            # We signal that we are done
+            # The Module will raise an error on resume, as intended
+            return True
+        return status == tej.RemoteQueue.JOB_DONE
+
+
+class Job(Module):
+    """A reference to a job in a queue.
+
+    Objects represented by this type only represent completed jobs, since else,
+    the creating module would have failed/suspended.
+
+    You probably won't use this module directly since it references a
+    pre-existing job by name.
+    """
+    _input_ports = [('id', '(basic:String)'),
+                    ('queue', Queue)]
+    _output_ports = [('job', '(org.vistrails.extra.tej:Job)'),
+                     ('exitcode', '(basic:Integer)')]
+
+    def compute(self):
+        queue = self.get_input('queue')
+        job_id = self.get_input('id')
+
+        # Check job status
+        try:
+            with ServerLogger.hide_output():
+                status, target, arg = queue.status(job_id)
+        except tej.JobNotFound:
+            raise ModuleError(self, "Job not found")
+
+        # Create job object
+        job = RemoteJob(queue=queue, job_id=job_id)
+
+        if status == tej.RemoteQueue.JOB_DONE:
+            self.set_output('job', job)
+            self.set_output('exitcode', int(arg))
+        elif status == tej.RemoteQueue.JOB_RUNNING:
+            raise ModuleSuspended(self, "Remote job is running",
+                                  handle=job)
+        else:
+            raise ModuleError(self, "Invalid job status %r" % status)
+
+
+class BaseSubmitJob(JobMixin, Module):
+    """Starts a job on a server.
+
+    Thanks to the suspension/job tracking mechanism, this module does much more
+    than start a job. If the job is running, it will suspend again. If the job
+    is finished, you can obtain files from it.
+    """
+    _settings = ModuleSettings(abstract=True)
+    _input_ports = [('queue', Queue)]
+    _output_ports = [('job', '(org.vistrails.extra.tej:Job)'),
+                     ('exitcode', '(basic:Integer)')]
+
+    def make_id(self):
+        """Makes a default identifier, using the pipeline signature.
+
+        Unused if we have an explicit identifier.
+        """
+        if not hasattr(self, 'signature'):
+            raise ModuleError(self,
+                              "No explicit job ID and module has no signature")
+        return "vistrails_module_%s" % self.signature
+
+    def job_read_inputs(self):
+        """Reads the input ports.
+        """
+        return {'destination': self.get_input('queue').destination_string,
+                'queue': str(self.get_input('queue').queue),
+                'job_id': self.make_id()}
+
+    def job_start(self, params):
+        """Submits a job.
+
+        Reimplement in subclasses to actually submit a job.
+        """
+        raise NotImplementedError
+
+    def job_get_handle(self, params):
+        """Gets a RemoteJob object to monitor a runnning job.
+        """
+        queue = QueueCache.get(params['destination'], params['queue'])
+        return RemoteJob(queue, params['job_id'])
+
+    def job_finish(self, params):
+        """Finishes job.
+
+        Gets the exit code from the server.
+        """
+        queue = QueueCache.get(params['destination'], params['queue'])
+        status, target, arg = queue.status(params['job_id'])
+        assert status == tej.RemoteQueue.JOB_DONE
+        params['exitcode'] = int(arg)
+        return params
+
+    def job_set_results(self, params):
+        """Sets the output ports once the job is finished.
+        """
+        queue = QueueCache.get(params['destination'], params['queue'])
+        self.set_output('exitcode', params['exitcode'])
+        self.set_output('job', RemoteJob(queue, params['job_id']))
+
+
+class SubmitJob(BaseSubmitJob):
+    """Submits a generic job (a directory).
+    """
+    _input_ports = [('job', '(basic:Directory)'),
+                    ('script', '(basic:String)',
+                     {'optional': True, 'defaults': "['start.sh']"})]
+
+    def job_start(self, params):
+        """Sends the directory and submits the job.
+        """
+        queue = QueueCache.get(params['destination'], params['queue'])
+
+        # First, check if job already exists
+        try:
+            with ServerLogger.hide_output():
+                queue.status(params['job_id'])
+        except (tej.JobNotFound, tej.QueueDoesntExist):
+            pass
+        else:
+            return params
+
+        # Alright, submit a new job
+        queue.submit(params['job_id'],
+                     self.get_input('job').name,
+                     self.get_input('script'))
+        return params
+
+
+class SubmitShellJob(BaseSubmitJob):
+    """Submits a shell script.
+    """
+    _settings = ModuleSettings(configure_widget=(
+            '%s.widgets' % this_pkg, 'ShellSourceConfigurationWidget'))
+    _input_ports = [('source', '(basic:String)')]
+    _output_ports = [('stderr', '(basic:File)'),
+                     ('stdout', '(basic:File)')]
+
+    _job_interpreter = '/bin/sh'
+
+    def job_start(self, params):
+        """Creates a temporary job with the given source, upload and submit it.
+        """
+        queue = QueueCache.get(params['destination'], params['queue'])
+
+        # First, check if job already exists
+        try:
+            with ServerLogger.hide_output():
+                queue.status(params['job_id'])
+        except (tej.JobNotFound, tej.QueueDoesntExist):
+            pass
+        else:
+            return params
+
+        # Alright, submit a new job
+        directory = self.interpreter.filePool.create_directory(
+                prefix='vt_tmp_shelljob_').name
+        # We use io.open() here because we could be writing scripts on Windows
+        # before uploading them to a POSIX server
+        source = urllib.unquote(self.get_input('source'))
+        if isinstance(source, bytes):
+            kwargs = {'mode': 'wb'}
+        else:
+            kwargs = {'mode': 'w', 'newline': '\n'}
+        with io.open(os.path.join(directory, 'vistrails_source.sh'),
+                     **kwargs) as fp:
+            fp.write(source)
+        with io.open(os.path.join(directory, 'start.sh'), 'w',
+                     newline='\n') as fp:
+            fp.write(u'%s '
+                     u'vistrails_source.sh '
+                     u'>_stdout.txt '
+                     u'2>_stderr.txt\n' % self._job_interpreter)
+
+        queue.submit(params['job_id'], directory)
+
+        return params
+
+    def job_set_results(self, params):
+        """Gets stderr and stdout.
+        """
+        super(SubmitShellJob, self).job_set_results(params)
+
+        temp_dir = self.interpreter.filePool.create_directory(
+                prefix='vt_tmp_shelljobout_').name
+        queue = QueueCache.get(params['destination'], params['queue'])
+        queue.download(params['job_id'], ['_stderr.txt', '_stdout.txt'],
+                       directory=temp_dir)
+        self.set_output('stderr',
+                        PathObject(os.path.join(temp_dir, '_stderr.txt')))
+        self.set_output('stdout',
+                        PathObject(os.path.join(temp_dir, '_stdout.txt')))
+
+
+class DownloadFile(Module):
+    """Downloads a file from a remote job.
+    """
+    _input_ports = [('job', Job),
+                    ('filename', '(basic:String)')]
+    _output_ports = [('file', '(basic:File)')]
+
+    def compute(self):
+        job = self.get_input('job')
+        assert isinstance(job, RemoteJob)
+
+        destination = self.interpreter.filePool.create_file(
+                prefix='vt_tmp_shelljobout_')
+        job.queue.download(job.job_id,
+                           self.get_input('filename'),
+                           destination=destination.name,
+                           recursive=False)
+
+        self.set_output('file', destination)
+
+
+class DownloadDirectory(Module):
+    """Downloads a directory from a remote job.
+    """
+    _input_ports = [('job', Job),
+                    ('pathname', '(basic:String)')]
+    _output_ports = [('directory', '(basic:Directory)')]
+
+    def compute(self):
+        job = self.get_input('job')
+        assert isinstance(job, RemoteJob)
+
+        destination = self.interpreter.filePool.create_directory(
+                prefix='vt_tmp_shelljobout_').name
+        target = os.path.join(destination, 'dir')
+        job.queue.download(job.job_id,
+                           self.get_input('pathname'),
+                           destination=target,
+                           recursive=True)
+
+        self.set_output('directory', PathObject(target))
+
+
+_tej_log_handler = None
+
+
+class _VisTrailsTejLogHandler(logging.Handler):
+    def emit(self, record):
+        msg = "tej: %s" % self.format(record)
+        if record.levelno >= logging.CRITICAL:
+            debug.critical(msg)
+        elif record.levelno >= logging.WARNING:
+            debug.warning(msg)
+        elif record.levelno >= logging.INFO:
+            debug.log(msg)
+        else:
+            debug.debug(msg)
+
+
+def initialize():
+    # Route tej log messages to VisTrails
+    global _tej_log_handler
+    _tej_log_handler = _VisTrailsTejLogHandler()
+    tej_logger = logging.getLogger('tej')
+    tej_logger.propagate = False
+    tej_logger.addHandler(_tej_log_handler)
+    tej_logger.setLevel(logging.DEBUG)
+
+
+def finalize():
+    # Unregister logging handler; useful for reloading support
+    global _tej_log_handler
+    tej_logger = logging.getLogger('tej')
+    if _tej_log_handler is not None:
+        tej_logger.removeHandler(_tej_log_handler)
+        _tej_log_handler = None
+    tej_logger.propagate = True
+
+
+_modules = [Queue,
+            Job, BaseSubmitJob, SubmitJob, SubmitShellJob,
+            DownloadFile, DownloadDirectory]
diff --git a/vistrails/packages/tej/widgets.py b/vistrails/packages/tej/widgets.py
new file mode 100644
index 0000000..3eaa289
--- /dev/null
+++ b/vistrails/packages/tej/widgets.py
@@ -0,0 +1,15 @@
+from PyQt4 import QtGui
+
+from vistrails.gui.modules.source_configure import SourceConfigurationWidget
+
+
+class ShellSourceConfigurationWidget(SourceConfigurationWidget):
+    """Configuration widget for SubmitShellJob.
+
+    Allows the user to edit a shell script that will be run on the server.
+    """
+    def __init__(self, module, controller, parent=None):
+        SourceConfigurationWidget.__init__(self, module, controller,
+                                           QtGui.QTextEdit,
+                                           has_inputs=False, has_outputs=False,
+                                           parent=parent)
diff --git a/vistrails/packages/vtk/__init__.py b/vistrails/packages/vtk/__init__.py
index a5d56cc..fec7c42 100644
--- a/vistrails/packages/vtk/__init__.py
+++ b/vistrails/packages/vtk/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,6 +38,8 @@ software system for 3D computer graphics, image processing, and
 visualization used by thousands of researchers and developers around
 the world. http://www.vtk.org"""
 
+from __future__ import division
+
 from identifiers import *
 import vistrails.core
 
diff --git a/vistrails/packages/vtk/base_module.py b/vistrails/packages/vtk/base_module.py
deleted file mode 100644
index 5f64fce..0000000
--- a/vistrails/packages/vtk/base_module.py
+++ /dev/null
@@ -1,272 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-################################################################################
-# This describes basic modules used by other VTK module
-################################################################################
-from itertools import izip
-import vtk
-
-from vistrails.core.interpreter.base import AbortExecution
-from vistrails.core.modules.module_registry import registry
-from vistrails.core.modules.vistrails_module import Module, ModuleError
-from identifiers import identifier as vtk_pkg_identifier
-
-################################################################################
-
-class vtkBaseModule(Module):
-    """
-    vtkBaseModule is the base class for all VTK modules in VisTrails, it acts
-    as a wrapper to direct all input/output ports to appropriate VTK function
-    calls
-    
-    """
-
-    def __init__(self):
-        """ vtkBaseModule() -> vtkBaseModule
-        Instantiate an emptt VTK Module with real VTK instance
-        
-        """
-        Module.__init__(self)
-        self.vtkInstance = None
-
-    def is_cacheable(self):
-        # VTK objects are by default cacheable only if they're subclasses
-        # of vtkAlgorithm
-        return (issubclass(self.vtkClass, vtk.vtkAlgorithm)
-                and (not issubclass(self.vtkClass, vtk.vtkAbstractMapper)))
-
-    def call_input_function(self, function, params):
-        """self.call_input_function(function, params) -> None
-        Calls the input function on the vtkInstance, or a special
-        input function if one exists in the class."""
-        if hasattr(self, '_special_input_function_' + function):
-            attr = getattr(self, '_special_input_function_' + function)
-        else:
-            try:
-                attr = getattr(self.vtkInstance, function)
-            except AttributeError:
-                # Compensates for overload by exploiting the fact that
-                # no VTK method has underscores.
-                f = function.find('_')
-                if f != -1:
-                    function = function[:f]
-                attr = getattr(self.vtkInstance, function)
-
-        from init import get_method_signature, prune_signatures
-
-        doc = ''
-        try:
-            # doc = self.provide_output_port_documentation(function)
-            doc = self.get_doc(function)
-        except:
-            doc = ''
-
-        setterSig = []
-        if doc != '': setterSig = get_method_signature(None, doc, function)
-
-        if len(setterSig) > 1:
-            prune_signatures(self, function, setterSig)
-
-        pp = []
-        for j in xrange(len(setterSig)):
-          setter = list(setterSig[j][1]) if setterSig[j][1] != None else None
-          aux = []
-          if setter != None and len(setter) == len(params) and pp == []:
-              for i in xrange(len(setter)):
-                  if setter[i].find('[') != -1:
-                      del aux[:]
-                      aux.append(params[i])
-                  elif setter[i].find(']') != -1:
-                      aux.append(params[i])
-                      pp.append(aux)
-                  else:
-                      if len(aux) > 0: 
-                          aux.append(params[i])
-                      else:
-                          pp.append(params[i])                
-        if pp != []:
-            params = pp 
-            attr(*params)
-        else: 
-            attr(*params)
-        # print "Called ",attr,function,params
-
-    @classmethod
-    def get_doc(cls, port_name):
-        f = port_name.find('_')
-        if f != -1:
-            name = port_name[:f]
-        else:
-            name = port_name
-        return getattr(cls.vtkClass, name).__doc__
-
-    # @classmethod
-    # def provide_input_port_documentation(cls, port_name):
-    #     return cls.get_doc(port_name)
-
-    # @classmethod
-    # def provide_output_port_documentation(cls, port_name):
-    #     return cls.get_doc(port_name)
-
-    def compute(self):
-        """ compute() -> None
-        Actually perform real VTK task by directing all input/output ports
-        to VTK function calls
-        
-        """
-
-        def call_it(function, p):
-            # Translate between VisTrails objects and VTK objects
-            if p is None:
-                # None indicates a call with no parameters
-                params = []
-            elif isinstance(p, tuple):
-                # A tuple indicates a call with many parameters
-                params = list(p)
-            else:
-                # Otherwise, it's a single parameter
-                params = [p]
-
-            # Unwraps VTK objects
-            for i in xrange(len(params)):
-                if hasattr(params[i], 'vtkInstance'):
-                    params[i] = params[i].vtkInstance
-            try:
-                self.call_input_function(function, params)
-            except Exception, e:
-                msg = 'VTK Exception: '
-                raise ModuleError(self, msg  + str(type(e)) + ': ' + str(e))
-
-        # Always re-create vtkInstance module, no caching here
-        if self.vtkInstance:
-            del self.vtkInstance
-        self.vtkInstance = self.vtkClass()
-
-        # We need to call method ports before anything else, and in
-        # the right order.
-
-        # FIXME: This does not belong here, it belongs in the main class
-        # No time for that now
-        methods = self.is_method.values()
-        methods.sort()
-        for value in methods:
-            (_, port) = value
-            conn = self.is_method.inverse[value]
-            p = conn()
-            call_it(port, p)
-
-        # Make sure all input ports are called correctly
-        for (function, connector_list) in self.inputPorts.iteritems():
-            paramList = self.forceGetInputListFromPort(function)
-            if function[:18]=='SetInputConnection':
-                paramList = zip([int(function[18:])]*len(paramList),
-                                 paramList)
-                function = 'SetInputConnection'
-            if function=='AddInputConnection':
-                desc = registry.get_descriptor_by_name(
-                    vtk_pkg_identifier,
-                    'vtkAlgorithmOutput')
-                for i in xrange(len(paramList)):
-                    if isinstance(paramList[i], desc.module):
-                        paramList[i] = (0, paramList[i])
-            for p,connector in izip(paramList, connector_list):
-                # Don't call method
-                if connector in self.is_method:
-                    continue
-                call_it(function, p)
-                
-        #In the case of a vtkRenderer, 
-        # we need to call the methods after the
-        #input ports are set.
-        if isinstance(self.vtkInstance, vtk.vtkRenderer):
-            for value in methods:
-                (_, port) = value
-                conn = self.is_method.inverse[value]
-                p = conn()
-                call_it(port, p)
-
-        # Call update if appropriate
-        if hasattr(self.vtkInstance, 'Update'):
-            is_aborted = False
-            isAlgorithm = issubclass(self.vtkClass, vtk.vtkAlgorithm)
-            cbId = None
-            if isAlgorithm:
-                def ProgressEvent(obj, event):
-                    try:
-                        self.logging.update_progress(self, obj.GetProgress())
-                    except AbortExecution:
-                        obj.SetAbortExecute(True)
-                        self.vtkInstance.RemoveObserver(cbId)
-                        is_aborted = True
-                cbId = self.vtkInstance.AddObserver('ProgressEvent', ProgressEvent)
-            self.vtkInstance.Update()
-            if isAlgorithm and not is_aborted:
-                self.vtkInstance.RemoveObserver(cbId)
-
-        # Then update the output ports also with appropriate function calls
-        for function in self.outputPorts.keys():
-            if function[:13]=='GetOutputPort':
-                i = int(function[13:])
-                vtkOutput = self.vtkInstance.GetOutputPort(i)
-                output = vtkBaseModule.wrapperModule('vtkAlgorithmOutput',
-                                                     vtkOutput)
-                self.setResult(function, output)
-            elif hasattr(self.vtkInstance, function):
-                retValues = getattr(self.vtkInstance, function)()
-                if issubclass(retValues.__class__, vtk.vtkObject):
-                    className = retValues.GetClassName()
-                    output  = vtkBaseModule.wrapperModule(className, retValues)
-                    self.setResult(function, output)
-                elif isinstance(retValues, (tuple, list)):
-                    result = list(retValues)
-                    for i in xrange(len(result)):
-                        if issubclass(result[i].__class__, vtk.vtkObject):
-                            className = result[i].GetClassName()
-                            result[i] = vtkBaseModule.wrapperModule(className,
-                                                                    result[i])
-                    self.setResult(function, type(retValues)(result))
-                else:
-                    self.setResult(function, retValues)
-
-    @staticmethod
-    def wrapperModule(classname, instance):
-        """ wrapperModule(classname: str, instance: vtk class) -> Module
-        Create a wrapper module in VisTrails with a vtk instance
-        
-        """
-        result = registry.get_descriptor_by_name(vtk_pkg_identifier,
-                                                 classname).module()
-        result.vtkInstance = instance
-        return result
diff --git a/vistrails/packages/vtk/class_tree.py b/vistrails/packages/vtk/class_tree.py
deleted file mode 100644
index 9451e0e..0000000
--- a/vistrails/packages/vtk/class_tree.py
+++ /dev/null
@@ -1,303 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-
-# Author: Prabhu Ramachandran
-# Copyright (c) 2004, Enthought, Inc.
-# License: BSD Style.
-
-"""This module generates the class hierarchy for any given Python
-modules.  This can be used (among other things) to generate the
-traitified VTK classes in the correct order.
-
-"""
-
-import __builtin__
-
-
-class TreeNode(object):
-    """Represents a node in the class tree.
-
-    Stores information on the sub and super classes of a particular
-    class.  It also stores the inheritance level of the class inside
-    the inheritance tree (essentially how many levels of inheritance
-    are there below this class).  This inheritance level is computed
-    when the `get_level` method is called.  The `get_level` method
-    works only when the parent information is complete.
-    
-    """
-
-    def __init__(self, klass):
-        """Given a class, create a node in the tree.
-
-        Parameters
-        ----------
-        - klass : `class`
-
-          The class which is represented as a node in the tree.
-
-        """
-        self.klass = klass
-        self.name = klass.__name__
-        self.children = []
-        self.parents = []
-        # Uninitialized level is set to None
-        self.level = None
-
-    def add_parent(self, parent):
-        """Add a parent node."""
-        assert isinstance(parent, TreeNode)
-        if parent not in self.parents:
-            self.parents.append(parent)
-
-    def add_child(self, child):
-        """Add a child node. """
-        assert isinstance(child, TreeNode)
-        if child not in self.children:
-            self.children.append(child)
-
-    def get_level(self):
-        """Returns the inheritance level of the node (an int).  If the
-        level has not been set, the method computes it.  Note however,
-        that this computation will fail if the parent information is
-        incorrect.
-
-        """
-        if not self.level:
-            if self.parents:
-                self.level = max([x.get_level() for x in self.parents]) + 1
-            else:
-                self.level = 0
-        return self.level
-
-    def get_ancestors(self):
-        """Returns a list of ancestor nodes from which this class has
-        descended.
-
-        """
-        def _get_ancestors(node, ancestors):
-            ancestors.extend(node.parents)
-            for p in node.parents:
-                _get_ancestors(p, ancestors)
-        ancestors = []
-        _get_ancestors(self, ancestors)
-        return ancestors
-
-
-class ClassTree(object):
-    """Contains and generates all the class tree information.
-
-    On initialization of the instance, nothing is done.  The classes
-    are obtained using the list of modules (or a single module) that
-    is used to initialize the instance.  One must then call the
-    `create` method to generate the tree structure.  The instance of
-    the class also can be treated as an iterator which iterates over
-    the nodes of the tree.
-
-    There are two ways in which the tree hierarchy is stored.  A
-    dictionary mapping class names to the tree node and a tree
-    represented as a list of lists containing the nodes.  The tree is
-    organized based on a concept of an inheritance level.  A class
-    that has no parent classes (no base classes) is said to be at
-    level zero.  If a class inherits successively from 7 classes, it
-    is at level 6.  An example of inheritance for a vtkFoo class is
-    given below:
-
-      vtkFoo -> vtkBar -> vtkObject -> vtkObjectBase
-
-    Here, vtkObjectBase has an inheritance level of 0 and vtkFoo a
-    level of 3.  One can traverse the tree by using the level as an
-    index and find all the classes at a particular level.
-
-    Here is some example usage of this class::
-
-        >>> import vtk
-        >>> t = ClassTree(vtk)
-        >>> t.create()
-        >>> print t.get_node('vtkObject').name
-        vtkObject
-        >>> print t.get_node('vtkObject').parents[0].name
-        vtkObjectBase
-        >>> print len(t.tree[0])
-        1
-        >>> t.tree[0][0].name
-        vtkObjectBase
-    
-    """
-
-    def __init__(self, modules):
-        """Initialize the instance with the given modules.
-
-        Parameters
-        ----------
-
-        - modules : `sequence` of modules or a module
-
-          This is either a single module or a sequence of modules.
-          The instance uses these list of modules to generate the
-          class tree.
-          
-        """
-        self.nodes = {}
-        self.tree = [[]]
-        if not hasattr(modules, '__iter__'):
-            self.modules = [modules]
-        else:
-            self.modules = modules
-
-    def __iter__(self):
-        return iter(self.nodes.values())
-
-    def _generate_hierarchy(self, klass):
-        """Does the hard work of generating the class hierarchy."""
-        node = self.get_node(klass.__name__, create=1)
-        for base in klass.__bases__:
-            base_node = self.get_node_from_class(base, create=1)
-            node.add_parent(base_node)
-            base_node.add_child(node)
-            self._generate_hierarchy(base)
-
-    def get_class(self, name):
-        """Given a class name in the given modules returns the class."""
-        klass = None
-        for m in self.modules:
-            if hasattr(m, name):
-                return getattr(m, name)
-        if hasattr(__builtin__, name):
-            klass = getattr(__builtin__, name)
-        if not klass:
-            try:
-                klass = self.nodes[name].klass
-            except KeyError:
-                raise KeyError, "Cannot find class of name %s"%name
-        return klass
-
-    def add_node(self, klass):
-        """Create a node for the given class."""
-        name = klass.__name__
-        if not self.nodes.has_key(name):
-            node = TreeNode(klass)
-            self.nodes[name] = node
-            return node
-
-    def get_node(self, name, create=0):
-        """Get a node of the given name.
-
-        Parameters
-        ----------
-
-        - name : `str`
-
-          Name of the node to get.
-
-        - create : `boolean`
-
-          If True, a new node will be added if no node of the given
-          name is available.  Defaults to False.
-
-        Returns
-        -------
-
-        - `TreeNode`
-
-        """
-        if self.nodes.has_key(name):
-            return self.nodes[name]
-        elif create:
-            return self.add_node(self.get_class(name))
-
-    def get_node_from_class(self, cls, create=0):
-        """Get a node of the given class.
-
-        Parameters
-        ----------
-
-        - cls : `class`
-
-          Class of the node to get.
-
-        - create : `boolean`
-
-          If True, a new node will be added if no node of the given
-          name is available.  Defaults to False.
-
-        Returns
-        -------
-
-        - `TreeNode`
-
-        """
-        name = cls.__name__
-        if self.nodes.has_key(name):
-            return self.nodes[name]
-        elif create:
-            return self.add_node(cls)
-
-    def create(self, class_names=None):
-        """This method generates the class tree given an optional list
-        of class names.
-
-        Parameters
-        ----------
-
-        - class_names - `list` of `str`
-
-          An optional list of names of the classes to generate the
-          tree for.  Defaults to None where the class list is computed
-          from the modules.        
-
-        """
-        if class_names is None:
-            class_names = []
-            for m in self.modules:            
-                class_names.extend(dir(m))
-            
-        # Generate the nodes.
-        for name in class_names:
-            klass = self.get_class(name)
-            if klass and hasattr(klass, '__bases__'):
-                self._generate_hierarchy(klass)
-
-        # Compute the inheritance level and store the nodes in the tree.
-        for node in self:
-            d = node.get_level()
-            while len(self.tree) <= d:
-                self.tree.append([])
-            self.tree[d].append(node)
-
-        # Sort the nodes alphabetically.
-        def _comp(x, y):
-            return cmp(x.name, y.name)
-        for nodes in self.tree:
-            nodes.sort(_comp)
diff --git a/vistrails/packages/vtk/common.py b/vistrails/packages/vtk/common.py
new file mode 100644
index 0000000..7e4e348
--- /dev/null
+++ b/vistrails/packages/vtk/common.py
@@ -0,0 +1,88 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from vistrails.core.modules.basic_modules import Color, Path, PathObject
+from vistrails.core.utils import InstanceObject
+
+#### Automatic conversion between some vistrail and python types ####
+def convert_input_param(value, _type):
+    if issubclass(_type, Path):
+        return value.name
+    if issubclass(_type, Color):
+        return value.tuple
+    return value
+
+def convert_output_param(value, _type):
+    if issubclass(_type, Path):
+        return PathObject(value)
+    if issubclass(_type, Color):
+        return InstanceObject(tuple=value)
+    return value
+
+def convert_input(value, signature):
+    if len(signature) == 1:
+        return convert_input_param(value, signature[0][0])
+    return tuple([convert_input_param(v, t[0]) for v, t in zip(value, signature)])
+
+def convert_output(value, signature):
+    if len(signature) == 1:
+        return convert_output_param(value, signature[0][0])
+    return tuple([convert_output_param(v, t[0]) for v, t in zip(value, signature)])
+
+
+def get_input_spec(cls, name):
+    """ Get named input spec from self or superclass
+    """
+    klasses = iter(cls.__mro__)
+    base = cls
+    while base and hasattr(base, '_input_spec_table'):
+        if name in base._input_spec_table:
+            return base._input_spec_table[name]
+        base = klasses.next()
+    return None
+
+def get_output_spec(cls, name):
+    """ Get named output spec from self or superclass
+    """
+    klasses = iter(cls.__mro__)
+    base = cls
+    while base and hasattr(base, '_output_spec_table'):
+        if name in base._output_spec_table:
+            return base._output_spec_table[name]
+        base = klasses.next()
+    return None
diff --git a/vistrails/packages/vtk/fix_classes.py b/vistrails/packages/vtk/fix_classes.py
deleted file mode 100644
index 084ea5f..0000000
--- a/vistrails/packages/vtk/fix_classes.py
+++ /dev/null
@@ -1,67 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-
-import vtk
-
-################################################################################
-# Some fixed classes that solve a few VTK API issues
-
-# This dictionary stores the patched class to vtk class mapping.
-# This would be naturally better stored as an attribute directly on the
-# patched class. VTK, however, doesn't like class attributes.
-description = {}
-
-# http://www.vtk.org/doc/nightly/html/classvtkImagePlaneWidget.html
-# SetUserControlledLookupTable needs to be set before calling
-# SetLookupTable.  VTK should do it automatically, so let's fix it
-
-
-# This fix seems to break on VTK versions larger than 5.0.3. It might also
-# be because of an interaction with python 2.6, but I haven't checked that.
-class vtkImagePlaneWidget_fixed(vtk.vtkImagePlaneWidget):
-    def SetLookupTable(self, lookup_table):
-        self.UserControlledLookupTableOn()
-        vtk.vtkImagePlaneWidget.SetLookupTable(self, lookup_table)
-v = vtk.vtkVersion()
-version = [v.GetVTKMajorVersion(),
-           v.GetVTKMinorVersion(),
-           v.GetVTKBuildVersion()]
-if version < [5, 0, 4]:
-    description[vtkImagePlaneWidget_fixed] = vtk.vtkImagePlaneWidget
-else:
-    description[id(vtkImagePlaneWidget_fixed)] = vtk.vtkImagePlaneWidget
-
-# Set docstring to wrap it correctly
-vtkImagePlaneWidget_fixed.SetLookupTable.__doc__ = vtk.vtkImagePlaneWidget.SetLookupTable.__doc__
diff --git a/vistrails/packages/vtk/hasher.py b/vistrails/packages/vtk/hasher.py
index a238541..7a9f3b1 100644
--- a/vistrails/packages/vtk/hasher.py
+++ b/vistrails/packages/vtk/hasher.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 # This is the user-defined hasher for VTK, that takes into account
 # incoming and outgoing connections
+from __future__ import division
+
 from vistrails.core.cache.hasher import Hasher
 
 def vtk_hasher(pipeline, module, chm):
diff --git a/vistrails/packages/vtk/identifiers.py b/vistrails/packages/vtk/identifiers.py
index 3402231..0dd2417 100644
--- a/vistrails/packages/vtk/identifiers.py
+++ b/vistrails/packages/vtk/identifiers.py
@@ -1,38 +1,42 @@
 ###############################################################################
 ##
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.vtk'
 old_identifiers = ['edu.utah.sci.vistrails.vtk']
 name = 'VTK'
-version = '0.9.4'
+version = '1.0.1'
diff --git a/vistrails/packages/vtk/init.py b/vistrails/packages/vtk/init.py
index 75961de..9b585a9 100644
--- a/vistrails/packages/vtk/init.py
+++ b/vistrails/packages/vtk/init.py
@@ -1,1221 +1,201 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-################################################################################
-# VTK Package for VisTrails
-################################################################################
+from __future__ import division
 
-from vistrails.core.debug import debug
-from vistrails.core.modules.basic_modules import Integer, Float, String, File, \
-     Color, identifier as basic_pkg
-from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.modules.vistrails_module import new_module, ModuleError
-from vistrails.core.system import get_vistrails_default_pkg_prefix
-from identifiers import identifier as vtk_pkg_identifier
-from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler
-from vistrails.core.utils import all, any, InstanceObject
-from vistrails.core.vistrail.connection import Connection
-
-from hasher import vtk_hasher
-from itertools import izip
-import os.path
+import copy
 import re
-import warnings
+import os.path
 
 import vtk
 
-from base_module import vtkBaseModule
-from class_tree import ClassTree
-import fix_classes
-import inspectors
-import offscreen
-import tf_widget
-from vtk_parser import VTKMethodParser
-
-
-#TODO: Change the Core > Module > Registry > Add Input : To support vector as type.
-
-################################################################################
-
-# filter some deprecation warnings coming from the fact that vtk calls
-# range() with float parameters
-
-warnings.filterwarnings("ignore",
-                        message="integer argument expected, got float")
-
-################################################################################
-v = vtk.vtkVersion()
-version = [v.GetVTKMajorVersion(),
-           v.GetVTKMinorVersion(),
-           v.GetVTKBuildVersion()]
-if version < [5, 0, 4]:
-    def get_description_class(klass):
-        """Because sometimes we need to patch VTK classes, the klass that
-        has the methods is different than the klass we want to
-        instantiate. get_description_class makes sure that for patched
-        classes we get the correct one."""
-        try:
-            return fix_classes.description[klass]
-        except KeyError:
-            return klass
-else:
-    # On VTK 5.0.4, we use the id of the class to hash, because it
-    # seems that VTK hasn't implemented hash() correctly for their
-    # classes.
-    def get_description_class(klass):
-        """Because sometimes we need to patch VTK classes, the klass that
-        has the methods is different than the klass we want to
-        instantiate. get_description_class makes sure that for patched
-        classes we get the correct one."""
-        try:
-            return fix_classes.description[id(klass)]
-        except KeyError:
-            return klass
-
-parser = VTKMethodParser()
-
-typeMapDict = {'int': Integer,
-               'long': Integer,
-               'float': Float,
-               'char*': String,
-               'char *': String,
-               'string': String,
-               'char': String,
-               'const char*': String,
-               'const char *': String,
-               '[float': Float,         
-               'float]': Float,
-               '[int': Integer,
-               'int]': Integer}
-typeMapDictValues = [Integer, Float, String]
-
-file_name_pattern = re.compile('.*FileName$')
-set_file_name_pattern = re.compile('Set.*FileName$')
-
-def resolve_overloaded_name(name, ix, signatures):
-    # VTK supports static overloading, VisTrails does not. The
-    # solution is to check whether the current function has
-    # overloads and change the names appropriately.
-    if len(signatures) == 1:
-        return name
-    else:
-        return name + '_' + str(ix+1)
-
-def typeMap(name, package=None):
-    """ typeMap(name: str) -> Module
-    Convert from C/C++ types into VisTrails Module type
-    
-    """
-    if package is None:
-        package = identifier
-    if isinstance(name, tuple):
-        return [typeMap(x, package) for x in name]
-    if name in typeMapDict:
-        return typeMapDict[name]
-    else:
-        registry = get_module_registry()
-        if not registry.has_descriptor_with_name(package, name):
-            return None
-        else:
-            return registry.get_descriptor_by_name(package,
-                                                   name).module
-
-def get_method_signature(method, docum='', name=''):
-    """ get_method_signature(method: vtkmethod) -> [ret, arg]
-    Re-wrap Prabu's method to increase performance
-
-    """
-    doc = method.__doc__ if docum=='' else docum
-    tmptmp = doc.split('\n')
-    tmp = []
-    for l in tmptmp:
-        l = l.strip('\n \t')
-        if l.startswith('V.') or l.startswith('C++:'):
-            tmp.append(l)
-        else:
-            if (len(tmp) != 0):       
-                tmp[-1] = tmp[-1] + ' ' + l
-    tmp.append('')
-    sig = []        
-    pat = re.compile(r'\b')
-
-    # Remove all the C++ function signatures and V.<method_name> field  
-    name = method.__name__ if name == '' else name
-    offset = 2+len(name)
-    for i in xrange(len(tmp)):
-        s = tmp[i]
-        if s=='': break
-        if i%2==0:
-            x = s.split('->')
-            arg = x[0].strip()[offset:]
-            if len(x) == 1: # No return value
-                ret = None
-            else:
-                ret = x[1].strip()
-
-            # Remove leading and trailing parens for arguments.
-            arg = arg[1:-1]
-            if not arg:
-                arg = None
-            if arg and arg[-1] == ')':
-                arg = arg + ','
-
-            # Now quote the args and eval them.  Easy!
-            if ret and ret[:3]!='vtk':
-                try:
-                    ret = eval(pat.sub('\"', ret))
-                except:
-                    continue
-            if arg:
-                if arg.find('(')!=-1:
-                    try:
-                        arg = eval(pat.sub('\"', arg))
-                    except:
-                        continue
-                else:
-                    arg = arg.split(', ')
-                    if len(arg)>1:
-                        arg = tuple(arg)
-                    else:
-                        arg = arg[0]
-                if isinstance(arg, str):
-                    arg = [arg]
-
-            sig.append(([ret], arg))
-    return sig    
-
-def prune_signatures(module, name, signatures, output=False):
-    """prune_signatures tries to remove redundant signatures to reduce
-    overloading. It _mutates_ the given parameter.
-
-    It does this by performing several operations:
-
-    1) It compares a 'flattened' version of the types
-    against the other 'flattened' signatures. If any of them match, we
-    keep only the 'flatter' ones.
-
-    A 'flattened' signature is one where parameters are not inside a
-    tuple.
-
-    2) We explicitly forbid a few signatures based on modules and names
-
-    """
-    # yeah, this is Omega(n^2) on the number of overloads. Who cares?
-
-    def flatten(type_):
-        if type_ is None:
-            return []
-        def convert(entry):
-            if isinstance(entry, tuple):
-                return list(entry)
-            elif isinstance(entry, str):
-                return [entry]
-            else:
-                result = []
-                first = True
-                lastList = True
-                for e in entry:
-                    if (isinstance(e, list)):
-                        if lastList == False: result[len(result)] = result[len(result)] + ']'  
-                        aux = e
-                        aux.reverse()
-                        aux[0] = '[' + aux[0]
-                        aux[-1] = aux[-1] + ']'
-                        result.extend(aux)
-                        lastList = True
-                    else:
-                        if first: e = '[' + e
-                        result.append(e)
-                        lastList = False
-                        first = False
-                return result
-        result = []
-        for entry in type_:
-            result.extend(convert(entry))
-        return result
-    flattened_entries = [flatten(sig[1]) for
-                         sig in signatures]
-    def hit_count(entry):
-        result = 0
-        for entry in flattened_entries:
-            if entry in flattened_entries:
-                result += 1
-        return result
-    hits = [hit_count(entry) for entry in flattened_entries]
-
-    def forbidden(flattened, hit_count, original):
-        if (issubclass(get_description_class(module.vtkClass), vtk.vtk3DWidget) and
-            name == 'PlaceWidget' and
-            flattened == []):
-            return True
-        # We forbid this because addPorts hardcodes this but
-        # SetInputArrayToProcess is an exception for the InfoVis
-        # package
-        if (get_description_class(module.vtkClass) == vtk.vtkAlgorithm and
-            name!='SetInputArrayToProcess'):
-            return True
-        return False
-
-    # This is messy: a signature is only allowed if there's no
-    # explicit disallowing of it. Then, if it's not overloaded,
-    # it is also allowed. If it is overloaded and not the flattened
-    # version, it is pruned. If these are output ports, there can be
-    # no parameters.
-
-    def passes(flattened, hit_count, original):
-        if forbidden(flattened, hit_count, original):
-            return False
-        if hit_count == 1:
-            return True
-        if original[1] is None:
-            return True
-        if output and len(original[1]) > 0:
-            return False
-        if hit_count > 1 and len(original[1]) == len(flattened):
-            return True
-        return False
-    
-    signatures[:] = [original for (flattened, hit_count, original)
-                     in izip(flattened_entries,
-                             hits,
-                             signatures)
-                     if passes(flattened, hit_count, original)]
-    
-    #then we remove the duplicates, if necessary
-    unique_signatures = []
-    
-    #Remove the arrays and tuples inside the signature
-    #  in order to transform it in a single array
-    #Also remove the '[]' from the Strings
-    def removeBracts(signatures):
-        result = []
-        stack = list(signatures)
-        while (len(stack) != 0):
-            curr = stack.pop(0)
-            if (isinstance(curr, (String, str))):
-                c = curr.replace('[', '')
-                c = c.replace(']', '')
-                result.append(c)
-            elif (curr == None):
-                result.append(curr)
-            elif (isinstance(curr, list)):
-                curr.reverse()
-                for c in curr: stack.insert(0, c)
-            elif (isinstance(curr, tuple)):
-                cc = list(curr)
-                cc.reverse()
-                for c in cc: stack.insert(0, c)
-            else:
-                result.append(curr)
-        return result
-
-    unique2 = []
-    for s in signatures:
-        aux = removeBracts(s)
-        if not unique2.count(aux): 
-            unique_signatures.append(s)
-            unique2.append(aux)
-    signatures[:] = unique_signatures
-    
-disallowed_classes = set(
-    [
-    'simplewrapper', # ticket 464: VTK 5.10 on OpenSuSE needs this
-    'vtkCriticalSection',
-    'vtkDataArraySelection',
-    'vtkDebugLeaks',
-    'vtkDirectory',
-    'vtkDynamicLoader',
-    'vtkFunctionParser',
-    'vtkGarbageCollector',
-    'vtkHeap',
-    'vtkInformationKey',
-    'vtkInstantiator',
-    'vtkLogLookupTable', # VTK: use vtkLookupTable.SetScaleToLog10() instead
-    'vtkMath',
-    'vtkModelMetadata',
-    'vtkMultiProcessController',
-    'vtkMutexLock',
-    'vtkOutputWindow',
-    'vtkPriorityQueue',
-    'vtkQtInitialization',
-    'vtkReferenceCount',
-    'vtkRenderWindowCollection',
-    'vtkRenderWindowInteractor',
-    'vtkTesting',
-    'vtkWindow',
-    'vtkContext2D',       #Not working for VTK 5.7.0
-    'vtkPLYWriter',       #Not working for VTK 5.7.0. 
-    'vtkBooleanTexture',  #Not working for VTK 5.7.0
-    'vtkImageMaskBits',   #Not working for VTK 5.7.0
-    'vtkHardwareSelector',#Not working for VTK 5.7.0
-     ])
-
-def is_class_allowed(module):
-    if module is None:
-        return False
-    try:
-        name = module.__name__
-        return not (name in disallowed_classes)
-    except AttributeError:
+from vistrails.core.configuration import ConfigField
+from vistrails.core.modules.basic_modules import PathObject, \
+                                                       identifier as basic_pkg
+from vistrails.core.modules.config import ModuleSettings
+from vistrails.core.modules.vistrails_module import ModuleError
+from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.modules.output_modules import OutputModule, ImageFileMode, \
+    ImageFileModeConfig, IPythonMode, IPythonModeConfig
+from vistrails.core.system import get_vistrails_default_pkg_prefix, systemType, current_dot_vistrails
+from vistrails.core.upgradeworkflow import UpgradeWorkflowHandler,\
+                                       UpgradeModuleRemap, UpgradePackageRemap
+from vistrails.core.vistrail.connection import Connection
+from .pythonclass import BaseClassModule, gen_class_module
+
+from .tf_widget import _modules as tf_modules
+from .inspectors import _modules as inspector_modules
+from .offscreen import _modules as offscreen_modules
+
+from identifiers import identifier, version as package_version
+
+from .vtk_wrapper import vtk_classes
+from . import hasher
+
+
+_modules = tf_modules + inspector_modules + offscreen_modules
+
+registry = get_module_registry()
+if registry.has_module('org.vistrails.vistrails.spreadsheet', 'SpreadsheetCell'):
+    # load these only if spreadsheet is enabled
+    from .vtkcell import _modules as cell_modules
+    from .vtkhandler import _modules as handler_modules
+    _modules += cell_modules + handler_modules
+
+
+################# OUTPUT MODULES #############################################
+
+def render_to_image(output_filename, vtk_format, renderer, w, h):
+    window = vtk.vtkRenderWindow()
+    window.OffScreenRenderingOn()
+    window.SetSize(w, h)
+
+    # FIXME think this may be fixed in VTK6 so we don't have this
+    # dependency...
+    widget = None
+    if systemType=='Darwin':
+        from PyQt4 import QtCore, QtGui
+        widget = QtGui.QWidget(None, QtCore.Qt.FramelessWindowHint)
+        widget.resize(w, h)
+        widget.show()
+        window.SetWindowInfo(str(int(widget.winId())))
+
+    window.AddRenderer(renderer)
+    window.Render()
+    win2image = vtk.vtkWindowToImageFilter()
+    win2image.SetInput(window)
+    win2image.Update()
+    writer = vtk_format()
+    writer.SetInput(win2image.GetOutput())
+    writer.SetFileName(output_filename)
+    writer.Write()
+    window.Finalize()
+    if widget!=None:
+        widget.close()
+
+class vtkRendererToFile(ImageFileMode):
+    config_cls = ImageFileModeConfig
+    formats = ['png', 'jpg', 'tif', 'pnm']
+
+    @classmethod
+    def can_compute(cls):
         return True
 
-def addAlgorithmPorts(module):
-    """ addAlgorithmPorts(module: Module) -> None
-    If module is a subclass of vtkAlgorithm, this function will add all
-    SetInputConnection([id],[port]) and GetOutputPort([id]) as
-    SetInputConnection{id}([port]) and GetOutputPort{id}.
+    def compute_output(self, output_module, configuration):
+        format_map = {'png': vtk.vtkPNGWriter,
+                      'jpg': vtk.vtkJPEGWriter,
+                      'tif': vtk.vtkTIFFWriter,
+                      'pnm': vtk.vtkPNMWriter}
+        r = output_module.get_input("value")[0].vtkInstance
+        w = configuration["width"]
+        h = configuration["height"]
+        img_format = self.get_format(configuration)
+        if img_format not in format_map:
+            raise ModuleError(output_module,
+                              'Cannot output in format "%s"' % img_format)
+        fname = self.get_filename(configuration, suffix='.%s' % img_format)
+
+        render_to_image(fname, format_map[img_format], r, w, h)
+
+class vtkRendererToIPythonModeConfig(IPythonModeConfig):
+    _fields = [ConfigField('width', 640, int),
+               ConfigField('height', 480, int)]
+
+class vtkRendererToIPythonMode(IPythonMode):
+    config_cls = vtkRendererToIPythonModeConfig
+
+    def compute_output(self, output_module, configuration=None):
+        from IPython.core.display import display, Image
+
+        r = output_module.get_input('value')[0].vtkInstance
+        width = configuration['width']
+        height = configuration['height']
+
+        window = vtk.vtkRenderWindow()
+        window.OffScreenRenderingOn()
+        window.SetSize(width, height)
+
+        fname = output_module.interpreter.filePool.create_file(
+                prefix='ipython_', suffix='.png').name
+
+        render_to_image(fname, vtk.vtkPNGWriter, r, width, height)
+        display(Image(filename=fname, width=width, height=height))
+
+class vtkRendererOutput(OutputModule):
+    _settings = ModuleSettings(configure_widget="vistrails.gui.modules."
+                       "output_configuration:OutputModuleConfigurationWidget")
+    _input_ports = [('value', 'vtkRenderer', {'depth':1}),
+                    ('interactorStyle', 'vtkInteractorStyle'),
+                    ('picker', 'vtkAbstractPicker')]
+    _output_modes = [vtkRendererToFile, vtkRendererToIPythonMode]
+    if registry.has_module('org.vistrails.vistrails.spreadsheet',
+                           'SpreadsheetCell'):
+        from .vtkcell import vtkRendererToSpreadsheet
+        _output_modes.append(vtkRendererToSpreadsheet)
 
-    """
-    if issubclass(get_description_class(module.vtkClass), vtk.vtkAlgorithm):
-        if get_description_class(module.vtkClass)!=vtk.vtkStructuredPointsGeometryFilter:
-            # We try to instantiate the class here to get the number of
-            # ports and to avoid abstract classes
-            try:
-                instance = module.vtkClass()
-            except TypeError:
-                pass
-            else:
-                reg = get_module_registry()
-                des = reg.get_descriptor_by_name(vtk_pkg_identifier,
-                                                      'vtkAlgorithmOutput')
-                for i in xrange(0,instance.GetNumberOfInputPorts()):
-                    reg.add_input_port(module, 'SetInputConnection%d'%i,
-                                       des.module, 
-                                       docstring=\
-                                           module.get_doc('SetInputConnection'))
-                for i in xrange(0,instance.GetNumberOfOutputPorts()):
-                    reg.add_output_port(module, 'GetOutputPort%d'%i, 
-                                        des.module, 
-                                        docstring=\
-                                            module.get_doc('GetOutputPort'))
-
-disallowed_set_get_ports = set(['ReferenceCount',
-                                'InputConnection',
-                                'OutputPort',
-                                'Progress',
-                                'ProgressText',
-                                'InputArrayToProcess',
-                                ])
-def addSetGetPorts(module, get_set_dict, delayed):
-    """ addSetGetPorts(module: Module, get_set_dict: dict) -> None
-    Convert all Setxxx methods of module into input ports and all Getxxx
-    methods of module into output ports
-
-    Keyword arguments:
-    module       --- Module
-    get_set_dict --- the Set/Get method signatures returned by vtk_parser
+_modules.append(vtkRendererOutput)
 
-    """
 
-    klass = get_description_class(module.vtkClass)
-    registry = get_module_registry()
-    for name in get_set_dict.iterkeys():
-        if name in disallowed_set_get_ports: continue
-        getterMethod = getattr(klass, 'Get%s'%name)
-        setterMethod = getattr(klass, 'Set%s'%name)
-        getterSig = get_method_signature(getterMethod)
-        setterSig = get_method_signature(setterMethod)
-        if len(getterSig) > 1:
-            prune_signatures(module, 'Get%s'%name, getterSig, output=True)
-        for order, getter in enumerate(getterSig):
-            if getter[1]:
-                debug("Can't handle getter %s (%s) of class %s: Needs input to "
-                    "get output" % (order+1, name, klass))
-                continue
-            if len(getter[0]) != 1:
-                debug("Can't handle getter %s (%s) of class %s: More than a "
-                    "single output" % (order+1, name, str(klass)))
-                continue
-            class_ = typeMap(getter[0][0])
-            if is_class_allowed(class_):
-                port_name = 'Get'+name
-                registry.add_output_port(module, port_name, class_, True,
-                                         docstring=module.get_doc(port_name))
-        if len(setterSig) > 1:
-            prune_signatures(module, 'Set%s'%name, setterSig)
-        for ix, setter in enumerate(setterSig):
-            if setter[1]==None: continue
-            n = resolve_overloaded_name('Set' + name, ix, setterSig)
-            if len(setter[1]) == 1 and is_class_allowed(typeMap(setter[1][0])):
-                registry.add_input_port(module, n,
-                                        typeMap(setter[1][0]),
-                                        setter[1][0] in typeMapDict,
-                                        docstring=module.get_doc(n))
-            else:
-                classes = [typeMap(i) for i in setter[1]]
-
-                if all(is_class_allowed(x) for x in classes):
-                    registry.add_input_port(module, n, classes, True, 
-                                            docstring=module.get_doc(n))
-
-
-            # Wrap SetFileNames for VisTrails file access
-            if file_name_pattern.match(name):
-                # FIXME add documentation...
-                registry.add_input_port(module, 'Set' + name[:-4], 
-                                        (File, 'input file'), False)
-            # Wrap SetRenderWindow for exporters
-            elif name == 'RenderWindow':
-                # cscheid 2008-07-11 This is messy: VTKCell isn't
-                # registered yet, so we can't use it as a port
-                # However, we can't register VTKCell before these either,
-                # because VTKCell requires vtkRenderer. The "right" way would
-                # be to add all modules first, then all ports. However, that would
-                # be too slow.
-                # Workaround: delay the addition of the port by storing
-                # the information in a list
-                if registry.has_module('%s.spreadsheet' % \
-                                       get_vistrails_default_pkg_prefix(),
-                                       'SpreadsheetCell'):
-                    from vtkcell import VTKCell
-                    # FIXME add documentation
-                    delayed.add_input_port.append((module, 'SetVTKCell', VTKCell, False))
-            # Wrap color methods for VisTrails GUI facilities
-            # FIXME add documentation for all of these!
-            elif name == 'DiffuseColor':
-                registry.add_input_port(module, 'SetDiffuseColorWidget',
-                                        (Color, 'color'), True)
-            elif name == 'Color':
-                registry.add_input_port(module, 'SetColorWidget', 
-                                        (Color, 'color'), True)
-            elif name == 'AmbientColor':
-                registry.add_input_port(module, 'SetAmbientColorWidget',
-                                        (Color, 'color'), True)
-            elif name == 'SpecularColor':
-                registry.add_input_port(module, 'SetSpecularColorWidget',
-                                        (Color, 'color'), True)
-            elif name == 'EdgeColor':
-                registry.add_input_port(module, 'SetEdgeColorWidget',
-                                        (Color, 'color'), True)
-            elif name == 'Background' :
-                registry.add_input_port(module, 'SetBackgroundWidget', 
-                                        (Color, 'color'), True)
-            elif name == 'Background2' :
-                registry.add_input_port(module, 'SetBackground2Widget', 
-                                        (Color, 'color'), True)
-
-disallowed_toggle_ports = set(['GlobalWarningDisplay',
-                               'Debug',
-                               ])
-def addTogglePorts(module, toggle_dict):
-    """ addTogglePorts(module: Module, toggle_dict: dict) -> None
-    Convert all xxxOn/Off methods of module into input ports
-
-    Keyword arguments:
-    module      --- Module
-    toggle_dict --- the Toggle method signatures returned by vtk_parser
+################# ADD VTK CLASSES ############################################
 
-    """
-    registry = get_module_registry()
-    for name in toggle_dict.iterkeys():
-        if name in disallowed_toggle_ports:
-            continue
-        port_name = name+'On'
-        registry.add_input_port(module, port_name, [], True,
-                                docstring=module.get_doc(port_name))
-        port_name = name+'Off'
-        registry.add_input_port(module, port_name, [], True,
-                                docstring=module.get_doc(port_name))
-
-disallowed_state_ports = set(['SetInputArrayToProcess'])
-def addStatePorts(module, state_dict):
-    """ addStatePorts(module: Module, state_dict: dict) -> None
-    Convert all SetxxxToyyy methods of module into input ports
-
-    Keyword arguments:
-    module     --- Module
-    state_dict --- the State method signatures returned by vtk_parser
 
-    """
-    klass = get_description_class(module.vtkClass)
-    registry = get_module_registry()
-    for name in state_dict.iterkeys():
-        for mode in state_dict[name]:
-            # Creates the port Set foo to bar
-            field = 'Set'+name+'To'+mode[0]
-            if field in disallowed_state_ports:
-                continue
-            if not registry.has_input_port(module, field):
-                registry.add_input_port(module, field, [], True,
-                                        docstring=module.get_doc(field))
-
-        # Now create the port Set foo with parameter
-        if hasattr(klass, 'Set%s'%name):
-            setterMethod = getattr(klass, 'Set%s'%name)
-            setterSig = get_method_signature(setterMethod)
-            # if the signature looks like an enum, we'll skip it, it shouldn't
-            # be necessary
-            if len(setterSig) > 1:
-                prune_signatures(module, 'Set%s'%name, setterSig)
-            for ix, setter in enumerate(setterSig):
-                n = resolve_overloaded_name('Set' + name, ix, setterSig)
-                tm = typeMap(setter[1][0])
-                if len(setter[1]) == 1 and is_class_allowed(tm):
-                    registry.add_input_port(module, n, tm,
-                                            setter[1][0] in typeMapDict,
-                                            docstring=module.get_doc(n))
-                else:
-                    classes = [typeMap(i) for i in setter[1]]
-                    if all(is_class_allowed(x) for x in classes):
-                        registry.add_input_port(module, n, classes, True,
-                                                docstring=module.get_doc(n))
-
-disallowed_other_ports = set(
-    [
-     'BreakOnError',
-     'DeepCopy',
-     'FastDelete',
-     'HasObserver',
-     'HasExecutive',
-     'InvokeEvent',
-     'IsA',
-     'Modified',
-     'NewInstance',
-     'PrintRevisions',
-     'RemoveAllInputs',
-     'RemoveObserver',
-     'RemoveObservers',
-     'SafeDownCast',
-#     'SetInputArrayToProcess',
-     'ShallowCopy',
-     'Update',
-     'UpdateInformation',
-     'UpdateProgress',
-     'UpdateWholeExtent',
-     # DAK: These are taken care of by s.upper() == s test
-     # 'GUI_HIDE',
-     # 'INPUT_ARRAYS_TO_PROCESS',
-     # 'INPUT_CONNECTION',
-     # 'INPUT_IS_OPTIONAL',
-     # 'INPUT_IS_REPEATABLE',
-     # 'INPUT_PORT',
-     # 'INPUT_REQUIRED_DATA_TYPE',
-     # 'INPUT_REQUIRED_FIELDS',
-     # 'IS_INTERNAL_VOLUME',
-     # 'IS_EXTERNAL_SURFACE',
-     # 'MANAGES_METAINFORMATION',
-     # 'POINT_DATA',
-     # 'POINTS',
-     # 'PRESERVES_ATTRIBUTES',
-     # 'PRESERVES_BOUNDS',
-     # 'PRESERVES_DATASET',
-     # 'PRESERVES_GEOMETRY',
-     # 'PRESERVES_RANGES',
-     # 'PRESERVES_TOPOLOGY',
-     ])
-
-
-
-force_not_optional_port = set(
-    ['ApplyViewTheme',
-     ])
-
-
-def addOtherPorts(module, other_list):
-    """ addOtherPorts(module: Module, other_list: list) -> None
-    Convert all other ports such as Insert/Add.... into input/output
-
-    Keyword arguments:
-    module     --- Module
-    other_dict --- any other method signatures that is not
-                   Algorithm/SetGet/Toggle/State type
-
-    """
-    klass = get_description_class(module.vtkClass)
-    registry = get_module_registry()
-    for name in other_list:
-        if name=='CopyImportVoidPointer':
-            # FIXME add documentation
-            registry.add_input_port(module, 'CopyImportVoidString', (String, 'value'), False)
-        if name[:3] in ['Add','Set'] or name[:6]=='Insert':
-            if name in disallowed_other_ports:
-                continue
-            method = getattr(klass, name)
-            signatures = ""
-            if not isinstance(method, int):
-                signatures = get_method_signature(method)
-
-            if len(signatures) > 1:
-                prune_signatures(module, name, signatures)
-            for (ix, sig) in enumerate(signatures):
-                ([result], params) = sig
-                types = []
-                if params:
-                    for p in params:
-                        t = typeMap(p)
-                        if not t:
-                            types = None
-                            break
-                        else: types.append(t)
-                else:
-                    types = [[]]
-                if types:
-                    if not all(is_class_allowed(x) for x in types):
-                        continue
-                    n = resolve_overloaded_name(name, ix, signatures)
-                    if len(types)<=1:
-                        registry.add_input_port(module, n, types[0],
-                                                types[0] in typeMapDictValues,
-                                                docstring=module.get_doc(n))
-                    else:
-                        registry.add_input_port(module, n, types, True,
-                                                docstring=module.get_doc(n))
-        else:
-            # DAK: check for static methods as name.upper() == name
-            if name in disallowed_other_ports or name.upper() == name:
-                continue
-            method = getattr(klass, name)
-            signatures = ""
-            if not isinstance(method, int):
-                signatures = get_method_signature(method)
-
-            if len(signatures) > 1:
-                prune_signatures(module, name, signatures)
-            for (ix, sig) in enumerate(signatures):
-                ([result], params) = sig
-                types = []
-                if params:
-                    paramsList = list(params)
-                    while (len(paramsList) != 0):
-                        p = paramsList.pop(0)
-                        if isinstance(p, list): 
-                            for aux in p: paramsList.insert(0, aux)
-                        else:
-                          types.append(typeMap(p))
-                else:
-                    types = []
-                if not all(is_class_allowed(x) for x in types):
-                    continue
-                if types==[] or (result==None):
-                    n = resolve_overloaded_name(name, ix, signatures)
-                    # print module.vtkClass.__name__, n
-                    try:
-                        doc = module.get_doc(n)
-                        registry.add_input_port(module, n, types,
-                                                not (n in force_not_optional_port),
-                                                docstring=module.get_doc(n))
-                    except:
-                        print "&*& ERROR WITH ", module.vtkClass.__name__, n
-
-disallowed_get_ports = set([
-    'GetClassName',
-    'GetErrorCode',
-    'GetNumberOfInputPorts',
-    'GetNumberOfOutputPorts',
-    'GetOutputPortInformation',
-    'GetTotalNumberOfInputConnections',
-    ])
-
-def addGetPorts(module, get_list):
-    klass = get_description_class(module.vtkClass)
-    registry = get_module_registry()
-    for name in get_list:
-        if name in disallowed_get_ports:
-            continue
-        method = getattr(klass, name)
-        signatures = get_method_signature(method)
-        if len(signatures) > 1:
-            prune_signatures(module, name, signatures, output=True)
-        for ix, getter in enumerate(signatures):
-            if getter[1] or len(getter[0]) > 1:
-                continue
-            class_ = typeMap(getter[0][0])
-            if is_class_allowed(class_):
-                if len(signatures) > 1:
-                    n = name + "_" + str(ix+1)
-                else:
-                    n = name
-                registry.add_output_port(module, n, class_, True,
-                                         docstring=module.get_doc(n))
-    
-def addPorts(module, delayed):
-    """ addPorts(module: VTK module inherited from Module,
-                 delayed: object with add_input_port slot
-    ) -> None
-    
-    Search all metamethods of module and add appropriate ports
-
-    ports that cannot be added immediately should be appended to
-    the delayed object that is passed. see the SetRenderWindow cases.
-
-    """
-    klass = get_description_class(module.vtkClass)
-    registry = get_module_registry()
-    registry.add_output_port(module, 'self', module)
-    parser.parse(klass)
-    addAlgorithmPorts(module)
-    addGetPorts(module, parser.get_get_methods())
-    addSetGetPorts(module, parser.get_get_set_methods(), delayed) 
-    addTogglePorts(module, parser.get_toggle_methods())
-    addStatePorts(module, parser.get_state_methods())
-    addOtherPorts(module, parser.get_other_methods())             
-    # CVS version of VTK doesn't support AddInputConnect(vtkAlgorithmOutput)
-    # FIXME Add documentation
-    basic_pkg = '%s.basic' % get_vistrails_default_pkg_prefix()
-    if klass==vtk.vtkAlgorithm:
-        registry.add_input_port(module, 'AddInputConnection',
-                                typeMap('vtkAlgorithmOutput'))
-    # vtkWriters have a custom File port
-    elif klass==vtk.vtkWriter:
-        registry.add_output_port(module, 'file', typeMap('File', basic_pkg))
-    elif klass==vtk.vtkImageWriter:
-        registry.add_output_port(module, 'file', typeMap('File', basic_pkg))
-    elif klass==vtk.vtkVolumeProperty:
-        registry.add_input_port(module, 'SetTransferFunction',
-                                typeMap('TransferFunction'))
-    elif klass==vtk.vtkDataSet:
-        registry.add_input_port(module, 'SetPointData', typeMap('vtkPointData'))
-        registry.add_input_port(module, 'SetCellData', typeMap('vtkCellData'))
-    elif klass==vtk.vtkCell:
-        registry.add_input_port(module, 'SetPointIds', typeMap('vtkIdList'))
-
-def setAllPorts(descriptor, delayed):
-    """ setAllPorts(descriptor: ModuleDescriptor) -> None
-    Traverse descriptor and all of its children/grand-children to add all ports
-
-    """
-    addPorts(descriptor.module, delayed)
-    for child in descriptor.children:
-        setAllPorts(child, delayed)
-
-def class_dict(base_module, node):
-    """class_dict(base_module, node) -> dict
-    Returns the class dictionary for the module represented by node and
-    with base class base_module"""
-
-    class_dict_ = {}
-    def update_dict(name, callable_):
-        if class_dict_.has_key(name):
-            class_dict_[name] = callable_(class_dict_[name])
-        elif hasattr(base_module, name):
-            class_dict_[name] = callable_(getattr(base_module, name))
-        else:
-            class_dict_[name] = callable_(None)
-
-    def guarded_SimpleScalarTree_wrap_compute(old_compute):
-        # This builds the scalar tree and makes it cacheable
-
-        def compute(self):
-            self.is_cacheable = lambda *args, **kwargs: True
-            old_compute(self)
-            self.vtkInstance.BuildTree()
-        return compute
-
-    def guarded_SetFileName_wrap_compute(old_compute):
-        # This checks for the presence of file in VTK readers
-        def compute(self):
-
-            # Skips the check if it's a vtkImageReader or vtkPLOT3DReader, because
-            # it has other ways of specifying files, like SetFilePrefix for
-            # multiple files
-            skip = [vtk.vtkBYUReader,
-                    vtk.vtkImageReader,
-                    vtk.vtkDICOMImageReader,
-                    vtk.vtkTIFFReader]
-
-            # vtkPLOT3DReader does not exist from version 6.0.0
-            v = vtk.vtkVersion()
-            version = [v.GetVTKMajorVersion(),
-                       v.GetVTKMinorVersion(),
-                       v.GetVTKBuildVersion()]
-            if version < [6, 0, 0]:
-                skip.append(vtk.vtkPLOT3DReader)
-            if any(issubclass(self.vtkClass, x) for x in skip):
-                old_compute(self)
-                return
-            if self.hasInputFromPort('SetFileName'):
-                name = self.getInputFromPort('SetFileName')
-            elif self.hasInputFromPort('SetFile'):
-                name = self.getInputFromPort('SetFile').name
-            else:
-                raise ModuleError(self, 'Missing filename')
-            if not os.path.isfile(name):
-                raise ModuleError(self, 'File does not exist')
-            old_compute(self)
-        return compute
-
-    def compute_SetDiffuseColorWidget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetDiffuseColorWidget(self, color):
-            self.vtkInstance.SetDiffuseColor(color.tuple)
-        return call_SetDiffuseColorWidget
-
-    def compute_SetAmbientColorWidget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetAmbientColorWidget(self, color):
-            self.vtkInstance.SetAmbientColor(color.tuple)
-        return call_SetAmbientColorWidget
-
-    def compute_SetSpecularColorWidget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetSpecularColorWidget(self, color):
-            self.vtkInstance.SetSpecularColor(color.tuple)
-        return call_SetSpecularColorWidget
-
-    def compute_SetColorWidget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetColorWidget(self, color):
-            self.vtkInstance.SetColor(color.tuple)
-        return call_SetColorWidget
-
-    def compute_SetEdgeColorWidget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetEdgeColorWidget(self, color):
-            self.vtkInstance.SetEdgeColor(color.tuple)
-        return call_SetEdgeColorWidget
-    
-    def compute_SetBackgroundWidget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetBackgroundWidget(self, color):
-            self.vtkInstance.SetBackground(color.tuple)
-        return call_SetBackgroundWidget
-    
-    def compute_SetBackground2Widget(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetBackground2Widget(self, color):
-            self.vtkInstance.SetBackground2(color.tuple)
-        return call_SetBackground2Widget
-    
-    def compute_SetVTKCell(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetRenderWindow(self, cellObj):
-            if cellObj.cellWidget:
-                self.vtkInstance.SetRenderWindow(cellObj.cellWidget.mRenWin)
-        return call_SetRenderWindow
-    
-    def compute_SetTransferFunction(old_compute):
-        # This sets the transfer function
-        if old_compute != None:
-            return old_compute
-        def call_SetTransferFunction(self, tf):
-            tf.set_on_vtk_volume_property(self.vtkInstance)
-        return call_SetTransferFunction
-
-    def compute_SetPointData(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetPointData(self, pd):
-            self.vtkInstance.GetPointData().ShallowCopy(pd)
-        return call_SetPointData
-
-    def compute_SetCellData(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetCellData(self, cd):
-            self.vtkInstance.GetCellData().ShallowCopy(cd)
-        return call_SetCellData            
-
-    def compute_SetPointIds(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_SetPointIds(self, point_ids):
-            self.vtkInstance.GetPointIds().SetNumberOfIds(point_ids.GetNumberOfIds())
-            for i in xrange(point_ids.GetNumberOfIds()):
-                self.vtkInstance.GetPointIds().SetId(i, point_ids.GetId(i))
-        return call_SetPointIds
-
-    def compute_CopyImportString(old_compute):
-        if old_compute != None:
-            return old_compute
-        def call_CopyImportVoidPointer(self, pointer):
-            self.vtkInstance.CopyImportVoidPointer(pointer, len(pointer))
-        return call_CopyImportVoidPointer
-
-    def guarded_Writer_wrap_compute(old_compute):
-        # The behavior for vtkWriter subclasses is to call Write()
-        # If the user sets a name, we will create a file with that name
-        # If not, we will create a temporary file from the file pool
-        def compute(self):
-            old_compute(self)
-            fn = self.vtkInstance.GetFileName()
-            if not fn:
-                o = self.interpreter.filePool.create_file(suffix='.vtk')
-                self.vtkInstance.SetFileName(o.name)
-            else:
-                o = File()
-                o.name = fn
-            self.vtkInstance.Write()
-            self.setResult('file', o)
-        return compute
-
-    for var in dir(node.klass):
-        # Everyone that has a Set.*FileName should have a Set.*File port too
-        if set_file_name_pattern.match(var):
-            def get_compute_SetFile(method_name):
-                def compute_SetFile(old_compute):
-                    if old_compute != None:
-                        return old_compute
-                    def call_SetFile(self, file_obj):
-                        getattr(self.vtkInstance, method_name)(file_obj.name)
-                    return call_SetFile
-                return compute_SetFile
-            update_dict('_special_input_function_' + var[:-4], 
-                        get_compute_SetFile(var))
-
-    if hasattr(node.klass, 'SetFileName'):
-        # ... BUT we only want to check existence of filenames on
-        # readers. VTK is nice enough to be consistent with names, but
-        # this is brittle..
-        if node.klass.__name__.endswith('Reader'):
-            if not node.klass.__name__.endswith('TiffReader'):
-                update_dict('compute', guarded_SetFileName_wrap_compute)
-    if hasattr(node.klass, 'SetRenderWindow'):
-        update_dict('_special_input_function_SetVTKCell',
-                    compute_SetVTKCell)
-    #color gui wrapping
-    if hasattr(node.klass, 'SetDiffuseColor'):
-        update_dict('_special_input_function_SetDiffuseColorWidget',
-                    compute_SetDiffuseColorWidget)
-    if hasattr(node.klass, 'SetAmbientColor'):
-        update_dict('_special_input_function_SetAmbientColorWidget',
-                    compute_SetAmbientColorWidget)
-    if hasattr(node.klass, 'SetSpecularColor'):
-        update_dict('_special_input_function_SetSpecularColorWidget',
-                    compute_SetSpecularColorWidget)
-    if hasattr(node.klass, 'SetEdgeColor'):
-        update_dict('_special_input_function_SetEdgeColorWidget',
-                    compute_SetEdgeColorWidget)
-    if hasattr(node.klass, 'SetColor'):
-        update_dict('_special_input_function_SetColorWidget',
-                    compute_SetColorWidget)
-    if (issubclass(node.klass, vtk.vtkRenderer) and 
-        hasattr(node.klass, 'SetBackground')):
-        update_dict('_special_input_function_SetBackgroundWidget',
-                    compute_SetBackgroundWidget)
-    if (issubclass(node.klass, vtk.vtkRenderer) and 
-        hasattr(node.klass, 'SetBackground2')):
-        update_dict('_special_input_function_SetBackground2Widget',
-                    compute_SetBackground2Widget)    
-    if issubclass(node.klass, vtk.vtkWriter):
-        update_dict('compute', guarded_Writer_wrap_compute)
-
-    if issubclass(node.klass, vtk.vtkScalarTree):
-        update_dict('compute', guarded_SimpleScalarTree_wrap_compute)
-
-    if issubclass(node.klass, vtk.vtkVolumeProperty):
-        update_dict('_special_input_function_SetTransferFunction',
-                    compute_SetTransferFunction)
-    if issubclass(node.klass, vtk.vtkDataSet):
-        update_dict('_special_input_function_SetPointData',
-                    compute_SetPointData)
-        update_dict('_special_input_function_SetCellData',
-                    compute_SetCellData)
-    if issubclass(node.klass, vtk.vtkCell):
-        update_dict('_special_input_function_SetPointIds',
-                    compute_SetPointIds)
-    if issubclass(node.klass, vtk.vtkImageImport):
-        update_dict('_special_input_function_CopyImportString',
-                    compute_CopyImportString)
-    return class_dict_
-
-disallowed_modules = set([
-        'vtkGeoAlignedImageCache',
-        'vtkGeoTerrainCache',
-        'vtkMPIGroup'
-        ])
-def createModule(baseModule, node):
-    """ createModule(baseModule: a Module subclass, node: TreeNode) -> None
-    Construct a module inherits baseModule with specification from node
-    
-    """
-    if node.name in disallowed_modules: return
-    def obsolete_class_list():
-        lst = []
-        items = ['vtkInteractorStyleTrackball',
-                 'vtkStructuredPointsGeometryFilter',
-                 'vtkConstrainedPointHandleRepresentation']
-        def try_to_add_item(item):
-            try:
-                lst.append(getattr(vtk, item))
-            except AttributeError:
-                pass
-        for item in items:
-            try_to_add_item(item)
-        return lst
-
-    obsolete_list = obsolete_class_list()
-    
-    def is_abstract():
-        """is_abstract tries to instantiate the class. If it's
-        abstract, this will raise."""
-        # Consider obsolete classes abstract        
-        if node.klass in obsolete_list:
-            return True
-        try:
-            getattr(vtk, node.name)()
-        except (TypeError, NotImplementedError): # VTK raises type error on abstract classes
-            return True
-        return False
-    module = new_module(baseModule, node.name,
-                       class_dict(baseModule, node),
-                       docstring=getattr(vtk, node.name).__doc__
-                       )
-
-    # This is sitting on the class
-    if hasattr(fix_classes, node.klass.__name__ + '_fixed'):
-        module.vtkClass = getattr(fix_classes, node.klass.__name__ + '_fixed')
-    else:
-        module.vtkClass = node.klass
-    registry = get_module_registry()
-    registry.add_module(module, abstract=is_abstract(), 
-                        signatureCallable=vtk_hasher)
-    for child in node.children:
-        if child.name in disallowed_classes:
-            continue
-        createModule(module, child)
-
-def createAllModules(g):
-    """ createAllModules(g: ClassTree) -> None
-    Traverse the VTK class tree and add all modules into the module registry
-    
-    """
-    v = vtk.vtkVersion()
-    version = [v.GetVTKMajorVersion(),
-               v.GetVTKMinorVersion(),
-               v.GetVTKBuildVersion()]
-    if version < [5, 7, 0]:
-        assert len(g.tree[0]) == 1
-        base = g.tree[0][0]
-        assert base.name == 'vtkObjectBase'
-
-    vtkObjectBase = new_module(vtkBaseModule, 'vtkObjectBase')
-    vtkObjectBase.vtkClass = vtk.vtkObjectBase
-    registry = get_module_registry()
-    registry.add_module(vtkObjectBase)
-    if version < [5, 7, 0]:
-        for child in base.children:
-            if child.name in disallowed_classes:
-                continue
-            createModule(vtkObjectBase, child)
-    else:
-        for base in g.tree[0]:
-            for child in base.children:
-                if child.name in disallowed_classes:
-                    continue
-                createModule(vtkObjectBase, child)
-
-
-################################################################################
+# keep track of created modules for use as subclasses
+klasses = {}
 
 def initialize():
-    """ initialize() -> None
-    Package-entry to initialize the package
-    
-    """
-    # Check VTK version
+    # First check if spec for this VTK version exists
     v = vtk.vtkVersion()
-    version = [v.GetVTKMajorVersion(),
-               v.GetVTKMinorVersion(),
-               v.GetVTKBuildVersion()]
-    if version < [5, 0, 0]:
-        raise RuntimeError("You need to upgrade your VTK install to version "
-                           ">= 5.0.0")
-    inheritanceGraph = ClassTree(vtk)
-    inheritanceGraph.create()
-
-    # Transfer Function constant
-    tf_widget.initialize()
-
-    delayed = InstanceObject(add_input_port=[])
-    # Add VTK modules
-    registry = get_module_registry()
-    registry.add_module(vtkBaseModule)
-    createAllModules(inheritanceGraph)
-    setAllPorts(registry.get_descriptor_by_name(identifier,
-                                                'vtkObjectBase'),
-                delayed)
-
-    # Register the VTKCell and VTKHandler type if the spreadsheet is up
-    if registry.has_module('%s.spreadsheet' % \
-                           get_vistrails_default_pkg_prefix(),
-                           'SpreadsheetCell'):
-        import vtkhandler
-        import vtkcell
-        import vtkviewcell
-        vtkhandler.registerSelf()
-        vtkcell.registerSelf()
-        vtkviewcell.registerSelf()
-
-    # register offscreen rendering module
-    offscreen.register_self()
-
-    # Now add all "delayed" ports - see comment on addSetGetPorts
-    for args in delayed.add_input_port:
-        
-        registry.add_input_port(*args)
-
-    # register Transfer Function adjustment
-    # This can't be reordered -- TransferFunction needs to go before
-    # vtkVolumeProperty, but vtkScaledTransferFunction needs
-    # to go after vtkAlgorithmOutput
-    getter = registry.get_descriptor_by_name
-    registry.add_module(tf_widget.vtkScaledTransferFunction)
-    # FIXME Add documentation
-    registry.add_input_port(tf_widget.vtkScaledTransferFunction,
-                            'Input', getter(vtk_pkg_identifier,
-                                            'vtkAlgorithmOutput').module)
-    registry.add_input_port(tf_widget.vtkScaledTransferFunction,
-                            'Dataset', getter (vtk_pkg_identifier,
-                                               'vtkDataObject').module)
-    registry.add_input_port(tf_widget.vtkScaledTransferFunction,
-                            'Range', [Float, Float])
-    registry.add_input_port(tf_widget.vtkScaledTransferFunction,
-                            'TransferFunction',
-                            tf_widget.TransferFunctionConstant)
-    registry.add_output_port(tf_widget.vtkScaledTransferFunction,
-                             'TransferFunction',
-                             tf_widget.TransferFunctionConstant)
-    registry.add_output_port(tf_widget.vtkScaledTransferFunction,
-                             'vtkPiecewiseFunction',
-                             getter(vtk_pkg_identifier, 
-                                    'vtkPiecewiseFunction').module)
-    registry.add_output_port(tf_widget.vtkScaledTransferFunction,
-                             'vtkColorTransferFunction',
-                             getter(vtk_pkg_identifier, 
-                                    'vtkColorTransferFunction').module)
-
-    inspectors.initialize()
-
-################################################################################
+    vtk_version = [v.GetVTKMajorVersion(),
+                   v.GetVTKMinorVersion(),
+                   v.GetVTKBuildVersion()]
+
+    # vtk-VTKVERSION-spec-PKGVERSION.xml
+    spec_name = os.path.join(current_dot_vistrails(),
+                             'vtk-%s-spec-%s.xml' %
+                             ('_'.join([str(v) for v in vtk_version]),
+                              package_version.replace('.', '_')))
+    # TODO: how to patch with diff/merge
+    if not os.path.exists(spec_name):
+        from .vtk_wrapper.parse import parse
+        parse(spec_name)
+    vtk_classes.initialize(spec_name)
+    _modules.insert(0, BaseClassModule)
+    _modules.extend([gen_class_module(spec, vtk_classes, klasses, signature=hasher.vtk_hasher)
+                     for spec in vtk_classes.specs.module_specs])
+
+################# UPGRADES ###################################################
 
 _remap = None
 _controller = None
@@ -1229,27 +209,111 @@ def _get_pipeline():
     global _pipeline
     return _pipeline
 
+module_name_remap = {'vtkPLOT3DReader': 'vtkMultiBlockPLOT3DReader'}
+
+def base_name(name):
+    """Returns name without overload index.
+    """
+    i = name.find('_')
+    if i != -1:
+        return name[:i]
+    return name
+
 def build_remap(module_name=None):
     global _remap, _controller
 
     reg = get_module_registry()
     uscore_num = re.compile(r"(.+)_(\d+)$")
-    
+
+    def create_function(module, *argv, **kwargs):
+        controller = _get_controller()
+        # create function using the current module version and identifier
+        # FIXME: This should really be handled by the upgrade code somehow
+        new_desc = reg.get_descriptor_by_name(module.package,
+                                              module.name,
+                                              module.namespace)
+        old_identifier = module.package
+        module.package = identifier
+        old_package_version = module.version
+        module.version = new_desc.package_version
+        new_function = controller.create_function(module, *argv, **kwargs)
+        module.package = old_identifier
+        module.version = old_package_version
+        return new_function
+
     def get_port_specs(descriptor, port_type):
         ports = {}
         for desc in reversed(reg.get_module_hierarchy(descriptor)):
             ports.update(reg.module_ports(port_type, desc))
         return ports
 
+    def get_input_port_spec(module, port_name):
+        # Get current desc
+        # FIXME: This should really be handled by the upgrade code somehow
+        new_desc = reg.get_descriptor_by_name(module.package,
+                                              module.name,
+                                              module.namespace)
+        port_specs = get_port_specs(new_desc, 'input')
+        return port_name in port_specs and port_specs[port_name]
+
+    def get_output_port_spec(module, port_name):
+        # Get current desc
+        new_desc = reg.get_descriptor_by_name(module.package,
+                                              module.name,
+                                              module.namespace)
+        port_specs = get_port_specs(new_desc, 'output')
+        return port_name in port_specs and port_specs[port_name]
+
+    def build_function(old_function, new_function_name, new_module):
+        controller = _get_controller()
+        if len(old_function.parameters) > 0:
+            new_param_vals, aliases = \
+                zip(*[(p.strValue, p.alias)
+                      for p in old_function.parameters])
+        else:
+            new_param_vals = []
+            aliases = []
+        new_function = create_function(new_module,
+                                       new_function_name,
+                                       new_param_vals,
+                                       aliases)
+        return new_function
+
+    def build_function_remap_method(desc, port_prefix, port_num):
+        f_map = {"vtkCellArray": {"InsertNextCell": 3}}
+
+        def remap(old_function, new_module):
+            for i in xrange(1, port_num):
+                port_name = "%s_%d" % (port_prefix, i)
+                port_spec = get_input_port_spec(new_module, port_name)
+                old_sigstring = \
+                    reg.expand_port_spec_string(old_function.sigstring,
+                                                basic_pkg)
+                if port_spec.sigstring == old_sigstring:
+                    new_function = build_function(old_function, port_name,
+                                                  new_module)
+                    new_module.add_function(new_function)
+                    return []
+            port_idx = 1
+            if desc.name in f_map:
+                if port_prefix in f_map[desc.name]:
+                    port_idx =  f_map[desc.name][port_prefix]
+            port_name = "%s_%d" % (port_prefix, port_idx)
+            new_function = build_function(old_function, port_name, new_module)
+            new_module.add_function(new_function)
+            return []
+
+        return remap
+
     def build_remap_method(desc, port_prefix, port_num, port_type):
         # for connection, need to differentiate between src and dst
         if port_type == 'input':
             conn_lookup = Connection._get_destination
-            get_port_spec = reg.get_input_port_spec
+            get_port_spec = get_input_port_spec
             idx = 1
         else:
             conn_lookup = Connection._get_source
-            get_port_spec = reg.get_output_port_spec
+            get_port_spec = get_output_port_spec
             idx = 0
 
         def remap(old_conn, new_module):
@@ -1271,7 +335,7 @@ def build_remap(module_name=None):
                                                      modules[1],
                                                      ports[1])
                     return [('add', new_conn)]
-                                                                  
+
             # if get here, just try to use _1 version?
             ports[idx] = "%s_%d" % (port_prefix, 1)
             new_conn = create_new_connection(_get_controller(),
@@ -1282,47 +346,7 @@ def build_remap(module_name=None):
             return [('add', new_conn)]
         return remap
 
-    def build_function_remap_method(desc, port_prefix, port_num):
-        f_map = {"vtkCellArray": {"InsertNextCell": 3}}
-        def build_function(old_function, new_function_name, new_module):
-            controller = _get_controller()
-            if len(old_function.parameters) > 0:
-                new_param_vals, aliases = \
-                    zip(*[(p.strValue, p.alias) 
-                          for p in old_function.parameters])
-            else:
-                new_param_vals = []
-                aliases = []
-            new_function = controller.create_function(new_module, 
-                                                      new_function_name,
-                                                      new_param_vals,
-                                                      aliases)
-            return new_function
-            
-        def remap(old_function, new_module):
-            for i in xrange(1, port_num):
-                port_name = "%s_%d" % (port_prefix, i)
-                port_spec = reg.get_input_port_spec(new_module, port_name)
-                old_sigstring = \
-                    reg.expand_port_spec_string(old_function.sigstring,
-                                                basic_pkg)
-                if port_spec.sigstring == old_sigstring:
-                    new_function = build_function(old_function, port_name,
-                                                  new_module)
-                    new_module.add_function(new_function)
-                    return []
-            port_idx = 1
-            if desc.name in f_map:
-                if port_prefix in f_map[desc.name]:
-                    port_idx =  f_map[desc.name][port_prefix]
-            port_name = "%s_%d" % (port_prefix, port_idx)
-            new_function = build_function(old_function, port_name, new_module)
-            new_module.add_function(new_function)
-            return []
-
-        return remap
-                    
-    def process_ports(desc, port_type):
+    def process_ports(desc, remap, port_type):
         if port_type == 'input':
             remap_dict_key = 'dst_port_remap'
         else:
@@ -1340,44 +364,320 @@ def build_remap(module_name=None):
                     port_nums[port_prefix] = port_num
                 elif port_num > port_nums[port_prefix]:
                     port_nums[port_prefix] = port_num
-        if desc.name not in _remap:
-            _remap[desc.name] = [(None, '0.9.3', None, dict())]
         for port_prefix, port_num in port_nums.iteritems():
-            my_remap_dict = _remap[desc.name][0][3]
-            if remap_dict_key not in my_remap_dict:
-                my_remap_dict[remap_dict_key] = dict()
-            remap = build_remap_method(desc, port_prefix, port_num, port_type)
-            my_remap_dict[remap_dict_key][port_prefix] = remap
+            m = build_remap_method(desc, port_prefix, port_num, port_type)
+            remap.add_remap(remap_dict_key, port_prefix, m)
             if port_type == 'input':
-                remap = build_function_remap_method(desc, port_prefix, port_num)
-                if 'function_remap' not in my_remap_dict:
-                    my_remap_dict['function_remap'] = {}
-                my_remap_dict['function_remap'][port_prefix] = remap
+                m = build_function_remap_method(desc, port_prefix, port_num)
+                remap.add_remap('function_remap', port_prefix, m)
+        if port_type == 'output' and desc.name in klasses:
+            remap.add_remap('src_port_remap', 'self', 'Instance')
+
+    def change_func(name, value):
+        def remap(old_func, new_module):
+            controller = _get_controller()
+            new_function = create_function(new_module, name, [value])
+            return [('add', new_function, 'module', new_module.id)]
+        return remap
+
+    def change_SetXint(spec):
+        # Fix old SetX methods that takes an int representing the enum
+        def remap(old_func, new_module):
+            controller = _get_controller()
+            value = int(old_func.params[0].strValue)
+            value = spec.values[0][value]
+            new_function = create_function(new_module, spec.name, [value])
+            return [('add', new_function, 'module', new_module.id)]
+        return remap
+
+    def color_func(name):
+        def remap(old_func, new_module):
+            controller = _get_controller()
+            value = ','.join([p.strValue for p in old_func.params])
+            new_function = create_function(new_module, name, [value])
+            return [('add', new_function, 'module', new_module.id)]
+        return remap
+
+    def file_func(name):
+        def remap(old_func, new_module):
+            controller = _get_controller()
+            value = PathObject(old_func.params[0].strValue)
+            new_function = create_function(new_module, name, [value])
+            return [('add', new_function, 'module', new_module.id)]
+        return remap
+
+    def to_file_func(name):
+        # Add Path module as name->File converter
+        def remap(old_conn, new_module):
+            controller = _get_controller()
+            create_new_connection = UpgradeWorkflowHandler.create_new_connection
+            pipeline = _get_pipeline()
+            module = pipeline.modules[old_conn.source.moduleId]
+            x = (module.location.x + new_module.location.x)/2
+            y = (module.location.y + new_module.location.y)/2
+            path_module = controller.create_module(basic_pkg, 'Path',
+                                                   '', x, y)
+            conn1 = create_new_connection(controller,
+                                          module,
+                                          old_conn.source,
+                                          path_module,
+                                          'name')
+            conn2 = create_new_connection(controller,
+                                          path_module,
+                                          'value',
+                                          new_module,
+                                          name)
+            return [('add', path_module),
+                    ('add', conn1),
+                    ('add', conn2)]
+        return remap
+
+    def wrap_block_func():
+        def remap(old_conn, new_module):
+            controller = _get_controller()
+            create_new_connection = UpgradeWorkflowHandler.create_new_connection
+            pipeline = _get_pipeline()
+            module1 = pipeline.modules[old_conn.destination.moduleId]
+            dest_port = old_conn.destination
+            candidates = ['AddInputData_1', 'AddInputData',
+                          'SetInputData_1', 'SetInputData',
+                          'AddInput', 'SetInput']
+            if 'Connection' in old_conn.destination.name:
+                _desc = reg.get_descriptor_by_name(identifier,
+                                                   module1.name)
+                ports = get_port_specs(_desc, 'input')
+                for c in candidates:
+                    if c in ports:
+                        dest_port = c
+                        break
+            conn = create_new_connection(controller,
+                                         new_module,
+                                         'StructuredGrid',
+                                         module1,
+                                         dest_port)
+            return [('add', conn)]
+        return remap
+
+    def fix_vtkcell_func():
+        # Move VTKCell.self -> X.VTKCell to
+        # vtkRenderer.Instance -> X.vtkRenderer
+        def remap(old_conn, new_module):
+            controller = _get_controller()
+            create_new_connection = UpgradeWorkflowHandler.create_new_connection
+            pipeline = _get_pipeline()
+            # find vtkRenderer
+            vtkRenderer = None
+            for conn in pipeline.connections.itervalues():
+                src_module_id = conn.source.moduleId
+                dst_module_id = conn.destination.moduleId
+                if dst_module_id == old_conn.source.moduleId and \
+                   pipeline.modules[src_module_id].name == 'vtkRenderer':
+                    vtkRenderer = pipeline.modules[src_module_id]
+            if vtkRenderer:
+                conn = create_new_connection(controller,
+                                             vtkRenderer,
+                                             'Instance',
+                                             new_module,
+                                             'vtkRenderer')
+                return [('add', conn)]
+            return []
+        return remap
+
+    def process_module(desc):
+        # 0.9.3 upgrades
+        if not desc.name in klasses:
+            return
+        remap = UpgradeModuleRemap(None, '0.9.3', '0.9.3',
+                                   module_name=desc.name)
+        process_ports(desc, remap, 'input')
+        process_ports(desc, remap, 'output')
+        _remap.add_module_remap(remap)
+        for old, new in module_name_remap.iteritems():
+            if desc.name == new:
+                # Remap using old name
+                remap.new_module = old
+                _remap.add_module_remap(remap, old)
+        # 0.9.5 upgrades
+        remap = UpgradeModuleRemap('0.9.3', '0.9.5', '0.9.5',
+                                   module_name=desc.name)
+        remap.add_remap('src_port_remap', 'self', 'Instance')
+        _remap.add_module_remap(remap)
+        for old, new in module_name_remap.iteritems():
+            if desc.name == new:
+                # Remap using old name
+                remap.new_module = old
+                _remap.add_module_remap(remap, old)
+        # 1.0.0 upgrades
+        input_mappings = {}
+        function_mappings = {}
+        input_specs = [desc.module._get_input_spec(s)
+                     for s in get_port_specs(desc, 'input')]
+        input_names = [s.name for s in input_specs]
+        for spec in input_specs:
+            if spec is None:
+                continue
+            elif spec.name == 'TextScaleMode':
+                function_mappings['ScaledTextOn'] = \
+                                           change_func('TextScaleMode', 'Prop')
+            elif spec.method_type == 'OnOff':
+                # Convert On/Off to single port
+                input_mappings[spec.name + 'On'] = spec.name
+                input_mappings[spec.name + 'Off'] = spec.name
+                function_mappings[spec.name + 'On'] = \
+                                              change_func(spec.name, True)
+                function_mappings[spec.name + 'Off'] = \
+                                             change_func(spec.name, False)
+            elif spec.method_type == 'nullary':
+                # Add True to execute empty functions
+                function_mappings[spec.name] = change_func(spec.name, True)
+            elif spec.method_type == 'SetXToY':
+                # Add one mapping for each default
+                for enum in spec.values[0]:
+                    input_mappings[spec.method_name + enum] = spec.name
+                    # Add enum value to function
+                    function_mappings[spec.method_name + enum] = \
+                                                  change_func(spec.name, enum)
+                # Convert SetX(int) methods
+                old_name = spec.method_name[:-2]
+                function_mappings[spec.method_name[:-2]] = change_SetXint(spec)
+            elif spec.port_type == 'basic:Color':
+                # Remove 'Widget' suffix on Color
+                input_mappings[spec.method_name + 'Widget'] = spec.name
+                # Remove 'Set prefix'
+                input_mappings[spec.method_name] = spec.name
+                # Change old type (float, float, float) -> (,)*3
+                function_mappings[spec.method_name] = color_func(spec.name)
+            elif spec.port_type == 'basic:File':
+                input_mappings[spec.method_name] = to_file_func(spec.name)  # Set*FileName -> (->File->*File)
+                input_mappings['Set' + spec.name] = spec.name # Set*File -> *File
+                function_mappings[spec.method_name] = file_func(spec.name)
+            elif base_name(spec.name) == 'AddDataSetInput':
+                # SetInput* does not exist in VTK 6
+                if spec.name[15:] == '_1':
+                    # Upgrade from version without overload
+                    input_mappings['AddInput'] = spec.name
+                input_mappings['AddInput' + spec.name[15:]] = spec.name
+            elif base_name(spec.name) == 'InputData':
+                # SetInput* does not exist in VTK 6
+                if spec.name[9:] == '_1':
+                    # Upgrade from version without overload
+                    input_mappings['SetInput'] = spec.name
+                input_mappings['SetInput' + spec.name[9:]] = spec.name
+            elif base_name(spec.name) == 'AddInputData':
+                # AddInput* does not exist in VTK 6
+                if spec.name[12:] == '_1':
+                    # Upgrade from version without overload
+                    input_mappings['AddInput'] = spec.name
+                input_mappings['AddInput' + spec.name[12:]] = spec.name
+            elif base_name(spec.name) ==  'SourceData':
+                # SetSource* does not exist in VTK 6
+                if spec.name[10:] == '_1':
+                    # Upgrade from version without overload
+                    input_mappings['SetSource'] = spec.name
+                input_mappings['SetSource' + spec.name[10:]] = spec.name
+            elif spec.method_name == 'Set' + base_name(spec.name):
+                if spec.name[-2:] == '_1':
+                    # Upgrade from versions without overload
+                    input_mappings[spec.name[:-2]] = spec.name
+                    input_mappings['Set' + spec.name[:-2]] = spec.name
+                # Remove 'Set' prefixes
+                input_mappings['Set' + spec.name] = spec.name
+            elif spec.name == 'AddInput_1':
+                # FIXME what causes this?
+                # New version does not have AddInput
+                input_mappings['AddInput'] = 'AddInput_1'
+            elif spec.name == 'vtkRenderer':
+                # Classes having SetRendererWindow also used to have VTKCell
+                input_mappings['SetVTKCell'] = fix_vtkcell_func()
+        output_mappings = {}
+        for spec_name in get_port_specs(desc, 'output'):
+            spec = desc.module._get_output_spec(spec_name)
+            if spec is None:
+                continue
+            if spec.method_name == 'Get' + spec.name:
+                # Remove 'Get' prefixes
+                output_mappings[spec.method_name] = spec.name
+        if desc.name == 'vtkMultiBlockPLOT3DReader':
+            # Move GetOutput to custom FirstBlock
+            output_mappings['GetOutput'] = wrap_block_func()  # what!?
+            # Move GetOutputPort0 to custom FirstBlock
+            # and change destination port to AddInputData_1 or similar
+            output_mappings['GetOutputPort0'] = wrap_block_func()
+
+        remap = UpgradeModuleRemap('0.9.5', '1.0.0', '1.0.0',
+                                   module_name=desc.name)
+        for k, v in input_mappings.iteritems():
+            remap.add_remap('dst_port_remap', k, v)
+        for k, v in output_mappings.iteritems():
+            remap.add_remap('src_port_remap', k, v)
+        for k, v in function_mappings.iteritems():
+            remap.add_remap('function_remap', k, v)
+        _remap.add_module_remap(remap)
+        for old, new in module_name_remap.iteritems():
+            if desc.name == new:
+                # Remap to new name
+                remap.new_module = new
+                _remap.add_module_remap(remap, old)
 
     pkg = reg.get_package_by_name(identifier)
     if module_name is not None:
-        # print 'building remap for', module_name
         desc = reg.get_descriptor_by_name(identifier, module_name)
-        process_ports(desc, 'input')
-        process_ports(desc, 'output')
+        process_module(desc)
     else:
-        # print 'building entire remap'
         # FIXME do this by descriptor first, then build the hierarchies for each
         # module after that...
         for desc in pkg.descriptor_list:
-            process_ports(desc, 'input')
-            process_ports(desc, 'output')    
+            process_module(desc)
 
 def handle_module_upgrade_request(controller, module_id, pipeline):
     global _remap, _controller, _pipeline
-    reg = get_module_registry()
+
     if _remap is None:
-        _remap = {}
-    
+        _remap = UpgradePackageRemap()
+        remap = UpgradeModuleRemap(None, '1.0.0', '1.0.0',
+                                   module_name='vtkInteractionHandler')
+        remap.add_remap('src_port_remap', 'self', 'Instance')
+        _remap.add_module_remap(remap)
+        remap = UpgradeModuleRemap(None, '1.0.0', '1.0.0',
+                                   module_name='VTKCell')
+        remap.add_remap('src_port_remap', 'self', 'Instance')
+        _remap.add_module_remap(remap)
+        remap = UpgradeModuleRemap(None, '1.0.0', '1.0.0',
+                                   module_name='VTKViewCell',
+                                   new_module='VTKCell')
+        _remap.add_module_remap(remap)
+
     _controller = controller
     _pipeline = pipeline
     module_name = pipeline.modules[module_id].name
-    if module_name not in _remap:
+    module_name = module_name_remap.get(module_name, module_name)
+    if not _remap.has_module_remaps(module_name):
         build_remap(module_name)
+
+    try:
+        from vistrails.packages.spreadsheet.init import upgrade_cell_to_output
+    except ImportError:
+        # Manually upgrade to 1.0.1
+        if _remap.get_module_remaps(module_name):
+            module_remap = copy.copy(_remap)
+            module_remap.add_module_remap(
+                    UpgradeModuleRemap('1.0.0', '1.0.1', '1.0.1',
+                                       module_name=module_name))
+        else:
+            module_remap = _remap
+    else:
+        module_remap = upgrade_cell_to_output(
+                _remap, module_id, pipeline,
+                'VTKCell', 'vtkRendererOutput',
+                '1.0.1', 'AddRenderer',
+                start_version='1.0.0')
+        if _remap.get_module_remaps(module_name):
+            remap = module_remap.get_module_upgrade(module_name, '1.0.0')
+            if remap is None:
+                # Manually upgrade to 1.0.1
+                module_remap.add_module_remap(
+                        UpgradeModuleRemap('1.0.0', '1.0.1', '1.0.1',
+                                           module_name=module_name))
+
     return UpgradeWorkflowHandler.remap_module(controller, module_id, pipeline,
-                                              _remap)
+                                               module_remap)
diff --git a/vistrails/packages/vtk/inspectors.py b/vistrails/packages/vtk/inspectors.py
index 2cd770b..5dc1708 100644
--- a/vistrails/packages/vtk/inspectors.py
+++ b/vistrails/packages/vtk/inspectors.py
@@ -1,244 +1,185 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 ##############################################################################
 # Data inspectors for VTK
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import ModuleError
-from vistrails.core.utils import VistrailsInternalError
 from vistrails.core.modules.basic_modules import Module, Float, Integer
-from vistrails.core.modules.module_registry import get_module_registry
+from vistrails.core.modules.config import ModuleSettings
 import vtk
-from base_module import vtkBaseModule
-from hasher import vtk_hasher
-from identifiers import identifier as vtk_pkg_identifier
+from .hasher import vtk_hasher
+from .vtk_wrapper.wrapper import VTKInstanceWrapper
 
 class vtkBaseInspector(Module):
 
-    @classmethod
-    def register_self(cls, **kwargs):
-        registry = get_module_registry()
-        def resolve_type(t):
-            if isinstance(t, tuple):
-                return registry.get_descriptor_by_name(*t).module
-            elif isinstance(t, type):
-                return t
-            else:
-                assert False, ("Unknown type " + str(type(t)))
-
-        registry.add_module(cls, **kwargs)
-        try:
-            ips = cls.input_ports
-        except AttributeError:
-            pass
-        else:
-            for (port_name, types) in ips:
-                registry.add_input_port(cls,
-                                        port_name,
-                                        list(resolve_type(t) for t in types))
-
-        try:
-            ops = cls.output_ports
-        except AttributeError:
-            pass
-        else:
-            for (port_name, types) in ops:
-                registry.add_output_port(cls,
-                                         port_name,
-                                         list(resolve_type(t) for t in types))
-
+    _settings = ModuleSettings(abstract=True)
     def auto_set_results(self, vtk_object):
+        mid = self.moduleInfo['moduleId']
         for function in self.outputPorts.keys():
             if hasattr(vtk_object, function):
                 retValues = getattr(vtk_object, function)()
                 if issubclass(retValues.__class__, vtk.vtkObject):
-                    className = retValues.GetClassName()
-                    output  = vtkBaseModule.wrapperModule(className, retValues)
-                    self.setResult(function, output)
+                    output  = VTKInstanceWrapper(retValues, mid)
+                    self.set_output(function, output)
                 elif isinstance(retValues, (tuple, list)):
                     result = list(retValues)
                     for i in xrange(len(result)):
                         if issubclass(result[i].__class__, vtk.vtkObject):
-                            className = result[i].GetClassName()
-                            result[i] = vtkBaseModule.wrapperModule(className,
-                                                                    result[i])
-                    self.setResult(function, type(retValues)(result))
+                            result[i] = VTKInstanceWrapper(result[i], mid)
+                    self.set_output(function, type(retValues)(result))
                 else:
-                    self.setResult(function, retValues)
+                    self.set_output(function, retValues)
 
 class vtkDataSetInspector(vtkBaseInspector):
 
+    _settings = ModuleSettings(abstract=False, signature=vtk_hasher)
+    _input_ports = [('SetInputConnection0', 'vtkAlgorithmOutput'),
+                    ('SetInput', 'vtkDataSet'),
+                    ]
+    _output_ports = [('GetBounds', [Float] * 6),
+                     ('GetScalarRange', [Float] * 2),
+                     ('GetLength', [Float]),
+                     ('GetCenter', [Float] * 3),
+                     ('GetNumberOfPoints', [Integer]),
+                     ('GetNumberOfCells', [Integer]),
+                     ('GetPointData', 'vtkPointData'),
+                     ('GetCellData', 'vtkCellData'),
+                     ]
+
     def compute(self):
-        vtk_object = None
-        if self.hasInputFromPort("SetInputConnection0"):
-            ic = self.getInputFromPort("SetInputConnection0")
-            port_object = ic.vtkInstance
-            ix = port_object.GetIndex()
-            producer = port_object.GetProducer()
+        port_object = None
+        if self.has_input("SetInputConnection0"):
+            ic = self.get_input("SetInputConnection0")
+            if hasattr(ic, "vtkInstance"):
+                ic = ic.vtkInstance
+            producer = ic.GetProducer()
             try:
-                vtk_object = producer.GetOutput()
+                port_object = producer.GetOutput()
             except AttributeError:
                 raise ModuleError(self, 
                                   "expected a module that supports GetOutput")
-        elif self.hasInputFromPort("SetInput"):
-            port_object = self.getInputFromPort("SetInput")
+        elif self.has_input("SetInput"):
+            port_object = self.get_input("SetInput")
             if hasattr(port_object, "vtkInstance"):
-                vtk_object = port_object.vtkInstance
-            else:
-                raise ModuleError(self, "expected a vtk module")
-        if vtk_object:
-            self.auto_set_results(vtk_object)
+                port_object = port_object.vtkInstance
+        if port_object:
+            self.auto_set_results(port_object)
 
-    input_ports = [('SetInputConnection0',
-                    [(vtk_pkg_identifier, 'vtkAlgorithmOutput')]),
-                   ('SetInput',
-                    [(vtk_pkg_identifier, 'vtkDataSet')]),
-                   ]
-    output_ports = [('GetBounds', [Float] * 6),
-                    ('GetScalarRange', [Float] * 2),
-                    ('GetLength', [Float]),
-                    ('GetCenter', [Float] * 3),
-                    ('GetNumberOfPoints', [Integer]),
-                    ('GetNumberOfCells', [Integer]),
-                    ('GetPointData', 
-                     [(vtk_pkg_identifier, 'vtkPointData')]),
-                    ('GetCellData',
-                     [(vtk_pkg_identifier, 'vtkCellData')]),
-                    ]
 
 class vtkDataSetAttributesInspector(vtkBaseInspector):
     
+    _settings = ModuleSettings(abstract=False, signature=vtk_hasher)
+    _input_ports = [('SetInput', 'vtkDataSetAttributes')]
+    _output_ports = [('GetScalars', 'vtkDataArray'),
+                     ('GetVectors', 'vtkDataArray'),
+                     ('GetNormals', 'vtkDataArray'),
+                     ('GetTCoords', 'vtkDataArray'),
+                     ('GetTensors', 'vtkDataArray'),
+                     ('GetGlobalIds', 'vtkDataArray'),
+                     ('GetPedigreeIds', 'vtkAbstractArray'),
+                     ]
+
     def compute(self):
         vtk_object = None
-        if self.hasInputFromPort("SetInput"):
-            port_object = self.getInputFromPort("SetInput")
-            if hasattr(port_object, "vtkInstance"):
-                vtk_object = port_object.vtkInstance
-            else:
-                raise ModuleError(self, "expected a vtk module")
+        if self.has_input("SetInput"):
+            vtk_object = self.get_input("SetInput")
+            if hasattr(vtk_object, "vtkInstance"):
+                vtk_object = vtk_object.vtkInstance
         if vtk_object:
             self.auto_set_results(vtk_object)
 
-    input_ports = [('SetInput',
-                    [(vtk_pkg_identifier, 'vtkDataSetAttributes')]),
-                   ]
-    output_ports = [('GetScalars', 
-                     [(vtk_pkg_identifier, 'vtkDataArray')]),
-                    ('GetVectors', 
-                     [(vtk_pkg_identifier, 'vtkDataArray')]),
-                    ('GetNormals', 
-                     [(vtk_pkg_identifier, 'vtkDataArray')]),
-                    ('GetTCoords', 
-                     [(vtk_pkg_identifier, 'vtkDataArray')]),
-                    ('GetTensors', 
-                     [(vtk_pkg_identifier, 'vtkDataArray')]),
-                    ('GetGlobalIds', 
-                     [(vtk_pkg_identifier, 'vtkDataArray')]),
-                    ('GetPedigreeIds', 
-                     [(vtk_pkg_identifier, 'vtkAbstractArray')]),
-                    ]
 
 class vtkDataArrayInspector(vtkBaseInspector):
 
-   def compute(self):
+    _settings = ModuleSettings(abstract=False, signature=vtk_hasher)
+    _input_ports = [('SetInput', 'vtkDataArray')]
+    _output_ports = [('GetMaxNorm', [Float]),
+                    ('GetRange', [Float] * 2)]
+
+    def compute(self):
         vtk_object = None
-        if self.hasInputFromPort("SetInput"):
-            port_object = self.getInputFromPort("SetInput")
-            if hasattr(port_object, "vtkInstance"):
-                vtk_object = port_object.vtkInstance
-            else:
-                raise ModuleError(self, "expected a vtk module")
+        if self.has_input("SetInput"):
+            vtk_object = self.get_input("SetInput")
+            if hasattr(vtk_object, "vtkInstance"):
+                vtk_object = vtk_object.vtkInstance
         if vtk_object:
             self.auto_set_results(vtk_object)
 
-   input_ports = [('SetInput',
-                   [(vtk_pkg_identifier, 'vtkDataArray')])]
-   output_ports = [('GetMaxNorm', [Float]),
-                   ('GetRange', [Float] * 2)]
-                   
+
 class vtkPolyDataInspector(vtkDataSetInspector):
 
+    _settings = ModuleSettings(abstract=False, signature=vtk_hasher)
+    _input_ports = [('SetInputConnection0', 'vtkAlgorithmOutput'),
+                    ('SetInput', 'vtkDataSet'),
+                    ]
+    _output_ports = [('GetVerts', 'vtkCellArray'),
+                     ('GetLines', 'vtkCellArray'),
+                     ('GetPolys', 'vtkCellArray'),
+                     ('GetStrips', 'vtkCellArray'),
+                     ('GetPoints', 'vtkPoints'),
+                     ('GetNumberOfVerts', [Integer]),
+                     ('GetNumberOfLines', [Integer]),
+                     ('GetNumberOfPolys', [Integer]),
+                     ('GetNumberOfStrips', [Integer]),
+                     ]
+
     def compute(self):
         vtk_object = None
-        if self.hasInputFromPort("SetInputConnection0"):
-            ic = self.getInputFromPort("SetInputConnection0")
-            port_object = ic.vtkInstance
-            ix = port_object.GetIndex()
+        if self.has_input("SetInputConnection0"):
+            port_object = self.get_input("SetInputConnection0")
+            if hasattr(port_object, "vtkInstance"):
+                port_object = port_object.vtkInstance
             producer = port_object.GetProducer()
             try:
                 vtk_object = producer.GetOutput()
             except AttributeError:
                 raise ModuleError(self, 
                                   "expected a module that supports GetOutput")
-        elif self.hasInputFromPort("SetInput"):
-            port_object = self.getInputFromPort("SetInput")
-            if hasattr(port_object, "vtkInstance"):
-                vtk_object = port_object.vtkInstance
-            else:
-                raise ModuleError(self, "expected a vtk module")
+        elif self.has_input("SetInput"):
+            vtk_object = self.get_input("SetInput")
+            if hasattr(vtk_object, "vtkInstance"):
+                vtk_object = vtk_object.vtkInstance
         if vtk_object:
             self.auto_set_results(vtk_object)
 
-    input_ports = [('SetInputConnection0',
-                    [(vtk_pkg_identifier, 'vtkAlgorithmOutput')]),
-                   ('SetInput',
-                    [(vtk_pkg_identifier, 'vtkDataSet')]),
-                   ]
-    output_ports = [('GetVerts',
-                     [(vtk_pkg_identifier, 'vtkCellArray')]),
-                    ('GetLines',
-                     [(vtk_pkg_identifier, 'vtkCellArray')]),
-                    ('GetPolys',
-                     [(vtk_pkg_identifier, 'vtkCellArray')]),
-                    ('GetStrips',
-                     [(vtk_pkg_identifier, 'vtkCellArray')]),
-                    ('GetPoints',
-                     [(vtk_pkg_identifier, 'vtkPoints')]),
-                    ('GetNumberOfVerts', [Integer]),
-                    ('GetNumberOfLines', [Integer]),
-                    ('GetNumberOfPolys', [Integer]),
-                    ('GetNumberOfStrips', [Integer]),
-                    ]
 
-def initialize():
-    vtkBaseInspector.register_self(abstract=True, signatureCallable=vtk_hasher)
-    vtkDataSetInspector.register_self(abstract=False, 
-                                      signatureCallable=vtk_hasher)
-    vtkDataSetAttributesInspector.register_self(abstract=False, 
-                                                signatureCallable=vtk_hasher)
-    vtkDataArrayInspector.register_self(abstract=False, 
-                                        signatureCallable=vtk_hasher)
-    vtkPolyDataInspector.register_self(abstract=False,
-                                       signatureCallable=vtk_hasher)
-    
+_modules = [vtkBaseInspector,
+            vtkDataSetInspector,
+            vtkDataSetAttributesInspector,
+            vtkDataArrayInspector,
+            vtkPolyDataInspector]
diff --git a/vistrails/packages/vtk/offscreen.py b/vistrails/packages/vtk/offscreen.py
index f8b2d15..852ab5e 100644
--- a/vistrails/packages/vtk/offscreen.py
+++ b/vistrails/packages/vtk/offscreen.py
@@ -1,52 +1,55 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-import vtk
-from identifiers import identifier as vtk_pkg_identifier
+from __future__ import division
 
-from vistrails.core.modules.module_registry import get_module_registry
+import vtk
 from vistrails.core.modules.vistrails_module import Module
-from vistrails.core.modules.basic_modules import File, Integer
 from vistrails.core import system
 
 class VTKRenderOffscreen(Module):
+    _input_ports = [('renderer', 'vtkRenderer'),
+                    ('width', 'basic:Integer'),
+                    ('height', 'basic:Integer')]
+    _output_ports = [('image', 'basic:File')]
 
     def compute(self):
-        r = self.getInputFromPort("renderer").vtkInstance
+        r = self.get_input("renderer").vtkInstance
         window = vtk.vtkRenderWindow()
-        w = self.forceGetInputFromPort("width", 512)
-        h = self.forceGetInputFromPort("height", 512)
+        w = self.force_get_input("width", 512)
+        h = self.force_get_input("height", 512)
         window.OffScreenRenderingOn()
         window.SetSize(w, h)
         # r.ResetCamera()
@@ -66,22 +69,17 @@ class VTKRenderOffscreen(Module):
         win2image.SetInput(window)
         win2image.Update()
         writer = vtk.vtkPNGWriter()
-        writer.SetInput(win2image.GetOutput())
+        if hasattr(writer, 'SetInput'):
+            writer.SetInput(win2image.GetOutput())
+        else:
+            # VTK 6 uses SetInputData
+            writer.SetInputData(win2image.GetOutput())
         output = self.interpreter.filePool.create_file(suffix='.png')
         writer.SetFileName(output.name)
         writer.Write()
         window.Finalize()
         if widget!=None:
             widget.close()
-        self.setResult("image", output)
-
-def register_self():
-    registry = get_module_registry()
-    r = registry.get_descriptor_by_name(vtk_pkg_identifier, 
-                                        'vtkRenderer').module
-    registry.add_module(VTKRenderOffscreen)
-    registry.add_input_port(VTKRenderOffscreen, 'renderer', r)
-    registry.add_input_port(VTKRenderOffscreen, 'width', Integer)
-    registry.add_input_port(VTKRenderOffscreen, 'height', Integer)
-    registry.add_output_port(VTKRenderOffscreen, 'image', File)
+        self.set_output("image", output)
 
+_modules = [VTKRenderOffscreen]
diff --git a/vistrails/packages/vtk/pythonclass.py b/vistrails/packages/vtk/pythonclass.py
new file mode 100644
index 0000000..9cc03f8
--- /dev/null
+++ b/vistrails/packages/vtk/pythonclass.py
@@ -0,0 +1,232 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+from __future__ import division
+
+from itertools import izip
+
+from vistrails.core.debug import format_exc
+from vistrails.core.modules.vistrails_module import Module, ModuleError
+from vistrails.core.modules.config import CIPort, COPort, ModuleSettings
+
+from .common import convert_input, convert_output, get_input_spec, get_output_spec
+
+
+class BaseClassModule(Module):
+    """ Wraps a python class as a vistrails Module using a ClassSpec
+        setter methods are used as inputs and getter methods as outputs
+
+    """
+    _settings = ModuleSettings(abstract=True)
+
+    _get_input_spec = classmethod(get_input_spec)
+    _get_output_spec = classmethod(get_output_spec)
+
+    def call_set_method(self, instance, port, params):
+        # convert params
+        params = convert_input(params, self.input_specs[port.name].signature)
+        if isinstance(params, tuple):
+            params = list(params)
+        elif not isinstance(params, list):
+            params = [params]
+        method_name = port.method_name
+        if port.method_type == 'OnOff':
+            # This converts OnOff ports to XOn(), XOff() calls
+            method_name = method_name + ('On' if params[0] else 'Off')
+            params = []
+        elif port.method_type == 'nullary':
+            # Call X() only if boolean is true
+            if params[0]:
+                params = []
+            else:
+                return
+        elif port.method_type == 'SetXToY':
+            # Append enum name to function name and delete params
+            method_name += params[0]
+            params = []
+        prepend_params = port.get_prepend_params()
+        # print "SETTING", method_name, prepend_params + params, instance.vtkInstance.__class__.__name__
+        method = getattr(instance, method_name)
+        try:
+            method(*(prepend_params + params))
+        except Exception, e:
+            raise
+
+    def call_get_method(self, instance, port):
+        # print "GETTING", port.method_name, port.get_prepend_params(), instance.vtkInstance.__class__.__name__
+        method = getattr(instance, port.method_name)
+        try:
+            value = method(*(port.get_prepend_params()))
+            # convert params
+            return convert_output(value, self.output_specs[port.name].signature)
+        except Exception, e:
+            raise
+
+    def call_inputs(self, instance):
+        # compute input methods and connections
+        # We need to preserve the order of the inputs
+        methods = self.is_method.values()
+        methods.sort()
+        methods_to_call = []
+        for value in methods:
+            (_, port) = value
+            conn = self.is_method.inverse[value]
+            p = conn()
+            # Convert to correct port depth
+            depth = conn.depth()
+            while depth < self._get_input_spec(port).depth:
+                p = [p]
+                depth += 1
+            methods_to_call.append([port, p])
+        connections_to_call = []
+        for (function, connector_list) in self.inputPorts.iteritems():
+            paramList = self.force_get_input_list(function)
+            for p,connector in izip(paramList, connector_list):
+                # Don't call method
+                if connector in self.is_method:
+                    continue
+                depth = connector.depth()
+                while depth < connector.spec.depth:
+                    p = [p]
+                    depth += 1
+                connections_to_call.append([function, p])
+        # Compute methods from visible ports last
+        #In the case of a vtkRenderer,
+        # we need to call the methods after the
+        #input ports are set.
+        if self._module_spec.methods_last:
+            to_call = connections_to_call + methods_to_call
+        else:
+            to_call = methods_to_call + connections_to_call
+        for port_name, params in to_call:
+            port = self._get_input_spec(port_name)
+            # Call method once for each item in depth1 lists
+            if port.depth == 0:
+                params = [params]
+            for ps in params:
+                self.call_set_method(instance, port, ps)
+
+    def call_outputs(self, instance):
+        outputs_list = self.output_specs_order
+        if 'self' in outputs_list:
+            outputs_list.remove('self')
+        if 'Instance' in outputs_list:
+            outputs_list.remove('Instance')
+        for port_name in outputs_list:
+            if not port_name in self.outputPorts:
+                # not connected
+                continue
+            port = self._get_output_spec(port_name)
+            result = self.call_get_method(instance, port)
+            self.set_output(port_name, result)
+
+    def compute(self):
+        spec = self._module_spec
+        # First create the instance
+        # TODO: How to handle parameters to instance
+        instance = getattr(self._lib, spec.code_ref)()
+
+        # Optional callback used for progress reporting
+        if spec.callback:
+            def callback(c):
+                self.logging.update_progress(self, c)
+            getattr(instance, spec.callback)(callback)
+        # Optional function for creating temporary files
+        if spec.tempfile:
+            getattr(instance, spec.tempfile)(self.interpreter.filePool.create_file)
+
+        # call input methods on instance
+        self.call_inputs(instance)
+
+        # optional compute method
+        if spec.compute:
+            getattr(instance, spec.compute)()
+
+        # convert outputs to dict
+        outputs = {}
+        outputs_list = self.output_specs_order
+        outputs_list.remove('self') # self is automatically set by base Module
+
+        # Get outputs
+        self.call_outputs(instance)
+
+        self.set_output('Instance', instance)
+
+        # optional cleanup method
+        if spec.cleanup:
+            getattr(instance, spec.cleanup)()
+
+
+def gen_class_module(spec, lib, klasses, **module_settings):
+    """Create a module from a python class specification
+
+    Parameters
+    ----------
+    spec : ClassSpec
+        A class to module specification
+    """
+    module_settings.update(spec.get_module_settings())
+    _settings = ModuleSettings(**module_settings)
+
+    # convert input/output specs into VT port objects
+    input_ports = [CIPort(ispec.name, ispec.get_port_type(), **ispec.get_port_attrs())
+                   for ispec in spec.input_port_specs]
+    output_ports = [COPort(ospec.name, ospec.get_port_type(), **ospec.get_port_attrs())
+                    for ospec in spec.output_port_specs]
+    output_ports.insert(0, COPort('Instance', spec.module_name)) # Adds instance output port
+
+    _input_spec_table = {}
+    for ps in spec.input_port_specs:
+        _input_spec_table[ps.name] = ps
+    _output_spec_table = {}
+    for ps in spec.output_port_specs:
+        _output_spec_table[ps.name] = ps
+
+    d = {'__module__': __name__,
+         '_settings': _settings,
+         '__doc__': spec.docstring,
+         '__name__': spec.name or spec.module_name,
+         '_input_ports': input_ports,
+         '_output_ports': output_ports,
+         '_input_spec_table': _input_spec_table,
+         '_output_spec_table': _output_spec_table,
+         '_module_spec': spec,
+         'is_cacheable': lambda self:spec.cacheable,
+         '_lib': lib}
+
+    superklass = klasses.get(spec.superklass, BaseClassModule)
+    new_klass = type(str(spec.module_name), (superklass,), d)
+    klasses[spec.module_name] = new_klass
+    return new_klass
diff --git a/vistrails/packages/vtk/tf_widget.py b/vistrails/packages/vtk/tf_widget.py
index b5ebc7e..f2d8688 100644
--- a/vistrails/packages/vtk/tf_widget.py
+++ b/vistrails/packages/vtk/tf_widget.py
@@ -1,46 +1,50 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 ##############################################################################
 # Transfer Function Widget for VTK
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
-from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin
-from vistrails.core.modules.basic_modules import new_constant, init_constant, Module
+from vistrails.core.modules.vistrails_module import Module
+from vistrails.core.modules.basic_modules import Constant
 from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.system import get_elementtree_library
 from vistrails.core.utils.color import ColorByName
+from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin
 import vtk
 import math
 import pickle
@@ -49,8 +53,6 @@ import StringIO
 import unittest
 ElementTree = get_elementtree_library()
 
-from identifiers import identifier as vtk_pkg_identifier
-
 ################################################################################
 # etc
 
@@ -175,7 +177,7 @@ class TransferFunction(object):
             
         return ElementTree.tostring(node)
    
-    @staticmethod         
+    @staticmethod
     def parse(strNode):
         """parse(strNode: str) -> TransferFunction
         Parses a string representing a TransferFunction and returns a 
@@ -210,6 +212,8 @@ class TransferFunction(object):
                                  float(colorNode.get('G','0.0')),
                                  float(colorNode.get('B','0.0')))
                         break
+                else:
+                    assert "'point' node has no 'color' child"
                 tf._pts.append((scalar,opacity,color))
         tf._pts.sort()
         return tf
@@ -261,7 +265,7 @@ class TransferFunctionPoint(QtGui.QGraphicsEllipseItem):
 
     def refresh(self):
         dx = self._fsx * 0.025 / self._sx
-        dy = self._fsy * 0.025/ self._sy
+        dy = self._fsy * 0.025 / self._sy
         # this is the setup
         self.setBrush(QtGui.QBrush(self._color))
         self.setRect(-dx,
@@ -303,8 +307,8 @@ class TransferFunctionPoint(QtGui.QGraphicsEllipseItem):
                 self._left_line.refresh()
             if self._right_line:
                 self._right_line.refresh()
-            if self.scene():
-                self.scene()._tf_poly.setup()
+            if self.parentItem():
+                self.parentItem()._tf_poly.setup()
             self.setToolTip("Double-click to change color\n"
                         "Right-click to remove point\n"
                         "Scalar: %.5f, Opacity: %.5f" % (self._scalar,
@@ -316,15 +320,15 @@ class TransferFunctionPoint(QtGui.QGraphicsEllipseItem):
         if not self._left_line or not self._right_line:
             # Ignore, self is a corner node that can't be removed
             return
-        
+
         # Removes the right line and self, re-ties data structure
         self._left_line._point_right = self._right_line._point_right
         self._left_line._point_right._left_line = self._left_line
-        
+
         # be friends with garbage collector
         self._right_line._point_left = None
         self._right_line._point_right = None
-        self.scene()._tf_poly.setup()
+        self.parentItem()._tf_poly.setup()
         self.scene().removeItem(self._right_line)
         self.scene().removeItem(self)
         self._left_line.refresh()
@@ -339,8 +343,10 @@ class TransferFunctionPoint(QtGui.QGraphicsEllipseItem):
         if self._right_line:
             self._right_line.refresh()
         self.refresh()
-        self.scene()._tf_poly.setup()
-        QtGui.QGraphicsEllipseItem.mouseDoubleClickEvent(self, event)
+        # sometimes the graphicsitem gets recreated, and we need to abort
+        if self.parentItem():
+            self.parentItem()._tf_poly.setup()
+            QtGui.QGraphicsEllipseItem.mouseDoubleClickEvent(self, event)
 
     def mousePressEvent(self, event):
         if event.button() == QtCore.Qt.RightButton:
@@ -348,18 +354,18 @@ class TransferFunctionPoint(QtGui.QGraphicsEllipseItem):
             self.remove_self()
         else:
             QtGui.QGraphicsEllipseItem.mousePressEvent(self, event)
-        
+
     def paint(self, painter, option, widget=None):
         """ paint(painter: QPainter, option: QStyleOptionGraphicsItem,
                   widget: QWidget) -> None
         Peform painting of the point without the ugly default dashed-line black
         square
-        
+
         """
         painter.setBrush(self.brush())
         painter.setPen(self.pen())
         painter.drawEllipse(self.rect())
-        
+
     def add_self_to_transfer_function(self, tf):
         tf.add_point(self._scalar,
                      self._opacity,
@@ -369,16 +375,15 @@ class TransferFunctionPoint(QtGui.QGraphicsEllipseItem):
 
 class TransferFunctionPolygon(QtGui.QGraphicsPolygonItem):
 
-    def __init__(self):
-        QtGui.QGraphicsPolygonItem.__init__(self)
+    def __init__(self, parent=None):
+        QtGui.QGraphicsPolygonItem.__init__(self, parent)
 
     def setup(self):
         # This inspects the scene, finds the left-most point, and
         # then builds the polygon traversing the linked list structure
-        if not self.scene():
+        pt = self.parentItem().get_leftmost_point()
+        if not pt:
             return
-        pt = self.scene().get_leftmost_point()
-        first_pt = pt
         self.setZValue(1.25)
         g = QtGui.QLinearGradient()
         g.setStart(0.0, 0.5)
@@ -468,7 +473,7 @@ class TransferFunctionLine(QtGui.QGraphicsPolygonItem):
         self.setup(self._sx, self._sy)
 
     def mouseDoubleClickEvent(self, event):
-        p = event.scenePos()
+        p = event.pos()
         c_left = self._point_left._color
         c_right = self._point_right._color
         u = ((p.x() - self._point_left._point.x()) /
@@ -476,12 +481,12 @@ class TransferFunctionLine(QtGui.QGraphicsPolygonItem):
         new_c = (u * c_right.redF() + (1-u) * c_left.redF(),
                  u * c_right.greenF() + (1-u) * c_left.greenF(),
                  u * c_right.blueF() + (1-u) * c_left.blueF())
-        new_point = TransferFunctionPoint(p.x()/ self._fsx, p.y()/self._fsy, new_c)
-        new_line = TransferFunctionLine(new_point, self._point_right)
+        new_point = TransferFunctionPoint(p.x()/ self._fsx, p.y()/self._fsy, new_c, self.parentItem())
+        self.parentItem()._tf_items.append(new_point)
+        new_line = TransferFunctionLine(new_point, self._point_right, self.parentItem())
+        self.parentItem()._tf_items.append(new_line)
         new_point._left_line = self
         self._point_right = new_point
-        self.scene().addItem(new_line)
-        self.scene().addItem(new_point)
         new_line.update_scale(self._point_left._sx,
                               self._point_left._sy)
         new_point.update_scale(self._point_left._sx,
@@ -493,25 +498,29 @@ class TransferFunctionLine(QtGui.QGraphicsPolygonItem):
         # This needs to be here, otherwise mouseDoubleClickEvent does
         # not get called.
         event.accept()
-        
 
 ##############################################################################
 # Scene, view, widget
 
-class TransferFunctionScene(QtGui.QGraphicsScene):
-
-    def __init__(self, tf, parent=None):
-        QtGui.QGraphicsScene.__init__(self, parent)
+class QGraphicsTransferFunction(QtGui.QGraphicsWidget, ConstantWidgetMixin):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+    def __init__(self, param, parent=None):
+        QtGui.QGraphicsWidget.__init__(self, parent)
+        ConstantWidgetMixin.__init__(self, param.strValue)
+        self.setAcceptHoverEvents(True)
+        if not param.strValue:
+            self._tf = copy.copy(default_tf)
+        else:
+            self._tf = TransferFunction.parse(param.strValue)
         self._tf_items = []
-        poly = TransferFunctionPolygon()
+        poly = TransferFunctionPolygon(self)
         poly.setup()
         self._tf_poly = poly
-        self.addItem(poly)
-        self.create_tf_items(tf)
+        self.create_tf_items(self._tf)
         self._tf_poly.setup()
         #current scale
         self._sx = 1.0
-        self._sy = 1.0    
+        self._sy = 1.0
         # Add outlines
         line_color = QtGui.QColor(200, 200, 200)
         pen = QtGui.QPen(line_color)
@@ -519,54 +528,51 @@ class TransferFunctionScene(QtGui.QGraphicsScene):
               QtCore.QPointF(GLOBAL_SCALE, 0.0),
               QtCore.QPointF(GLOBAL_SCALE, GLOBAL_SCALE),
               QtCore.QPointF(0.0, GLOBAL_SCALE)]
-        outline = QtGui.QPolygonF(ps)
-        self.addPolygon(outline, pen)
+        polygon = QtGui.QGraphicsPolygonItem(QtGui.QPolygonF(ps), self)
+        polygon.setPen(pen)
 
         for i in xrange(51):
             u = GLOBAL_SCALE * float(i) / 50.0
-            self.addLine(QtCore.QLineF(u, 0.0, u, GLOBAL_SCALE), pen)
-            self.addLine(QtCore.QLineF(0.0, u, GLOBAL_SCALE, u), pen)
+
+            line = QtGui.QGraphicsLineItem(QtCore.QLineF(u, 0.0, u, GLOBAL_SCALE), self)
+            line.setPen(pen)
+            line = QtGui.QGraphicsLineItem(QtCore.QLineF(0.0, u, GLOBAL_SCALE, u), self)
+            line.setPen(pen)
+
+        self.setGeometry(self.boundingRect())
+        # restore y axis inversion
+        self.setTransform(QtGui.QTransform(1, 0, 0, -1, 0, GLOBAL_SCALE))
+        self.setTransformOriginPoint(0, GLOBAL_SCALE)
+        self.reset_transfer_function(self._tf)
+
+    def boundingRect(self):
+        return QtCore.QRectF(0.0, 0.0, GLOBAL_SCALE, GLOBAL_SCALE)
 
     def reset_transfer_function(self, tf):
         self.create_tf_items(tf)
         self.update_scale(self._sx, self._sy)
         self._tf_poly.setup()
-        
-    def removeItem(self, item):
-        if item in self._tf_items:
-            self._tf_items.remove(item)
-        QtGui.QGraphicsScene.removeItem(self, item)
-
-    def addItem(self, item):
-        # Ugly, but hey
-        if isinstance(item, TransferFunctionLine) or \
-           isinstance(item, TransferFunctionPoint):
-            self._tf_items.append(item)
-        QtGui.QGraphicsScene.addItem(self, item)
 
     def create_tf_items(self, tf):
+        if self._tf_items and not self.scene(): # not added to scene yet
+            return
         items = copy.copy(self._tf_items)
         for item in items:
-            self.removeItem(item)
+            self.scene().removeItem(item)
         self._tf_items = []
         if len(tf._pts) == 0:
-            pt_left = TransferFunctionPoint(0.0, 0.0, (0.0, 0.0, 0.0))
-            pt_right = TransferFunctionPoint(1.0, 0.0, (0.0, 0.0, 0.0))
-            line = TransferFunctionLine(pt_left, pt_right)
-            
-            self.addItem(pt_left)
-            self.addItem(pt_right)
-            self.addItem(line)
-            
+            pt_left = TransferFunctionPoint(0.0, 0.0, (0.0, 0.0, 0.0), self)
+            self._tf_items.append(pt_left)
+            pt_right = TransferFunctionPoint(1.0, 0.0, (0.0, 0.0, 0.0), self)
+            self._tf_items.append(pt_right)
+            self._tf_items.append(TransferFunctionLine(pt_left, pt_right, self))
         else:
-            pts = [TransferFunctionPoint(*pt)
+            pts = [TransferFunctionPoint(*pt, parent=self)
                    for pt in tf._pts]
-            lines = [TransferFunctionLine(pt_l, pt_r)
-                     for (pt_l, pt_r) in zip(pts[:-1], pts[1:])]
-            for pt in pts:
-                self.addItem(pt)
-            for line in lines:
-                self.addItem(line)
+            self._tf_items.extend(pts)
+            lns = [TransferFunctionLine(pt_l, pt_r, self)
+                   for (pt_l, pt_r) in zip(pts[:-1], pts[1:])]
+            self._tf_items.extend(lns)
 
     def add_knot(self, scalar, opacity):
         pass
@@ -584,8 +590,7 @@ class TransferFunctionScene(QtGui.QGraphicsScene):
             if hasattr(item, '_left_line') and not item._left_line:
                 pt = item
                 break
-        assert pt
-        return pt        
+        return pt
 
     def get_transfer_function(self):
         result = TransferFunction()
@@ -598,6 +603,29 @@ class TransferFunctionScene(QtGui.QGraphicsScene):
                 break
         return result
 
+    def contents(self):
+        return self.get_transfer_function().serialize()
+
+    def setContents(self, strValue, silent=True):
+        if not strValue:
+            self._tf = copy.copy(default_tf)
+        else:
+            self._tf = TransferFunction.parse(strValue)
+        self.reset_transfer_function(self._tf)
+        if not silent:
+            self.update_parent()    
+
+    def hoverLeaveEvent(self, event):
+        self.update_parent()
+        QtGui.QGraphicsWidget.hoverLeaveEvent(self, event)
+
+class TransferFunctionScene(QtGui.QGraphicsScene):
+
+    def __init__(self, param, parent=None):
+        QtGui.QGraphicsScene.__init__(self, parent)
+        self.tf = QGraphicsTransferFunction(param)
+        self.addItem(self.tf)
+
 class TransferFunctionView(QtGui.QGraphicsView):
     def __init__(self, parent=None):
         QtGui.QGraphicsView.__init__(self, parent)
@@ -608,8 +636,8 @@ class TransferFunctionView(QtGui.QGraphicsView):
     def resizeEvent(self, event):
         self.resetMatrix()
         self.setMatrix(QtGui.QMatrix(event.size().width() / (GLOBAL_SCALE *10.0/9) , 0,
-                                     0, -event.size().height() / (GLOBAL_SCALE*10.0/9), 0, 0))
-        self.scene().update_scale(event.size().width()/(2000.0/9), event.size().height()/(2000.0/9))
+                                     0, event.size().height() / (GLOBAL_SCALE*10.0/9), GLOBAL_SCALE, 0))
+        self.scene().tf.update_scale(event.size().width()/(2000.0/9), event.size().height()/(2000.0/9))
         
     def focusOutEvent(self, event):
         self.parent().update_parent()
@@ -618,17 +646,16 @@ class TransferFunctionView(QtGui.QGraphicsView):
 default_tf = TransferFunction()
 default_tf.add_point(0.0, 0.0, (0.0, 0.0, 0.0))
 default_tf.add_point(1.0, 0.0, (0.0, 0.0, 0.0))
-    
+
 class TransferFunctionWidget(QtGui.QWidget, ConstantWidgetMixin):
+    contentsChanged = QtCore.pyqtSignal(tuple)
+
+    GraphicsItem = QGraphicsTransferFunction
 
     def __init__(self, param, parent=None):
         QtGui.QWidget.__init__(self, parent)
-        ConstantWidgetMixin.__init__(self, param.strValue)
-        if not param.strValue:
-            self._tf = copy.copy(default_tf)
-        else:
-            self._tf = TransferFunction.parse(param.strValue)
-        self._scene = TransferFunctionScene(self._tf, self)
+        self._scene = TransferFunctionScene(param, self)
+        self._scene.tf.update_parent = self.update_parent
         layout = QtGui.QVBoxLayout()
         self.setLayout(layout)
         self._view = TransferFunctionView(self)
@@ -638,7 +665,8 @@ class TransferFunctionWidget(QtGui.QWidget, ConstantWidgetMixin):
         self._view.show()
         self._view.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                  QtGui.QSizePolicy.Expanding)
-        self._view.setMatrix(QtGui.QMatrix(1, 0, 0, -1, 0, 0))
+        # TODO remove this
+        self._view.setMatrix(QtGui.QMatrix(1, 0, 0, -1, GLOBAL_SCALE, 0))
         self.setMinimumSize(260,240)
         caption = QtGui.QLabel("Double-click on the line to add a point")
         font = QtGui.QFont('Arial', 11)
@@ -648,68 +676,77 @@ class TransferFunctionWidget(QtGui.QWidget, ConstantWidgetMixin):
         layout.addWidget(caption)
 
     def contents(self):
-        return self._scene.get_transfer_function().serialize()
-    
+        return self._scene.tf.contents()
+
     def setContents(self, strValue, silent=True):
-        if not strValue:
-            self._tf = copy.copy(default_tf)
-        else:
-            self._tf = TransferFunction.parse(strValue)
-        self._scene.reset_transfer_function(self._tf)
-        if not silent:
-            self.update_parent()    
-            
+        self._scene.tf.setContents(strValue, silent)
+
+    def set_last_contents(self, contents):
+        self._scene.tf._last_contents = contents
+    def get_last_contents(self):
+        return self._scene.tf._last_contents
+    _last_contents = property(get_last_contents, set_last_contents)
+
 ##############################################################################
 # Helper module to adjust range
 
 class vtkScaledTransferFunction(Module):
 
+    # FIXME Add documentation
+    _input_ports = [
+        ['Input', 'vtkAlgorithmOutput'],
+        ['Dataset', 'vtkDataObject'],
+        ['Range', '(basic:Float, basic:Float)'],
+        ['TransferFunction', 'TransferFunction']]
+
+    _output_ports = [
+        ['TransferFunction', 'TransferFunction'],
+        ['vtkPiecewiseFunction', 'vtkPiecewiseFunction'],
+        ['vtkColorTransferFunction', 'vtkColorTransferFunction']]
+
     def compute(self):
         reg = get_module_registry()
-        tf = self.getInputFromPort('TransferFunction')
+        tf = self.get_input('TransferFunction')
         new_tf = copy.copy(tf)
-        if self.hasInputFromPort('Input'):
-            port = self.getInputFromPort('Input')
-            algo = port.vtkInstance.GetProducer()
-            output = algo.GetOutput(port.vtkInstance.GetIndex())
+        if self.has_input('Input'):
+            port = self.get_input('Input')
+            algo = port.GetProducer()
+            output = algo.GetOutput(port.GetIndex())
             (new_tf._min_range, new_tf._max_range) = output.GetScalarRange()
-        elif self.hasInputFromPort('Dataset'):
-            algo = self.getInputFromPort('Dataset').vtkInstance
+        elif self.has_input('Dataset'):
+            algo = self.get_input('Dataset')
             output = algo
             (new_tf._min_range, new_tf._max_range) = output.GetScalarRange()
         else:
-            (new_tf._min_range, new_tf._max_range) = self.getInputFromPort('Range')
-            
-        self.setResult('TransferFunction', new_tf)
+            (new_tf._min_range, new_tf._max_range) = self.get_input('Range')
+
+        self.set_output('TransferFunction', new_tf)
         (of,cf) = new_tf.get_vtk_transfer_functions()
         
-        of_module = reg.get_descriptor_by_name(vtk_pkg_identifier, 
-                                               'vtkPiecewiseFunction').module()
-        of_module.vtkInstance  = of
-        
-        cf_module = reg.get_descriptor_by_name(vtk_pkg_identifier, 
-                                               'vtkColorTransferFunction').module()
-        cf_module.vtkInstance  = cf
-        
-        self.setResult('vtkPicewiseFunction', of_module)
-        self.setResult('vtkColorTransferFunction', cf_module)
-
-string_conversion = staticmethod(lambda x: x.serialize())
-conversion = staticmethod(lambda x: TransferFunction.parse(x))
-validation = staticmethod(lambda x: isinstance(x, TransferFunction))
-TransferFunctionConstant = new_constant('TransferFunction',
-                                        conversion,
-                                        default_tf,
-                                        validation,
-                                        TransferFunctionWidget)
-TransferFunctionConstant.translate_to_string = string_conversion
+        self.set_output('vtkPicewiseFunction', of)
+        self.set_output('vtkColorTransferFunction', cf)
 
-##############################################################################
+class TransferFunctionConstant(Constant):
+    default_value = default_tf
+
+    @staticmethod
+    def translate_to_python(x):
+        return TransferFunction.parse(x)
+
+    @staticmethod
+    def translate_to_string(x):
+        return x.serialize()
+
+    @staticmethod
+    def validate(x):
+        return isinstance(x, TransferFunction)
+
+    @staticmethod
+    def get_widget_class():
+        return TransferFunctionWidget
 
-def initialize():
-    init_constant(TransferFunctionConstant)
-    
 ##############################################################################
+
 class TestTransferFunction(unittest.TestCase):
     def test_serialization(self):
         tf = TransferFunction()
@@ -731,6 +768,10 @@ class TestTransferFunction(unittest.TestCase):
         assert tf == tf1
         assert tf == tf2
         assert tf1 == tf2
-        
+
+TransferFunctionConstant.__name__ = "TransferFunction"
+
+_modules = [TransferFunctionConstant, vtkScaledTransferFunction]
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/vistrails/packages/vtk/vtk_parser.py b/vistrails/packages/vtk/vtk_parser.py
deleted file mode 100644
index 2306ad9..0000000
--- a/vistrails/packages/vtk/vtk_parser.py
+++ /dev/null
@@ -1,548 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-
-# Author: Prabhu Ramachandran
-# Copyright (c) 2004, Enthought, Inc.
-# License: BSD Style.
-
-# Modified for VisTrails by the VisTrails team.
-
-"""This module parses the VTK methods, obtains the argument and return
-type information, and organizes them.
-
-"""
-import re
-import vtk
-import class_tree
-import vistrails.core.debug
-
-log      = vistrails.core.debug.log
-warning  = vistrails.core.debug.warning
-critical = vistrails.core.debug.critical
-debug    = vistrails.core.debug.debug
-
-class VTKMethodParser(object):
-    """This class provides useful methods for parsing methods of a VTK
-    class or instance.
-
-    The class allows one to categorize the methods of the VTK class
-    and also obtain the method signatures in a form that is easy to
-    use.  When the `parse` method is called, it in turn calls the
-    `_organize_methods` method.  This method organizes the VTK methods
-    into different instance variables described in the following.
-    `self.toggle_meths` contains a dictionary of all the boolean
-    methods of the form <Value>On/Off.  The dictionary keys are
-    strings with the <Value>'s and the value of each item is the
-    default value (0/1) of the item (the example below will clarify
-    this).  `self.state_meths` contains a dictionary which collects
-    the Set<Prop>To<Value> type of methods.  The key is the <Prop> and
-    the value is a list containing the different string <Value>'s and
-    their corresponding mapped value.  The first value in these is the
-    default value of the <Prop>.  `self.get_set_meths` will contain a
-    dictionary which collects all the methods of the form
-    Set/Get<Prop> that are not already specified in
-    `self.toggle_meths` or `self.state_meths`.  The default value of
-    the Get<Prop> is stored.  If the value accepted by the method has
-    a range (via the methods `Get<Prop>MinValue` and
-    `Get<Prop>MaxValue`), then that range is computed and stored.
-    `self.get_meths` stores the methods that are of the form
-    `Get<Prop>`.  `self.other_meths` stores the remaining methods.
-    The parsing is quite fast.  Parsing every class in the VTK API
-    takes a couple of seconds (on a Pentium III @ 450Mhz).
-
-    Here is an example::
-        
-       >>> import vtk
-       >>> p = VTKMethodParser()
-       >>> p.parse(vtk.vtkProperty)
-       >>> print p.get_toggle_methods()
-       {'EdgeVisibility': 0, 'BackfaceCulling': 0, 'FrontfaceCulling': 0}
-       >>> print p.get_state_methods()['Representation']
-       [['Surface', 2], ['Points', 0], ['Surface', 2], ['Wireframe', 1]]
-       >>> print p.get_get_set_methods()['Opacity']
-       (1.0, (0.0, 1.0))
-       >>> print p.get_get_methods()
-       ['GetClassName']
-       >>> print p.get_other_methods()[:3]
-       ['BackfaceRender', 'DeepCopy', 'IsA']
-
-
-    The class also provides a method called `get_method_signature`
-    that obtains the Python method signature given the VTK method
-    object.  Here is an example::
-    
-       >>> import vtk
-       >>> p = VTKMethodParser()
-       >>> o = vtk.vtkProperty
-       >>> print p.get_method_signature(o.GetClassName)
-       [(['string'], None)]
-       >>> print p.get_method_signature(o.GetColor)[0]
-       ([('float', 'float', 'float')], None)
-       >>> print p.get_method_signature(o.GetColor)[1]
-       ([None], (('float', 'float', 'float'),))
-
-    The `get_method_signature` is fairly efficient and obtaining the
-    signature for every method in every class in the VTK API takes
-    around 6 seconds (on a Pentium III @ 450Mhz).
-
-    """
-
-    def __init__(self, use_tree=True):
-        """Initializes the object.
-
-        Parameters
-        ----------
-
-        - use_tree : `bool`
-
-          If True (default), use a ClassTree instance to obtain a
-          concrete subclass for an abstract base class.  This is used
-          only to find the range and default values for some of the
-          methods.  If False, no ClassTree instance is created.
-
-          This is optional because, creating a ClassTree is expensive.
-          The parser functionality can be very useful even without the
-          use of a ClassTree.  For example, if one wants to save the
-          state of a VTK object one only needs to know the names of
-          the methods and not their default values, ranges etc.  In
-          that case using a parser should be cheap.
-
-        """
-        # The ClassTree is needed to find an instantiable child class
-        # for an abstract VTK parent class.  This instance is used to
-        # obtain the state values and the ranges of the arguments
-        # accepted by the Get/Set methods that have a
-        # Get<Prop>{MaxValue,MinValue} method.
-        if use_tree:
-            self._tree = class_tree.ClassTree(vtk)
-            self._tree.create()
-        else:
-            self._tree = None
-        self._state_patn = re.compile('To[A-Z0-9]')
-        self._initialize()
-
-    #################################################################
-    # 'VTKMethodParser' interface.
-    #################################################################
-
-    def parse(self, obj, no_warn=True):
-        """Parse the methods for a given VTK object/class.
-
-        Given a VTK class or object, this method parses the methods
-        and orgaizes them into useful categories.  The categories and
-        their usage is documented in the documentation for the class.
-
-        Parameters
-        ----------
-
-        - obj : VTK class or instance
-
-        - no_warn : `bool` (default: True)
-
-          If True (default), it suppresses any warnings generated by
-          the VTK object when parsing the methods.  This is safe to
-          use.
-        
-        """
-        if not hasattr(obj, '__bases__'):
-            klass = obj.__class__
-        else:
-            klass = obj
-
-        methods = self.get_methods(klass)
-
-        if no_warn:
-            # Save warning setting and shut it off before parsing.
-            warn = vtk.vtkObject.GetGlobalWarningDisplay()
-            if klass.__name__ <> 'vtkObject':
-                vtk.vtkObject.GlobalWarningDisplayOff()
-
-        self._organize_methods(klass, methods)
-
-        if no_warn:
-            # Reset warning status.
-            vtk.vtkObject.SetGlobalWarningDisplay(warn)
-
-    def get_methods(self, klass):
-        """Returns all the relevant methods of the given VTK class."""
-        methods = dir(klass)[:]
-        if hasattr(klass, '__members__'):
-            # Only VTK versions < 4.5 have these.
-            for m in klass.__members__:
-                methods.remove(m)
-
-        return methods
-
-    def get_toggle_methods(self):        
-        """Returns a dictionary of the parsed <Value>On/Off methods
-        along with the default value.
-
-        """
-        return self.toggle_meths
-    
-    def get_state_methods(self):
-        """Returns a dict of the parsed Set<Prop>To<Value>.
-
-        The keys are the <Prop> string with a list of the different
-        <Value> strings along with their corresponding value (if
-        obtainable).  The first value is the default value of the
-        state.
-        
-        """
-        return self.state_meths
-
-    def get_get_set_methods(self):
-        """Returns a dict of the parsed Get/Set<Value> methods.
-
-        The keys of the dict are the <Value> strings and contain a
-        two-tuple containing the default value (or None if it is not
-        obtainable for some reason) and a pair of numbers specifying
-        an acceptable range of values (or None if not obtainable).
-
-        """
-        return self.get_set_meths
-    
-    def get_get_methods(self):
-        """Return a list of parsed Get<Value> methods.
-
-        All of these methods do NOT have a corresponding Set<Value>.
-
-        """
-        return self.get_meths
-    
-    def get_other_methods(self):
-        """Return list of all other methods, that are not
-        categorizable.
-
-        """
-        return self.other_meths    
-
-    def get_method_signature(self, method):
-        """Returns information on the Python method signature given
-        the VTK method.
-
-        The doc string of the given method object to get the method
-        signature.  The method returns a list of tuples, each of which
-        contains 2 items, the first is a list representing the return
-        value the second represents the arguments to be passed to the
-        function.  If the method supports different return values and
-        arguments, this function returns all of their signatures.
-
-        Parameters
-        ----------
-
-        - method : `method`
-
-          A VTK method object.
-
-        """
-        doc = method.__doc__
-        doc = doc[:doc.find('\n\n')]
-        sig = doc.split('\n')
-        sig = [x.strip() for x in sig]
-
-        # Remove all the C++ function signatures.
-        for i in sig[:]:
-            if i[:4] == 'C++:':
-                sig.remove(i)
-
-        # Remove the V.<method_name>
-        sig = [x.replace('V.' + method.__name__, '') for x in sig]
-
-        pat = re.compile(r'\b')
-
-        # Split into [return_value, arguments] after processing them.
-        tmp = list(sig)
-        sig = []
-        for i in tmp:
-            # Split to get return values.
-            x = i.split('->')
-            # Strip each part.
-            x = [y.strip() for y in x]
-
-            if len(x) == 1: # No return value
-                x = [None, x[0]]
-            else:
-                x.reverse()
-
-            ret, arg = x        
-
-            # Remove leading and trailing parens for arguments.
-            arg = arg[1:-1]
-            if not arg:
-                arg = None
-            if arg and arg[-1] == ')':
-                arg = arg + ','
-
-            # Now quote the args and eval them.  Easy!
-            if ret:
-                ret = eval(pat.sub('\"', ret))
-            if arg:
-                arg = eval(pat.sub('\"', arg))
-                if isinstance(arg, basestring):
-                    arg = [arg]
-
-            sig.append(([ret], arg))
-
-        return sig
-
-    def get_tree(self):
-        """Return the ClassTree instance used by this class."""
-        return self._tree
-
-    #################################################################
-    # Non-public interface.
-    #################################################################
-
-    def _initialize(self):
-        """Initializes the method categories."""
-        # Collects the <Value>On/Off methods.
-        self.toggle_meths = {}
-        # Collects the Set<Prop>To<Value> methods.
-        self.state_meths = {}
-        # Collects the Set/Get<Value> pairs.
-        self.get_set_meths = {}
-        # Collects the Get<Value> methods.
-        self.get_meths = []
-        # Collects all the remaining methods.
-        self.other_meths = []
-
-    def _organize_methods(self, klass, methods):
-        """Organizes the given methods of a VTK class into different
-        categories.
-
-        Parameters
-        ----------
-
-        - klass : A VTK class
-
-        - methods : `list` of `str`
-
-          A list of the methods to be categorized.
-
-        """
-        self._initialize()
-        meths = methods[:]
-        meths = self._find_toggle_methods(klass, meths)
-        meths = self._find_state_methods(klass, meths)
-        meths = self._find_get_set_methods(klass, meths)
-        meths = self._find_get_methods(klass, meths)
-        self.other_meths = [x for x in meths if '__' not in x]
-
-    def _remove_method(self, meths, method):
-        try:
-            meths.remove(method)
-        except ValueError:
-            pass
-
-    def _find_toggle_methods(self, klass, methods):
-        """Find/store methods of the form <Value>{On,Off} in the given
-        `methods`.  Returns the remaining list of methods.
-
-        """
-        meths = methods[:]
-        tm = self.toggle_meths
-        for method in meths[:]:
-            if method[-2:] == 'On':
-                key = method[:-2]
-                if (key + 'Off') in meths and ('Get' + key) in meths:
-                    tm[key] = None
-                    meths.remove(method)
-                    meths.remove(key + 'Off')
-                    self._remove_method(meths, 'Set' + key)
-                    self._remove_method(meths, 'Get' + key)
-        # get defaults
-        if tm:
-            obj = self._get_instance(klass)
-            if obj:
-                for key in tm:
-                    try:
-                        tm[key] = getattr(obj, 'Get%s'%key)()
-                    except TypeError, e:
-                        log("Type error during parsing: class %s will not expose method %s " % (klass.__name__, key))
-                    except AttributeError, e:
-                        log("Attribute error during parsing: class %s will not expose method %s " % (klass.__name__, key))
-        return meths
-
-    def _find_state_methods(self, klass, methods):
-        """Find/store methods of the form Set<Prop>To<Value> in the
-        given `methods`.  Returns the remaining list of methods.  The
-        method also computes the mapped value of the different
-        <Values>.
-
-        """
-        # These ignored ones are really not state methods.
-        ignore = ['SetUpdateExtentToWholeExtent']
-        meths = methods[:]
-        sm = self.state_meths
-        for method in meths[:]:
-            if method not in ignore and method[:3] == 'Set':
-                # Methods of form Set<Prop>To<Value>
-                match = self._state_patn.search(method)
-                # Second cond. ensures that this is not an accident.
-                if match and (('Get'+method[3:]) not in meths):
-                    key = method[3:match.start()] # The <Prop> part.
-                    if (('Get' + key) in methods):
-                        val = method[match.start()+2:] # <Value> part.
-                        meths.remove(method)
-                        if sm.has_key(key):
-                            sm[key].append([val, None])
-                        else:
-                            sm[key] = [[val, None]]
-                            meths.remove('Get'+ key)
-                            self._remove_method(meths, 'Set'+ key)
-                            if ('Get' + key + 'MaxValue') in meths:
-                                meths.remove('Get' + key + 'MaxValue')
-                                meths.remove('Get' + key + 'MinValue')
-                            try:
-                                meths.remove('Get' + key + 'AsString')
-                            except ValueError:
-                                pass
-
-        # Find the values for each of the states, i.e. find that
-        # vtkProperty.SetRepresentationToWireframe() corresponds to
-        # vtkProperty.SetRepresentation(1).
-        if sm:
-            obj = self._get_instance(klass)
-            if obj:
-                for key, values in sm.items():
-                    default = getattr(obj, 'Get%s'%key)()
-                    for x in values[:]:
-                        try:
-                            getattr(obj, 'Set%sTo%s'%(key, x[0]))()
-                        except:
-                            continue
-                        val = getattr(obj, 'Get%s'%key)()
-                        x[1] = val
-                        if val == default:
-                            values.insert(0, [x[0], val])
-        return meths
-
-    def _find_get_set_methods(self, klass, methods):
-        """Find/store methods of the form {Get,Set}Prop in the given
-        `methods` and returns the remaining list of methods.
-
-        Note that it makes sense to call this *after*
-        `_find_state_methods` is called in order to avoid incorrect
-        duplication.  This method also computes the default value and
-        the ranges of the arguments (when possible) by using the
-        Get<Prop>{MaxValue,MinValue} methods.
-
-        """
-        meths = methods[:]
-        gsm = self.get_set_meths
-        
-        for method in meths[:]:
-            # Methods of the Set/Get form.
-            if method in ['Get', 'Set']:
-                # This occurs with the vtkInformation class.
-                continue
-            elif (method[:3] == 'Set') and ('Get' + method[3:]) in methods:
-                key = method[3:]
-                meths.remove('Set' + key)
-                meths.remove('Get' + key)                    
-                if ('Get' + key + 'MaxValue') in meths:
-                    meths.remove('Get' + key + 'MaxValue')
-                    meths.remove('Get' + key + 'MinValue')
-                    gsm[key] = 1
-                else:
-                    gsm[key] = None
-
-        # Find the default and range of the values.
-        if gsm:
-            obj = self._get_instance(klass)
-            if obj:
-                klass_name = klass.__name__
-                for key, value in gsm.items():
-                    if klass_name == 'vtkPolyData':
-                        # Evil hack, this class segfaults!
-                        default = None
-                    else:
-                        try:
-                            default = getattr(obj, 'Get%s'%key)()
-                        except TypeError:
-                            default = None
-                    if value:
-                        low = getattr(obj, 'Get%sMinValue'%key)()
-                        high = getattr(obj, 'Get%sMaxValue'%key)()
-                        gsm[key] = (default, (low, high))
-                    else:
-                        gsm[key] = (default, None)
-            else:
-                # We still might have methods that have a default range.
-                for key, value in gsm.items():
-                    if value == 1:
-                        gsm[key] = None
-        
-        return meths
-
-    def _find_get_methods(self, klass, methods):
-        """Find/store methods of the form Get<Value> in the given
-        `methods` and returns the remaining list of methods.
-
-        """
-        meths = methods[:]
-        gm = self.get_meths
-        for method in meths[:]:
-            if method == 'Get':
-                # Occurs with vtkInformation
-                continue
-            elif method[:3] == 'Get':        
-                gm.append(method)
-                meths.remove(method)
-        return meths
-
-    def _get_instance(self, klass):
-        """Given a VTK class, `klass`, returns an instance of the
-        class.
-
-        If the class is abstract, it uses the class tree to return an
-        instantiable subclass.  This is necessary to get the values of
-        the 'state' methods and the ranges for the Get/Set methods.
-        
-        """
-        obj = None
-        try:
-            obj = klass()
-        except (TypeError, NotImplementedError):
-            if self._tree:
-                t = self._tree
-                n = t.get_node(klass.__name__)
-                for c in n.children:
-                    obj = self._get_instance(t.get_class(c.name))
-                    if obj:
-                        break
-        return obj
-
diff --git a/vistrails/tests/resources/import_pkg/__init__.py b/vistrails/packages/vtk/vtk_wrapper/__init__.py
similarity index 100%
copy from vistrails/tests/resources/import_pkg/__init__.py
copy to vistrails/packages/vtk/vtk_wrapper/__init__.py
diff --git a/vistrails/packages/vtk/vtk_wrapper/class_tree.py b/vistrails/packages/vtk/vtk_wrapper/class_tree.py
new file mode 100644
index 0000000..2f8ae65
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/class_tree.py
@@ -0,0 +1,305 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+# Author: Prabhu Ramachandran
+# Copyright (c) 2004, Enthought, Inc.
+# License: BSD Style.
+
+"""This module generates the class hierarchy for any given Python
+modules.  This can be used (among other things) to generate the
+traitified VTK classes in the correct order.
+
+"""
+
+from __future__ import division
+
+import __builtin__
+
+
+class TreeNode(object):
+    """Represents a node in the class tree.
+
+    Stores information on the sub and super classes of a particular
+    class.  It also stores the inheritance level of the class inside
+    the inheritance tree (essentially how many levels of inheritance
+    are there below this class).  This inheritance level is computed
+    when the `get_level` method is called.  The `get_level` method
+    works only when the parent information is complete.
+    
+    """
+
+    def __init__(self, klass):
+        """Given a class, create a node in the tree.
+
+        Parameters
+        ----------
+        - klass : `class`
+
+          The class which is represented as a node in the tree.
+
+        """
+        self.klass = klass
+        self.name = klass.__name__
+        self.children = []
+        self.parents = []
+        # Uninitialized level is set to None
+        self.level = None
+
+    def add_parent(self, parent):
+        """Add a parent node."""
+        assert isinstance(parent, TreeNode)
+        if parent not in self.parents:
+            self.parents.append(parent)
+
+    def add_child(self, child):
+        """Add a child node. """
+        assert isinstance(child, TreeNode)
+        if child not in self.children:
+            self.children.append(child)
+
+    def get_level(self):
+        """Returns the inheritance level of the node (an int).  If the
+        level has not been set, the method computes it.  Note however,
+        that this computation will fail if the parent information is
+        incorrect.
+
+        """
+        if not self.level:
+            if self.parents:
+                self.level = max([x.get_level() for x in self.parents]) + 1
+            else:
+                self.level = 0
+        return self.level
+
+    def get_ancestors(self):
+        """Returns a list of ancestor nodes from which this class has
+        descended.
+
+        """
+        def _get_ancestors(node, ancestors):
+            ancestors.extend(node.parents)
+            for p in node.parents:
+                _get_ancestors(p, ancestors)
+        ancestors = []
+        _get_ancestors(self, ancestors)
+        return ancestors
+
+
+class ClassTree(object):
+    """Contains and generates all the class tree information.
+
+    On initialization of the instance, nothing is done.  The classes
+    are obtained using the list of modules (or a single module) that
+    is used to initialize the instance.  One must then call the
+    `create` method to generate the tree structure.  The instance of
+    the class also can be treated as an iterator which iterates over
+    the nodes of the tree.
+
+    There are two ways in which the tree hierarchy is stored.  A
+    dictionary mapping class names to the tree node and a tree
+    represented as a list of lists containing the nodes.  The tree is
+    organized based on a concept of an inheritance level.  A class
+    that has no parent classes (no base classes) is said to be at
+    level zero.  If a class inherits successively from 7 classes, it
+    is at level 6.  An example of inheritance for a vtkFoo class is
+    given below:
+
+      vtkFoo -> vtkBar -> vtkObject -> vtkObjectBase
+
+    Here, vtkObjectBase has an inheritance level of 0 and vtkFoo a
+    level of 3.  One can traverse the tree by using the level as an
+    index and find all the classes at a particular level.
+
+    Here is some example usage of this class::
+
+        >>> import vtk
+        >>> t = ClassTree(vtk)
+        >>> t.create()
+        >>> print t.get_node('vtkObject').name
+        vtkObject
+        >>> print t.get_node('vtkObject').parents[0].name
+        vtkObjectBase
+        >>> print len(t.tree[0])
+        1
+        >>> t.tree[0][0].name
+        vtkObjectBase
+    
+    """
+
+    def __init__(self, modules):
+        """Initialize the instance with the given modules.
+
+        Parameters
+        ----------
+
+        - modules : `sequence` of modules or a module
+
+          This is either a single module or a sequence of modules.
+          The instance uses these list of modules to generate the
+          class tree.
+          
+        """
+        self.nodes = {}
+        self.tree = [[]]
+        if not hasattr(modules, '__iter__'):
+            self.modules = [modules]
+        else:
+            self.modules = modules
+
+    def __iter__(self):
+        return iter(self.nodes.values())
+
+    def _generate_hierarchy(self, klass):
+        """Does the hard work of generating the class hierarchy."""
+        node = self.get_node(klass.__name__, create=1)
+        for base in klass.__bases__:
+            base_node = self.get_node_from_class(base, create=1)
+            node.add_parent(base_node)
+            base_node.add_child(node)
+            self._generate_hierarchy(base)
+
+    def get_class(self, name):
+        """Given a class name in the given modules returns the class."""
+        klass = None
+        for m in self.modules:
+            if hasattr(m, name):
+                return getattr(m, name)
+        if hasattr(__builtin__, name):
+            klass = getattr(__builtin__, name)
+        if not klass:
+            try:
+                klass = self.nodes[name].klass
+            except KeyError:
+                raise KeyError, "Cannot find class of name %s"%name
+        return klass
+
+    def add_node(self, klass):
+        """Create a node for the given class."""
+        name = klass.__name__
+        if not self.nodes.has_key(name):
+            node = TreeNode(klass)
+            self.nodes[name] = node
+            return node
+
+    def get_node(self, name, create=0):
+        """Get a node of the given name.
+
+        Parameters
+        ----------
+
+        - name : `str`
+
+          Name of the node to get.
+
+        - create : `boolean`
+
+          If True, a new node will be added if no node of the given
+          name is available.  Defaults to False.
+
+        Returns
+        -------
+
+        - `TreeNode`
+
+        """
+        if self.nodes.has_key(name):
+            return self.nodes[name]
+        elif create:
+            return self.add_node(self.get_class(name))
+
+    def get_node_from_class(self, cls, create=0):
+        """Get a node of the given class.
+
+        Parameters
+        ----------
+
+        - cls : `class`
+
+          Class of the node to get.
+
+        - create : `boolean`
+
+          If True, a new node will be added if no node of the given
+          name is available.  Defaults to False.
+
+        Returns
+        -------
+
+        - `TreeNode`
+
+        """
+        name = cls.__name__
+        if self.nodes.has_key(name):
+            return self.nodes[name]
+        elif create:
+            return self.add_node(cls)
+
+    def create(self, class_names=None):
+        """This method generates the class tree given an optional list
+        of class names.
+
+        Parameters
+        ----------
+
+        - class_names - `list` of `str`
+
+          An optional list of names of the classes to generate the
+          tree for.  Defaults to None where the class list is computed
+          from the modules.        
+
+        """
+        if class_names is None:
+            class_names = []
+            for m in self.modules:            
+                class_names.extend(dir(m))
+            
+        # Generate the nodes.
+        for name in class_names:
+            klass = self.get_class(name)
+            if klass and hasattr(klass, '__bases__'):
+                self._generate_hierarchy(klass)
+
+        # Compute the inheritance level and store the nodes in the tree.
+        for node in self:
+            d = node.get_level()
+            while len(self.tree) <= d:
+                self.tree.append([])
+            self.tree[d].append(node)
+
+        # Sort the nodes alphabetically.
+        def _comp(x, y):
+            return cmp(x.name, y.name)
+        for nodes in self.tree:
+            nodes.sort(_comp)
diff --git a/vistrails/packages/vtk/vtk_wrapper/fix_classes.py b/vistrails/packages/vtk/vtk_wrapper/fix_classes.py
new file mode 100644
index 0000000..3533cb3
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/fix_classes.py
@@ -0,0 +1,70 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import vtk
+
+################################################################################
+# Some fixed classes that solve a few VTK API issues
+
+# This dictionary stores the patched class to vtk class mapping.
+# This would be naturally better stored as an attribute directly on the
+# patched class. VTK, however, doesn't like class attributes.
+description = {}
+
+# http://www.vtk.org/doc/nightly/html/classvtkImagePlaneWidget.html
+# SetUserControlledLookupTable needs to be set before calling
+# SetLookupTable.  VTK should do it automatically, so let's fix it
+
+
+# This fix seems to break on VTK versions larger than 5.0.3. It might also
+# be because of an interaction with python 2.6, but I haven't checked that.
+class vtkImagePlaneWidget_fixed(vtk.vtkImagePlaneWidget):
+    def SetLookupTable(self, lookup_table):
+        self.UserControlledLookupTableOn()
+        vtk.vtkImagePlaneWidget.SetLookupTable(self, lookup_table)
+v = vtk.vtkVersion()
+version = [v.GetVTKMajorVersion(),
+           v.GetVTKMinorVersion(),
+           v.GetVTKBuildVersion()]
+if version < [5, 0, 4]:
+    description[vtkImagePlaneWidget_fixed] = vtk.vtkImagePlaneWidget
+else:
+    description[id(vtkImagePlaneWidget_fixed)] = vtk.vtkImagePlaneWidget
+
+# Set docstring to wrap it correctly
+vtkImagePlaneWidget_fixed.SetLookupTable.__doc__ = vtk.vtkImagePlaneWidget.SetLookupTable.__doc__
diff --git a/vistrails/packages/vtk/vtk_wrapper/parse.py b/vistrails/packages/vtk/vtk_wrapper/parse.py
new file mode 100644
index 0000000..484a995
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/parse.py
@@ -0,0 +1,931 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+from itertools import izip, chain
+import re
+
+import vtk
+
+from .class_tree import ClassTree
+from .specs import ClassSpec, SpecList, \
+                   ClassInputPortSpec as InputPortSpec, \
+                   ClassOutputPortSpec as OutputPortSpec
+from .vtk_parser import VTKMethodParser
+
+parser = VTKMethodParser()
+
+disallowed_classes = set(
+    [
+        'simplewrapper', # ticket 464: VTK 5.10 on OpenSuSE needs this
+        'vtkEventQtSlotConnect', # VTK 5.10.1 OpenSuSE (uses QObject)
+        'vtkQtView', # VTK 5.10.1 OpenSuSE (uses QWidget)
+        'vtkCriticalSection',
+        'vtkDataArraySelection',
+        'vtkDebugLeaks',
+        'vtkDirectory',
+        'vtkDynamicLoader',
+        'vtkFunctionParser',
+        'vtkGarbageCollector',
+        'vtkHeap',
+        'vtkInformationKey',
+        'vtkInstantiator',
+        'vtkLogLookupTable', # use vtkLookupTable.SetScaleToLog10() instead
+        'vtkMath',
+        'vtkModelMetadata',
+        'vtkMultiProcessController',
+        'vtkMutexLock',
+        'vtkOutputWindow',
+        'vtkPriorityQueue',
+        'vtkQtInitialization',
+        'vtkReferenceCount',
+        'vtkRenderWindowCollection',
+        'vtkRenderWindowInteractor',
+        'vtkTesting',
+        'vtkWindow',
+        'vtkContext2D',       #Not working for VTK 5.7.0
+        'vtkPLYWriter',       #Not working for VTK 5.7.0.
+        'vtkBooleanTexture',  #Not working for VTK 5.7.0
+        'vtkImageMaskBits',   #Not working for VTK 5.7.0
+        'vtkHardwareSelector',#Not working for VTK 5.7.0
+        'vtkOpenGLExtensionManager',
+
+        # these show up with new parse
+        'vtkAbstractContextBufferId',
+        'vtkAbstractElectronicData',
+        'vtkCallbackCommand',
+        'vtkImageComplex',
+        'vtkInformationDataObjectKey',
+        'vtkInformationDoubleKey',
+        'vtkInformationDoubleVectorKey',
+        'vtkInformationIdTypeKey',
+        'vtkInformationInformationKey',
+        'vtkInformationInformationVectorKey',
+        'vtkInformationIntegerKey',
+        'vtkInformationIntegerPointerKey',
+        'vtkInformationIntegerVectorKey',
+        'vtkInformationKeyVectorKey',
+        'vtkInformationObjectBaseKey',
+        'vtkInformationRequestKey',
+        'vtkInformationStringKey',
+        'vtkInformationStringVectorKey',
+        'vtkInformationUnsignedLongKey',
+        'vtkRenderWindow',
+        'vtkShaderProgram2',
+        'vtkShadowMapBakerPassLightCameras',
+        'vtkShadowMapBakerPassTextures',
+        'vtkTDxMotionEventInfo',
+        'vtkVolumeRayCastDynamicInfo',
+        'vtkVolumeRayCastStaticInfo',
+        # For VTK 5.8
+        'vtkMPICommunicatorOpaqueComm',
+        # For VTK 6
+        'vtkBlueObeliskData',
+        'vtkSocketController',
+        'vtkMPIController',
+        'vtkInformationVariantVectorKey',
+        'vtkInformationVariantKey',
+        'QImage',
+        'vtkPLOT3DReader',
+        # For VTK 6.2
+        'QuantileDefinitionType'
+    ])
+
+disallowed_modules = set(
+    [
+        'vtkGeoAlignedImageCache',
+        'vtkGeoTerrainCache',
+        'vtkMPIGroup'
+    ])
+
+def create_module(base_cls_name, node):
+    """create_module(base_cls_name: String, node: TreeNode) -> [ModuleSpec]
+
+    Construct a module spec that inherits from base_cls_name with
+    specification from node.
+
+    """
+    if node.name in disallowed_modules: return []
+    if node.name == 'int': return [] #enum
+    def obsolete_class_list():
+        lst = []
+        items = ['vtkInteractorStyleTrackball',
+                 'vtkStructuredPointsGeometryFilter',
+                 'vtkConstrainedPointHandleRepresentation',
+                 'vtkRenderViewBase',
+                 'vtkRenderView']
+        def try_to_add_item(item):
+            try:
+                lst.append(getattr(vtk, item))
+            except AttributeError:
+                pass
+        for item in items:
+            try_to_add_item(item)
+        return lst
+
+    obsolete_list = obsolete_class_list()
+
+    def is_abstract():
+        """is_abstract tries to instantiate the class. If it's
+        abstract, this will raise."""
+        # Consider obsolete classes abstract
+        if node.klass in obsolete_list:
+            return True
+        try:
+            getattr(vtk, node.name)()
+        except (TypeError, NotImplementedError): # VTK raises type error on abstract classes
+            return True
+        return False
+
+    try:
+        node.klass.__doc__.decode('latin-1')
+    except UnicodeDecodeError:
+        print "ERROR decoding docstring", node.name
+        raise
+
+    input_ports, output_ports = get_ports(node.klass)
+    output_ports = list(output_ports) # drop generator
+
+    cacheable = (issubclass(node.klass, vtk.vtkAlgorithm) and
+                 (not issubclass(node.klass, vtk.vtkAbstractMapper))) or \
+                issubclass(node.klass, vtk.vtkScalarTree)
+
+    is_algorithm = issubclass(node.klass, vtk.vtkAlgorithm)
+    tempfile = '_set_tempfile' if issubclass(node.klass, vtk.vtkWriter) else None
+    callback = '_set_callback' if is_algorithm else None
+    methods_last = hasattr(node.klass, 'SetRenderWindow')
+
+    module_spec = ClassSpec(node.name, base_cls_name, node.name,
+                            node.klass.__doc__.decode('latin-1'), callback,
+                            tempfile, cacheable, input_ports, output_ports,
+                            compute='Update', cleanup='_cleanup',
+                            methods_last=methods_last, abstract=is_abstract())
+
+    module_specs = [module_spec]
+    for child in node.children:
+        if child.name in disallowed_classes:
+            continue
+        module_specs.extend(create_module(node.name, child))
+
+    return module_specs
+
+def get_doc(cls, port_name):
+    f = re.match(r"(.*)_\d+$", port_name)
+    if f:
+        name = f.group(1)
+    else:
+        name = port_name
+
+    doc = getattr(cls, name).__doc__
+    # Remove all the C++ function signatures.
+    idx = doc.find('\n\n')
+    if idx > 0:
+        doc = doc[idx+2:]
+    return doc
+
+def prune_signatures(cls, name, signatures, output=False):
+    """prune_signatures tries to remove redundant signatures to reduce
+    overloading. It _mutates_ the given parameter.
+
+    It does this by performing several operations:
+
+    1) It compares a 'flattened' version of the types
+    against the other 'flattened' signatures. If any of them match, we
+    keep only the 'flatter' ones.
+
+    A 'flattened' signature is one where parameters are not inside a
+    tuple.
+
+    2) We explicitly forbid a few signatures based on modules and names
+
+    """
+    # yeah, this is Omega(n^2) on the number of overloads. Who cares?
+
+    def flatten(type_):
+        if type_ is None:
+            return []
+        def convert(entry):
+            if isinstance(entry, tuple):
+                return list(entry)
+            elif isinstance(entry, str):
+                return [entry]
+            else:
+                result = []
+                first = True
+                lastList = True
+                for e in entry:
+                    if (isinstance(e, list)):
+                        if lastList == False: result[len(result)] = result[len(result)] + ']'
+                        aux = e
+                        aux.reverse()
+                        aux[0] = '[' + aux[0]
+                        aux[-1] = aux[-1] + ']'
+                        result.extend(aux)
+                        lastList = True
+                    else:
+                        if first: e = '[' + e
+                        result.append(e)
+                        lastList = False
+                        first = False
+                return result
+        result = []
+        for entry in type_:
+            result.extend(convert(entry))
+        return result
+    flattened_entries = [flatten(sig[1]) for
+                         sig in signatures]
+    def hit_count(entry):
+        result = 0
+        for entry in flattened_entries:
+            if entry in flattened_entries:
+                result += 1
+        return result
+    hits = [hit_count(entry) for entry in flattened_entries]
+
+    def forbidden(flattened, hit_count, original):
+        if (issubclass(cls, vtk.vtk3DWidget) and
+            name == 'PlaceWidget' and
+            flattened == []):
+            return True
+        # We forbid this because addPorts hardcodes this but
+        # SetInputArrayToProcess is an exception for the InfoVis
+        # package
+        if (cls == vtk.vtkAlgorithm and
+            name!='SetInputArrayToProcess'):
+            return True
+        return False
+
+    # This is messy: a signature is only allowed if there's no
+    # explicit disallowing of it. Then, if it's not overloaded,
+    # it is also allowed. If it is overloaded and not the flattened
+    # version, it is pruned. If these are output ports, there can be
+    # no parameters.
+
+    def passes(flattened, hit_count, original):
+        if forbidden(flattened, hit_count, original):
+            return False
+        if hit_count == 1:
+            return True
+        if original[1] is None:
+            return True
+        if output and len(original[1]) > 0:
+            return False
+        if hit_count > 1 and len(original[1]) == len(flattened):
+            return True
+        return False
+
+    signatures[:] = [original for (flattened, hit_count, original)
+                     in izip(flattened_entries,
+                             hits,
+                             signatures)
+                     if passes(flattened, hit_count, original)]
+
+    #then we remove the duplicates, if necessary
+    unique_signatures = []
+
+    #Remove the arrays and tuples inside the signature
+    #  in order to transform it in a single array
+    #Also remove the '[]' from the Strings
+    def removeBracts(signatures):
+        result = []
+        stack = list(signatures)
+        while (len(stack) != 0):
+            curr = stack.pop(0)
+            if (isinstance(curr, str)):
+                c = curr.replace('[', '')
+                c = c.replace(']', '')
+                result.append(c)
+            elif (curr == None):
+                result.append(curr)
+            elif (isinstance(curr, list)):
+                curr.reverse()
+                for c in curr: stack.insert(0, c)
+            elif (isinstance(curr, tuple)):
+                cc = list(curr)
+                cc.reverse()
+                for c in cc: stack.insert(0, c)
+            else:
+                result.append(curr)
+        return result
+
+    unique2 = []
+    for s in signatures:
+        aux = removeBracts(s)
+        if not unique2.count(aux):
+            unique_signatures.append(s)
+            unique2.append(aux)
+    signatures[:] = unique_signatures
+
+file_name_pattern = re.compile('.*FileName$')
+set_file_name_pattern = re.compile('Set.*FileName$')
+
+def resolve_overloaded_name(name, ix, signatures):
+    # VTK supports static overloading, VisTrails does not. The
+    # solution is to check whether the current function has
+    # overloads and change the names appropriately.
+    if len(signatures) == 1:
+        return name
+    else:
+        return name + '_' + str(ix+1)
+
+type_map_dict = {'int': "basic:Integer",
+                 'long': "basic:Integer",
+                 'float': "basic:Float",
+                 'char*': "basic:String",
+                 'char *': "basic:String",
+                 'string': "basic:String",
+                 'char': "basic:String",
+                 'const char*': "basic:String",
+                 'const char *': "basic:String",
+                 '[float': "basic:Float",
+                 'float]': "basic:Float",
+                 '[int': "basic:Integer",
+                 'int]': "basic:Integer",
+                 'bool': "basic:Boolean",
+                 'unicode': 'basic:String'}
+
+type_map_values = set(type_map_dict.itervalues())
+# ["basic:Integer", "basic:Float", "basic:String", "basic:Boolean"]
+
+def get_port_types(name):
+    """ get_port_types(name: str) -> str
+    Convert from C/C++ types into VisTrails port type
+
+    """
+    if isinstance(name, tuple) or isinstance(name, list):
+        return [get_port_types(x) for x in name]
+    if name in type_map_dict:
+        return type_map_dict[name]
+    else:
+        if name is not None and name.strip():
+            #if not name.startswith("vtk"):
+            #    print "RETURNING RAW TYPE:", name
+            return name
+    return None
+
+def is_type_allowed(t):
+    if isinstance(t, list):
+        return all(is_type_allowed(sub_t) for sub_t in t)
+    if t is None:
+        return False
+    if t == "tuple" or t == "function":
+        return False
+    return t not in disallowed_classes
+
+def get_algorithm_ports(cls):
+    """ get_algorithm_ports(cls: class) -> None
+    If module is a subclass of vtkAlgorithm, this function will add all
+    SetInputConnection([id],[port]) and GetOutputPort([id]) as
+    SetInputConnection{id}([port]) and GetOutputPort{id}.
+
+    """
+    input_ports = []
+    output_ports = []
+
+    if issubclass(cls, vtk.vtkAlgorithm):
+        # We try to instantiate the class here to get the number of
+        # ports and to avoid abstract classes
+        try:
+            instance = cls()
+        except TypeError:
+            pass
+        else:
+            for i in xrange(instance.GetNumberOfInputPorts()):
+                port_name = "SetInputConnection%d" % i
+                port_spec = InputPortSpec(name=port_name,
+                                          method_name="SetInputConnection",
+                                          port_type="vtkAlgorithmOutput",
+                                          docstring=get_doc(cls,
+                                                        "SetInputConnection"),
+                                          show_port=True,
+                                          prepend_params=[i])
+                input_ports.append(port_spec)
+            for i in xrange(instance.GetNumberOfOutputPorts()):
+                port_name = "GetOutputPort%d" % i
+                port_spec = OutputPortSpec(name=port_name,
+                                           method_name="GetOutputPort",
+                                           port_type="vtkAlgorithmOutput",
+                                           docstring=get_doc(cls,
+                                                             "GetOutputPort"),
+                                           show_port=True)
+                output_ports.append(port_spec)
+
+    return input_ports, output_ports
+
+disallowed_get_ports = set([
+    'GetClassName',
+    'GetErrorCode',
+    'GetNumberOfInputPorts',
+    'GetNumberOfOutputPorts',
+    'GetOutputPortInformation',
+    'GetTotalNumberOfInputConnections',
+    ])
+
+def get_get_ports(cls, get_list):
+    output_ports = []
+    for name in get_list:
+        if name in disallowed_get_ports:
+            continue
+        method = getattr(cls, name)
+        signatures = parser.get_method_signature(method)
+        if len(signatures) > 1:
+            prune_signatures(cls, name, signatures, output=True)
+        for ix, getter in enumerate(signatures):
+            if getter[1]:
+                #print ("Can't handle getter %s (%s) of class %s: Needs input "
+                #       "to get output" % (ix+1, name, cls.__name__))
+                continue
+            if len(getter[0]) != 1:
+                #print ("Can't handle getter %s (%s) of class %s: More than a "
+                #       "single output" % (ix+1, name, cls.__name__))
+                continue
+            port_type = get_port_types(getter[0][0])
+            if is_type_allowed(port_type):
+                n = resolve_overloaded_name(name[3:], ix, signatures)
+                port_spec = OutputPortSpec(name=n,
+                                           method_name=name,
+                                           port_type=port_type,
+                                           show_port=False,
+                                           docstring=get_doc(cls, name))
+                output_ports.append(port_spec)
+    return [], output_ports
+
+disallowed_get_set_ports = set(['ReferenceCount',
+                                'InputConnection',
+                                'OutputPort',
+                                'Progress',
+                                'ProgressText',
+                                'InputArrayToProcess',
+                                ])
+
+color_ports = set(["DiffuseColor", "Color", "AmbientColor", "SpecularColor",
+                   "EdgeColor", "Background", "Background2"])
+
+to_vtk6_names = {'AddInput':  'AddInputData',
+                 'SetInput':  'SetInputData',
+                'AddSource': 'AddSourceData',
+                'SetSource': 'SetSourceData'}
+def get_vtk6_name(cls, name):
+    # Return SetInputData for SetInput etc.
+    if name == 'AddInput' and cls == vtk.vtkXYPlotActor:
+        return 'AddDataSetInput'
+    return to_vtk6_names.get(name, name)
+
+# FIXME use defaults and ranges!
+def get_get_set_ports(cls, get_set_dict):
+    """get_get_set_ports(cls: class, get_set_dict: dict) -> None
+    Convert all Setxxx methods of cls into input ports and all Getxxx
+    methods of module into output ports
+
+    Keyword arguments:
+    cls          --- class
+    get_set_dict --- the Set/Get method signatures returned by vtk_parser
+
+    """
+
+    input_ports = []
+    output_ports = []
+    for name in get_set_dict:
+        if name in disallowed_get_set_ports:
+            continue
+        getter_name = 'Get%s' % name
+        setter_name = 'Set%s' % name
+        getter_method = getattr(cls, getter_name)
+        setter_method = getattr(cls, setter_name)
+        getter_sig = parser.get_method_signature(getter_method)
+        setter_sig = parser.get_method_signature(setter_method)
+        if len(getter_sig) > 1:
+            prune_signatures(cls, getter_name, getter_sig, output=True)
+        for order, getter in enumerate(getter_sig):
+            if getter[1]:
+                #print ("Can't handle getter %s (%s) of class %s: Needs input "
+                #       "to get output" % (order+1, name, cls.__name__))
+                continue
+            if len(getter[0]) != 1:
+                #print ("Can't handle getter %s (%s) of class %s: More than a "
+                #       "single output" % (order+1, name, cls.__name__))
+                continue
+            port_type = get_port_types(getter[0][0])
+            if is_type_allowed(port_type):
+                if name in color_ports:
+                    ps = OutputPortSpec(name=name,
+                                        method_name=getter_name,
+                                        port_type="basic:Color",
+                                        show_port=False,
+                                        docstring=get_doc(cls, getter_name))
+                    input_ports.append(ps)
+                else:
+                    ps = OutputPortSpec(name=name,
+                                        method_name=getter_name,
+                                        port_type=port_type,
+                                        show_port=False,
+                                        docstring=get_doc(cls, getter_name))
+                    output_ports.append(ps)
+
+        if len(setter_sig) > 1:
+            prune_signatures(cls, setter_name, setter_sig)
+        docstring = get_doc(cls, setter_name)
+        v = vtk.vtkVersion()
+        version = [v.GetVTKMajorVersion(),
+                   v.GetVTKMinorVersion(),
+                   v.GetVTKBuildVersion()]
+        if version < [6, 0, 0]:
+            # Always use VTK6-style names for InputData-style types
+            setter_name = get_vtk6_name(cls, setter_name)
+            name = setter_name[3:]
+        for ix, setter in enumerate(setter_sig):
+            if setter[1] is None:
+                continue
+
+            # Wrap SetFileNames for VisTrails file access
+            # FIXME add documentation
+            if file_name_pattern.match(name):
+                ps = InputPortSpec(name=name[:-4],
+                                   method_name=setter_name,
+                                   port_type="basic:File",
+                                   show_port=True)
+                input_ports.append(ps)
+            # Wrap color methods for VisTrails GUI facilities
+            # FIXME add documentation
+            elif name in color_ports:
+                ps = InputPortSpec(name=name,
+                                   method_name=setter_name,
+                                   port_type="basic:Color",
+                                   show_port=False)
+                input_ports.append(ps)
+            # Wrap SetRenderWindow for exporters
+            # FIXME Add documentation
+            elif name == 'RenderWindow' and cls == vtk.vtkExporter:
+                ps = InputPortSpec(name="vtkRenderer",
+                                   port_type="vtkRenderer",
+                                   show_port=True)
+                input_ports.append(ps)
+            else:
+                n = resolve_overloaded_name(name, ix, setter_sig)
+                port_types = get_port_types(setter[1])
+                if is_type_allowed(port_types):
+                    if len(setter[1]) == 1:
+                        show_port = True
+                        try:
+                            show_port = port_types[0] not in type_map_values
+                        except TypeError: # hash error
+                            pass
+                        port_types = port_types[0]
+                    else:
+                        show_port = False
+                    ps = InputPortSpec(name=n,
+                                       method_name=setter_name,
+                                       port_type=port_types,
+                                       show_port=show_port,
+                                       docstring=docstring,
+                                       depth=1)
+                    input_ports.append(ps)
+
+    return input_ports, output_ports
+
+disallowed_toggle_ports = set(['GlobalWarningDisplay',
+                               'Debug',
+                               ])
+def get_toggle_ports(cls, toggle_dict):
+    """ get_toggle_ports(cls: class, toggle_dict: dict) -> None
+    Convert all xxxOn/Off methods of module into boolean input ports
+
+    Keyword arguments:
+    module      --- Module
+    toggle_dict --- the Toggle method signatures returned by vtk_parser
+
+    """
+
+    input_ports = []
+    for name, default_val in toggle_dict.iteritems():
+        if name in disallowed_toggle_ports:
+            continue
+        ps = InputPortSpec(name=name,
+                           method_name=name, # With On/Off appended
+                           method_type='OnOff',
+                           port_type="basic:Boolean",
+                           show_port=False,
+                           defaults=[bool(default_val)],
+                           docstring=get_doc(cls, name + "On"))
+        input_ports.append(ps)
+    return input_ports, []
+
+disallowed_state_ports = set([('InputArray', 'Process')])
+def get_state_ports(cls, state_dict):
+    """ get_state_ports(cls: class, state_dict: dict) -> None
+    Convert all SetxxxToyyy methods of module into input ports
+
+    Keyword arguments:
+    module     --- Module
+    state_dict --- the State method signatures returned by vtk_parser
+
+    """
+    input_ports = []
+    for name in state_dict:
+        enum_values = []
+        translations = {}
+        method_name = "Set%sTo%s" % (name, state_dict[name][0][0])
+        method_name_short = "Set%sTo" % name
+        for mode in state_dict[name]:
+            if (name, mode[0]) in disallowed_state_ports:
+                continue
+            if mode[0] in translations:
+                if translations[mode[0]] != mode[1]:
+                    raise Exception("Duplicate entry with different value")
+                continue
+            translations[mode[0]] = mode[1]
+            enum_values.append(mode[0])
+
+        ps = InputPortSpec(name=name,
+                           method_name=method_name_short,
+                           method_type='SetXToY',
+                           port_type="basic:String",
+                           entry_types=['enum'],
+                           values=[enum_values],
+                           show_port=False,
+                           docstring=get_doc(cls, method_name))
+        input_ports.append(ps)
+
+    return input_ports, []
+
+
+disallowed_other_ports = set(
+    [
+     'BreakOnError',
+     'DeepCopy',
+     'FastDelete',
+     'HasObserver',
+     'HasExecutive',
+     'InvokeEvent',
+     'IsA',
+     'Modified',
+     'NewInstance',
+     'PrintRevisions',
+     'RemoveAllInputs',
+     'RemoveObserver',
+     'RemoveObservers',
+     'SafeDownCast',
+#     'SetInputArrayToProcess',
+     'ShallowCopy',
+     'Update',
+     'UpdateInformation',
+     'UpdateProgress',
+     'UpdateWholeExtent',
+     # DAK: These are taken care of by s.upper() == s test
+     # 'GUI_HIDE',
+     # 'INPUT_ARRAYS_TO_PROCESS',
+     # 'INPUT_CONNECTION',
+     # 'INPUT_IS_OPTIONAL',
+     # 'INPUT_IS_REPEATABLE',
+     # 'INPUT_PORT',
+     # 'INPUT_REQUIRED_DATA_TYPE',
+     # 'INPUT_REQUIRED_FIELDS',
+     # 'IS_INTERNAL_VOLUME',
+     # 'IS_EXTERNAL_SURFACE',
+     # 'MANAGES_METAINFORMATION',
+     # 'POINT_DATA',
+     # 'POINTS',
+     # 'PRESERVES_ATTRIBUTES',
+     # 'PRESERVES_BOUNDS',
+     # 'PRESERVES_DATASET',
+     # 'PRESERVES_GEOMETRY',
+     # 'PRESERVES_RANGES',
+     # 'PRESERVES_TOPOLOGY',
+     # for VTK 6
+     'SetMaterialProperties',
+     ])
+
+
+# FIXME deal with this in diff...
+force_not_optional_port = set(
+    ['ApplyViewTheme',
+     ])
+
+def get_other_ports(cls, other_list):
+    """ addOtherPorts(cls: Module, other_list: list) -> None
+    Convert all other ports such as Insert/Add.... into input/output
+
+    Keyword arguments:
+    cls        --- class
+    other_dict --- any other method signatures that is not
+                   Algorithm/SetGet/Toggle/State type
+
+    """
+    input_ports = []
+    for name in other_list:
+        # DAK: check for static methods as name.upper() == name
+        if name in disallowed_other_ports or name.upper() == name:
+            continue
+        elif name=='CopyImportVoidPointer':
+            # FIXME add documentation
+            ps = InputPortSpec(name='CopyImportVoidString',
+                               method_name='CopyImportVoidPointer',
+                               port_type='basic:String',
+                               show_port=True)
+
+        # elif name[:3] in ['Add','Set'] or name[:6]=='Insert':
+        else:
+            method = getattr(cls, name)
+            signatures = ""
+            if not isinstance(method, int):
+                signatures = parser.get_method_signature(method)
+            if len(signatures) > 1:
+                prune_signatures(cls, name, signatures)
+            docstring = get_doc(cls, name)
+            v = vtk.vtkVersion()
+            version = [v.GetVTKMajorVersion(),
+                       v.GetVTKMinorVersion(),
+                       v.GetVTKBuildVersion()]
+            if version < [6, 0, 0]:
+                # Always use VTK6-style names for InputData-style types
+                name = get_vtk6_name(cls, name)
+            for (ix, sig) in enumerate(signatures):
+                ([result], params) = sig
+                port_types = get_port_types(params)
+                if not (name[:3] in ['Add','Set'] or
+                        name[:6]=='Insert' or
+                        (port_types is not None and len(port_types) == 0) or
+                        result is None):
+                    continue
+                if is_type_allowed(port_types):
+                    n = resolve_overloaded_name(name, ix, signatures)
+                    if n.startswith('Set'):
+                        n = n[3:]
+                    show_port = False
+                    if len(port_types) < 1:
+                        raise Exception("Shouldn't have empty input")
+                    elif len(port_types) == 1:
+                        if name[:3] in ['Add','Set'] or name[:6]=='Insert':
+                            try:
+                                show_port = port_types[0] not in type_map_values
+                            except TypeError:
+                                pass
+                        port_types = port_types[0]
+                    ps = InputPortSpec(name=n,
+                                       method_name=name,
+                                       port_type=port_types,
+                                       show_port=show_port,
+                                       docstring=docstring,
+                                       depth=1)
+                    input_ports.append(ps)
+                elif result == None or port_types == []:
+                    n = resolve_overloaded_name(name, ix, signatures)
+                    ps = InputPortSpec(name=n,
+                                       method_name=name,
+                                       port_type='basic:Boolean',
+                                       method_type='nullary',
+                                       docstring=get_doc(cls, name),
+                                       depth=1)
+                    input_ports.append(ps)
+    return input_ports, []
+
+def get_custom_ports(cls):
+    """ get_custom_ports(cls: Module) -> None
+    Patch other ports needed to get a good wrapping
+
+    Keyword arguments:
+    cls        --- class
+
+    """
+    input_ports = []
+    output_ports = []
+
+    if cls == vtk.vtkAlgorithm:
+        ps = InputPortSpec(name='AddInputConnection',
+                           port_type='vtkAlgorithmOutput',
+                           show_port=True,
+                           docstring='Adds an input connection',
+                           depth=1)
+        input_ports.append(ps)
+    # vtkWriters have a custom File port
+    if cls in [vtk.vtkWriter, vtk.vtkImageWriter]:
+        ps = OutputPortSpec(name='file',
+                            port_type='basic:File',
+                            show_port=True,
+                            docstring='The written file')
+        output_ports.append(ps)
+    elif cls == vtk.vtkVolumeProperty:
+        ps = InputPortSpec(name='TransferFunction',
+                           method_name='SetTransferFunction',
+                           port_type='TransferFunction',
+                           docstring='Sets the transfer function to use')
+        input_ports.append(ps)
+    elif cls == vtk.vtkDataSet:
+        ps = InputPortSpec(name='SetPointData',
+                           method_name='PointData',
+                           port_type='vtkPointData',
+                           show_port=True,
+                           docstring='Sets the point data')
+        input_ports.append(ps)
+        ps = InputPortSpec(name='SetCellData',
+                           method_name='CellData',
+                           port_type='vtkCellData',
+                           show_port=True,
+                           docstring='Sets the cell data')
+        input_ports.append(ps)
+    elif cls==vtk.vtkCell:
+        ps = InputPortSpec(name='SetPointIds',
+                           method_name='PointIds',
+                           port_type='vtkIdList',
+                           show_port=True,
+                           docstring='Sets the point id list')
+        input_ports.append(ps)
+    elif cls==vtk.vtkMultiBlockPLOT3DReader:
+        ps = OutputPortSpec(name='StructuredGrid',
+                            method_name='FirstBlock',
+                            port_type='vtkStructuredGrid',
+                            show_port=True,
+                            docstring='Returns .GetOutput().GetBlock(0)')
+        output_ports.append(ps)
+
+    return input_ports, output_ports
+
+
+def get_ports(cls):
+    """get_ports(cls: vtk class) -> None
+
+    Search all metamethods of module and add appropriate ports
+
+    """
+
+    parser.parse(cls)
+    ports_tuples = []
+    ports_tuples.append(get_algorithm_ports(cls))
+    ports_tuples.append(get_get_ports(cls, parser.get_get_methods()))
+    ports_tuples.append(get_get_set_ports(cls, parser.get_get_set_methods()))
+    ports_tuples.append(get_toggle_ports(cls, parser.get_toggle_methods()))
+    ports_tuples.append(get_state_ports(cls, parser.get_state_methods()))
+    ports_tuples.append(get_other_ports(cls, parser.get_other_methods()))
+    ports_tuples.append(get_custom_ports(cls))
+
+    zipped_ports = izip(*ports_tuples)
+    input_ports = chain(*zipped_ports.next())
+    output_ports = chain(*zipped_ports.next())
+    return input_ports, output_ports
+
+def parse(filename="vtk_raw.xml"):
+    inheritance_graph = ClassTree(vtk)
+    inheritance_graph.create()
+
+    v = vtk.vtkVersion()
+    version = [v.GetVTKMajorVersion(),
+               v.GetVTKMinorVersion(),
+               v.GetVTKBuildVersion()]
+    if version < [5, 7, 0]:
+        assert len(inheritance_graph.tree[0]) == 1
+        base = inheritance_graph.tree[0][0]
+        assert base.name == 'vtkObjectBase'
+
+    specs_list = []
+    if version < [5, 7, 0]:
+        for child in base.children:
+            if child.name in disallowed_classes:
+                continue
+            specs_list.extend(create_module("vtkObjectBase", child))
+    else:
+        for base in inheritance_graph.tree[0]:
+            for child in base.children:
+                if child.name in disallowed_classes:
+                    continue
+                specs_list.extend(create_module("vtkObjectBase", child))
+
+    specs = SpecList(specs_list)
+    specs.write_to_xml(filename)
+
+
+if __name__ == '__main__':
+    parse()
diff --git a/vistrails/packages/vtk/vtk_wrapper/specs.py b/vistrails/packages/vtk/vtk_wrapper/specs.py
new file mode 100644
index 0000000..b1c65d7
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/specs.py
@@ -0,0 +1,704 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
+import ast
+from xml.etree import cElementTree as ET
+
+class SpecList(object):
+    """ A class with module specifications and custom code
+        This describes how the wrapped methods/classes will
+        maps to modules in vistrails
+    """
+
+    def __init__(self, module_specs=None):
+        if module_specs is None:
+            module_specs = []
+        self.module_specs = module_specs
+
+    def write_to_xml(self, fname):
+        root = ET.Element("specs")
+        for spec in self.module_specs:
+            root.append(spec.to_xml())
+        tree = ET.ElementTree(root)
+
+        def indent(elem, level=0):
+            i = "\n" + level*"  "
+            if len(elem):
+                if not elem.text or not elem.text.strip():
+                    elem.text = i + "  "
+                if not elem.tail or not elem.tail.strip():
+                    elem.tail = i
+                for elem in elem:
+                    indent(elem, level+1)
+                if not elem.tail or not elem.tail.strip():
+                    elem.tail = i
+            else:
+                if level and (not elem.tail or not elem.tail.strip()):
+                    elem.tail = i
+        indent(tree.getroot())
+
+        tree.write(fname)
+
+    @staticmethod
+    def read_from_xml(fname, klass=None):
+        if klass is None:
+            klass = ModuleSpec
+        module_specs = []
+        tree = ET.parse(fname)
+        for elt in tree.getroot():
+            if elt.tag == klass.xml_name:
+                module_specs.append(klass.from_xml(elt))
+        retval = SpecList(module_specs)
+        # for spec in retval.module_specs:
+        #     print "==", spec.name, "=="
+        #     for ps in spec.port_specs:
+        #         print " ", ps.arg, ps.name
+        return retval
+
+######### BASE MODULE SPEC ###########
+
+class PortSpec(object):
+    """ Represents specification of a port
+    """
+    xml_name = "portSpec"
+    # attrs tuple means (default value, [is subelement, [run eval]])
+    # Subelement: ?
+    # eval: serialize as string and use eval to get value back
+    # FIXME: subelement/eval not needed if using json
+    attrs = {"name": "",                         # port name
+             "port_type": None,                  # type signature in vistrails
+             "docstring": ("", True),            # documentation
+             "min_conns": (0, False, True),      # set min_conns (1=required)
+             "max_conns": (-1, False, True),     # Set max_conns (default -1)
+             "show_port": (False, False, True),  # Set not optional (use connection)
+             "sort_key": (-1, False, True),      # sort_key
+             "shape": (None, False, True),       # physical shape
+             "depth": (0, False, True)}          # expected list depth
+
+    def __init__(self, **kwargs):
+        self.set_defaults(**kwargs)
+        self.port_types = []
+
+    def set_defaults(self, **kwargs):
+        for attr, props in self.attrs.iteritems():
+            if isinstance(props, tuple):
+                default_val = props[0]
+            else:
+                default_val = props
+            if attr in kwargs:
+                setattr(self, attr, kwargs[attr])
+            else:
+                setattr(self, attr, default_val)
+
+    def to_xml(self, elt=None):
+        if elt is None:
+            elt = ET.Element(self.xml_name)
+        for attr, props in self.attrs.iteritems():
+            attr_val = getattr(self, attr)
+            is_subelt = False
+            if isinstance(props, tuple):
+                default_val = props[0]
+                if len(props) > 1:
+                    is_subelt = props[1]
+            else:
+                default_val = props
+
+            if default_val != attr_val:
+                if is_subelt:
+                    subelt = ET.Element(attr)
+                    subelt.text = unicode(getattr(self, attr))
+                    elt.append(subelt)
+                else:
+                    elt.set(attr, unicode(attr_val))
+        return elt
+
+    @classmethod
+    def internal_from_xml(cls, elt, obj=None):
+        if obj is None:
+            obj = cls()
+
+        child_elts = {}
+        for child in elt.getchildren():
+            # if child.tag not in obj.attrs:
+            #     raise RuntimeError('Cannot deal with tag "%s"' % child.tag)
+            if child.tag not in child_elts:
+                child_elts[child.tag] = []
+            child_elts[child.tag].append(child)
+
+        kwargs = {}
+        for attr, props in obj.attrs.iteritems():
+            is_subelt = False
+            run_eval = False
+            if isinstance(props, tuple):
+                if len(props) > 1:
+                    is_subelt = props[1]
+                if len(props) > 2:
+                    run_eval = props[2]
+            attr_vals = []
+            if is_subelt:
+                if attr in child_elts:
+                    attr_vals = [c.text for c in child_elts[attr]
+                                 if c.text is not None]
+            else:
+                attr_val = elt.get(attr)
+                if attr_val is not None:
+                    attr_vals = [attr_val]
+
+            if len(attr_vals) > 1:
+                raise ValueError('Should have only one value for '
+                                'attribute "%s"' % attr)
+            if len(attr_vals) > 0:
+                attr_val = attr_vals[0]
+                if run_eval:
+                    try:
+                        kwargs[attr] = ast.literal_eval(attr_val)
+                    except (NameError, SyntaxError, ValueError):
+                        kwargs[attr] = attr_val
+                else:
+                    kwargs[attr] = attr_val
+        obj.set_defaults(**kwargs)
+        return obj, child_elts
+
+    @classmethod
+    def from_xml(cls, elt, obj=None):
+        obj, child_elts = cls.internal_from_xml(elt, obj)
+        return obj
+
+    @classmethod
+    def create_from_xml(cls, elt):
+        if elt.tag == cls.InputSpecType.xml_name:
+            return cls.InputSpecType.from_xml(elt)
+        elif elt.tag == cls.OutputSpecType.xml_name:
+            return cls.OutputSpecType.from_xml(elt)
+        raise TypeError('Cannot create spec from element of type "%s"' %
+                        elt.tag)
+
+    def get_port_type(self):
+        if self.port_type is None:
+            return "basic:Null"
+        try:
+            port_types = ast.literal_eval(self.port_type)
+            def flatten(t):
+                if not isinstance(t, list):
+                    raise Exception("Expected a list")
+                flat = []
+                for elt in t:
+                    if isinstance(elt, list):
+                        flat.extend(flatten(elt))
+                    else:
+                        flat.append(elt)
+                return flat
+            return ','.join(flatten(port_types))
+        except (SyntaxError, ValueError):
+            pass
+        return self.port_type
+
+    def get_prepend_params(self):
+        if self.prepend_params is None:
+            return []
+        return self.prepend_params
+
+
+class InputPortSpec(PortSpec):
+    xml_name = "inputPortSpec"
+    attrs = {"entry_types": (None, True, True),# custom entry type (like enum)
+             "values": (None, True, True),     # values for enums
+             "labels": (None, True, True),   # custom labels on enum values
+             "defaults": (None, True, True),   # default value list
+             }
+    attrs.update(PortSpec.attrs)
+
+    def get_port_attrs(self):
+        """ Port attribute dict that will be used to create the port
+
+        """
+        attrs = {}
+        if self.sort_key != -1:
+            attrs["sort_key"] = self.sort_key
+        if self.shape:
+            attrs["shape"] = self.shape
+        if self.depth:
+            attrs["depth"] = self.depth
+        if self.values:
+            attrs["values"] = unicode(self.values)
+        if self.labels:
+            attrs["labels"] = unicode(self.labels)
+        if self.entry_types:
+            attrs["entry_types"] = unicode(self.entry_types)
+        if self.defaults:
+            attrs["defaults"] = unicode(self.defaults)
+        if self.docstring:
+            attrs["docstring"] = self.docstring
+        if self.min_conns:
+            attrs["min_conns"] = self.min_conns
+        if self.max_conns != -1:
+            attrs["max_conns"] = self.max_conns
+        if not self.show_port:
+            attrs["optional"] = True
+        return attrs
+
+
+class OutputPortSpec(PortSpec):
+    xml_name = "outputPortSpec"
+    attrs = {}
+    attrs.update(PortSpec.attrs)
+
+    def get_port_attrs(self):
+        """ Port attribute dict that will be used to create the port
+
+        """
+        attrs = {}
+        if self.sort_key != -1:
+            attrs["sort_key"] = self.sort_key
+        if self.shape:
+            attrs["shape"] = self.shape
+        if self.depth:
+            attrs["depth"] = self.depth
+        if self.docstring:
+            attrs["docstring"] = self.docstring
+        if self.min_conns:
+            attrs["min_conns"] = self.min_conns
+        if self.max_conns != -1:
+            attrs["max_conns"] = self.max_conns
+        if not self.show_port:
+            attrs["optional"] = True
+        return attrs
+
+class ModuleSpec(object):
+    """ Represents specification of a module
+        This mirrors how the module will look in the vistrails registry
+    """
+    xml_name = 'moduleSpec'
+    InputSpecType = InputPortSpec
+    OutputSpecType = OutputPortSpec
+
+    # From Modulesettings. See core.modules.config._documentation
+    ms_attrs = ['name',
+                'configure_widget',
+                'constant_widget',
+                'constant_widgets',
+                'signature',
+                'constant_signature',
+                'color',
+                'fringe',
+                'left_fringe',
+                'right_fringe',
+                'abstract',
+                'namespace',
+                'package_version',
+                'hide_descriptor']
+    attrs = [
+             # basic attributes
+             'module_name', # Name of module (can be overridden by modulesettings)
+             'superklass',  # class to inherit from
+             'code_ref',    # reference to wrapped class/method
+             'docstring',   # module __doc__
+             'cacheable',   # should this module be cached
+             # special attributes
+             'callback',    # name of attribute for progress callback
+             'tempfile']    # attribute name for temporary file creation method
+    attrs.extend(ms_attrs)
+
+    def __init__(self, module_name='', superklass='', code_ref='',
+                 docstring='', callback=None, tempfile=None, cacheable=True,
+                 input_port_specs=None, output_port_specs=None, **kwargs):
+        if input_port_specs is None:
+            input_port_specs = []
+        if output_port_specs is None:
+            output_port_specs = []
+
+        self.module_name = module_name
+        self.superklass = superklass
+        self.code_ref = code_ref
+        self.docstring = docstring
+        self.callback = callback
+        self.tempfile = tempfile
+        self.cacheable = cacheable
+
+        self.input_port_specs = input_port_specs
+        self.output_port_specs = output_port_specs
+
+        for attr in self.ms_attrs:
+            setattr(self, attr, kwargs.get(attr, None))
+
+    def to_xml(self, elt=None):
+        if elt is None:
+            elt = ET.Element(self.xml_name)
+        elt.set("module_name", self.module_name)
+        elt.set("superklass", self.superklass)
+        elt.set("code_ref", self.code_ref)
+        subelt = ET.Element("docstring")
+        subelt.text = unicode(self.docstring)
+        elt.append(subelt)
+        if self.callback is not None:
+            elt.set("callback", self.callback)
+        if self.tempfile is not None:
+            elt.set("tempfile", self.tempfile)
+        if self.cacheable is False:
+            elt.set("cacheable", 'False')
+        for attr in self.ms_attrs:
+            value = getattr(self, attr)
+            if value is not None:
+                elt.set(attr, repr(value))
+
+        for port_spec in self.input_port_specs:
+            subelt = port_spec.to_xml()
+            elt.append(subelt)
+        for port_spec in self.output_port_specs:
+            subelt = port_spec.to_xml()
+            elt.append(subelt)
+        return elt
+
+    @staticmethod
+    def from_xml(elt, klass=None):
+        if klass is None:
+            klass = ModuleSpec
+        module_name = elt.get("module_name", '')
+        superklass = elt.get("superklass", '')
+        code_ref = elt.get("code_ref", '')
+        callback = elt.get("callback", None)
+        tempfile = elt.get("tempfile", None)
+        cacheable = ast.literal_eval(elt.get("cacheable", "True"))
+
+        kwargs = {}
+        for attr in klass.ms_attrs:
+            value = elt.get(attr, None)
+            if value is not None:
+                kwargs[attr] = ast.literal_eval(value)
+
+        docstring = ""
+        input_port_specs = []
+        output_port_specs = []
+        for child in elt.getchildren():
+            if child.tag == klass.InputSpecType.xml_name:
+                input_port_specs.append(klass.InputSpecType.from_xml(child))
+            elif child.tag == klass.OutputSpecType.xml_name:
+                output_port_specs.append(klass.OutputSpecType.from_xml(child))
+            elif child.tag == "docstring":
+                if child.text:
+                    docstring = child.text
+        return klass(module_name=module_name, superklass=superklass,
+                   code_ref=code_ref, docstring=docstring,
+                   callback=callback, tempfile=tempfile, cacheable=cacheable,
+                   input_port_specs=input_port_specs,
+                   output_port_specs=output_port_specs, **kwargs)
+
+    def get_output_port_spec(self, compute_name):
+        for ps in self.output_port_specs:
+            if ps.compute_name == compute_name:
+                return ps
+        return None
+
+    def get_module_settings(self):
+        """ Returns modulesettings dict
+
+        """
+        attrs = {}
+        for attr in self.ms_attrs:
+            value = getattr(self, attr)
+            if value is not None:
+                attrs[attr] = value
+        return attrs
+
+
+######### PYTHON FUNCTION SPEC ###########
+
+class FunctionInputPortSpec(InputPortSpec):
+    xml_name = "functionInputPortSpec"
+    attrs = {"arg": ""}                  # attribute name
+    attrs.update(InputPortSpec.attrs)
+
+
+class FunctionOutputPortSpec(OutputPortSpec):
+    xml_name = "functionOutputPortSpec"
+
+
+class FunctionSpec(ModuleSpec):
+    """ Specification for wrapping a python function
+    """
+    xml_name = 'functionSpec'
+    InputSpecType = FunctionInputPortSpec
+    OutputSpecType = FunctionOutputPortSpec
+
+    attrs = ['output_type'] # None(=single), list(ordered), or dict(attr=value)
+    attrs.extend(ModuleSpec.attrs)
+
+    def __init__(self, module_name, superklass='', code_ref='', docstring="",
+                 output_type=None, callback=None, tempfile=None,
+                 cacheable=True, input_port_specs=None, output_port_specs=None,
+                 **kwargs):
+        ModuleSpec.__init__(self, module_name, superklass, code_ref,
+                            docstring, callback, tempfile, cacheable,
+                            input_port_specs, output_port_specs, **kwargs)
+        self.output_type = output_type
+
+    def to_xml(self, elt=None):
+        if elt is None:
+            elt = ET.Element(self.xml_name)
+        elt = ModuleSpec.to_xml(self, elt)
+        if self.output_type is not None:
+            elt.set("output_type", self.output_type)
+        return elt
+
+    @staticmethod
+    def from_xml(elt):
+        inst = ModuleSpec.from_xml(elt, FunctionSpec)
+        inst.output_type = elt.get("output_type", None)
+        return inst
+
+######### PYTHON CLASS SPEC ###########
+
+
+class ClassInputPortSpec(InputPortSpec):
+    xml_name = "classInputPortSpec"
+    attrs = {"method_name": "",                  # method name
+             "method_type": "",                  # Type like nullary, OnOff or SetXToY
+             "prepend_params": (None, True, True)} # prepended params like index
+    attrs.update(InputPortSpec.attrs)
+
+    def __init__(self, **kwargs):
+        InputPortSpec.__init__(self, **kwargs)
+        if not self.method_name:
+            self.method_name = self.name
+
+
+class ClassOutputPortSpec(OutputPortSpec):
+    xml_name = "classOutputPortSpec"
+    attrs = {"method_name": "",                    # method/attribute name
+             "prepend_params": (None, True, True)} # prepended params used with indexed methods
+    attrs.update(OutputPortSpec.attrs)
+
+    def __init__(self, **kwargs):
+        OutputPortSpec.__init__(self, **kwargs)
+        if not self.method_name:
+            self.method_name = self.name
+
+
+class ClassSpec(ModuleSpec):
+    """ Specification for wrapping a python class
+    """
+    xml_name = 'classSpec'
+    InputSpecType = ClassInputPortSpec
+    OutputSpecType = ClassOutputPortSpec
+    attrs = ['methods_last', # If True will compute methods before connections
+             'compute', # Function to call after input methods
+             'cleanup'] # Function to call after output methods
+    attrs.extend(ModuleSpec.attrs)
+
+    def __init__(self, module_name, superklass='', code_ref='', docstring="",
+                 callback=None, tempfile=None,
+                 cacheable=True, input_port_specs=None, output_port_specs=None,
+                 compute=None, cleanup=None, methods_last=False, **kwargs):
+        ModuleSpec.__init__(self, module_name, superklass, code_ref,
+                            docstring, callback, tempfile, cacheable,
+                            input_port_specs, output_port_specs, **kwargs)
+        self.methods_last = methods_last
+        self.compute = compute
+        self.cleanup = cleanup
+
+    def to_xml(self, elt=None):
+        if elt is None:
+            elt = ET.Element(self.xml_name)
+        if self.methods_last is not False:
+            elt.set("methods_last", unicode(self.methods_last))
+        if self.compute is not None:
+            elt.set("compute", self.compute)
+        if self.cleanup is not None:
+            elt.set("cleanup", self.cleanup)
+        elt = ModuleSpec.to_xml(self, elt)
+        return elt
+
+    @staticmethod
+    def from_xml(elt):
+        inst = ModuleSpec.from_xml(elt, ClassSpec)
+        inst.methods_last = ast.literal_eval(elt.get("methods_last", 'False'))
+        inst.compute = elt.get("compute", None)
+        inst.cleanup = elt.get("cleanup", None)
+        return inst
+
+###############################################################################
+
+import unittest
+
+
+class TestModuleSpec(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        try:
+            import vtk
+        except ImportError:
+            raise unittest.SkipTest("vtk is not installed")
+
+        from vistrails.tests.utils import enable_package
+        from ..identifiers import identifier
+
+        enable_package(identifier)
+
+    def test_module_spec(self):
+        input_spec = InputPortSpec(name='myportname',
+                                   port_type='basic:String',
+                                   docstring='my port doc',
+                                   min_conns=1,
+                                   max_conns=3,
+                                   show_port=True,
+                                   sort_key=5,
+                                   depth=1,
+                                   entry_type='enum')
+        in_attrs = input_spec.get_port_attrs()
+
+        output_spec = OutputPortSpec(name='myportname',
+                                   port_type='basic:String',
+                                   docstring='my port doc',
+                                   min_conns=1,
+                                   max_conns=3,
+                                   show_port=False,
+                                   sort_key=5,
+                                   depth=1)
+        out_attrs = output_spec.get_port_attrs()
+
+        ms = ModuleSpec(module_name='myclassname',
+                        superklass='mysuperclassname',
+                        code_ref='theclassname',
+                        docstring='my documentation',
+                        callback=None,
+                        tempfile=None,
+                        cacheable=False,
+                        input_port_specs=[input_spec],
+                        output_port_specs=[output_spec])
+        as_string = ET.tostring(ms.to_xml())
+        from_string = ET.fromstring(as_string)
+        ms2 = ModuleSpec.from_xml(from_string)
+        in_attrs2 = ms2.input_port_specs[0].get_port_attrs()
+        out_attrs2 = ms2.output_port_specs[0].get_port_attrs()
+        self.assertEqual(in_attrs, in_attrs2)
+        self.assertEqual(out_attrs, out_attrs2)
+
+    def test_function_spec(self):
+        input_spec = FunctionInputPortSpec(name='myportname',
+                                   port_type='basic:String',
+                                   docstring='my port doc',
+                                   min_conns=1,
+                                   max_conns=3,
+                                   show_port=False,
+                                   sort_key=5,
+                                   depth=1,
+                                   arg='myargname',
+                                   )
+        in_attrs = input_spec.get_port_attrs()
+
+        output_spec = FunctionOutputPortSpec(name='myportname',
+                                   port_type='basic:String',
+                                   docstring='my port doc',
+                                   min_conns=1,
+                                   max_conns=3,
+                                   show_port=False,
+                                   sort_key=5,
+                                   depth=1)
+        out_attrs = output_spec.get_port_attrs()
+
+        ms = FunctionSpec(module_name='myclassname',
+                        superklass='mysuperclassname',
+                        code_ref='theclassname',
+                        docstring='my documentation',
+                        callback=None,
+                        tempfile=None,
+                        cacheable=False,
+                        input_port_specs=[input_spec],
+                        output_port_specs=[output_spec],
+                        output_type='list')
+        as_string = ET.tostring(ms.to_xml())
+        from_string = ET.fromstring(as_string)
+        ms2 = FunctionSpec.from_xml(from_string)
+        in_attrs2 = ms2.input_port_specs[0].get_port_attrs()
+        out_attrs2 = ms2.output_port_specs[0].get_port_attrs()
+        self.assertEqual(in_attrs, in_attrs2)
+        self.assertEqual(out_attrs, out_attrs2)
+
+    def test_class_spec(self):
+        input_spec = ClassInputPortSpec(name='myportname',
+                                   port_type='basic:String',
+                                   docstring='my port doc',
+                                   min_conns=1,
+                                   max_conns=3,
+                                   show_port=False,
+                                   sort_key=5,
+                                   depth=1,
+                                   method_name='MyClassMethodName',
+                                   method_type='SetXToY',
+                                   prepend_params=[1])
+        in_attrs = input_spec.get_port_attrs()
+
+        output_spec = ClassOutputPortSpec(name='myportname',
+                                   port_type='basic:String',
+                                   docstring='my port doc',
+                                   min_conns=1,
+                                   max_conns=3,
+                                   show_port=False,
+                                   sort_key=5,
+                                   depth=1,
+                                   method_name='MyClassMethodName',
+                                   prepend_params=[1])
+        out_attrs = output_spec.get_port_attrs()
+
+        ms = ClassSpec(module_name='myclassname',
+                        superklass='mysuperclassname',
+                        code_ref='theclassname',
+                        docstring='my documentation',
+                        callback=None,
+                        tempfile=None,
+                        cacheable=False,
+                        input_port_specs=[input_spec],
+                        output_port_specs=[output_spec],
+                        methods_last=True,
+                        compute='myCompute',
+                        cleanup='myCleanup')
+        as_string = ET.tostring(ms.to_xml())
+        from_string = ET.fromstring(as_string)
+        ms2 = ClassSpec.from_xml(from_string)
+        in_attrs2 = ms2.input_port_specs[0].get_port_attrs()
+        out_attrs2 = ms2.output_port_specs[0].get_port_attrs()
+        self.assertEqual(in_attrs, in_attrs2)
+        self.assertEqual(out_attrs, out_attrs2)
+
+
+#def run():
+#    specs = SpecList.read_from_xml("mpl_plots_raw.xml")
+#    specs.write_to_xml("mpl_plots_raw_out.xml")
+
+#if __name__ == '__main__':
+#    run()
diff --git a/vistrails/packages/vtk/vtk_wrapper/vtk_classes.py b/vistrails/packages/vtk/vtk_wrapper/vtk_classes.py
new file mode 100644
index 0000000..8a229bd
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/vtk_classes.py
@@ -0,0 +1,321 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+""" Convert VTK classes into functions using spec in vtk.xml"""
+
+from __future__ import division
+
+import locale
+import os
+import tempfile
+import types
+
+from  platform import system
+
+import vtk
+
+from . import fix_classes
+from .wrapper import VTKInstanceWrapper
+from .specs import SpecList, ClassSpec
+
+################################################################################
+
+# filter some deprecation warnings coming from the fact that vtk calls
+# range() with float parameters
+
+#### METHOD PATCHING CODE ####
+
+def patch_methods(base_module, cls):
+    """class_dict(base_module, cls: vtkClass) -> dict
+    Returns the class dictionary for the module represented by base_module and
+    with base class base_module"""
+
+    instance_dict = {}
+    def update_dict(name, callable_):
+        if instance_dict.has_key(name):
+            instance_dict[name] = callable_(types.MethodType(instance_dict[name], base_module))
+        elif hasattr(base_module, name):
+            instance_dict[name] = callable_(getattr(base_module, name))
+        else:
+            instance_dict[name] = callable_(None)
+
+    def compute_UpdateAlgorithm(oldUpdate):
+        def call_UpdateAlgorithm(self):
+            if self._callback is None:
+                oldUpdate()
+                return
+            is_aborted = [False]
+            cbId = None
+            def ProgressEvent(obj, event):
+                try:
+                    self._callback(obj.GetProgress())
+                except Exception, e:
+                    if e.__name__ == 'AbortExecution':
+                        obj.SetAbortExecute(True)
+                        self.RemoveObserver(cbId)
+                        is_aborted[0] = True
+                    else:
+                        raise
+            cbId = self.AddObserver('ProgressEvent', ProgressEvent)
+            oldUpdate()
+            if not is_aborted[0]:
+                self.RemoveObserver(cbId)
+        return call_UpdateAlgorithm
+    if issubclass(cls, vtk.vtkAlgorithm):
+        update_dict('Update', compute_UpdateAlgorithm)
+
+    def guarded_SimpleScalarTree_wrap_compute(old_compute):
+        # This builds the scalar tree
+        def compute(self):
+            old_compute(self)
+            self.vtkInstance.BuildTree()
+        return compute
+    if issubclass(cls, vtk.vtkScalarTree):
+        update_dict('Update', guarded_SimpleScalarTree_wrap_compute)
+
+    def guarded_Writer_wrap_compute(self):
+        # The behavior for vtkWriter subclasses is to call Write()
+        # If the user sets a name, we will create a file with that name
+        # If not, we will create a temporary file using _tempfile
+        fn = self.vtkInstance.GetFileName()
+        if not fn:
+            fn = self._tempfile(suffix='.vtk')
+            self.vtkInstance.SetFileName(fn)
+        self.vtkInstance.Write()
+        return fn
+    if issubclass(cls, vtk.vtkWriter):
+        instance_dict['file'] = guarded_Writer_wrap_compute
+
+    def guarded_SetFileName(old_compute):
+        # This builds the scalar tree
+        def check_SetFileName(self):
+            # This checks for the presence of file in VTK readers
+            # Skips the check if it's a vtkImageReader or vtkPLOT3DReader, because
+            # it has other ways of specifying files, like SetFilePrefix for
+            # multiple files
+            skip = [vtk.vtkBYUReader,
+                    vtk.vtkImageReader,
+                    vtk.vtkDICOMImageReader,
+                    vtk.vtkTIFFReader]
+            # vtkPLOT3DReader does not exist from version 6.0.0
+            v = vtk.vtkVersion()
+            version = [v.GetVTKMajorVersion(),
+                       v.GetVTKMinorVersion(),
+                       v.GetVTKBuildVersion()]
+            if version < [6, 0, 0]:
+                skip.append(vtk.vtkPLOT3DReader)
+            if not any(issubclass(cls, x) for x in skip):
+                filename = self.vtkInstance.GetFileName()
+                if not os.path.isfile(filename):
+                    raise Exception('File does not exist')
+            old_compute()
+        return check_SetFileName
+    if hasattr(cls, 'SetFileName') and \
+       cls.__name__.endswith('Reader') and \
+       not cls.__name__.endswith('TiffReader'):
+        update_dict('Update', guarded_SetFileName)
+
+    def call_SetRenderWindow(self, vtkRenderer):
+        window = vtk.vtkRenderWindow()
+        w = 512
+        h = 512
+        window.OffScreenRenderingOn()
+        window.SetSize(w, h)
+
+        widget = None
+        if system() == 'Darwin':
+            from PyQt4 import QtCore, QtGui
+            widget = QtGui.QWidget(None, QtCore.Qt.FramelessWindowHint)
+            widget.resize(w, h)
+            widget.show()
+            window.SetWindowInfo(str(int(widget.winId())))
+
+        window.AddRenderer(vtkRenderer.vtkInstance)
+        window.Render()
+        self.vtkInstance.SetRenderWindow(window)
+    if hasattr(cls, 'SetRenderWindow'):
+        instance_dict['vtkRenderer'] = call_SetRenderWindow
+
+    def call_TransferFunction(self, tf):
+        tf.set_on_vtk_volume_property(self.vtkInstance)
+    if issubclass(cls, vtk.vtkVolumeProperty):
+        instance_dict['SetTransferFunction'] = call_TransferFunction
+
+    def call_PointData(self, pd):
+        self.vtkInstance.GetPointData().ShallowCopy(pd.vtkInstance)
+    def call_CellData(self, cd):
+        self.vtkInstance.GetCellData().ShallowCopy(cd.vtkInstance)
+    if issubclass(cls, vtk.vtkDataSet):
+        instance_dict['PointData'] = call_PointData
+        instance_dict['CellData'] = call_CellData
+
+    def call_PointIds(self, point_ids):
+        self.vtkInstance.GetPointIds().SetNumberOfIds(point_ids.GetNumberOfIds())
+        for i in xrange(point_ids.GetNumberOfIds()):
+            self.vtkInstance.GetPointIds().SetId(i, point_ids.vtkInstance.GetId(i))
+    if issubclass(cls, vtk.vtkCell):
+        instance_dict['PointIds'] = call_PointIds
+
+    def call_CopyImportVoidPointer(self, pointer):
+        self.CopyImportVoidPointer(pointer, len(pointer))
+        return call_CopyImportVoidPointer
+    if issubclass(cls, vtk.vtkImageImport):
+        instance_dict['CopyImportString'] = call_CopyImportVoidPointer
+
+    def call_GetFirstBlock(self):
+        return VTKInstanceWrapper(self.vtkInstance.GetOutput().GetBlock(0))
+    if issubclass(cls, vtk.vtkMultiBlockPLOT3DReader):
+        instance_dict['FirstBlock'] = call_GetFirstBlock
+
+    for name, method in instance_dict.iteritems():
+        setattr(base_module, name, types.MethodType(method, base_module))
+
+#### END METHOD PATCHING CODE ####
+
+
+class vtkObjectInfo(object):
+    """ Each instance represents a VTK class
+
+    """
+    def __init__(self, spec, parent=None):
+        self.parent = parent
+        self.spec = spec
+        self.vtkClass = getattr(vtk, spec.code_ref)
+        # use fixed classes
+        if hasattr(fix_classes, self.vtkClass.__name__ + '_fixed'):
+            self.vtkClass = getattr(fix_classes, self.vtkClass.__name__ + '_fixed')
+
+class VTKInstancePatcher(object):
+    """ This is used in place of the vtk instance because it may not be
+        safe to set attributes directly on the vtk object.
+
+    """
+    def __init__(self, info_obj):
+        # fixes reading data files on non-C locales
+        self._previous_locale = locale.setlocale(locale.LC_ALL)
+        locale.setlocale(locale.LC_ALL, 'C')
+
+        self._info_obj = info_obj
+        self._callback = None
+        self._tempfile = tempfile.mkstemp
+        self.vtkInstance = info_obj.vtkClass()
+        patch_methods(self, info_obj.vtkClass)
+
+    def _cleanup(self):
+        locale.setlocale(locale.LC_ALL, self._previous_locale)
+
+    def __getattr__(self, name):
+        v = vtk.vtkVersion()
+        version = [v.GetVTKMajorVersion(),
+                   v.GetVTKMinorVersion(),
+                   v.GetVTKBuildVersion()]
+        if version < [6, 0, 0]:
+            # Translate vtk6 method names to vtk5 method names
+            to_vtk5_names = {'AddInputData':  'AddInput',
+                          'AddDataSetInput':  'AddInput',
+                             'SetInputData':  'SetInput',
+                            'AddSourceData': 'AddSource',
+                            'SetSourceData': 'SetSource'}
+            for new, old in to_vtk5_names.iteritems():
+                if name.startswith(new):
+                    # Keep suffix
+                    name = old + name[len(new):]
+                    break
+        # redirect calls to vtkInstance
+        def call_wrapper(*args):
+            args = list(args)
+            for i in xrange(len(args)):
+                if hasattr(args[i], 'vtkInstance'):
+                    # Unwrap VTK objects
+                    args[i] = args[i].vtkInstance
+            args = tuple(args)
+
+            #print "CALLING", name, [a.__class__.__name__ for a in args]
+            result = getattr(self.vtkInstance, name)(*args)
+            #print "GOT", result.__class__.__name__
+
+            if isinstance(result, vtk.vtkObjectBase):
+                # Wrap VTK objects
+                result = VTKInstanceWrapper(result)
+            return result
+        return call_wrapper
+
+    def _set_callback(self, callback):
+        self._callback = callback
+
+    def _set_tempfile(self, tempfile):
+        self._tempfile = tempfile
+        
+    def Update(self):
+        if hasattr(self.vtkInstance, 'Update'):
+            self.vtkInstance.Update()
+
+# keep track of created modules for use as subclasses
+infoObjs = {}
+
+
+def gen_instance_factory(spec):
+    """Create an instance factory from a vtk class specification
+
+    """
+    infoObj = vtkObjectInfo(spec, infoObjs.get(spec.superklass, None))
+    infoObjs[spec.module_name] = infoObj
+    def instanceFactory():
+        return VTKInstancePatcher(infoObj)
+    return instanceFactory
+
+
+specs = None
+
+
+def initialize(spec_name=None):
+    """ Generate class wrappers and add them to current module namespace
+        Also adds spec so it can be referenced by module wrapper
+
+    """
+    global specs
+    if spec_name is None:
+        # The spec can be placed in the same folder if used as a standalone package
+        spec_name = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'vtk.xml')
+        if not os.path.exists(spec_name):
+            return
+    specs = SpecList.read_from_xml(spec_name, ClassSpec)
+    for spec in specs.module_specs:
+        globals()[spec.module_name] = gen_instance_factory(spec)
+
+
+# Initialize if possible
+initialize()
diff --git a/vistrails/packages/vtk/vtk_wrapper/vtk_module.py b/vistrails/packages/vtk/vtk_wrapper/vtk_module.py
new file mode 100644
index 0000000..b124f58
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/vtk_module.py
@@ -0,0 +1,22 @@
+"""Abstracts all VTK related modules into one module.  This makes it trivial to
+support local VTK classes that a user may have built.
+
+By default it imports all of VTK and then looks for a tvtk_local module and
+imports everything from that.  In order to add local classes to the TVTK build
+one may simply provide a tvtk_local.py module somewhere with any classes that
+need to be wrapped.
+
+"""
+
+# Author: Prabhu Ramachandran <prabhu [at] aero.iitb.ac.in>
+# Copyright (c) 2007,  Enthought, Inc.
+# License: BSD Style.
+
+from __future__ import division
+
+from vtk import *
+
+try:
+    from tvtk_local import *
+except ImportError:
+    pass
diff --git a/vistrails/packages/vtk/vtk_wrapper/vtk_parser.py b/vistrails/packages/vtk/vtk_wrapper/vtk_parser.py
new file mode 100644
index 0000000..60fd693
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/vtk_parser.py
@@ -0,0 +1,733 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+# Author: Prabhu Ramachandran
+# Copyright (c) 2004, Enthought, Inc.
+# License: BSD Style.
+
+# Modified for VisTrails by the VisTrails team.
+
+"""This module parses the VTK methods, obtains the argument and return
+type information, and organizes them.
+
+"""
+# Author: Prabhu Ramachandran
+# Copyright (c) 2004-2007, Enthought, Inc.
+# License: BSD Style.
+
+from __future__ import division
+
+import re
+
+# Local imports (these are relative imports for a good reason).
+import class_tree
+import vtk_module as vtk
+
+
+class VTKMethodParser:
+    """This class provides useful methods for parsing methods of a VTK
+    class or instance.
+
+    The class allows one to categorize the methods of the VTK class
+    and also obtain the method signatures in a form that is easy to
+    use.  When the `parse` method is called, it in turn calls the
+    `_organize_methods` method.  This method organizes the VTK methods
+    into different instance variables described in the following.
+    `self.toggle_meths` contains a dictionary of all the boolean
+    methods of the form <Value>On/Off.  The dictionary keys are
+    strings with the <Value>'s and the value of each item is the
+    default value (0/1) of the item (the example below will clarify
+    this).  `self.state_meths` contains a dictionary which collects
+    the Set<Prop>To<Value> type of methods.  The key is the <Prop> and
+    the value is a list containing the different string <Value>'s and
+    their corresponding mapped value.  The first value in these is the
+    default value of the <Prop>.  `self.get_set_meths` will contain a
+    dictionary which collects all the methods of the form
+    Set/Get<Prop> that are not already specified in
+    `self.toggle_meths` or `self.state_meths`.  The default value of
+    the Get<Prop> is stored.  If the value accepted by the method has
+    a range (via the methods `Get<Prop>MinValue` and
+    `Get<Prop>MaxValue`), then that range is computed and stored.
+    `self.get_meths` stores the methods that are of the form
+    `Get<Prop>`.  `self.other_meths` stores the remaining methods.
+    The parsing is quite fast.  Parsing every class in the VTK API
+    takes a couple of seconds (on a Pentium III @ 450Mhz).
+
+    Here is an example::
+
+       >>> import vtk
+       >>> p = VTKMethodParser()
+       >>> p.parse(vtk.vtkProperty)
+       >>> print p.get_toggle_methods()
+       {'EdgeVisibility': 0, 'BackfaceCulling': 0, 'FrontfaceCulling': 0}
+       >>> print p.get_state_methods()['Representation']
+       [['Surface', 2], ['Points', 0], ['Surface', 2], ['Wireframe', 1]]
+       >>> print p.get_get_set_methods()['Opacity']
+       (1.0, (0.0, 1.0))
+       >>> print p.get_get_methods()
+       ['GetClassName']
+       >>> print p.get_other_methods()[:3]
+       ['BackfaceRender', 'DeepCopy', 'IsA']
+
+
+    The class also provides a method called `get_method_signature`
+    that obtains the Python method signature given the VTK method
+    object.  Here is an example::
+
+       >>> import vtk
+       >>> p = VTKMethodParser()
+       >>> o = vtk.vtkProperty
+       >>> print p.get_method_signature(o.GetClassName)
+       [(['string'], None)]
+       >>> print p.get_method_signature(o.GetColor)[0]
+       ([('float', 'float', 'float')], None)
+       >>> print p.get_method_signature(o.GetColor)[1]
+       ([None], (('float', 'float', 'float'),))
+
+    The `get_method_signature` is fairly efficient and obtaining the
+    signature for every method in every class in the VTK API takes
+    around 6 seconds (on a Pentium III @ 450Mhz).
+
+    """
+
+    def __init__(self, use_tree=True):
+        """Initializes the object.
+
+        Parameters
+        ----------
+
+        - use_tree : `bool`
+
+          If True (default), use a ClassTree instance to obtain a
+          concrete subclass for an abstract base class.  This is used
+          only to find the range and default values for some of the
+          methods.  If False, no ClassTree instance is created.
+
+          This is optional because, creating a ClassTree is expensive.
+          The parser functionality can be very useful even without the
+          use of a ClassTree.  For example, if one wants to save the
+          state of a VTK object one only needs to know the names of
+          the methods and not their default values, ranges etc.  In
+          that case using a parser should be cheap.
+
+        """
+        # The ClassTree is needed to find an instantiable child class
+        # for an abstract VTK parent class.  This instance is used to
+        # obtain the state values and the ranges of the arguments
+        # accepted by the Get/Set methods that have a
+        # Get<Prop>{MaxValue,MinValue} method.
+        if use_tree:
+            self._tree = class_tree.ClassTree(vtk)
+            self._tree.create()
+        else:
+            self._tree = None
+        self._state_patn = re.compile('To[A-Z0-9]')
+        self._initialize()
+
+    #################################################################
+    # 'VTKMethodParser' interface.
+    #################################################################
+
+    def parse(self, obj, no_warn=True):
+        """Parse the methods for a given VTK object/class.
+
+        Given a VTK class or object, this method parses the methods
+        and orgaizes them into useful categories.  The categories and
+        their usage is documented in the documentation for the class.
+
+        Parameters
+        ----------
+
+        - obj : VTK class or instance
+
+        - no_warn : `bool` (default: True)
+
+          If True (default), it suppresses any warnings generated by
+          the VTK object when parsing the methods.  This is safe to
+          use.
+
+        """
+        if not hasattr(obj, '__bases__'):
+            klass = obj.__class__
+        else:
+            klass = obj
+
+        methods = self.get_methods(klass)
+
+        if no_warn:
+            # Save warning setting and shut it off before parsing.
+            warn = vtk.vtkObject.GetGlobalWarningDisplay()
+            if klass.__name__ <> 'vtkObject':
+                vtk.vtkObject.GlobalWarningDisplayOff()
+
+        self._organize_methods(klass, methods)
+
+        if no_warn:
+            # Reset warning status.
+            vtk.vtkObject.SetGlobalWarningDisplay(warn)
+
+    def _get_parent_methods(self, klass):
+        """Returns all the methods of the classes parents."""
+        methods = {}
+        while len(klass.__bases__) > 0:
+            klass = klass.__bases__[0]
+            meths = dir(klass)
+            d = methods.fromkeys(meths)
+            methods.update(d)
+        return methods.keys()
+
+    def get_methods(self, klass):
+        """Returns all the relevant methods of the given VTK class."""
+        methods = dir(klass)[:]
+        if hasattr(klass, '__members__'):
+            # Only VTK versions < 4.5 have these.
+            for m in klass.__members__:
+                methods.remove(m)
+        # Ignore the parent methods.
+        ignore = self._get_parent_methods(klass)
+
+        # Skip some of the ignores.
+        skip = ['GetInput', 'SetInput']
+        # Sometimes the child has only GetInput while the parent has
+        # SetInput.
+        if hasattr(klass, 'SetInput') and \
+            'SetInput' not in methods and \
+            'GetInput' in methods:
+            methods.append('SetInput')
+
+        # Get/set pairs that are overridden.  Basically, if a parent
+        # class has a 'GetThing' and the child overrides/has a
+        # 'SetThing' (or vice-versa), then the removal of the parent
+        # methods is wrong since the child changes the trait definition
+        # which breaks things.  We therefore do not remove any of the
+        # Get/SetThings that are ignored due to them being in the
+        # parent.  However one has to be careful about cases where these are
+        # really Toggle (ThingOn) or State (SetThingToThong) etc. methods and
+        # in those cases we really should ignore the method.  So in essence,
+        # any Get/Set pair that is not a State or Toggle should be redefined.
+        overrides = []
+        for m in methods:
+            check = False
+            if m.startswith('Get'):
+                m1 = 'Set' + m[3:]
+                check = True
+            elif m.startswith('Set'):
+                m1 = 'Get' + m[3:]
+                check = True
+            if check:
+                if m1 in methods and (m1 in ignore or m in ignore):
+                    # Skips are stored as Set followed by Get.
+                    skip.extend(['Set' +m[3:], 'Get'+m[3:]])
+
+        for m in skip[:]:
+            if m.startswith('Set'):
+                base = m[3:]
+                mg, ms = 'Get' + base, 'Set' + base
+                m_st = 'Set' + base + 'To'
+                m_t = base + 'Off'
+                for method in methods:
+                    if m_st in method or m_t == method:
+                        skip.remove(ms)
+                        skip.remove(mg)
+                        break
+
+        if 'GetViewProp' in methods and 'GetProp' in methods:
+            ignore.extend(['GetProp', 'SetProp'])
+        if 'GetViewProps' in methods and 'GetProps' in methods:
+            ignore.extend(['GetProps', 'SetProps'])
+        # Remove any deprecated traits.
+        if 'GetScaledText' in methods and 'GetTextScaleMode' in methods:
+            ignore.extend(['GetScaledText', 'SetScaledText',
+                           'ScaledTextOn', 'ScaledTextOff'])
+
+        # Now we can safely remove the methods.
+        for m in methods[:]:
+            if m in ignore and m not in skip:
+                methods.remove(m)
+
+        return methods
+
+    def get_toggle_methods(self):
+        """Returns a dictionary of the parsed <Value>On/Off methods
+        along with the default value.
+
+        """
+        return self.toggle_meths
+
+    def get_state_methods(self):
+        """Returns a dict of the parsed Set<Prop>To<Value>.
+
+        The keys are the <Prop> string with a list of the different
+        <Value> strings along with their corresponding value (if
+        obtainable).  The first value is the default value of the
+        state.
+
+        """
+        return self.state_meths
+
+    def get_get_set_methods(self):
+        """Returns a dict of the parsed Get/Set<Value> methods.
+
+        The keys of the dict are the <Value> strings and contain a
+        two-tuple containing the default value (or None if it is not
+        obtainable for some reason) and a pair of numbers specifying
+        an acceptable range of values (or None if not obtainable).
+
+        """
+        return self.get_set_meths
+
+    def get_get_methods(self):
+        """Return a list of parsed Get<Value> methods.
+
+        All of these methods do NOT have a corresponding Set<Value>.
+
+        """
+        return self.get_meths
+
+    def get_other_methods(self):
+        """Return list of all other methods, that are not
+        categorizable.
+
+        """
+        return self.other_meths
+
+    def get_method_signature(self, method):
+        """Returns information on the Python method signature given
+        the VTK method.
+
+        The doc string of the given method object to get the method
+        signature.  The method returns a list of tuples, each of which
+        contains 2 items, the first is a list representing the return
+        value the second represents the arguments to be passed to the
+        function.  If the method supports different return values and
+        arguments, this function returns all of their signatures.
+
+        Parameters
+        ----------
+
+        - method : `method`
+
+          A VTK method object.
+
+        """
+        # Remove all the C++ function signatures.
+        doc = method.__doc__
+        if not doc:
+            print "Ignoring method %r, no __doc__" % method
+            return []
+        doc = doc[:doc.find('\n\n')]
+        sig = []
+        c_sig = [] # The C++ signature
+        in_sig = False
+        in_c_sig = False
+        counter = 0
+        for line in doc.split('\n'):
+            if line.startswith('V.'):
+                in_sig = True
+                in_c_sig = False
+                sig.append(line.strip())
+            elif line.startswith('C++:'):
+                in_sig = False
+                in_c_sig = True
+                c_sig.append(line.strip())
+                counter += 1
+            elif in_sig:
+                sig[counter] = sig[counter] + line.strip()
+            elif in_c_sig:
+                c_sig[counter-1] = c_sig[counter-1] + line.strip()
+
+
+        # Remove the V.<method_name>
+        sig = [x.replace('V.' + method.__name__, '') for x in sig]
+        c_sig = [x[x.find('('):] for x in c_sig]
+
+        pat = re.compile(r'\b')
+
+        # Split into [return_value, arguments] after processing them.
+        tmp = list(sig)
+        sig = []
+        for sig_idx, i in enumerate(tmp):
+            # Split to get return values.
+            x = i.split('->')
+            # Strip each part.
+            x = [y.strip() for y in x]
+
+            if len(x) == 1: # No return value
+                x = [None, x[0]]
+            else:
+                x.reverse()
+
+            ret, arg = x
+
+            # Remove leading and trailing parens for arguments.
+            arg = arg[1:-1]
+            if not arg:
+                arg = None
+            if arg and arg[-1] in [')', ']']:
+                arg = arg + ','
+
+            # Check if we are able to parse all the arguments -- some
+            # unstable versions of VTK have problems generating the
+            # docstring and in this case we will try to use the C++
+            # docstring signature.
+
+            n_arg = 0
+            arg_map = {'unsigned int': 'int', 'unsigned char': 'int',
+                    'unsigned long': 'long', 'unsigned short': 'int'}
+            if arg is not None and c_sig:
+                n_arg = arg.count(',') + 1
+                # The carguments have parenthesis like: (int, int)
+                carg = c_sig[sig_idx][1:-1].split(',')
+                if n_arg > 0:
+                    args = []
+                    if len(carg) == n_arg:
+                        for idx, x in enumerate(arg.split(',')):
+                            if len(x.strip()) == 0:
+                                carg_val = carg[idx].strip()
+                                if 'unsigned' in carg_val and \
+                                    carg_val in arg_map:
+                                    args.append(arg_map[carg_val])
+                                elif 'void' in carg_val:
+                                    args.append("string")
+                                else:
+                                    args.append(x)
+                            else:
+                                args.append(x)
+                        arg = ', '.join(args)
+
+            if ret is not None and ret.startswith('(') and '...' in ret:
+                # A tuple (new in VTK-5.7)
+                ret = "tuple"
+
+            if arg is not None:
+                if '[float, ...]' in arg:
+                    arg = arg.replace('[float, ...]', 'tuple')
+                elif '(float, ...)' in arg:
+                    arg = arg.replace('(float, ...)', 'tuple')
+
+            if ret == '(, )':
+                ret = None
+
+            # Now quote the args and eval them.  Easy!
+            try:
+                if ret:
+                    ret = eval(pat.sub('\"', ret))
+                if arg:
+                    arg = eval(pat.sub('\"', arg))
+                    if type(arg) == type('str'):
+                        arg = [arg]
+            except SyntaxError:
+                pass
+            else:
+                sig.append(([ret], arg))
+
+        return sig
+
+    def get_tree(self):
+        """Return the ClassTree instance used by this class."""
+        return self._tree
+
+    #################################################################
+    # Non-public interface.
+    #################################################################
+
+    def _initialize(self):
+        """Initializes the method categories."""
+        # Collects the <Value>On/Off methods.
+        self.toggle_meths = {}
+        # Collects the Set<Prop>To<Value> methods.
+        self.state_meths = {}
+        # Collects the Set/Get<Value> pairs.
+        self.get_set_meths = {}
+        # Collects the Get<Value> methods.
+        self.get_meths = []
+        # Collects all the remaining methods.
+        self.other_meths = []
+
+    def _organize_methods(self, klass, methods):
+        """Organizes the given methods of a VTK class into different
+        categories.
+
+        Parameters
+        ----------
+
+        - klass : A VTK class
+
+        - methods : `list` of `str`
+
+          A list of the methods to be categorized.
+
+        """
+        self._initialize()
+        meths = methods[:]
+        meths = self._find_toggle_methods(klass, meths)
+        meths = self._find_state_methods(klass, meths)
+        meths = self._find_get_set_methods(klass, meths)
+        meths = self._find_get_methods(klass, meths)
+        self.other_meths = [x for x in meths \
+                            if callable(getattr(klass, x)) and
+                                '__' not in x and
+                                not isinstance(getattr(klass, x), type)]
+
+    def _remove_method(self, meths, method):
+        try:
+            meths.remove(method)
+        except ValueError:
+            pass
+
+    def _find_toggle_methods(self, klass, methods):
+        """Find/store methods of the form <Value>{On,Off} in the given
+        `methods`.  Returns the remaining list of methods.
+
+        """
+        meths = methods[:]
+        tm = self.toggle_meths
+        klass_name = klass.__name__
+        problem_methods = ['CopyVectors', 'CopyTensors',
+                           'CopyTCoords', 'CopyScalars',
+                           'CopyNormals', 'CopyGlobalIds',
+                           'CopyPedigreeIds']
+        for method in meths[:]:
+            if klass_name == 'vtkDataSetAttributes' and \
+               method[:-2] in problem_methods:
+                continue
+            elif method[:-2] == 'AlphaBitPlanes':
+                continue
+            if method[-2:] == 'On':
+                key = method[:-2]
+                if (key + 'Off') in meths and ('Get' + key) in meths:
+                    tm[key] = None
+                    meths.remove(method)
+                    meths.remove(key + 'Off')
+                    self._remove_method(meths, 'Set' + key)
+                    self._remove_method(meths, 'Get' + key)
+        # get defaults
+        if tm:
+            obj = self._get_instance(klass)
+            if obj:
+                for key in tm:
+                    try:
+                        tm[key] = getattr(obj, 'Get%s'%key)()
+                    except (TypeError, AttributeError):
+                        print klass.__name__, key
+                        pass
+        return meths
+
+    def _find_state_methods(self, klass, methods):
+        """Find/store methods of the form Set<Prop>To<Value> in the
+        given `methods`.  Returns the remaining list of methods.  The
+        method also computes the mapped value of the different
+        <Values>.
+
+        """
+        # These ignored ones are really not state methods.
+        ignore = ['SetUpdateExtentToWholeExtent',
+                  'SetDataExtentToWholeExtent',
+                  'SetOutputSpacingToDefault', # In vtkImageReslice.
+                  'SetOutputOriginToDefault', # In vtkImageReslice
+                  'SetOutputExtentToDefault' # In vtkImageReslice
+                  ]
+        meths = methods[:]
+        sm = self.state_meths
+        for method in meths[:]:
+            if method not in ignore and method[:3] == 'Set':
+                # Methods of form Set<Prop>To<Value>
+                match = self._state_patn.search(method)
+                # Second cond. ensures that this is not an accident.
+                if match and (('Get'+method[3:]) not in meths):
+                    key = method[3:match.start()] # The <Prop> part.
+                    if (('Get' + key) in methods):
+                        val = method[match.start()+2:] # <Value> part.
+                        meths.remove(method)
+                        if sm.has_key(key):
+                            sm[key].append([val, None])
+                        else:
+                            sm[key] = [[val, None]]
+                            meths.remove('Get'+ key)
+                            self._remove_method(meths, 'Set'+ key)
+                            if ('Get' + key + 'MaxValue') in meths:
+                                meths.remove('Get' + key + 'MaxValue')
+                                meths.remove('Get' + key + 'MinValue')
+                            try:
+                                meths.remove('Get' + key + 'AsString')
+                            except ValueError:
+                                pass
+        # Find the values for each of the states, i.e. find that
+        # vtkProperty.SetRepresentationToWireframe() corresponds to
+        # vtkProperty.SetRepresentation(1).
+        if sm:
+            obj = self._get_instance(klass)
+            klass_name = klass.__name__
+            if obj and not klass_name.endswith('Viewer'):
+                # We do not try to inspect viewers, because they'll
+                # trigger segfaults during the inspection
+                for key, values in sm.items():
+                    default = getattr(obj, 'Get%s'%key)()
+                    for x in values[:]:
+                        try:
+                            getattr(obj, 'Set%sTo%s'%(key, x[0]))()
+                        except TypeError:
+                            # vtkRenderedGraphRepresentation has some of
+                            # its SetIvarToState methods that have
+                            # non-standard arguments, this throws off
+                            # the parser and we ignore these.
+                            #print klass.__name__, key
+                            pass
+                        else:
+                            val = getattr(obj, 'Get%s'%key)()
+                            x[1] = val
+                            if val == default:
+                                values.insert(0, [x[0], val])
+        return meths
+
+    def _find_get_set_methods(self, klass, methods):
+        """Find/store methods of the form {Get,Set}Prop in the given
+        `methods` and returns the remaining list of methods.
+
+        Note that it makes sense to call this *after*
+        `_find_state_methods` is called in order to avoid incorrect
+        duplication.  This method also computes the default value and
+        the ranges of the arguments (when possible) by using the
+        Get<Prop>{MaxValue,MinValue} methods.
+
+        """
+        meths = methods[:]
+        gsm = self.get_set_meths
+        klass_name = klass.__name__
+
+        for method in meths[:]:
+            # Methods of the Set/Get form.
+            if method in ['Get', 'Set']:
+                # This occurs with the vtkInformation class.
+                continue
+            elif klass_name == 'vtkProp' and method[3:] == 'AllocatedRenderTime':
+                # vtkProp.Get/SetAllocatedRenderTime is private and
+                # SetAllocatedRenderTime takes two args, don't wrap it.
+                continue
+            elif klass_name == 'vtkGenericAttributeCollection' and \
+                method[3:] == 'AttributesToInterpolate':
+                continue
+            elif klass_name == 'vtkOverlappingAMR' and method[3:] == 'Origin':
+                continue
+            elif (klass_name == 'vtkOrientationMarkerWidget'
+                  and method[3:] in ['OutlineColor', 'Viewport']):
+                continue
+            elif (klass_name == 'vtkImageDataGeometryFilter'
+                  and method[3:] == 'Extent'):
+                continue
+            elif (klass_name == 'vtkVolumeMapper'
+                  and method[3:] == 'CroppingRegionPlanes'):
+                continue
+            elif (method[:3] == 'Set') and ('Get' + method[3:]) in methods:
+                key = method[3:]
+                meths.remove('Set' + key)
+                meths.remove('Get' + key)
+                if ('Get' + key + 'MaxValue') in meths:
+                    meths.remove('Get' + key + 'MaxValue')
+                    meths.remove('Get' + key + 'MinValue')
+                    gsm[key] = 1
+                else:
+                    gsm[key] = None
+
+        # Find the default and range of the values.
+        if gsm:
+            obj = self._get_instance(klass)
+            if obj:
+                for key, value in gsm.items():
+                    if klass_name in ['vtkPolyData', 'vtkContext2D']:
+                        # Evil hack, these classes segfault!
+                        default = None
+                    elif klass_name == 'vtkHyperOctree' and \
+                            key == 'Dimension':
+                        # This class breaks standard VTK conventions.
+                        gsm[key] = (3, (1, 3))
+                        continue
+                    else:
+                        try:
+                            default = getattr(obj, 'Get%s'%key)()
+                        except TypeError:
+                            default = None
+                    if value:
+                        low = getattr(obj, 'Get%sMinValue'%key)()
+                        high = getattr(obj, 'Get%sMaxValue'%key)()
+                        gsm[key] = (default, (low, high))
+                    else:
+                        gsm[key] = (default, None)
+            else:
+                # We still might have methods that have a default range.
+                for key, value in gsm.items():
+                    if value == 1:
+                        gsm[key] = None
+
+        return meths
+
+    def _find_get_methods(self, klass, methods):
+        """Find/store methods of the form Get<Value> in the given
+        `methods` and returns the remaining list of methods.
+
+        """
+        meths = methods[:]
+        gm = self.get_meths
+        for method in meths[:]:
+            if method == 'Get':
+                # Occurs with vtkInformation
+                continue
+            elif method[:3] == 'Get':
+                gm.append(method)
+                meths.remove(method)
+        return meths
+
+    def _get_instance(self, klass):
+        """Given a VTK class, `klass`, returns an instance of the
+        class.
+
+        If the class is abstract, it uses the class tree to return an
+        instantiable subclass.  This is necessary to get the values of
+        the 'state' methods and the ranges for the Get/Set methods.
+
+        """
+        obj = None
+        try:
+            obj = klass()
+        except (TypeError, NotImplementedError):
+            if self._tree:
+                t = self._tree
+                n = t.get_node(klass.__name__)
+                for c in n.children:
+                    obj = self._get_instance(t.get_class(c.name))
+                    if obj:
+                        break
+        return obj
diff --git a/vistrails/packages/vtk/vtk_wrapper/wrapper.py b/vistrails/packages/vtk/vtk_wrapper/wrapper.py
new file mode 100644
index 0000000..05518dc
--- /dev/null
+++ b/vistrails/packages/vtk/vtk_wrapper/wrapper.py
@@ -0,0 +1,56 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+#import warnings
+
+
+from __future__ import division
+
+class VTKInstanceWrapper(object):
+    def __init__(self, instance, module_id=None):
+        self.vtkInstance = instance
+        self.module_id = module_id
+    # For future use: warns when .vtkInstance is used
+    #@property
+    #def vtkInstance(self):
+    #    warnings.warn(
+    #            "Dereferencing VTK object with '.vtkInstance' is not needed "
+    #            "anymore, call method directly",
+    #            DeprecationWarning,
+    #            stacklevel=2)
+    #    return self.__vtkInstance
+
+    def __getattr__(self, name):
+        return getattr(self.vtkInstance, name)
diff --git a/vistrails/packages/vtk/vtkcell.py b/vistrails/packages/vtk/vtkcell.py
index 10f4dbf..0c6c423 100644
--- a/vistrails/packages/vtk/vtkcell.py
+++ b/vistrails/packages/vtk/vtkcell.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -37,37 +38,47 @@
 # File for displaying a vtkRenderWindow in a Qt's QWidget ported from
 # VTK/GUISupport/QVTK. Combine altogether to a single class: QVTKWidget
 ################################################################################
+from __future__ import division
+
 import vtk
+import os
 from PyQt4 import QtCore, QtGui
 import sip
 from vistrails.core import system
-from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, CellLocation
+from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, SpreadsheetMode
 from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, QCellToolBar
 from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
-import vtkcell_rc
-import gc
 from vistrails.gui.qt import qt_super
 import vistrails.core.db.action
-from vistrails.core.vistrail.action import Action
-from vistrails.core.vistrail.port import Port
-from vistrails.core.vistrail import module
-from vistrails.core.vistrail import connection
-from vistrails.core.vistrail.module_function import ModuleFunction
-from vistrails.core.vistrail.module_param import ModuleParam
-from vistrails.core.vistrail.location import Location
 from vistrails.core.modules.vistrails_module import ModuleError
-import copy
 
 from identifiers import identifier as vtk_pkg_identifier
 
 ################################################################################
 
+class vtkRendererToSpreadsheet(SpreadsheetMode):
+    def compute_output(self, output_module, configuration=None):
+        d = dict([(c(), c.obj) for c in output_module.inputPorts['value']])
+        for ren, m in d.iteritems():
+            ren.module_id = m.moduleInfo['moduleId']
+        renderers = output_module.force_get_input('value') or []
+        style = output_module.force_get_input('interactorStyle')
+        picker = output_module.force_get_input('picker')
+        input_ports = (renderers, None, [], style, picker)
+        self.cellWidget = self.display_and_wait(output_module, configuration,
+                                                QVTKWidget, input_ports)
+
 class VTKCell(SpreadsheetCell):
     """
     VTKCell is a VisTrails Module that can display vtkRenderWindow inside a cell
     
     """
+    _input_ports = [("Location", "spreadsheet:CellLocation"),
+                    ("AddRenderer", "vtkRenderer", {'depth':1}),
+                    ("SetRenderView", "vtkRenderView", {'depth':1}),
+                    ("InteractionHandler", "vtkInteractionHandler", {'depth':1}),
+                    ("InteractorStyle", "vtkInteractorStyle"),
+                    ("AddPicker", "vtkAbstractPicker")]
 
     def __init__(self):
         SpreadsheetCell.__init__(self)
@@ -77,18 +88,23 @@ class VTKCell(SpreadsheetCell):
         """ compute() -> None
         Dispatch the vtkRenderer to the actual rendering widget
         """
-        renderers = self.forceGetInputListFromPort('AddRenderer')
-        renderViews = self.forceGetInputListFromPort('SetRenderView')
+        # Set module_id on wrapped renderers
+        if self.has_input('AddRenderer'):
+            d = dict([(c(), c.obj) for c in self.inputPorts['AddRenderer']])
+            for ren, m in d.iteritems():
+                ren.module_id = m.moduleInfo['moduleId']
+        renderers = self.force_get_input('AddRenderer', [])
+        renderViews = self.force_get_input('SetRenderView', [])
         if len(renderViews)>1:
             raise ModuleError(self, 'There can only be one vtkRenderView '
                               'per cell')
         if len(renderViews)==1 and len(renderers)>0:
             raise ModuleError(self, 'Cannot set both vtkRenderView '
                               'and vtkRenderer to a cell')
-        renderView = self.forceGetInputFromPort('SetRenderView')
-        iHandlers = self.forceGetInputListFromPort('InteractionHandler')
-        iStyle = self.forceGetInputFromPort('InteractorStyle')
-        picker = self.forceGetInputFromPort('AddPicker')
+        renderView = renderViews[0] if renderViews else None
+        iHandlers = self.force_get_input('InteractionHandler', [])
+        iStyle = self.force_get_input('InteractorStyle')
+        picker = self.force_get_input('AddPicker')
         self.displayAndWait(QVTKWidget, (renderers, renderView, iHandlers, iStyle, picker))
 
 AsciiToKeySymTable = ( None, None, None, None, None, None, None,
@@ -138,6 +154,8 @@ class QVTKWidget(QCellWidget):
     vtkRenderer inside a Qt QWidget
     
     """
+    save_formats = ["PNG image (*.png)", "PDF files (*.pdf)"]
+
     def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
         """ QVTKWidget(parent: QWidget, f: WindowFlags) -> QVTKWidget
         Initialize QVTKWidget with a toolbar with its own device
@@ -158,7 +176,7 @@ class QVTKWidget(QCellWidget):
         self.iHandlers = []
         self.setAnimationEnabled(True)
         self.renderer_maps = {}
-        
+
     def removeObserversFromInteractorStyle(self):
         """ removeObserversFromInteractorStyle() -> None        
         Remove all python binding from interactor style observers for
@@ -227,18 +245,25 @@ class QVTKWidget(QCellWidget):
 
         (renderers, renderView, self.iHandlers, iStyle, picker) = inputPorts
         if renderView:
-            renderView.vtkInstance.SetupRenderWindow(renWin)
+            renderView.vtkInstance.SetRenderWindow(renWin)
+            renderView.vtkInstance.ResetCamera()
+            self.addObserversToInteractorStyle()
             renderers = [renderView.vtkInstance.GetRenderer()]
         self.renderer_maps = {}
         self.usecameras = False
-        if cameralist != None and len(cameralist) == len(renderers):
+        if cameralist is not None and len(cameralist) == len(renderers):
             self.usecameras = True
         j = 0
         for renderer in renderers:
             if renderView==None:
-                vtkInstance = renderer.vtkInstance
+                vtkInstance = renderer
+                # Check deprecated vtkInstance
+                if hasattr(renderer, 'vtkInstance'):
+                    vtkInstance = renderer.vtkInstance
+                    # Old scripts may call this without setting module_id
+                    if hasattr(renderer, 'module_id'):
+                        self.renderer_maps[id(vtkInstance)] = renderer.module_id
                 renWin.AddRenderer(vtkInstance)
-                self.renderer_maps[vtkInstance] = renderer.moduleInfo['moduleId']
             else:
                 vtkInstance = renderer
             if hasattr(vtkInstance, 'IsActiveCameraCreated'):
@@ -252,21 +277,33 @@ class QVTKWidget(QCellWidget):
             
         iren = renWin.GetInteractor()
         if picker:
-            iren.SetPicker(picker.vtkInstance)
-            
+            if hasattr(picker, 'vtkInstance'):
+                picker = picker.vtkInstance
+            iren.SetPicker(picker)
+
         # Update interactor style
         self.removeObserversFromInteractorStyle()
         if renderView==None:
             if iStyle==None:
                 iStyleInstance = vtk.vtkInteractorStyleTrackballCamera()
             else:
-                iStyleInstance = iStyle.vtkInstance
+                iStyleInstance = iStyle
+                # Check deprecated vtkInstance
+                if hasattr(iStyleInstance, 'vtkInstance'):
+                    iStyleInstance = iStyleInstance.vtkInstance
             iren.SetInteractorStyle(iStyleInstance)
         self.addObserversToInteractorStyle()
         
-        for iHandler in self.iHandlers:
+        for i in xrange(len(self.iHandlers)):
+            iHandler = self.iHandlers[i]
+            if hasattr(iHandler, 'vtkInstance'):
+                iHandler = iHandler.vtkInstance
+                self.iHandler[i] = iHandler
             if iHandler.observer:
-                iHandler.observer.vtkInstance.SetInteractor(iren)
+                observer = iHandler.observer
+                if hasattr(observer, 'vtkInstance'):
+                    observer = observer.vtkInstance
+                observer.SetInteractor(iren)
         renWin.Render()
 
         # Capture window into history for playback
@@ -308,20 +345,26 @@ class QVTKWidget(QCellWidget):
             if self.mRenWin.GetMapped():
                 self.mRenWin.Finalize()
             if system.systemType=='Linux':
+                display = None
                 try:
-                    vp = '_%s_void_p' % (hex(int(QtGui.QX11Info.display()))[2:])
+                    display = int(QtGui.QX11Info.display())
                 except TypeError:
-                    #This was change for PyQt4.2
-                    if isinstance(QtGui.QX11Info.display(),QtGui.Display):
+                    # This was changed for PyQt4.2
+                    if isinstance(QtGui.QX11Info.display(), QtGui.Display):
                         display = sip.unwrapinstance(QtGui.QX11Info.display())
-                        vp = '_%s_void_p' % (hex(display)[2:])
-                v = vtk.vtkVersion()
-                version = [v.GetVTKMajorVersion(),
-                           v.GetVTKMinorVersion(),
-                           v.GetVTKBuildVersion()]
-                if version < [5, 7, 0]:
-                    vp = vp + '\0x00'                
-                self.mRenWin.SetDisplayId(vp)
+                if display is not None:
+                    v = vtk.vtkVersion()
+                    version = [v.GetVTKMajorVersion(),
+                               v.GetVTKMinorVersion(),
+                               v.GetVTKBuildVersion()]
+                    display = hex(display)[2:]
+                    if version < [5, 7, 0]:
+                        vp = ('_%s_void_p\0x00' % display)
+                    elif version < [6, 2, 0]:
+                        vp = ('_%s_void_p' % display)
+                    else:
+                        vp = ('_%s_p_void' % display)
+                    self.mRenWin.SetDisplayId(vp)
                 self.resizeWindow(1,1)
             self.mRenWin.SetWindowInfo(str(int(self.winId())))
             if self.isVisible():
@@ -636,10 +679,10 @@ class QVTKWidget(QCellWidget):
         if not keysym:
             keysym = self.qt_key_to_key_sym(e.key())
 
-        # Ignore 'q' or 'e' or Ctrl-anykey
+        # Ignore Ctrl-anykey
         ctrl = (e.modifiers()&QtCore.Qt.ControlModifier)
         shift = (e.modifiers()&QtCore.Qt.ShiftModifier)
-        if (keysym in ['q','e'] or ctrl):
+        if ctrl:
             e.ignore()
             return
         
@@ -716,7 +759,7 @@ class QVTKWidget(QCellWidget):
         Convert Qt key code into key name
         
         """
-        handler = {QtCore.Qt.Key_Backspace:"BackSpace",
+        handler = {QtCore.Qt.Key_Backspace:"Backspace",
                    QtCore.Qt.Key_Tab:"Tab",
                    QtCore.Qt.Key_Backtab:"Tab",
                    QtCore.Qt.Key_Return:"Return",
@@ -932,7 +975,7 @@ class QVTKWidget(QCellWidget):
         """ saveToPNG(filename: str) -> filename or vtkUnsignedCharArray
         
         Save the current widget contents to an image file. If
-        str==None, then it returns the vtkUnsignedCharArray containing
+        filename is None, then it returns the vtkUnsignedCharArray containing
         the PNG image. Otherwise, the filename is returned.
         
         """
@@ -954,25 +997,10 @@ class QVTKWidget(QCellWidget):
         else:
             writer.WriteToMemoryOn()
         writer.Write()
-        if filename:
+        if filename is not None:
             return filename
         else:
             return writer.GetResult()
-
-    def captureWindow(self):
-        """ captureWindow() -> None        
-        Capture the window contents to file
-        
-        """
-        fn = QtGui.QFileDialog.getSaveFileName(None,
-                                               "Save file as...",
-                                               "screenshot.png",
-                                               "Images (*.png);;PDF files (*.pdf)")
-        if fn:
-            if fn.lower().endswith("png"):
-                self.saveToPNG(fn)
-            elif fn.lower().endswith("pdf"):
-                self.saveToPDF(fn)
         
     def grabWindowPixmap(self):
         """ grabWindowImage() -> QPixmap
@@ -997,32 +1025,11 @@ class QVTKWidget(QCellWidget):
         """dumpToFile() -> None
         Dumps itself as an image to a file, calling saveToPNG
         """
-        self.saveToPNG(filename)
-
-class QVTKWidgetCapture(QtGui.QAction):
-    """
-    QVTKWidgetCapture is the action to capture the vtk rendering
-    window to an image
-    
-    """
-    def __init__(self, parent=None):
-        """ QVTKWidgetCapture(parent: QWidget) -> QVTKWidgetCapture
-        Setup the image, status tip, etc. of the action
-        
-        """
-        QtGui.QAction.__init__(self,
-                               QtGui.QIcon(":/images/camera.png"),
-                               "&Capture image to file",
-                               parent)
-        self.setStatusTip("Capture the rendered image to a file")
-
-    def triggeredSlot(self, checked=False):
-        """ toggledSlot(checked: boolean) -> None
-        Execute the action when the button is clicked
-        
-        """
-        cellWidget = self.toolBar.getSnappedWidget()
-        cellWidget.captureWindow()
+        ext = os.path.splitext(filename)[1].lower()
+        if ext == '.pdf':
+            self.saveToPDF(filename)
+        else:
+            self.saveToPNG(filename)
 
 class QVTKWidgetSaveCamera(QtGui.QAction):
     """
@@ -1050,13 +1057,13 @@ class QVTKWidgetSaveCamera(QtGui.QAction):
             cpos = cam.GetPosition()
             cfol = cam.GetFocalPoint()
             cup = cam.GetViewUp()
-            rendererId = cellWidget.renderer_maps[ren]
             # Looking for SetActiveCamera()
             camera = None
+            rendererId = cellWidget.renderer_maps[id(ren)]
             renderer = pipeline.modules[rendererId]
             for c in pipeline.connections.values():
                 if c.destination.moduleId==rendererId:
-                    if c.destination.name=='SetActiveCamera':
+                    if c.destination.name=='ActiveCamera':
                         camera = pipeline.modules[c.source.moduleId]
                         break
             
@@ -1068,9 +1075,9 @@ class QVTKWidgetSaveCamera(QtGui.QAction):
                 ops.append(('add', camera))
 
                 # Connect camera to renderer
-                camera_conn = controller.create_connection(camera, 'self',
-                                                           renderer, 
-                                                           'SetActiveCamera')
+                camera_conn = controller.create_connection(
+                        camera, 'Instance',
+                        renderer, 'ActiveCamera')
                 ops.append(('add', camera_conn))
             # update functions
             def convert_to_str(arglist):
@@ -1078,9 +1085,9 @@ class QVTKWidgetSaveCamera(QtGui.QAction):
                 for arg in arglist:
                     new_arglist.append(str(arg))
                 return new_arglist
-            functions = [('SetPosition', convert_to_str(cpos)),
-                         ('SetFocalPoint', convert_to_str(cfol)),
-                         ('SetViewUp', convert_to_str(cup))]
+            functions = [('Position', convert_to_str(cpos)),
+                         ('FocalPoint', convert_to_str(cfol)),
+                         ('ViewUp', convert_to_str(cup))]
             ops.extend(controller.update_functions_ops(camera, functions))
 
         action = vistrails.core.db.action.create_action(ops)
@@ -1106,8 +1113,7 @@ class QVTKWidgetSaveCamera(QtGui.QAction):
                         controller = view.controller
                         controller.change_selected_version(info['version'])
                         self.setCamera(controller)
-                        
-                
+
 class QVTKWidgetToolBar(QCellToolBar):
     """
     QVTKWidgetToolBar derives from QCellToolBar to give the VTKCell
@@ -1119,28 +1125,7 @@ class QVTKWidgetToolBar(QCellToolBar):
         This will get call initiallly to add customizable widgets
         
         """
-        self.appendAction(QVTKWidgetCapture(self))
         self.addAnimationButtons()
         self.appendAction(QVTKWidgetSaveCamera(self))
 
-def registerSelf():
-    """ registerSelf() -> None
-    Registry module with the registry
-    """
-    registry = get_module_registry()
-    registry.add_module(VTKCell)
-    registry.add_input_port(VTKCell, "Location", CellLocation)
-    import vistrails.core.debug
-    for (port,module) in [("AddRenderer",'vtkRenderer'),
-                          ("SetRenderView",'vtkRenderView'),
-                          ("InteractionHandler",'vtkInteractionHandler'),
-                          ("InteractorStyle", 'vtkInteractorStyle'),
-                          ("AddPicker",'vtkAbstractPicker')]:
-        try:
-            registry.add_input_port(VTKCell, port,'(%s:%s)' % \
-                                        (vtk_pkg_identifier,module))
-            
-        except Exception, e:
-            vistrails.core.debug.warning(str(e))
-
-    registry.add_output_port(VTKCell, "self", VTKCell)
+_modules = [VTKCell,]
diff --git a/vistrails/packages/vtk/vtkcell_rc.py b/vistrails/packages/vtk/vtkcell_rc.py
deleted file mode 100644
index ae51b30..0000000
--- a/vistrails/packages/vtk/vtkcell_rc.py
+++ /dev/null
@@ -1,198 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-# -*- coding: utf-8 -*-
-
-# Resource object code
-#
-# Created: Mon Jul 19 16:02:11 2010
-#      by: The Resource Compiler for PyQt (Qt v4.6.3)
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore
-
-qt_resource_data = b"\
-\x00\x00\x07\xb6\
-\x89\
-\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
-\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
-\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xaf\xc8\x37\x05\x8a\xe9\
-\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\
-\x00\x41\x64\x6f\x62\x65\x20\x49\x6d\x61\x67\x65\x52\x65\x61\x64\
-\x79\x71\xc9\x65\x3c\x00\x00\x07\x48\x49\x44\x41\x54\x78\xda\x62\
-\xfc\xff\xff\x3f\xc3\x40\x02\x80\x00\x62\x62\x18\x60\x00\x10\x40\
-\x03\xee\x00\x80\x00\x1a\x70\x07\x00\x04\xd0\x80\x3b\x00\x20\x80\
-\x58\x40\x84\xb1\x71\x2a\xc3\x8f\x1f\x3f\x99\x7e\xfe\xfc\xce\xfd\
-\xff\xff\xbf\xbf\x4a\x4a\xaa\x86\x52\x52\x02\x59\x3c\x3c\x8c\x66\
-\x7f\xfe\xfc\x61\x7e\xf2\xe4\xed\x8d\xd3\xa7\xf7\x2d\xfb\xf6\xed\
-\xdd\x76\x25\x25\xc7\x9f\x0c\x0c\xff\xa0\xda\x19\x21\xbe\x60\x82\
-\xf8\x83\x91\x91\x11\x8e\x99\x98\x18\x19\x40\xe9\x1b\xc4\x86\xc9\
-\x81\xc4\x98\x98\x98\x19\x7f\xff\xfe\xf4\xe5\xcc\x99\xa5\xe0\xd4\
-\x0f\x10\x40\x60\x07\xfc\xfb\xf7\xdf\x4e\x45\x45\xa6\x41\x50\x90\
-\x97\x07\x98\x2b\xfe\x72\x70\x70\x6a\x70\x71\x31\x0a\xb0\xb1\x31\
-\x81\x2d\xe1\xe5\xe5\x55\x94\x92\x8a\x75\xff\xf7\xef\xef\x65\x06\
-\x86\xff\x3f\x41\x86\xb0\xb3\xb3\x83\x03\x10\x64\xfe\xef\xdf\xbf\
-\x41\x06\x83\x2d\x01\x7a\x00\xcc\x06\x3b\xe0\xdf\x7f\x86\xff\x70\
-\x87\x81\x4c\x02\x3a\x80\x99\x99\xf1\xc5\x8b\x97\xaf\x1e\x3c\x50\
-\xa9\x7f\xf3\xe6\xce\x19\x80\x00\x02\x3b\x40\x4d\x4d\x76\x62\x6f\
-\x6f\x9a\x81\xa0\x20\x1f\xd8\xd5\x9f\x3f\x7f\x67\xf8\xf8\xf1\x2b\
-\xc3\xb7\x6f\xbf\xc1\x7c\x16\x16\x66\x06\x56\x56\x56\xa0\x47\x99\
-\xf4\x41\x86\xb1\xb1\x73\x30\x5c\xbf\x7c\x9c\xe1\xf1\x83\x3b\x0c\
-\x6a\xda\x46\x0c\xc2\x22\x62\x40\x75\x7f\x80\x1e\xf9\xc7\xc0\xcc\
-\xcc\xcc\xf0\xf7\x2f\x13\x03\x07\x07\x1f\x03\x3b\x3b\x50\x2d\x0b\
-\x23\x03\x33\x28\x10\x18\x99\x18\xbe\x7c\xfd\xc1\xf0\xfd\x27\x2b\
-\xd0\xfc\xbf\x0c\xf7\xef\x5f\x66\x02\x3a\x20\x09\x20\x80\xc0\x0e\
-\x10\x15\xe5\x96\x65\x61\xf9\xc7\xf0\xe5\xcb\x67\xb0\xeb\x3f\x7d\
-\xfa\xca\xf0\xf2\xe5\x7b\x86\x0f\x1f\xbe\x83\x83\x8f\x99\x99\x05\
-\x8c\x41\x72\x5c\x9c\x5c\x0c\x77\x6f\x9f\x60\x68\x59\x75\x9c\x41\
-\xc9\x3a\x80\xe1\x45\xd3\x74\x86\x25\xfd\xb9\x0c\x4b\x96\xaf\x66\
-\xf8\xf8\xe1\x03\x43\x45\x45\x25\xd8\xe7\x97\xaf\x5e\x64\x10\x91\
-\x92\x65\x10\x92\x94\x61\x78\xf1\x8d\x91\xe1\xf9\xd7\xff\x0c\xaf\
-\xdf\xfd\x64\xe0\x7a\x78\x83\x41\x54\x50\x11\xe8\x40\x0e\x05\xa0\
-\xd1\x0a\x00\x01\x04\x8e\xbc\x5f\xbf\x7e\xfd\xfd\xfd\xfb\x2f\x3c\
-\xbe\x50\xe3\x0c\x82\x41\x7c\x66\x66\x26\x70\xb4\xbf\x7c\x76\x93\
-\xe1\xfe\x27\x1e\x86\xdd\x8f\xa5\x18\x18\x39\x44\x19\x04\xf8\x78\
-\x18\x56\x2c\x5f\xc1\xb0\x60\xc1\x22\x86\xef\xdf\x7f\x30\x28\xab\
-\x28\x33\xd8\x58\x9b\x31\x3c\xff\xc6\xc4\x70\xe6\xfe\x67\x86\xcb\
-\xf7\xde\x30\x7c\xff\xf2\x9b\x81\xf9\xe7\x37\x06\x0e\x60\xd4\xfd\
-\xfe\xf5\x07\x18\x6d\x7f\x41\x96\xb1\x01\x04\x10\x0b\x2c\x31\x21\
-\xd9\x8d\x15\x40\x1c\xc7\xc8\xf0\xf8\xf1\x0d\x06\x77\x5f\x6f\x06\
-\x0e\xc1\x13\x0c\x07\x8f\x75\x31\x64\x97\x86\x30\xc8\x29\x6b\x31\
-\x2c\x5d\xba\x14\x68\xf9\x77\x06\x0d\x0d\x75\x60\x82\xfe\x0d\x8c\
-\x32\x76\x06\x0b\x25\x01\x86\x5f\x3f\x7e\x32\x5c\xb9\x72\x95\x41\
-\x98\x4b\x8d\x81\x55\x90\x9f\xe1\x1d\x23\x3b\x30\x7a\x7f\xc2\x3c\
-\xfb\x1f\x20\x80\x58\x88\xcd\x2e\x20\xdf\xbf\x7a\xf5\x88\x41\x4c\
-\x8c\x9f\x41\x52\x52\x9e\x21\x39\x5e\x99\x21\x3b\x25\x92\x81\x85\
-\x83\x07\x2c\x6f\x67\x67\x07\x57\xfb\xfb\x37\x24\x97\xf0\xf0\xf0\
-\x32\xfc\x66\xe7\x62\x30\x30\x34\x66\xb8\x78\xf1\x1a\x83\xa4\x94\
-\x38\x30\x3d\x81\x92\xe5\x0f\xb8\x87\x01\x02\x88\x05\xe1\xbb\xff\
-\x78\x7c\xcf\x04\xf4\xd5\x0f\xa0\xaf\xfe\x30\xc8\xc9\x29\x83\x83\
-\x99\x81\x81\x95\x81\x81\x9b\x93\x81\x0d\x18\x9c\x5f\xbe\x7c\x02\
-\x3a\xee\x05\x58\x0d\x1f\x1f\x3f\x30\x4d\x49\x80\x13\xee\xb7\x6f\
-\x3f\xc1\x39\x84\x99\x85\x1d\x68\xb9\x08\xc3\xa3\x47\x57\x18\x04\
-\x04\x54\x19\x90\xab\x1f\x80\x00\x22\x2a\x04\x40\x89\xef\xc3\x87\
-\x97\x0c\xb2\xb2\x52\xc0\x14\xfe\x1f\xec\x58\x90\xa3\x81\xd9\x92\
-\xe1\xde\xbd\x07\x0c\x2f\x5e\xbc\x06\x0a\xb1\x03\x2d\x62\x03\x26\
-\xde\x27\xc0\x68\x7a\xc2\xa0\xa2\xa2\xca\xc0\xc5\xc5\x0f\x4c\x5f\
-\xa0\xf8\xfe\xc3\x20\x2c\x2c\x0e\x4e\xd8\x3f\x7e\x7c\x87\x46\x39\
-\x24\x08\x00\x02\x88\x89\x50\x81\x08\x52\xf8\xf7\xef\x6f\xa0\x41\
-\x5f\x19\xd8\xd8\xb8\xc0\x96\x42\xa2\x84\x99\xe1\xcd\x9b\x97\x0c\
-\xaf\x5f\xbf\x63\xe0\xe1\x95\x64\x78\xfd\xe6\x23\xc3\xb9\x73\x67\
-\x19\x38\x38\x85\x80\x39\x8e\x87\xe1\xc6\x8d\x6b\x0c\xc0\x82\x0d\
-\x5a\x36\x00\xcb\x83\xff\x4c\x0c\xdc\xdc\xec\xc0\xd0\x7a\x0b\x0c\
-\x1d\x84\xbf\x01\x02\x88\x09\x62\x09\xde\xe4\x07\xf4\xc1\x2f\x06\
-\x4e\x4e\xa0\x0f\x99\x59\xc1\x86\xc1\x7c\xff\xfe\xfd\x7b\x06\x31\
-\x71\x39\x86\x53\xa7\x8e\x30\x24\xa7\x84\x30\x14\x15\xa5\x02\xb3\
-\x61\x16\xb0\xe0\xe2\x07\x46\x17\x17\xc3\xdb\xb7\xaf\x80\x96\x41\
-\x3c\xf7\xf7\xef\x5f\xb0\x19\x3f\x7e\x7c\x00\x47\x29\x0c\x00\x04\
-\x10\x11\x0e\x60\x00\x5b\x0a\x2a\xf9\x60\x6d\x07\x50\xd1\xfb\xf3\
-\xe7\x0f\x70\xaa\x11\x13\x17\x65\x58\xb8\x60\x26\xc3\xe7\x4f\x9f\
-\x40\x25\x2a\xc3\x89\xe3\x47\x18\xce\x9c\x39\xc6\x20\x2e\x21\x05\
-\x2c\x70\x3e\xc2\x2d\x83\x98\xc1\x01\xe4\xff\x03\xab\x83\x15\xe3\
-\x00\x01\xc4\x84\x5c\xa6\xe3\x03\x10\x4d\x08\x07\x81\x1c\xf1\x0f\
-\xe8\xab\xff\xc0\x7a\x41\x50\x48\x18\x45\x2d\xbf\x00\x3f\xc3\x1f\
-\x60\xb4\xfd\xfd\xfb\x0f\x29\x2a\x19\xc0\x25\xe5\xbf\x7f\xa8\xe6\
-\x02\x04\x10\x52\x2e\xc0\x57\x06\x30\x83\xf3\x38\xc2\x31\xff\x80\
-\xe9\x81\x13\x98\xe8\x58\x18\x5e\x3e\x7f\xca\x50\x5e\x51\xcd\xf0\
-\x13\x98\xb8\x5e\x3c\x7f\xce\xe0\xe1\xed\xc3\x60\x6e\x6e\xc9\x70\
-\xe3\xfa\x45\x06\x49\x09\x49\x68\x94\x41\xec\x00\x25\x40\x26\x26\
-\x56\xb0\xe3\x61\x76\x02\x04\x10\x0b\xa1\x28\x00\x19\xc0\xc6\xc6\
-\x06\xcc\x05\xff\x80\x3e\xfa\x05\x54\xcb\x0e\x97\x13\x03\xd6\x01\
-\xf7\xee\xdf\x65\x10\x11\x91\x60\x98\x39\x7b\x3e\x38\x7b\xf2\xf0\
-\x70\x33\xdc\xbd\x73\x1d\x58\xda\xfd\x64\x90\x90\x90\x02\xc7\x3d\
-\xac\x3e\xf9\xf1\xe3\x17\x50\x5e\x84\x01\x58\xc3\xc2\xed\x04\x08\
-\x20\x22\xb2\x21\x24\xb8\x39\x39\xf9\x19\xbe\x7e\xfd\xc4\xc0\xcf\
-\x2f\x08\x4f\x54\xc2\x22\xa2\x40\xd7\xff\x67\x78\xf2\xe4\x31\xc3\
-\xdb\x9f\x7f\x80\xc1\xfe\x87\xe1\xc5\xb3\x3f\xc0\xc4\xca\xc8\x60\
-\x6a\x6a\x01\x2e\x0d\x7f\xff\xfe\x01\xcd\x49\xbf\x80\x69\xe2\x27\
-\x30\x27\x08\x00\x13\xef\x57\x78\xb4\x03\x04\x10\x51\x51\x00\xb2\
-\x8c\x8f\x4f\x88\xe1\xd9\xb3\x7b\xc0\x52\x50\x12\xe8\x20\x48\x28\
-\x80\x7c\x22\x21\x21\x0d\x2c\x1d\x45\x81\x86\x7f\x01\xe7\x16\x16\
-\x16\x56\xa0\x2f\xf9\xc1\xf1\xff\xfd\xfb\x4f\xb0\x3a\x36\x36\x56\
-\x86\xdb\xb7\x6f\x03\x1d\x26\x08\xae\xd4\x90\x01\x40\x00\x11\x99\
-\x08\xff\x83\x35\x72\x72\x8a\x82\xf3\x37\x28\x38\x61\x8e\xfe\x0b\
-\xf4\x35\x0b\xb0\xa4\x13\x11\x11\x01\x3a\x4e\x0a\x48\x8b\x82\x83\
-\x17\xe4\x68\x10\x60\x65\x65\x01\x46\xdf\x6b\x60\xf9\xff\x97\x41\
-\x46\x46\x0d\xac\x1e\xb9\xee\x01\x08\x20\xa2\xb2\x21\x2c\x14\x84\
-\x84\x44\x81\x05\x12\x2b\xc3\xe5\xcb\xe7\xc0\x7a\x40\x69\x03\x51\
-\xd0\x20\xd4\x81\xf8\xa0\x82\x8a\x9d\x9d\x8d\xe1\xdd\xbb\xd7\x0c\
-\x77\xee\x3c\x06\x56\x52\xe6\xf0\x34\x85\x0c\x00\x02\x88\x09\x5a\
-\xaa\x31\x83\x2a\x1b\x6c\x55\x30\x72\x13\x0b\x54\xf8\x48\x4a\x2a\
-\x00\x83\x96\x95\xe1\xc8\x91\xa3\x0c\xcf\x9f\x3f\x01\xfa\x90\x19\
-\x5c\xd8\xc0\x13\x15\x30\x74\x40\x05\x0e\xa8\x14\xbc\x7a\xf5\x32\
-\x30\xe8\x9f\x31\xe8\xe8\x58\x03\x8b\x65\x0e\x70\x6b\x09\x62\x16\
-\x13\xb8\x69\x06\x52\x0f\x10\x40\xe0\x08\x79\xf2\xe4\xcd\xed\x87\
-\x0f\xdf\x09\x2b\x2a\x4a\x01\xe3\x15\x54\x9b\x81\xe2\x17\x98\xcf\
-\xff\x31\xc1\x2b\x23\x18\x06\xb5\x1b\x84\x85\xe5\x80\x29\xfa\x1b\
-\xb0\x04\xbc\x07\xac\x6a\xef\x01\x43\x86\x17\xe8\x30\x71\xb0\x8f\
-\x3f\x00\x1b\x25\xcf\x9e\x01\xeb\xff\xef\xff\x80\xe9\x46\x8a\x41\
-\x5b\x5b\x05\xec\xf8\x5f\xbf\x80\x25\xc6\x3f\x90\x67\x58\x80\x0d\
-\x9e\xcf\xa0\x68\x01\xd5\x68\xff\x01\x02\x88\x11\x14\x24\x52\x52\
-\x7a\x76\xe2\xe2\x72\xd5\xbc\xbc\xdc\xb2\xa0\xf8\x06\x66\xf3\xff\
-\xa0\x82\x07\x56\xec\x22\xb7\x07\x40\x86\xc1\x2a\x28\x50\xf9\x00\
-\xf2\xe9\xb7\x6f\x9f\x80\x21\xc1\x08\xf6\x3d\xa8\xf2\x01\x25\x52\
-\x7e\x7e\x21\x50\x33\x0e\x68\xd6\x1f\xa8\xc5\x90\xb4\x04\x64\x33\
-\x7e\xfc\xf8\xe6\xe7\xb5\x6b\x07\xf7\x7c\xff\xfe\x69\x0e\x40\x00\
-\x31\x42\x2d\x01\x49\x4b\x01\xb1\x1c\x28\x46\xe8\xd0\x1a\x07\x95\
-\x87\xc0\x2a\x94\xe1\x11\x40\x00\x31\x0e\x74\xdf\x10\x20\x80\x06\
-\xbc\x63\x02\x10\x40\x03\xee\x00\x80\x00\x1a\x70\x07\x00\x04\x18\
-\x00\x4e\x12\xc6\x99\x32\x89\xe5\xec\x00\x00\x00\x00\x49\x45\x4e\
-\x44\xae\x42\x60\x82\
-"
-
-qt_resource_name = b"\
-\x00\x06\
-\x07\x03\x7d\xc3\
-\x00\x69\
-\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\
-\x00\x0a\
-\x0c\x91\x67\x27\
-\x00\x63\
-\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x70\x00\x6e\x00\x67\
-"
-
-qt_resource_struct = b"\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
-\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-"
-
-def qInitResources():
-    QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
-
-def qCleanupResources():
-    QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
-
-qInitResources()
diff --git a/vistrails/packages/vtk/vtkhandler.py b/vistrails/packages/vtk/vtkhandler.py
index 337c36e..61e83a2 100644
--- a/vistrails/packages/vtk/vtkhandler.py
+++ b/vistrails/packages/vtk/vtkhandler.py
@@ -1,50 +1,63 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """Modules for handling vtkRenderWindowInteractor events"""
-from PyQt4 import QtCore, QtGui
-from vistrails.core.modules.basic_modules import String
+from __future__ import division
+
 from vistrails.core.modules.vistrails_module import Module, NotCacheable
-from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.core.vistrail.module_function import ModuleFunction, ModuleParam
 from vistrails.gui.modules.source_configure import SourceConfigurationWidget
 from vistrails.gui.modules.python_source_configure import PythonEditor
 import urllib
 
-from identifiers import identifier as vtk_pkg_identifier
-
 ################################################################################
+class HandlerConfigurationWidget(SourceConfigurationWidget):
+    def __init__(self, module, controller, parent=None):
+        """ HandlerConfigurationWidget(module: Module,
+                                       controller: VistrailController,
+                                       parent: QWidget)
+                                       -> HandlerConfigurationWidget
+        Setup the dialog to similar to PythonSource but with a
+        different name
+
+        """
+        SourceConfigurationWidget.__init__(self, module, controller,
+                                           PythonEditor, False, False, parent,
+                                           portName='Handler')
+
+
+
 class vtkInteractionHandler(NotCacheable, Module):
     """
     vtkInteractionHandler allow users to insert callback code for interacting
@@ -52,6 +65,14 @@ class vtkInteractionHandler(NotCacheable, Module):
     
     """
 
+    _settings={'configureWidgetType': HandlerConfigurationWidget}
+
+    _input_ports = [('Observer', 'vtkInteractorObserver'),
+                    ('Handler', 'basic:String', True),
+                    ('SharedData', 'basic:Variant')]
+
+    _output_ports =[('Instance', 'vtkInteractionHandler')]
+
     # Since vtkCommand is not wrapped in Python, we need to hardcoded all events
     # string from vtkCommand.h
     vtkEvents = [
@@ -137,9 +158,9 @@ class vtkInteractionHandler(NotCacheable, Module):
         """ compute() -> None
         Actually compute nothing
         """        
-        self.observer = self.forceGetInputFromPort('Observer')
-        self.handler = self.forceGetInputFromPort('Handler', '')
-        self.shareddata = self.forceGetInputListFromPort('SharedData')
+        self.observer = self.force_get_input('Observer')
+        self.handler = self.force_get_input('Handler', '')
+        self.shareddata = self.force_get_input_list('SharedData')
         if len(self.shareddata)==1:
             self.shareddata = self.shareddata[0]
         if self.observer:
@@ -154,6 +175,7 @@ class vtkInteractionHandler(NotCacheable, Module):
             exec(source)
             if hasattr(self.observer.vtkInstance, 'PlaceWidget'):
                 self.observer.vtkInstance.PlaceWidget()
+        self.set_output('Instance', self)
 
     def eventHandler(self, obj, event):
         """ eventHandler(obj: vtkObject, event: str) -> None
@@ -191,30 +213,5 @@ class vtkInteractionHandler(NotCacheable, Module):
              import RepaintCurrentSheetEvent
         spreadsheetController.postEventToSpreadsheet(RepaintCurrentSheetEvent())
 
-class HandlerConfigurationWidget(SourceConfigurationWidget):
-    def __init__(self, module, controller, parent=None):
-        """ HandlerConfigurationWidget(module: Module,
-                                       controller: VistrailController,
-                                       parent: QWidget)
-                                       -> HandlerConfigurationWidget
-        Setup the dialog to similar to PythonSource but with a
-        different name
-        
-        """
-        SourceConfigurationWidget.__init__(self, module, controller, 
-                                           PythonEditor, False, False, parent,
-                                           portName='Handler')
 
-def registerSelf():
-    """ registerSelf() -> None
-    Registry module with the registry
-    """
-    registry = get_module_registry()
-    vIO = registry.get_descriptor_by_name(vtk_pkg_identifier,
-                                          'vtkInteractorObserver').module
-    registry.add_module(vtkInteractionHandler, configureWidgetType=HandlerConfigurationWidget)
-    registry.add_input_port(vtkInteractionHandler, 'Observer', vIO)
-    registry.add_input_port(vtkInteractionHandler, 'Handler', String, True)
-    registry.add_input_port(vtkInteractionHandler, 'SharedData', Module)
-    registry.add_output_port(vtkInteractionHandler, 'self',
-                             vtkInteractionHandler)
+_modules = [vtkInteractionHandler]
diff --git a/vistrails/packages/vtk/vtkviewcell.py b/vistrails/packages/vtk/vtkviewcell.py
deleted file mode 100644
index 1eed757..0000000
--- a/vistrails/packages/vtk/vtkviewcell.py
+++ /dev/null
@@ -1,1045 +0,0 @@
-###############################################################################
-##
-## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
-## All rights reserved.
-## Contact: contact at vistrails.org
-##
-## This file is part of VisTrails.
-##
-## "Redistribution and use in source and binary forms, with or without 
-## modification, are permitted provided that the following conditions are met:
-##
-##  - Redistributions of source code must retain the above copyright notice, 
-##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
-##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
-##    this software without specific prior written permission.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
-## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-###############################################################################
-################################################################################
-# File QVTKViewWidget.py
-# File for displaying a vtkRenderWindow in a Qt's QWidget ported from
-# VTK/GUISupport/QVTK. Combine altogether to a single class: QVTKViewWidget
-################################################################################
-import vtk
-from PyQt4 import QtCore, QtGui
-import sip
-from vistrails.core import system
-from vistrails.core.modules.module_registry import get_module_registry
-from vistrails.packages.spreadsheet.basic_widgets import SpreadsheetCell, CellLocation
-from vistrails.packages.spreadsheet.spreadsheet_cell import QCellWidget, QCellToolBar
-import vtkcell_rc
-import gc
-from vistrails.gui.qt import qt_super
-import vistrails.core.db.action
-from vistrails.core.vistrail.action import Action
-from vistrails.core.vistrail.port import Port
-from vistrails.core.vistrail import module
-from vistrails.core.vistrail import connection
-from vistrails.core.vistrail.module_function import ModuleFunction
-from vistrails.core.vistrail.module_param import ModuleParam
-from vistrails.core.vistrail.location import Location
-from vistrails.core.modules.vistrails_module import ModuleError
-import copy
-
-from identifiers import identifier as vtk_pkg_identifier
-
-################################################################################
-
-class VTKViewCell(SpreadsheetCell):
-    """
-    VTKViewCell is a VisTrails Module that can display vtkRenderWindow inside a cell
-    
-    """
-
-    def __init__(self):
-        SpreadsheetCell.__init__(self)
-        self.cellWidget = None
-    
-    def compute(self):
-        """ compute() -> None
-        Dispatch the vtkRenderer to the actual rendering widget
-        """
-        renderView = self.forceGetInputFromPort('SetRenderView')
-        if renderView==None:
-            raise ModuleError(self, 'A vtkRenderView input is required.')
-        self.displayAndWait(QVTKViewWidget, (renderView,))
-
-AsciiToKeySymTable = ( None, None, None, None, None, None, None,
-                       None, None,
-                       "Tab", None, None, None, None, None, None,
-                       None, None, None, None, None, None,
-                       None, None, None, None, None, None,
-                       None, None, None, None,
-                       "space", "exclam", "quotedbl", "numbersign",
-                       "dollar", "percent", "ampersand", "quoteright",
-                       "parenleft", "parenright", "asterisk", "plus",
-                       "comma", "minus", "period", "slash",
-                       "0", "1", "2", "3", "4", "5", "6", "7",
-                       "8", "9", "colon", "semicolon", "less", "equal",
-                       "greater", "question",
-                       "at", "A", "B", "C", "D", "E", "F", "G",
-                       "H", "I", "J", "K", "L", "M", "N", "O",
-                       "P", "Q", "R", "S", "T", "U", "V", "W",
-                       "X", "Y", "Z", "bracketleft",
-                       "backslash", "bracketright", "asciicircum",
-                       "underscore",
-                       "quoteleft", "a", "b", "c", "d", "e", "f", "g",
-                       "h", "i", "j", "k", "l", "m", "n", "o",
-                       "p", "q", "r", "s", "t", "u", "v", "w",
-                       "x", "y", "z", "braceleft", "bar", "braceright",
-                       "asciitilde", "Delete",
-                       None, None, None, None, None, None, None, None, 
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None, 
-                       None, None, None, None, None, None, None, None, 
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None,
-                       None, None, None, None, None, None, None, None)
-
-class QVTKViewWidget(QCellWidget):
-    """
-    QVTKViewWidget is the actual rendering widget that can display
-    vtkRenderer inside a Qt QWidget
-    
-    """
-    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
-        """ QVTKViewWidget(parent: QWidget, f: WindowFlags) -> QVTKViewWidget
-        Initialize QVTKViewWidget with a toolbar with its own device
-        context
-        
-        """
-        QCellWidget.__init__(self, parent, f | QtCore.Qt.MSWindowsOwnDC)
-
-        self.interacting = None
-        self.mRenWin = None
-        self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
-        self.setAttribute(QtCore.Qt.WA_PaintOnScreen)
-        self.setMouseTracking(True)
-        self.setFocusPolicy(QtCore.Qt.StrongFocus)
-        self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
-                                             QtGui.QSizePolicy.Expanding))
-        self.toolBarType = QVTKViewWidgetToolBar
-        self.setAnimationEnabled(True)
-        
-    def removeObserversFromInteractorStyle(self):
-        """ removeObserversFromInteractorStyle() -> None        
-        Remove all python binding from interactor style observers for
-        safely freeing the cell
-        
-        """
-        iren = self.mRenWin.GetInteractor()
-        if iren:
-            style = iren.GetInteractorStyle()
-            style.RemoveObservers("InteractionEvent")
-            style.RemoveObservers("EndPickEvent")
-            style.RemoveObservers("CharEvent")
-            style.RemoveObservers("MouseWheelForwardEvent")
-            style.RemoveObservers("MouseWheelBackwardEvent")
-        
-    def addObserversToInteractorStyle(self):
-        """ addObserversToInteractorStyle() -> None        
-        Assign observer to the current interactor style
-        
-        """
-        iren = self.mRenWin.GetInteractor()
-        if iren:
-            style = iren.GetInteractorStyle()
-            style.AddObserver("InteractionEvent", self.interactionEvent)
-            style.AddObserver("EndPickEvent", self.interactionEvent)
-            style.AddObserver("CharEvent", self.charEvent)
-            style.AddObserver("MouseWheelForwardEvent", self.interactionEvent)
-            style.AddObserver("MouseWheelBackwardEvent", self.interactionEvent)
-
-    def deleteLater(self):
-        """ deleteLater() -> None        
-        Make sure to free render window resource when
-        deallocating. Overriding PyQt deleteLater to free up
-        resources
-        
-        """
-        self.renderer_maps = {}
-        for ren in self.getRendererList():
-            self.mRenWin.RemoveRenderer(ren)
-        self.removeObserversFromInteractorStyle()
-        self.SetRenderWindow(None)
-        QCellWidget.deleteLater(self)
-
-    def updateContents(self, inputPorts):
-        """ updateContents(inputPorts: tuple)
-        Updates the cell contents with new vtkRenderer
-        
-        """
-        (renderView, ) = inputPorts
-        renWin = renderView.vtkInstance.GetRenderWindow()
-        renWin.DoubleBufferOn()
-        self.SetRenderWindow(renWin)
-        renderView.vtkInstance.ResetCamera()
-        self.addObserversToInteractorStyle()
-        
-#        renWin = self.GetRenderWindow()
-#        renderers = [renderView.vtkInstance.GetRenderer()]
-#        iren = renWin.GetInteractor()
-        # Update interactor style
-#         self.removeObserversFromInteractorStyle()
-#         if renderView==None:
-#             if iStyle==None:
-#                 iStyleInstance = vtk.vtkInteractorStyleTrackballCamera()
-#             else:
-#                 iStyleInstance = iStyle.vtkInstance
-#             iren.SetInteractorStyle(iStyleInstance)
-#         self.addObserversToInteractorStyle()
-        # Capture window into history for playback
-        # Call this at the end to capture the image after rendering
-        QCellWidget.updateContents(self, inputPorts)
-
-    def GetRenderWindow(self):
-        """ GetRenderWindow() -> vtkRenderWindow
-        Return the associated vtkRenderWindow
-        
-        """
-        if not self.mRenWin:
-            win = vtk.vtkRenderWindow()
-            win.DoubleBufferOn()
-            self.SetRenderWindow(win)
-            del win
-
-        return self.mRenWin
-
-    def SetRenderWindow(self,w):
-        """ SetRenderWindow(w: vtkRenderWindow)        
-        Set a new render window to QVTKViewWidget and initialize the
-        interactor as well
-        
-        """
-        if w == self.mRenWin:
-            return
-        
-        if self.mRenWin:
-            if self.mRenWin.GetMapped():
-                self.mRenWin.Finalize()
-                
-        self.mRenWin = w
-        
-        if self.mRenWin:
-            self.mRenWin.Register(None)
-            if system.systemType=='Linux':
-                try:
-                    vp = '_%s_void_p' % (hex(int(QtGui.QX11Info.display()))[2:])
-                except TypeError:
-                    #This was change for PyQt4.2
-                    if isinstance(QtGui.QX11Info.display(),QtGui.Display):
-                        display = sip.unwrapinstance(QtGui.QX11Info.display())
-                        vp = '_%s_void_p' % (hex(display)[2:])
-                self.mRenWin.SetDisplayId(vp)
-                if not self.mRenWin.GetMapped():
-                    self.mRenWin.GetInteractor().Initialize()
-                    system.XDestroyWindow(self.mRenWin.GetGenericDisplayId(),
-                                          self.mRenWin.GetGenericWindowId())
-                    self.mRenWin.Finalize()
-                self.mRenWin.SetWindowInfo(str(int(self.winId())))
-            else:
-                self.mRenWin.SetWindowInfo(str(int(self.winId())))                
-            if self.isVisible():
-                self.mRenWin.Start()
-
-    def GetInteractor(self):
-        """ GetInteractor() -> vtkInteractor
-        Return the vtkInteractor control this QVTKViewWidget
-        """
-        return self.GetRenderWindow().GetInteractor()
-
-    def event(self, e):
-        """ event(e: QEvent) -> depends on event type
-        Process window and interaction events
-        
-        """
-        if e.type()==QtCore.QEvent.ParentAboutToChange:
-            if self.mRenWin:
-                if self.mRenWin.GetMapped():
-                    self.mRenWin.Finalize()
-        else:
-            if e.type()==QtCore.QEvent.ParentChange:
-                if self.mRenWin:
-                    self.mRenWin.SetWindowInfo(str(int(self.winId())))
-                    if self.isVisible():
-                        self.mRenWin.Start()
-        
-        if QtCore.QObject.event(self,e):
-            return 1
-
-        if e.type() == QtCore.QEvent.KeyPress:
-            self.keyPressEvent(e)
-            if e.isAccepted():
-                return e.isAccepted()
-
-        return qt_super(QVTKViewWidget, self).event(e)
-        
-        # return QtGui.QWidget.event(self,e)
-        # Was this right? Wasn't this supposed to be QCellWidget.event()?
-
-    def resizeWindow(self, width, height):
-        """ resizeWindow(width: int, height: int) -> None
-        Work around vtk bugs for resizing window
-        
-        """
-        ########################################################
-        # VTK - BUGGGGGGGGG - GRRRRRRRRR
-        # This is a 'bug' in vtkWin32OpenGLRenderWindow(.cxx)
-        # If a render window is mapped to screen, the actual
-        # window size is the client area of the window in Win32.
-        # However, this real window size is only updated through
-        # vtkWin32OpenGLRenderWindow::GetSize(). So this has to
-        # be called here to get the cell size correctly. This
-        # invalidates the condition in the next SetSize().
-        # We can use self.mRenWin.SetSize(0,0) here but it will
-        # cause flickering and decrease performance!
-        # SetPosition(curX,curY) also works here but slower.
-        self.mRenWin.GetSize()
-        
-        self.mRenWin.SetSize(width, height)
-        if self.mRenWin.GetInteractor():
-            self.mRenWin.GetInteractor().SetSize(width, height)
-
-    def resizeEvent(self, e):
-        """ resizeEvent(e: QEvent) -> None
-        Re-adjust the vtkRenderWindow size then QVTKViewWidget resized
-        
-        """
-        qt_super(QVTKViewWidget, self).resizeEvent(e)
-        if not self.mRenWin:
-            return
-
-        self.resizeWindow(self.width(), self.height())
-        self.mRenWin.Render()
-
-    def moveEvent(self,e):
-        """ moveEvent(e: QEvent) -> None
-        Echo the move event into vtkRenderWindow
-        
-        """
-        qt_super(QVTKViewWidget, self).moveEvent(e)
-        if not self.mRenWin:
-            return
-
-        self.mRenWin.SetPosition(self.x(),self.y())
-
-    def paintEvent(self, e):
-        """ paintEvent(e: QPaintEvent) -> None
-        Paint the QVTKViewWidget with vtkRenderWindow
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        if hasattr(self.mRenWin, 'UpdateGLRegion'):
-            self.mRenWin.UpdateGLRegion()
-        self.mRenWin.Render()
-
-    def SelectActiveRenderer(self,iren):
-        """ SelectActiveRenderer(iren: vtkRenderWindowIteractor) -> None
-        Only make the vtkRenderer below the mouse cursor active
-        
-        """
-        epos = iren.GetEventPosition()
-        rens = iren.GetRenderWindow().GetRenderers()
-        rens.InitTraversal()
-        for i in xrange(rens.GetNumberOfItems()):
-            ren = rens.GetNextItem()
-            ren.SetInteractive(ren.IsInViewport(epos[0], epos[1]))
-
-    def mousePressEvent(self,e):
-        """ mousePressEvent(e: QMouseEvent) -> None
-        Echo mouse event to vtkRenderWindowwInteractor
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        ctrl = (e.modifiers()&QtCore.Qt.ControlModifier)
-        isDoubleClick = e.type()==QtCore.QEvent.MouseButtonDblClick
-        iren.SetEventInformationFlipY(e.x(),e.y(),
-                                      ctrl,
-                                      (e.modifiers()&QtCore.Qt.ShiftModifier),
-                                      chr(0),
-                                      isDoubleClick,
-                                      None)
-        invoke = {QtCore.Qt.LeftButton:"LeftButtonPressEvent",
-                  QtCore.Qt.MidButton:"MiddleButtonPressEvent",
-                  QtCore.Qt.RightButton:"RightButtonPressEvent"}
-
-        self.SelectActiveRenderer(iren)
-
-        if ctrl:
-            e.ignore()
-            return
-
-        self.interacting = self.getActiveRenderer(iren)
-        
-        if e.button() in invoke:
-            iren.InvokeEvent(invoke[e.button()])
-
-    def mouseMoveEvent(self,e):
-        """ mouseMoveEvent(e: QMouseEvent) -> None
-        Echo mouse event to vtkRenderWindowwInteractor
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        iren.SetEventInformationFlipY(e.x(),e.y(),
-                                      (e.modifiers()&QtCore.Qt.ControlModifier),
-                                      (e.modifiers()&QtCore.Qt.ShiftModifier),
-                                      chr(0), 0, None)
-
-        iren.InvokeEvent("MouseMoveEvent")
-                  
-    def enterEvent(self,e):
-        """ enterEvent(e: QEvent) -> None
-        Echo mouse event to vtkRenderWindowwInteractor
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        iren.InvokeEvent("EnterEvent")
-
-    def leaveEvent(self,e):
-        """ leaveEvent(e: QEvent) -> None
-        Echo mouse event to vtkRenderWindowwInteractor
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        iren.InvokeEvent("LeaveEvent")
-
-    def mouseReleaseEvent(self,e):
-        """ mouseReleaseEvent(e: QEvent) -> None
-        Echo mouse event to vtkRenderWindowwInteractor
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        iren.SetEventInformationFlipY(e.x(),e.y(),
-                                      (e.modifiers()&QtCore.Qt.ControlModifier),
-                                      (e.modifiers()&QtCore.Qt.ShiftModifier),
-                                      chr(0),0,None)
-
-        invoke = {QtCore.Qt.LeftButton:"LeftButtonReleaseEvent",
-                  QtCore.Qt.MidButton:"MiddleButtonReleaseEvent",
-                  QtCore.Qt.RightButton:"RightButtonReleaseEvent"}
-
-        self.interacting = None
-        
-        if e.button() in invoke:
-            iren.InvokeEvent(invoke[e.button()])
-
-    def keyPressEvent(self,e):
-        """ keyPressEvent(e: QKeyEvent) -> None
-        Disallow 'quit' key in vtkRenderWindowwInteractor and sync the others
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        ascii_key = None
-        if len(e.text())>0:
-            ascii_key = e.text()[0]
-        else:
-            ascii_key = chr(0)
-
-        keysym = self.ascii_to_key_sym(ord(ascii_key))
-
-        if not keysym:
-            keysym = self.qt_key_to_key_sym(e.key())
-
-        # Ignore 'q' or 'e' or Ctrl-anykey
-        ctrl = (e.modifiers()&QtCore.Qt.ControlModifier)
-        shift = (e.modifiers()&QtCore.Qt.ShiftModifier)
-        if (keysym in ['q', 'e'] or ctrl):
-            e.ignore()
-            return
-        
-        iren.SetKeyEventInformation(ctrl,shift,ascii_key, e.count(), keysym)
-
-        iren.InvokeEvent("KeyPressEvent")
-
-        if ascii_key:
-            iren.InvokeEvent("CharEvent")
-
-        
-    def keyReleaseEvent(self,e):
-        """ keyReleaseEvent(e: QKeyEvent) -> None
-        Disallow 'quit' key in vtkRenderWindowwInteractor and sync the others
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        ascii_key = None
-        if len(e.text())>0:
-            ascii_key = e.text()[0]
-        else:
-            ascii_key = chr(0)
-
-        keysym = self.ascii_to_key_sym(ord(ascii_key))
-
-        if not keysym:
-            keysym = self.qt_key_to_key_sym(e.key())
-
-        # Ignore 'q' or 'e' or Ctrl-anykey
-        ctrl = (e.modifiers()&QtCore.Qt.ControlModifier)
-        shift = (e.modifiers()&QtCore.Qt.ShiftModifier)
-        if (keysym in ['q','e'] or ctrl):
-            e.ignore()
-            return
-        
-        iren.SetKeyEventInformation(ctrl, shift, ascii_key, e.count(), keysym)
-
-        iren.InvokeEvent("KeyReleaseEvent")
-
-    def wheelEvent(self,e):
-        """ wheelEvent(e: QWheelEvent) -> None
-        Zoom in/out while scrolling the mouse
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        iren.SetEventInformationFlipY(e.x(),e.y(),
-                                      (e.modifiers()&QtCore.Qt.ControlModifier),
-                                      (e.modifiers()&QtCore.Qt.ShiftModifier),
-                                      chr(0),0,None)
-        
-        self.SelectActiveRenderer(iren)
-        
-        if e.delta()>0:
-            iren.InvokeEvent("MouseWheelForwardEvent")
-        else:
-            iren.InvokeEvent("MouseWheelBackwardEvent")
-
-    def focusInEvent(self,e):
-        """ focusInEvent(e: QFocusEvent) -> None
-        Ignore focus event
-        
-        """
-        pass
-
-    def focusOutEvent(self,e):
-        """ focusOutEvent(e: QFocusEvent) -> None
-        Ignore focus event
-        
-        """
-        pass
-
-    def contextMenuEvent(self,e):
-        """ contextMenuEvent(e: QContextMenuEvent) -> None        
-        Make sure to get the right mouse position for the context menu
-        event, i.e. also the right click
-        
-        """
-        iren = None
-        if self.mRenWin:
-            iren = self.mRenWin.GetInteractor()
-
-        if (not iren) or (not iren.GetEnabled()):
-            return
-
-        ctrl = int(e.modifiers()&QtCore.Qt.ControlModifier)
-        shift = int(e.modifiers()&QtCore.Qt.ShiftModifier)
-        iren.SetEventInformationFlipY(e.x(),e.y(),ctrl,shift,chr(0),0,None)
-        iren.InvokeEvent("ContextMenuEvent")
-
-    def ascii_to_key_sym(self,i):
-        """ ascii_to_key_sym(i: int) -> str
-        Convert ASCII code into key name
-        
-        """
-        global AsciiToKeySymTable
-        return AsciiToKeySymTable[i]
-
-    def qt_key_to_key_sym(self,i):
-        """ qt_key_to_key_sym(i: QtCore.Qt.Keycode) -> str
-        Convert Qt key code into key name
-        
-        """
-        handler = {QtCore.Qt.Key_Backspace:"BackSpace",
-                   QtCore.Qt.Key_Tab:"Tab",
-                   QtCore.Qt.Key_Backtab:"Tab",
-                   QtCore.Qt.Key_Return:"Return",
-                   QtCore.Qt.Key_Enter:"Return",
-                   QtCore.Qt.Key_Shift:"Shift_L",
-                   QtCore.Qt.Key_Control:"Control_L",
-                   QtCore.Qt.Key_Alt:"Alt_L",
-                   QtCore.Qt.Key_Pause:"Pause",
-                   QtCore.Qt.Key_CapsLock:"Caps_Lock",
-                   QtCore.Qt.Key_Escape:"Escape",
-                   QtCore.Qt.Key_Space:"space",
-                   QtCore.Qt.Key_End:"End",
-                   QtCore.Qt.Key_Home:"Home",
-                   QtCore.Qt.Key_Left:"Left",
-                   QtCore.Qt.Key_Up:"Up",
-                   QtCore.Qt.Key_Right:"Right",
-                   QtCore.Qt.Key_Down:"Down",
-                   QtCore.Qt.Key_SysReq:"Snapshot",
-                   QtCore.Qt.Key_Insert:"Insert",
-                   QtCore.Qt.Key_Delete:"Delete",
-                   QtCore.Qt.Key_Help:"Help",
-                   QtCore.Qt.Key_0:"0",
-                   QtCore.Qt.Key_1:"1",
-                   QtCore.Qt.Key_2:"2",
-                   QtCore.Qt.Key_3:"3",
-                   QtCore.Qt.Key_4:"4",
-                   QtCore.Qt.Key_5:"5",
-                   QtCore.Qt.Key_6:"6",
-                   QtCore.Qt.Key_7:"7",
-                   QtCore.Qt.Key_8:"8",
-                   QtCore.Qt.Key_9:"9",
-                   QtCore.Qt.Key_A:"a",
-                   QtCore.Qt.Key_B:"b",
-                   QtCore.Qt.Key_C:"c",
-                   QtCore.Qt.Key_D:"d",
-                   QtCore.Qt.Key_E:"e",
-                   QtCore.Qt.Key_F:"f",
-                   QtCore.Qt.Key_G:"g",
-                   QtCore.Qt.Key_H:"h",
-                   QtCore.Qt.Key_I:"i",
-                   QtCore.Qt.Key_J:"h",
-                   QtCore.Qt.Key_K:"k",
-                   QtCore.Qt.Key_L:"l",
-                   QtCore.Qt.Key_M:"m",
-                   QtCore.Qt.Key_N:"n",
-                   QtCore.Qt.Key_O:"o",
-                   QtCore.Qt.Key_P:"p",
-                   QtCore.Qt.Key_Q:"q",
-                   QtCore.Qt.Key_R:"r",
-                   QtCore.Qt.Key_S:"s",
-                   QtCore.Qt.Key_T:"t",
-                   QtCore.Qt.Key_U:"u",
-                   QtCore.Qt.Key_V:"v",
-                   QtCore.Qt.Key_W:"w",
-                   QtCore.Qt.Key_X:"x",
-                   QtCore.Qt.Key_Y:"y",
-                   QtCore.Qt.Key_Z:"z",
-                   QtCore.Qt.Key_Asterisk:"asterisk",
-                   QtCore.Qt.Key_Plus:"plus",
-                   QtCore.Qt.Key_Minus:"minus",
-                   QtCore.Qt.Key_Period:"period",
-                   QtCore.Qt.Key_Slash:"slash",
-                   QtCore.Qt.Key_F1:"F1",
-                   QtCore.Qt.Key_F2:"F2",
-                   QtCore.Qt.Key_F3:"F3",
-                   QtCore.Qt.Key_F4:"F4",
-                   QtCore.Qt.Key_F5:"F5",
-                   QtCore.Qt.Key_F6:"F6",
-                   QtCore.Qt.Key_F7:"F7",
-                   QtCore.Qt.Key_F8:"F8",
-                   QtCore.Qt.Key_F9:"F9",
-                   QtCore.Qt.Key_F10:"F10",
-                   QtCore.Qt.Key_F11:"F11",
-                   QtCore.Qt.Key_F12:"F12",
-                   QtCore.Qt.Key_F13:"F13",
-                   QtCore.Qt.Key_F14:"F14",
-                   QtCore.Qt.Key_F15:"F15",
-                   QtCore.Qt.Key_F16:"F16",
-                   QtCore.Qt.Key_F17:"F17",
-                   QtCore.Qt.Key_F18:"F18",
-                   QtCore.Qt.Key_F19:"F19",
-                   QtCore.Qt.Key_F20:"F20",
-                   QtCore.Qt.Key_F21:"F21",
-                   QtCore.Qt.Key_F22:"F22",
-                   QtCore.Qt.Key_F23:"F23",
-                   QtCore.Qt.Key_F24:"F24",
-                   QtCore.Qt.Key_NumLock:"Num_Lock",
-                   QtCore.Qt.Key_ScrollLock:"Scroll_Lock"}
-        if i in handler:            
-            return handler[i]
-        else:
-            return "None"
-
-    def getRendererList(self):
-        """ getRendererList() -> list
-        Return a list of vtkRenderer running in this QVTKViewWidget
-        """
-        result = []
-        renWin = self.GetRenderWindow()
-        renderers = renWin.GetRenderers()
-        renderers.InitTraversal()
-        for i in xrange(renderers.GetNumberOfItems()):
-            result.append(renderers.GetNextItem())
-        return result
-
-    def getActiveRenderer(self, iren):
-        """ getActiveRenderer(iren: vtkRenderWindowwInteractor) -> vtkRenderer
-        Return the active vtkRenderer under mouse
-        
-        """
-        epos = list(iren.GetEventPosition())
-        if epos[1]<0:
-            epos[1] = -epos[1]
-        rens = iren.GetRenderWindow().GetRenderers()
-        rens.InitTraversal()
-        for i in xrange(rens.GetNumberOfItems()):
-            ren = rens.GetNextItem()
-            if ren.IsInViewport(epos[0], epos[1]):
-                return ren
-        return None
-
-    def findSheetTabWidget(self):
-        """ findSheetTabWidget() -> QTabWidget
-        Find and return the sheet tab widget
-        
-        """
-        p = self.parent()
-        while p:
-            if hasattr(p, 'isSheetTabWidget'):
-                if p.isSheetTabWidget()==True:
-                    return p
-            p = p.parent()
-        return None
-
-    def getRenderersInCellList(self, sheet, cells):
-        """ isRendererIn(sheet: spreadsheet.StandardWidgetSheet,
-                         cells: [(int,int)]) -> bool
-        Get the list of renderers in side a list of (row, column)
-        cells.
-        
-        """
-        rens = []
-        for (row, col) in cells:
-            cell = sheet.getCell(row, col)
-            if hasattr(cell, 'getRendererList'):
-                rens += cell.getRendererList()
-        return rens
-
-    def getSelectedCellWidgets(self):
-        sheet = self.findSheetTabWidget()
-        if sheet:
-            iren = self.mRenWin.GetInteractor()
-            ren = self.interacting
-            if not ren: ren = self.getActiveRenderer(iren)
-            if ren:
-                cells = sheet.getSelectedLocations()
-                if (ren in self.getRenderersInCellList(sheet, cells)):
-                    return [sheet.getCell(row, col)
-                            for (row, col) in cells
-                            if hasattr(sheet.getCell(row, col), 
-                                       'getRendererList')]
-        return []
-
-    def interactionEvent(self, istyle, name):
-        """ interactionEvent(istyle: vtkInteractorStyle, name: str) -> None
-        Make sure interactions sync across selected renderers
-        
-        """
-        if name=='MouseWheelForwardEvent':
-            istyle.OnMouseWheelForward()
-        if name=='MouseWheelBackwardEvent':
-            istyle.OnMouseWheelBackward()
-        ren = self.interacting
-        if not ren:
-            ren = self.getActiveRenderer(istyle.GetInteractor())
-        if ren:
-            cam = ren.GetActiveCamera()
-            cpos = cam.GetPosition()
-            cfol = cam.GetFocalPoint()
-            cup = cam.GetViewUp()
-            for cell in self.getSelectedCellWidgets():
-                if cell!=self and hasattr(cell, 'getRendererList'): 
-                    rens = cell.getRendererList()
-                    for r in rens:
-                        if r!=ren:
-                            dcam = r.GetActiveCamera()
-                            dcam.SetPosition(cpos)
-                            dcam.SetFocalPoint(cfol)
-                            dcam.SetViewUp(cup)
-                            r.ResetCameraClippingRange()
-                    cell.update()
-
-    def charEvent(self, istyle, name):
-        """ charEvent(istyle: vtkInteractorStyle, name: str) -> None
-        Make sure key presses also sync across selected renderers
-
-        """
-        iren = istyle.GetInteractor()
-        ren = self.interacting
-        if not ren: ren = self.getActiveRenderer(iren)
-        if ren:
-            keyCode = iren.GetKeyCode()
-            if keyCode in ['w','W','s','S','r','R','p','P']:
-                for cell in self.getSelectedCellWidgets():
-                    if hasattr(cell, 'GetInteractor'):
-                        selectedIren = cell.GetInteractor()
-                        selectedIren.SetKeyCode(keyCode)
-                        selectedIren.GetInteractorStyle().OnChar()
-                        selectedIren.Render()
-            istyle.OnChar()
-
-    def saveToPNG(self, filename):
-        """ saveToPNG(filename: str) -> filename or vtkUnsignedCharArray
-        
-        Save the current widget contents to an image file. If
-        str==None, then it returns the vtkUnsignedCharArray containing
-        the PNG image. Otherwise, the filename is returned.
-        
-        """
-        w2i = vtk.vtkWindowToImageFilter()
-        w2i.ReadFrontBufferOff()
-        w2i.SetInput(self.mRenWin)
-        # Render twice to get a clean image on the back buffer
-        self.mRenWin.Render()
-        self.mRenWin.Render()
-        w2i.Update()
-        writer = vtk.vtkPNGWriter()
-        writer.SetInputConnection(w2i.GetOutputPort())
-        if filename!=None:
-            writer.SetFileName(filename)
-        else:
-            writer.WriteToMemoryOn()
-        writer.Write()
-        if filename:
-            return filename
-        else:
-            return writer.GetResult()
-
-    def captureWindow(self):
-        """ captureWindow() -> None        
-        Capture the window contents to file
-        
-        """
-        fn = QtGui.QFileDialog.getSaveFileName(None,
-                                               "Save file as...",
-                                               "screenshot.png",
-                                               "Images (*.png)")
-        if fn:
-            self.saveToPNG(fn)
-        
-    def grabWindowPixmap(self):
-        """ grabWindowImage() -> QPixmap
-        Widget special grabbing function
-        
-        """
-        uchar = self.saveToPNG(None)
-
-        ba = QtCore.QByteArray()
-        buf = QtCore.QBuffer(ba)
-        buf.open(QtCore.QIODevice.WriteOnly)
-        for i in xrange(uchar.GetNumberOfTuples()):
-            c = uchar.GetValue(i)
-            buf.putChar(chr(c))
-        buf.close()
-        
-        pixmap = QtGui.QPixmap()
-        pixmap.loadFromData(ba, 'PNG')
-        return pixmap
-
-    def dumpToFile(self, filename):
-        """dumpToFile() -> None
-        Dumps itself as an image to a file, calling saveToPNG
-        """
-        self.saveToPNG(filename)
-
-class QVTKViewWidgetCapture(QtGui.QAction):
-    """
-    QVTKViewWidgetCapture is the action to capture the vtk rendering
-    window to an image
-    
-    """
-    def __init__(self, parent=None):
-        """ QVTKViewWidgetCapture(parent: QWidget) -> QVTKViewWidgetCapture
-        Setup the image, status tip, etc. of the action
-        
-        """
-        QtGui.QAction.__init__(self,
-                               QtGui.QIcon(":/images/camera.png"),
-                               "&Capture image to file",
-                               parent)
-        self.setStatusTip("Capture the rendered image to a file")
-
-    def triggeredSlot(self, checked=False):
-        """ toggledSlot(checked: boolean) -> None
-        Execute the action when the button is clicked
-        
-        """
-        cellWidget = self.toolBar.getSnappedWidget()
-        cellWidget.captureWindow()
-
-class QVTKViewWidgetSaveCamera(QtGui.QAction):
-    """
-    QVTKViewWidgetSaveCamera is the action to capture the current camera
-    of the vtk renderers and save it back to the pipeline
-    
-    """
-    def __init__(self, parent=None):
-        """ QVTKViewWidgetSaveCamera(parent: QWidget) -> QVTKViewWidgetSaveCamera
-        Setup the image, status tip, etc. of the action
-        
-        """
-        QtGui.QAction.__init__(self,
-                               "Save &Camera",
-                               parent)
-        self.setStatusTip("Save current camera views to the pipeline")
-
-    def setCamera(self, controller):
-        ops = []
-        pipeline = controller.current_pipeline                        
-        cellWidget = self.toolBar.getSnappedWidget()
-        renderers = cellWidget.getRendererList()
-        for ren in renderers:
-            cam = ren.GetActiveCamera()
-            cpos = cam.GetPosition()
-            cfol = cam.GetFocalPoint()
-            cup = cam.GetViewUp()
-            rendererId = cellWidget.renderer_maps[ren]
-            # Looking for SetActiveCamera()
-            camera = None
-            renderer = pipeline.modules[rendererId]
-            for c in pipeline.connections.values():
-                if c.destination.moduleId==rendererId:
-                    if c.destination.name=='SetActiveCamera':
-                        camera = pipeline.modules[c.source.moduleId]
-                        break
-            
-            if not camera:
-                # Create camera
-                vtk_package = vtk_pkg_identifier
-                camera = controller.create_module(vtk_package, 'vtkCamera', '',
-                                                  0.0, 0.0)
-                ops.append(('add', camera))
-
-                # Connect camera to renderer
-                camera_conn = controller.create_connection(camera, 'self',
-                                                           renderer, 
-                                                           'SetActiveCamera')
-                ops.append(('add', camera_conn))
-            # update functions
-            def convert_to_str(arglist):
-                new_arglist = []
-                for arg in arglist:
-                    new_arglist.append(str(arg))
-                return new_arglist
-            functions = [('SetPosition', convert_to_str(cpos)),
-                         ('SetFocalPoint', convert_to_str(cfol)),
-                         ('SetViewUp', convert_to_str(cup))]
-            ops.extend(controller.update_functions_ops(camera, functions))
-
-        action = vistrails.core.db.action.create_action(ops)
-        controller.add_new_action(action)
-        controller.perform_action(action)
-        controller.select_latest_version()
-
-    def triggeredSlot(self, checked=False):
-        """ toggledSlot(checked: boolean) -> None
-        Execute the action when the button is clicked
-        
-        """
-        visApp = QtCore.QCoreApplication.instance()
-        if hasattr(visApp, 'builderWindow'):
-            builderWindow = visApp.builderWindow
-            if builderWindow:
-                info = self.toolBar.sheet.getCellPipelineInfo(
-                    self.toolBar.row, self.toolBar.col)
-                if info:
-                    info = info[0]
-                    viewManager = builderWindow.viewManager
-                    view = viewManager.ensureController(info['controller'])
-                    if view:
-                        controller = view.controller
-                        controller.change_selected_version(info['version'])
-                        self.setCamera(controller)
-                
-class QVTKViewWidgetToolBar(QCellToolBar):
-    """
-    QVTKViewWidgetToolBar derives from QCellToolBar to give the VTKViewCell
-    a customizable toolbar
-    
-    """
-    def createToolBar(self):
-        """ createToolBar() -> None
-        This will get call initiallly to add customizable widgets
-        
-        """
-        self.appendAction(QVTKViewWidgetCapture(self))
-        self.addAnimationButtons()
-        self.appendAction(QVTKViewWidgetSaveCamera(self))
-
-def registerSelf():
-    """ registerSelf() -> None
-    Registry module with the registry
-    """
-    registry = get_module_registry()
-    registry.add_module(VTKViewCell)
-    registry.add_input_port(VTKViewCell, "Location", CellLocation)
-    import vistrails.core.debug
-    for (port,module) in [("SetRenderView",'vtkRenderView')]:
-        try:
-            registry.add_input_port(VTKViewCell, port,'(%s:%s)'% \
-                                        (vtk_pkg_identifier, module))
- 
-        except Exception, e:
-            vistrails.core.debug.warning(str(e))
-
-    registry.add_output_port(VTKViewCell, "self", VTKViewCell)
diff --git a/vistrails/packages/vtlcreator/__init__.py b/vistrails/packages/vtlcreator/__init__.py
index a3b950f..a23d16e 100644
--- a/vistrails/packages/vtlcreator/__init__.py
+++ b/vistrails/packages/vtlcreator/__init__.py
@@ -1,40 +1,43 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """This package contains a module that generates a .vtl file for the 
 workflow it is contained into."""
 
+from __future__ import division
+
 identifier = 'org.vistrails.vistrails.vtlcreator'
 name = 'vtlCreator'
 version = '0.0.4'
diff --git a/vistrails/packages/vtlcreator/init.py b/vistrails/packages/vtlcreator/init.py
index 9a1ae0f..f1ef78a 100644
--- a/vistrails/packages/vtlcreator/init.py
+++ b/vistrails/packages/vtlcreator/init.py
@@ -1,37 +1,40 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
+from __future__ import division
+
 import base64
 import os
 import vistrails.core.db.action
@@ -137,32 +140,32 @@ class VtlFileCreator(NotCacheable, Module):
     def compute(self):
         self.get_locator_and_version()
         
-        if self.hasInputFromPort('execute'):
-            self.execute = self.getInputFromPort('execute')
+        if self.has_input('execute'):
+            self.execute = self.get_input('execute')
         
-        if self.hasInputFromPort('forceDB'):
-            self.forceDB = self.getInputFromPort('forceDB')
+        if self.has_input('forceDB'):
+            self.forceDB = self.get_input('forceDB')
         
-        if self.hasInputFromPort('showSpreadsheetOnly'):
-            self.showSpreadsheetOnly = self.getInputFromPort('showSpreadsheetOnly')
+        if self.has_input('showSpreadsheetOnly'):
+            self.showSpreadsheetOnly = self.get_input('showSpreadsheetOnly')
             
-        if self.hasInputFromPort('embedWorkflow'):
-            self.embedWorkflow = self.getInputFromPort('embedWorkflow')
+        if self.has_input('embedWorkflow'):
+            self.embedWorkflow = self.get_input('embedWorkflow')
         
         xmlstring = self.generate_vtl(self.locator,self.version,self.pipeline,
                                       self.execute,self.forceDB,
                                       self.showSpreadsheetOnly,self.embedWorkflow)
         
-        if self.hasInputFromPort('filename'):
-            filename = self.getInputFromPort('filename')
-            if self.hasInputFromPort('directory'):
-                directory = self.getInputFromPort('directory').name
+        if self.has_input('filename'):
+            filename = self.get_input('filename')
+            if self.has_input('directory'):
+                directory = self.get_input('directory').name
                 filename = os.path.join(directory,filename)
             file_ = open(filename,'w')
             file_.write(xmlstring)
             file_.close()
         
-        self.setResult("xmlstring", xmlstring)
+        self.set_output("xmlstring", xmlstring)
         
     _input_ports = [('execute', Boolean, True), 
                     ('showspreadsheetOnly', Boolean, True),
diff --git a/vistrails/packages/webServices/__init__.py b/vistrails/packages/webServices/__init__.py
index 9049569..b18b4d2 100644
--- a/vistrails/packages/webServices/__init__.py
+++ b/vistrails/packages/webServices/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -57,6 +58,8 @@ ChangeLog
     * Updated package to version 0.9.1 
     * Expanded map of simple types
 """
+from __future__ import division
+
 from vistrails.core.configuration import ConfigurationObject
 import vistrails.core
 
diff --git a/vistrails/packages/webServices/enumeration_widget.py b/vistrails/packages/webServices/enumeration_widget.py
index 4712bd2..e8ac8ce 100644
--- a/vistrails/packages/webServices/enumeration_widget.py
+++ b/vistrails/packages/webServices/enumeration_widget.py
@@ -1,50 +1,55 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
 ##############################################################################
 # Enumeration Widget for Web Services
+from __future__ import division
+
 from PyQt4 import QtCore, QtGui
-import vistrails.core.modules
-from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin, \
-    StandardConstantWidget
-from vistrails.core.modules.basic_modules import Constant, Module
-import vistrails.core.modules.module_registry
+
+from vistrails.core.modules.basic_modules import Constant
+from vistrails.core.modules.module_registry import get_module_registry
 from vistrails.core.modules.vistrails_module import new_module
+from vistrails.gui.modules.constant_configuration import ConstantWidgetMixin
+
 import vistrails.packages.webServices
 
+
 class EnumerationWidget(QtGui.QComboBox, ConstantWidgetMixin):
+    contentsChanged = QtCore.pyqtSignal(tuple)
     enumerationlist = []
     def __init__(self, param, parent=None):
         """__init__(param: core.vistrail.module_param.ModuleParam,
@@ -78,38 +83,23 @@ class EnumerationWidget(QtGui.QComboBox, ConstantWidgetMixin):
     
     def change_state(self, state):
         self.update_parent()
-    
-def initialize(namemodule,namespace,identifier, version):
-    enumerationConstant = new_constant(namemodule,
-                                            namespace,
-                                            identifier,
-                                            version,
-                                            EnumerationWidget)
-    return enumerationConstant
-
-def new_constant(name, namespace, identifier, 
-                 version, widget_type=StandardConstantWidget):
-    """new_constant(name: str, namespace: str,widget_type: QWidget type) -> Module
-    
-    new_constant dynamically creates a new Module derived from Constant
-    with a widget type."""
-    reg = vistrails.core.modules.module_registry.get_module_registry()
-    
-    def __init__(self):
-        Constant.__init__(self)
 
     @staticmethod
     def get_widget_class():
-        return widget_type
+        return EnumerationWidget
 
     @staticmethod
-    def conversion(self): return self
-    
-    m = new_module(Constant, name, {'__init__': __init__,
-                                    'get_widget_class': get_widget_class,
-                                    'translate_to_python': conversion})
-    m.name = name
-    m.isEnumeration = True
-    reg.add_module(m,namespace=namespace,package=identifier,
+    def translate_to_python(self):
+        return self
+
+
+def initialize(namemodule,namespace,identifier, version):
+    reg = get_module_registry()
+
+    enumerationConstant = new_module(Constant, namemodule, {})
+    enumerationConstant.name = namemodule
+    enumerationConstant.isEnumeration = True
+    reg.add_module(enumerationConstant, namespace=namespace, package=identifier,
                    package_version=version)
-    return m
+
+    return enumerationConstant
diff --git a/vistrails/packages/webServices/init.py b/vistrails/packages/webServices/init.py
index f9165bc..884260a 100644
--- a/vistrails/packages/webServices/init.py
+++ b/vistrails/packages/webServices/init.py
@@ -1,38 +1,41 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 
+from __future__ import division
+
 import sys
 import os.path
 import httplib
@@ -125,7 +128,7 @@ def webServiceTypesDict(WBobj):
             nameattrib = nameattrib[0].upper() + nameattrib[1:]
             sentence = "visobj" + "." + nameattrib
             visdata = eval(sentence)
-            if visdata != None:
+            if visdata is not None:
                 try:
                     Type = wsdlTypesDict[str(typechild)]
                     setattr(libobj,nameattrib,visdata)
@@ -148,7 +151,7 @@ def webServiceTypesDict(WBobj):
                 nameattribute = nameattrib[0].upper() + nameattrib[1:]
                 sentence = "visobj" + "." + nameattribute
                 visdata = eval(sentence)
-                if visdata != None:
+                if visdata is not None:
                     nameattrib = "attribute_typecode_dict[" + nameattrib + "].pname"
                     setattr(libobj,nameattrib,visdata)
 
@@ -157,11 +160,11 @@ def webServiceTypesDict(WBobj):
         #Check if it is an enumeration
         if WBobj.typeobj == 'Enumeration':
             nameport = str(WBobj.ports[0][0])
-            if self.hasInputFromPort(nameport):
-                inputport = self.getInputFromPort(nameport)
+            if self.has_input(nameport):
+                inputport = self.get_input(nameport)
                 self.holder = inputport
-                self.setResult(WBobj.name,self)
-                self.setResult('self',self)
+                self.set_output(WBobj.name,self)
+                self.set_output('self',self)
         else:
             #Check if it is a request type
             modbyname = reg.get_module_by_name(identifier = identifier, name = WBobj.name, namespace = WBobj.namespace)
@@ -187,9 +190,9 @@ def webServiceTypesDict(WBobj):
                 #Set the values of the input ports in the resquest object
                 for types in WBobj.ports:
                     nameport = str(types[0])
-                    if self.hasInputFromPort(nameport):
+                    if self.has_input(nameport):
                         #We need to distinguish between simple and complex types.
-                        inputport = self.getInputFromPort(nameport)
+                        inputport = self.get_input(nameport)
                         try:
                             Type = str(types[1])
                             if isArray(Type):
@@ -218,8 +221,8 @@ def webServiceTypesDict(WBobj):
                 if WBobj.hasAttributes:
                     for types in WBobj.attributes:
                         nameport = str(types[0])
-                        if self.hasInputFromPort(nameport):
-                            inputport = self.getInputFromPort(nameport)
+                        if self.has_input(nameport):
+                            inputport = self.get_input(nameport)
                             Type = wsdlTypesDict[str(types[1])]
                             nameattrib = "attribute_typecode_dict[" + nameport + "].pname"
                             setattr(req, nameattrib,inputport)
@@ -236,8 +239,8 @@ def webServiceTypesDict(WBobj):
                         if str(WBobj.name.strip()) == str(attributes[0].strip()):
                             nameport = WBobj.vistrailsname
                             break
-                self.setResult(nameport,req)
-                self.setResult('self',req)
+                self.set_output(nameport,req)
+                self.set_output('self',req)
             else:
                 nameport = str(WBobj.name)
                 for ports in WBobj.ports:
@@ -249,36 +252,36 @@ def webServiceTypesDict(WBobj):
                         if str(WBobj.name.strip()) == str(attributes[0].strip()):
                             nameport = WBobj.vistrailsname
                             break
-                if self.hasInputFromPort(nameport):
+                if self.has_input(nameport):
                     #Output modules
-                    inputport = self.getInputFromPort(nameport)
+                    inputport = self.get_input(nameport)
                     for nameport in WBobj.ports:
                         nameattrib = nameport[0][0].upper() + nameport[0][1:]
                         sentence = "inputport" + "." + nameattrib
                         outputport = eval(sentence)
-                        self.setResult(nameport[0],outputport)
+                        self.set_output(nameport[0],outputport)
                     if WBobj.hasAttributes:
                         for attributes in WBobj.attributes:
                             nameattrib = attributes[0][0].upper() + attributes[0][1:]
                             sentence = "inputport" + "." + nameattrib
                             outputport = eval(sentence)
-                            self.setResult(attributes[0],outputport)
-                elif self.hasInputFromPort('self'):
+                            self.set_output(attributes[0],outputport)
+                elif self.has_input('self'):
                     #Now we use the 'self' input port name
                     #we keep the old for backwards compatibility
                     #Output modules
-                    inputport = self.getInputFromPort('self')
+                    inputport = self.get_input('self')
                     for nameport in WBobj.ports:
                         nameattrib = nameport[0][0].upper() + nameport[0][1:]
                         sentence = "inputport" + "." + nameattrib
                         outputport = eval(sentence)
-                        self.setResult(nameport[0],outputport)
+                        self.set_output(nameport[0],outputport)
                     if WBobj.hasAttributes:
                         for attributes in WBobj.attributes:
                             nameattrib = attributes[0][0].upper() + attributes[0][1:]
                             sentence = "inputport" + "." + nameattrib
                             outputport = eval(sentence)
-                            self.setResult(attributes[0],outputport)
+                            self.set_output(attributes[0],outputport)
                 else:    
                     #Set the values in the input ports
                     #Input modules
@@ -286,8 +289,8 @@ def webServiceTypesDict(WBobj):
                         nameport = str(types[0])
                         nameattrib = str(nameport)
                         nameattrib = nameattrib[0].upper() + nameattrib[1:]
-                        if self.hasInputFromPort(nameport):
-                            inputport = self.getInputFromPort(nameport)
+                        if self.has_input(nameport):
+                            inputport = self.get_input(nameport)
                             setattr(self,nameattrib,inputport)
                         else:
                             setattr(self,nameattrib,None)
@@ -296,8 +299,8 @@ def webServiceTypesDict(WBobj):
                             nameport = str(types[0])
                             nameattrib = str(nameport)
                             nameattrib = nameattrib[0].upper() + nameattrib[1:]
-                            if self.hasInputFromPort(nameport):
-                                inputport = self.getInputFromPort(nameport)
+                            if self.has_input(nameport):
+                                inputport = self.get_input(nameport)
                                 setattr(self,nameattrib,inputport)
                             else:
                                 setattr(self,nameattrib,None)
@@ -313,8 +316,8 @@ def webServiceTypesDict(WBobj):
                             if str(WBobj.name.strip()) == str(attributes[0].strip()):
                                 nameport = WBobj.vistrailsname
                                 break
-                    self.setResult(nameport,self)
-                    self.setResult('self',self)
+                    self.set_output(nameport,self)
+                    self.set_output('self',self)
 
     return {'compute':compute}
 
@@ -330,7 +333,7 @@ def webServiceParamsMethodDict(name, server, inparams, outparams):
         if isinstance(resp, list):
             ptype = resp[0].typecode.type[1]
         else:
-            if resp.typecode.type[1] == None:
+            if resp.typecode.type[1] is None:
                 ptype = resp.typecode.pname
             else:    
                 ptype = resp.typecode.type[1]
@@ -434,14 +437,11 @@ def webServiceParamsMethodDict(name, server, inparams, outparams):
                 if str(element.name) == str(name):
                     #get the request method name
                     reqname = element.input.getMessage().name
-            try:
-                req = getattr(self.modclient,reqname)()
-            except:
-                print "sys.exc_value: ", sys.exc_value
+            req = getattr(self.modclient,reqname)()
             for inparam in inparams:
                 #Now set all attributes for the request object
-                if self.hasInputFromPort(inparam.name):
-                    inputport = self.getInputFromPort(inparam.name)
+                if self.has_input(inparam.name):
+                    inputport = self.get_input(inparam.name)
                     namemethod = "set_element_" + inparam.name
                     try:
                         getattr(req, namemethod)(inputport)
@@ -461,12 +461,12 @@ def webServiceParamsMethodDict(name, server, inparams, outparams):
                 namemethod = outparams[0].name
                 sentence = "resp" + "." + namemethod
                 result = eval(sentence)
-            self.setResult(outparams[0].name,result)
+            self.set_output(outparams[0].name,result)
         except KeyError:
             #This part is for the complex types methods parameters
             inparam = str(inparams[0].name)
-            if self.hasInputFromPort(inparam):
-                request = self.getInputFromPort(inparam)
+            if self.has_input(inparam):
+                request = self.get_input(inparam)
                 try:
                     resp = getattr(port,name)(request)
                 except:
@@ -483,7 +483,7 @@ def webServiceParamsMethodDict(name, server, inparams, outparams):
                                                   namespace=obj.namespace)
                 visobj = visclass()
                 wrapResponseobj(self,resp, visobj)
-                self.setResult(outparams[0].name,visobj)
+                self.set_output(outparams[0].name,visobj)
 
     return {'compute':compute}
 
@@ -553,12 +553,12 @@ def processType(complexschema,w):
 
     if complexschema.isElement():
         try:
-            if complexschema.content.content == None:
+            if complexschema.content.content is None:
                 contentschema = []
             else:    
                 contentschema = complexschema.content.content.content
             objModule.typeobj = 'ComplexType'
-            if (complexschema.content.content == None or
+            if (complexschema.content.content is None or
                 complexschema.content.content.content == ()):
                 objModule.isEmptySequence = True
         except AttributeError:
@@ -577,7 +577,7 @@ def processType(complexschema,w):
             contentschema = complexschema.content.content
     try:       
         #Get all the attributes of the complex type
-        if complexschema.attr_content != None:
+        if complexschema.attr_content is not None:
             for attribute in complexschema.attr_content:
                 nametype = attribute.getAttributeName()
                 Type = 'string'
@@ -985,10 +985,8 @@ be loaded again." % w
         directoryname = directoryname.replace(".","_")
         directoryname = directoryname.replace("%","_")
         directoryname = directoryname.replace("+","_")
-        package_subdirectory = os.path.join(package_directory, directoryname)
         wsm = WriteServiceModule(wsdl)
         client_mod = wsm.getClientModuleName()
-        types_mod = wsm.getTypesModuleName()
 
         #import the stub generated files
         try:
@@ -1340,17 +1338,17 @@ def verify_wsdl(wsdlList):
         response = conn.getresponse()
         remoteHeader = response.msg.getheader('last-modified')
         isoutdated = False
-        if remoteHeader != None:
+        if remoteHeader is not None:
             localFile = client_file
             reg = vistrails.core.modules.module_registry.get_module_registry()
             httpfile = reg.get_descriptor_by_name(
-                'org.vistrails.vistrails.http', 'HTTPFile').module()
+                'org.vistrails.vistrails.url', 'DownloadFile').module()
             try:
                 isoutdated = httpfile._is_outdated(remoteHeader, localFile)
             except OSError:
                 print "File doesn't exist"
                 isoutdated = True
-        if isoutdated or remoteHeader == None:
+        if isoutdated or remoteHeader is None:
             outdated_list.append(w)
         else:
             updated_list.append(w)
@@ -1362,18 +1360,11 @@ def initialize(*args, **keywords):
     global webServicesmodulesDict
     global complexsdict
     wsdlList = []
-    if configuration.showWarning == True:
-        msg = "The Web Services package is deprecated and will be removed from \
-next VisTrails release. Please consider using the new SUDS Web Services package. \
-This message will not be shown again."
-        pm.show_error_message(pm.get_package(identifier),msg)
-        try:
-            from vistrails.gui.application import get_vistrails_application
-            if get_vistrails_application() is not None:
-                configuration.showWarning = False
-                VisTrailsApplication.save_configuration()
-        except:
-            pass
+    if configuration.showWarning:
+        msg = ("The Web Services package is deprecated and will be removed "
+               "from the next VisTrails release. Please consider using the "
+               "new SUDS Web Services package.")
+        pm.show_error_message(pm.get_package(identifier), msg)
     if configuration.check('wsdlList'):
         wsdlList = configuration.wsdlList.split(";")
 
diff --git a/vistrails/run.py b/vistrails/run.py
index a5034de..90ca401 100644
--- a/vistrails/run.py
+++ b/vistrails/run.py
@@ -1,40 +1,44 @@
 #!/usr/bin/env python
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
 """Main file for the VisTrails distribution."""
 
+from __future__ import division
+
 import os
 import sys
 
@@ -108,19 +112,26 @@ def fix_paths():
     if vistrails_dir not in sys.path:
         sys.path.insert(0, vistrails_dir)
 
-if __name__ == '__main__':
+def main():
     fix_paths()
     disable_lion_restore()
     fix_site()
 
+    # Load the default locale (from environment)
+    import locale
+    locale.setlocale(locale.LC_ALL, '')
+
+    # Log to the console
+    from vistrails.core import debug
+    debug.DebugPrint.getInstance().log_to_console()
+
     from vistrails.gui.requirements import require_pyqt4_api2
     require_pyqt4_api2()
 
-    from PyQt4 import QtGui
     import vistrails.gui.application
     from vistrails.core.application import APP_SUCCESS, APP_FAIL, APP_DONE
     try:
-        v = vistrails.gui.application.start_application()
+        v = vistrails.gui.application.start_application(args=sys.argv[1:])
         if v != APP_SUCCESS:
             app = vistrails.gui.application.get_vistrails_application()
             if app:
@@ -136,13 +147,17 @@ if __name__ == '__main__':
         app = vistrails.gui.application.get_vistrails_application()
         if app:
             app.finishSession()
-        print "Uncaught exception on initialization: %s" % e
         import traceback
-        traceback.print_exc()
+        print >>sys.stderr, "Uncaught exception on initialization: %s" % (
+                traceback._format_final_exc_line(type(e).__name__, e).strip())
+        traceback.print_exc(None, sys.stderr)
         sys.exit(255)
-    if (app.temp_configuration.interactiveMode and
-        not app.temp_configuration.check('spreadsheetDumpCells')): 
+    if (not app.temp_configuration.batch and
+        not app.temp_configuration.check('outputDirectory')):
         v = app.exec_()
-        
+
     vistrails.gui.application.stop_application()
     sys.exit(v)
+
+if __name__ == '__main__':
+    main()
diff --git a/vistrails/stop_vistrails_server.py b/vistrails/stop_vistrails_server.py
index 2eb817e..911dffa 100644
--- a/vistrails/stop_vistrails_server.py
+++ b/vistrails/stop_vistrails_server.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/__init__.py b/vistrails/tests/__init__.py
index 4808ee9..3cc08c9 100644
--- a/vistrails/tests/__init__.py
+++ b/vistrails/tests/__init__.py
@@ -1,50 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
-
-class NotModule(Exception):
-    """This is a special exception that is caught by the testing
-    infrastructure. If a particular python file is not meant to be
-    imported as a module, that file should have the following lines:
-
-    if __name__ != '__main__':
-        from vistrails.tests import NotModule
-        raise NotModule('This should not be imported as a module')
-
-    This way, the testing infrastructure will know not to report failure
-    to import that file as an error.
-    """
-
-    pass
-
diff --git a/vistrails/tests/__main__.py b/vistrails/tests/__main__.py
new file mode 100644
index 0000000..082ffe1
--- /dev/null
+++ b/vistrails/tests/__main__.py
@@ -0,0 +1,4 @@
+# pragma: no testimport
+
+# This files allows one to run python -m vistrails.tests
+import vistrails.tests.runtestsuite
diff --git a/vistrails/tests/resources/__init__.py b/vistrails/tests/resources/__init__.py
index 86c4a06..8a88e1e 100644
--- a/vistrails/tests/resources/__init__.py
+++ b/vistrails/tests/resources/__init__.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/console_mode_test.py b/vistrails/tests/resources/console_mode_test.py
index 6e7c899..e49f726 100644
--- a/vistrails/tests/resources/console_mode_test.py
+++ b/vistrails/tests/resources/console_mode_test.py
@@ -1,34 +1,35 @@
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -49,8 +50,8 @@ old_identifiers = ['edu.utah.sci.vistrails.console_mode_test']
 class TestTupleExecution(Module):
 
     def compute(self):
-        v1, v2 = self.getInputFromPort('input')
-        self.setResult('output', v1 + v2)
+        v1, v2 = self.get_input('input')
+        self.set_output('output', v1 + v2)
 
 
 class TestDynamicModuleError(Module):
@@ -65,8 +66,8 @@ class TestDynamicModuleError(Module):
 class TestChangeVistrail(NotCacheable, Module):
 
     def compute(self):
-        if self.hasInputFromPort('foo'):
-            v1 = self.getInputFromPort('foo')
+        if self.has_input('foo'):
+            v1 = self.get_input('foo')
         else:
             v1 = 0
         if v1 != 12:
diff --git a/vistrails/tests/resources/dummy.xml b/vistrails/tests/resources/dummy.xml
index bb546b4..05f589c 100644
--- a/vistrails/tests/resources/dummy.xml
+++ b/vistrails/tests/resources/dummy.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/dummy_broken.xml b/vistrails/tests/resources/dummy_broken.xml
index 0d17a63..57316c4 100644
--- a/vistrails/tests/resources/dummy_broken.xml
+++ b/vistrails/tests/resources/dummy_broken.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/dummy_new.xml b/vistrails/tests/resources/dummy_new.xml
index b342d08..7bb6411 100644
--- a/vistrails/tests/resources/dummy_new.xml
+++ b/vistrails/tests/resources/dummy_new.xml
@@ -1,35 +1,36 @@
 <?xml version="1.0" ?>
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/dynamic_module_error.xml b/vistrails/tests/resources/dynamic_module_error.xml
index 1215d17..ef12802 100644
--- a/vistrails/tests/resources/dynamic_module_error.xml
+++ b/vistrails/tests/resources/dynamic_module_error.xml
@@ -1,35 +1,36 @@
 <?xml version="1.0" ?>
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/empty_bookmarks.xml b/vistrails/tests/resources/empty_bookmarks.xml
index 45ff5f3..1b4d366 100644
--- a/vistrails/tests/resources/empty_bookmarks.xml
+++ b/vistrails/tests/resources/empty_bookmarks.xml
@@ -1,34 +1,35 @@
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/import_pkg/__init__.py b/vistrails/tests/resources/import_pkg/__init__.py
index e69de29..199126c 100644
--- a/vistrails/tests/resources/import_pkg/__init__.py
+++ b/vistrails/tests/resources/import_pkg/__init__.py
@@ -0,0 +1 @@
+# pragma: no testimport
diff --git a/vistrails/tests/resources/import_pkg/test_import_pkg/__init__.py b/vistrails/tests/resources/import_pkg/test_import_pkg/__init__.py
index ae172b9..35c9500 100644
--- a/vistrails/tests/resources/import_pkg/test_import_pkg/__init__.py
+++ b/vistrails/tests/resources/import_pkg/test_import_pkg/__init__.py
@@ -1,3 +1,4 @@
+# pragma: no testimport
 name = 'test_import_pkg'
 identifier = 'org.vistrails.tests.test_import_pkg'
 version = '0.42'
diff --git a/vistrails/tests/resources/import_pkg/test_import_pkg/init.py b/vistrails/tests/resources/import_pkg/test_import_pkg/init.py
index 1d4ff55..b5f4659 100644
--- a/vistrails/tests/resources/import_pkg/test_import_pkg/init.py
+++ b/vistrails/tests/resources/import_pkg/test_import_pkg/init.py
@@ -1 +1,2 @@
+# pragma: no testimport
 import module2
diff --git a/vistrails/tests/resources/import_pkg/test_import_pkg/module1.py b/vistrails/tests/resources/import_pkg/test_import_pkg/module1.py
index f3f9c43..56bec5f 100644
--- a/vistrails/tests/resources/import_pkg/test_import_pkg/module1.py
+++ b/vistrails/tests/resources/import_pkg/test_import_pkg/module1.py
@@ -1,2 +1,3 @@
+# pragma: no testimport
 import vistrails.tests.resources.import_targets.test3
 import tests.resources.import_targets.test4
diff --git a/vistrails/tests/resources/import_pkg/test_import_pkg/module2.py b/vistrails/tests/resources/import_pkg/test_import_pkg/module2.py
index 0f295a5..fe765ac 100644
--- a/vistrails/tests/resources/import_pkg/test_import_pkg/module2.py
+++ b/vistrails/tests/resources/import_pkg/test_import_pkg/module2.py
@@ -1,2 +1,3 @@
+# pragma: no testimport
 import vistrails.tests.resources.import_targets.test5
 import tests.resources.import_targets.test6
diff --git a/vistrails/tests/resources/import_targets/__init__.py b/vistrails/tests/resources/import_targets/__init__.py
index 65a1ff1..fecdaef 100644
--- a/vistrails/tests/resources/import_targets/__init__.py
+++ b/vistrails/tests/resources/import_targets/__init__.py
@@ -1,3 +1,4 @@
+# pragma: no testimport
 """This is a target for importing a non-package module.
 
 It is used in the PackageManager's tests to check that the dependency-tracking
diff --git a/vistrails/tests/resources/import_targets/test1.py b/vistrails/tests/resources/import_targets/test1.py
index 3a2255a..917f017 100644
--- a/vistrails/tests/resources/import_targets/test1.py
+++ b/vistrails/tests/resources/import_targets/test1.py
@@ -1,3 +1,4 @@
+# pragma: no testimport
 try:
     import core.packagemanager
 except ImportError:
diff --git a/vistrails/tests/resources/import_targets/test2.py b/vistrails/tests/resources/import_targets/test2.py
index e69de29..199126c 100644
--- a/vistrails/tests/resources/import_targets/test2.py
+++ b/vistrails/tests/resources/import_targets/test2.py
@@ -0,0 +1 @@
+# pragma: no testimport
diff --git a/vistrails/tests/resources/import_targets/test3.py b/vistrails/tests/resources/import_targets/test3.py
index e69de29..199126c 100644
--- a/vistrails/tests/resources/import_targets/test3.py
+++ b/vistrails/tests/resources/import_targets/test3.py
@@ -0,0 +1 @@
+# pragma: no testimport
diff --git a/vistrails/tests/resources/import_targets/test4.py b/vistrails/tests/resources/import_targets/test4.py
index e69de29..199126c 100644
--- a/vistrails/tests/resources/import_targets/test4.py
+++ b/vistrails/tests/resources/import_targets/test4.py
@@ -0,0 +1 @@
+# pragma: no testimport
diff --git a/vistrails/tests/resources/import_targets/test5.py b/vistrails/tests/resources/import_targets/test5.py
index e69de29..199126c 100644
--- a/vistrails/tests/resources/import_targets/test5.py
+++ b/vistrails/tests/resources/import_targets/test5.py
@@ -0,0 +1 @@
+# pragma: no testimport
diff --git a/vistrails/tests/resources/import_targets/test6.py b/vistrails/tests/resources/import_targets/test6.py
index e69de29..199126c 100644
--- a/vistrails/tests/resources/import_targets/test6.py
+++ b/vistrails/tests/resources/import_targets/test6.py
@@ -0,0 +1 @@
+# pragma: no testimport
diff --git a/vistrails/tests/resources/pythonsource.xml b/vistrails/tests/resources/pythonsource.xml
index cb95484..a7cf52c 100644
--- a/vistrails/tests/resources/pythonsource.xml
+++ b/vistrails/tests/resources/pythonsource.xml
@@ -1,35 +1,36 @@
 <?xml version="1.0" ?>
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/startup-0.1.xml.tmpl b/vistrails/tests/resources/startup-0.1.xml.tmpl
new file mode 100644
index 0000000..1450105
--- /dev/null
+++ b/vistrails/tests/resources/startup-0.1.xml.tmpl
@@ -0,0 +1,63 @@
+<startup version="0.1">
+  <configuration>
+    <key name="nologger">
+      <bool value="True"/>
+    </key>
+    <key name="shell">
+      <configuration>
+        <key name="font_face">
+  	  <str value="Bitstream Vera mono"/>
+        </key>
+        <key name="font_size">
+	  <int value="9"/>
+        </key>
+      </configuration>
+    </key>
+    <key name="showMovies">
+      <bool value="False"/>
+    </key>
+    <!-- test dirname changes -->
+    <key name="userPackageDirectory">
+      <str value="${startup_dir}/userpackages"/>
+    </key>
+    <key name="logFile">
+      <str value="${startup_dir}/vistrails.log"/>
+    </key>
+    <key name="abstractionsDirectory">
+      <str value="/path/to/subworkflows"/>
+    </key>
+    <key name="subworkflowsDir">
+      <str value="subworkflows"/>
+    </key>
+    <key name="thumbs">
+      <configuration>
+	<key name="cacheDirectory">
+	  <str value="/path/to/thumbs"/>
+	</key>
+      </configuration>
+    </key>
+    <key name="fixedSpreadsheetCells">
+      <bool value="True"/>
+    </key>
+    <key name="spreadsheetDumpPDF">
+      <bool value="False"/>
+    </key>
+  </configuration>
+  <packages>
+    <package name="vtk"/>
+    <package name="pythonCalc"/>
+    <package name="spreadsheet"/>
+    <package name="dialogs"/>
+    <package name="URL"/>
+    <package name="controlflow"/>
+    <package name="tabledata"/>
+    <package name="afront">
+      <configuration>
+	<key name="debug">
+	  <bool value="True"/>
+	</key>
+      </configuration>
+    </package>
+  </packages>
+  <disabledpackages/>
+</startup>
diff --git a/vistrails/tests/resources/test-implicit-while.vt b/vistrails/tests/resources/test-implicit-while.vt
new file mode 100644
index 0000000..e405014
Binary files /dev/null and b/vistrails/tests/resources/test-implicit-while.vt differ
diff --git a/vistrails/tests/resources/test-list-custom.vt b/vistrails/tests/resources/test-list-custom.vt
new file mode 100644
index 0000000..79e1360
Binary files /dev/null and b/vistrails/tests/resources/test-list-custom.vt differ
diff --git a/vistrails/tests/resources/test-streaming.vt b/vistrails/tests/resources/test-streaming.vt
new file mode 100644
index 0000000..76e1407
Binary files /dev/null and b/vistrails/tests/resources/test-streaming.vt differ
diff --git a/vistrails/tests/resources/test_abstraction.xml b/vistrails/tests/resources/test_abstraction.xml
index 9532b60..496e5a3 100644
--- a/vistrails/tests/resources/test_abstraction.xml
+++ b/vistrails/tests/resources/test_abstraction.xml
@@ -222,6 +222,78 @@
       <port id="31" moduleId="11" moduleName="List" name="head" signature="(org.vistrails.vistrails.basic:Module)" type="destination" />
     </add>
   </action>
+  <action date="2014-04-21 17:18:19" id="12" prevId="11" session="4" user="Remi">
+    <annotation id="7" key="__description__" value="Upgrade" />
+    <delete id="91" objectId="30" parentObjId="15" parentObjType="connection" what="port" />
+    <delete id="92" objectId="31" parentObjId="15" parentObjType="connection" what="port" />
+    <delete id="93" objectId="15" parentObjId="" parentObjType="" what="connection" />
+    <delete id="94" objectId="9" parentObjId="9" parentObjType="module" what="location" />
+    <delete id="95" objectId="9" parentObjId="" parentObjType="" what="module" />
+    <delete id="96" objectId="28" parentObjId="14" parentObjType="connection" what="port" />
+    <delete id="97" objectId="29" parentObjId="14" parentObjType="connection" what="port" />
+    <delete id="98" objectId="14" parentObjId="" parentObjType="" what="connection" />
+    <delete id="99" objectId="11" parentObjId="11" parentObjType="module" what="location" />
+    <delete id="100" objectId="11" parentObjId="" parentObjType="" what="module" />
+    <delete id="101" objectId="26" parentObjId="13" parentObjType="connection" what="port" />
+    <delete id="102" objectId="27" parentObjId="13" parentObjType="connection" what="port" />
+    <delete id="103" objectId="13" parentObjId="" parentObjType="" what="connection" />
+    <delete id="104" objectId="8" parentObjId="8" parentObjType="module" what="location" />
+    <delete id="105" objectId="8" parentObjId="" parentObjType="" what="module" />
+    <delete id="106" objectId="10" parentObjId="10" parentObjType="module" what="location" />
+    <delete id="107" objectId="10" parentObjId="" parentObjType="" what="module" />
+    <add id="108" objectId="12" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="12" name="Float" namespace="" package="org.vistrails.vistrails.basic" version="2.1.1" />
+    </add>
+    <add id="109" objectId="12" parentObjId="12" parentObjType="module" what="location">
+      <location id="12" x="62.0" y="180.0" />
+    </add>
+    <add id="110" objectId="13" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="13" name="List" namespace="" package="org.vistrails.vistrails.basic" version="2.1.1" />
+    </add>
+    <add id="111" objectId="13" parentObjId="13" parentObjType="module" what="location">
+      <location id="13" x="18.0" y="85.0" />
+    </add>
+    <add id="112" objectId="18" parentObjId="" parentObjType="" what="connection">
+      <connection id="18" />
+    </add>
+    <add id="113" objectId="36" parentObjId="18" parentObjType="connection" what="port">
+      <port id="36" moduleId="12" moduleName="Float" name="value" signature="(org.vistrails.vistrails.basic:Float)" type="source" />
+    </add>
+    <add id="114" objectId="37" parentObjId="18" parentObjType="connection" what="port">
+      <port id="37" moduleId="13" moduleName="List" name="head" signature="(org.vistrails.vistrails.basic:Variant)" type="destination" />
+    </add>
+    <add id="115" objectId="14" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="14" name="List" namespace="" package="org.vistrails.vistrails.basic" version="2.1.1" />
+    </add>
+    <add id="116" objectId="14" parentObjId="14" parentObjType="module" what="location">
+      <location id="14" x="17.0" y="-31.0" />
+    </add>
+    <add id="117" objectId="20" parentObjId="" parentObjType="" what="connection">
+      <connection id="20" />
+    </add>
+    <add id="118" objectId="40" parentObjId="20" parentObjType="connection" what="port">
+      <port id="40" moduleId="13" moduleName="List" name="value" signature="(org.vistrails.vistrails.basic:List)" type="source" />
+    </add>
+    <add id="119" objectId="41" parentObjId="20" parentObjType="connection" what="port">
+      <port id="41" moduleId="14" moduleName="List" name="tail" signature="(org.vistrails.vistrails.basic:List)" type="destination" />
+    </add>
+    <add id="120" objectId="15" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="15" name="Float" namespace="" package="org.vistrails.vistrails.basic" version="2.1.1" />
+    </add>
+    <add id="121" objectId="15" parentObjId="15" parentObjType="module" what="location">
+      <location id="15" x="-109.0" y="146.0" />
+    </add>
+    <add id="122" objectId="21" parentObjId="" parentObjType="" what="connection">
+      <connection id="21" />
+    </add>
+    <add id="123" objectId="42" parentObjId="21" parentObjType="connection" what="port">
+      <port id="42" moduleId="15" moduleName="Float" name="value" signature="(org.vistrails.vistrails.basic:Float)" type="source" />
+    </add>
+    <add id="124" objectId="43" parentObjId="21" parentObjType="connection" what="port">
+      <port id="43" moduleId="14" moduleName="List" name="head" signature="(org.vistrails.vistrails.basic:Variant)" type="destination" />
+    </add>
+  </action>
   <actionAnnotation actionId="9" date="2012-08-02 17:59:40" id="2" key="__upgrade__" user="tommy" value="10" />
   <actionAnnotation actionId="10" date="2013-05-08 17:48:29" id="6" key="__upgrade__" user="dakoop" value="11" />
+  <actionAnnotation actionId="11" date="2014-04-21 17:18:19" id="8" key="__upgrade__" user="Remi" value="12" />
 </vistrail>
diff --git a/vistrails/tests/resources/test_alias.xml b/vistrails/tests/resources/test_alias.xml
index e2c76af..3e5a94f 100644
--- a/vistrails/tests/resources/test_alias.xml
+++ b/vistrails/tests/resources/test_alias.xml
@@ -1,35 +1,36 @@
 <?xml version="1.0" ?>
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/test_ticket_73.xml b/vistrails/tests/resources/test_ticket_73.xml
index a26ea43..94182b1 100644
--- a/vistrails/tests/resources/test_ticket_73.xml
+++ b/vistrails/tests/resources/test_ticket_73.xml
@@ -1,35 +1,36 @@
 <?xml version="1.0" ?>
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/resources/test_upgrades_layout/__init__.py b/vistrails/tests/resources/test_upgrades_layout/__init__.py
new file mode 100644
index 0000000..95f41e1
--- /dev/null
+++ b/vistrails/tests/resources/test_upgrades_layout/__init__.py
@@ -0,0 +1,3 @@
+identifier = 'org.vistrails.test.upgrades_layout'
+name ='test_upgrades_layout'
+version = '0.3'
diff --git a/vistrails/tests/resources/test_upgrades_layout/init.py b/vistrails/tests/resources/test_upgrades_layout/init.py
new file mode 100644
index 0000000..1dfa4de
--- /dev/null
+++ b/vistrails/tests/resources/test_upgrades_layout/init.py
@@ -0,0 +1,8 @@
+from vistrails.core.modules.vistrails_module import Module
+
+
+class Mod(Module):
+    pass
+
+
+_modules = [Mod]
diff --git a/vistrails/tests/resources/triangle_count.vt b/vistrails/tests/resources/triangle_count.vt
index 33950e5..6a8ca95 100644
Binary files a/vistrails/tests/resources/triangle_count.vt and b/vistrails/tests/resources/triangle_count.vt differ
diff --git a/vistrails/tests/resources/upgrades/__init__.py b/vistrails/tests/resources/upgrades/__init__.py
new file mode 100644
index 0000000..a4ae806
--- /dev/null
+++ b/vistrails/tests/resources/upgrades/__init__.py
@@ -0,0 +1,3 @@
+identifier = "org.vistrails.vistrails.tests.upgrade"
+name = "TestUpgrades"
+version = "1.0"
diff --git a/vistrails/tests/resources/upgrades/init.py b/vistrails/tests/resources/upgrades/init.py
new file mode 100644
index 0000000..0e6aa38
--- /dev/null
+++ b/vistrails/tests/resources/upgrades/init.py
@@ -0,0 +1,19 @@
+from vistrails.core.modules.vistrails_module import Module
+from vistrails.core.modules.config import IPort, OPort
+from vistrails.core.upgradeworkflow import  UpgradeModuleRemap
+
+class TestUpgradeA(Module):
+    _input_ports = [IPort("aaa", "basic:String")]
+    _output_ports = [OPort("zzz", "basic:Integer")]
+
+class TestUpgradeB(Module):
+    _input_ports = [IPort("b", "basic:Integer")]
+
+_modules = [TestUpgradeA, TestUpgradeB]
+_upgrades = {"TestUpgradeA": 
+             [UpgradeModuleRemap('0.8', '0.9', '0.9', None,
+                                 function_remap={'a': 'aa'},
+                                 src_port_remap={'z': 'zz'}),
+              UpgradeModuleRemap('0.9', '1.0', '1.0', None,
+                                 function_remap={'aa': 'aaa'},
+                                 src_port_remap={'zz': 'zzz'})]}
diff --git a/vistrails/tests/resources/upgrades1.xml b/vistrails/tests/resources/upgrades1.xml
new file mode 100644
index 0000000..0405273
--- /dev/null
+++ b/vistrails/tests/resources/upgrades1.xml
@@ -0,0 +1,152 @@
+<vistrail id="" name="" version="1.0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vistrails.org/vistrail.xsd">
+  <action date="2015-03-26 17:09:29" id="1" prevId="0" session="0" user="Remi">
+    <add id="0" objectId="0" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="0" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.1" />
+    </add>
+    <add id="1" objectId="0" parentObjId="0" parentObjType="module" what="location">
+      <location id="0" x="-25.0" y="30.0" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:09:47" id="2" prevId="1" session="1" user="Remi">
+    <annotation id="1" key="__description__" value="Upgrade" />
+    <delete id="2" objectId="0" parentObjId="0" parentObjType="module" what="location" />
+    <delete id="3" objectId="0" parentObjId="" parentObjType="" what="module" />
+    <add id="4" objectId="1" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="1" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="5" objectId="1" parentObjId="1" parentObjType="module" what="location">
+      <location id="1" x="-25.0" y="30.0" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:10:02" id="3" prevId="2" session="2" user="Remi">
+    <annotation id="3" key="__description__" value="Upgrade" />
+    <delete id="6" objectId="1" parentObjId="1" parentObjType="module" what="location" />
+    <delete id="7" objectId="1" parentObjId="" parentObjType="" what="module" />
+    <add id="8" objectId="2" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="2" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.3" />
+    </add>
+    <add id="9" objectId="2" parentObjId="2" parentObjType="module" what="location">
+      <location id="2" x="-25.0" y="30.0" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:10:09" id="4" prevId="3" session="2" user="Remi">
+    <change id="10" newObjId="3" oldObjId="2" parentObjId="2" parentObjType="module" what="location">
+      <location id="3" x="-58.5033557047" y="1.65100671141" />
+    </change>
+  </action>
+  <action date="2015-03-26 17:12:06" id="5" prevId="0" session="3" user="Remi">
+    <add id="11" objectId="4" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="4" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.1" />
+    </add>
+    <add id="12" objectId="5" parentObjId="4" parentObjType="module" what="location">
+      <location id="5" x="-36.9395973154" y="74.7382550336" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:12:28" id="6" prevId="5" session="4" user="Remi">
+    <annotation id="8" key="__description__" value="Upgrade" />
+    <delete id="13" objectId="5" parentObjId="4" parentObjType="module" what="location" />
+    <delete id="14" objectId="4" parentObjId="" parentObjType="" what="module" />
+    <add id="15" objectId="5" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="5" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="16" objectId="6" parentObjId="5" parentObjType="module" what="location">
+      <location id="6" x="-36.9395973154" y="74.7382550336" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:12:42" id="7" prevId="6" session="5" user="Remi">
+    <annotation id="10" key="__description__" value="Upgrade" />
+    <delete id="17" objectId="6" parentObjId="5" parentObjType="module" what="location" />
+    <delete id="18" objectId="5" parentObjId="" parentObjType="" what="module" />
+    <add id="19" objectId="6" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="6" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.3" />
+    </add>
+    <add id="20" objectId="7" parentObjId="6" parentObjType="module" what="location">
+      <location id="7" x="-36.9395973154" y="74.7382550336" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:12:46" id="8" prevId="7" session="5" user="Remi">
+    <change id="21" newObjId="8" oldObjId="7" parentObjId="6" parentObjType="module" what="location">
+      <location id="8" x="-110.818791946" y="71.3020134229" />
+    </change>
+  </action>
+  <action date="2015-03-26 17:14:05" id="9" prevId="5" session="6" user="Remi">
+    <change id="22" newObjId="10" oldObjId="5" parentObjId="4" parentObjType="module" what="location">
+      <location id="10" x="-18.0402684563" y="77.3154362417" />
+    </change>
+  </action>
+  <action date="2015-03-26 17:14:22" id="10" prevId="9" session="7" user="Remi">
+    <annotation id="12" key="__description__" value="Upgrade" />
+    <delete id="23" objectId="10" parentObjId="4" parentObjType="module" what="location" />
+    <delete id="24" objectId="4" parentObjId="" parentObjType="" what="module" />
+    <add id="25" objectId="7" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="7" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="26" objectId="11" parentObjId="7" parentObjType="module" what="location">
+      <location id="11" x="-18.0402684563" y="77.3154362417" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:14:53" id="11" prevId="10" session="7" user="Remi">
+    <change id="27" newObjId="12" oldObjId="11" parentObjId="7" parentObjType="module" what="location">
+      <location id="12" x="22.3355704699" y="74.7382550336" />
+    </change>
+  </action>
+  <action date="2015-03-26 17:15:15" id="12" prevId="10" session="8" user="Remi">
+    <annotation id="16" key="__description__" value="Upgrade" />
+    <delete id="28" objectId="11" parentObjId="7" parentObjType="module" what="location" />
+    <delete id="29" objectId="7" parentObjId="" parentObjType="" what="module" />
+    <add id="30" objectId="9" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="9" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.3" />
+    </add>
+    <add id="31" objectId="14" parentObjId="9" parentObjType="module" what="location">
+      <location id="14" x="-18.0402684563" y="77.3154362417" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:15:25" id="13" prevId="12" session="8" user="Remi">
+    <change id="32" newObjId="15" oldObjId="14" parentObjId="9" parentObjType="module" what="location">
+      <location id="15" x="-55.8389261744" y="109.100671141" />
+    </change>
+  </action>
+  <action date="2015-03-26 17:16:17" id="14" prevId="0" session="9" user="Remi">
+    <add id="33" objectId="11" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="11" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.1" />
+    </add>
+    <add id="34" objectId="17" parentObjId="11" parentObjType="module" what="location">
+      <location id="17" x="-12.8859060403" y="13.744966443" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:16:32" id="15" prevId="14" session="10" user="Remi">
+    <annotation id="18" key="__description__" value="Upgrade" />
+    <delete id="35" objectId="17" parentObjId="11" parentObjType="module" what="location" />
+    <delete id="36" objectId="11" parentObjId="" parentObjType="" what="module" />
+    <add id="37" objectId="12" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="12" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="38" objectId="18" parentObjId="12" parentObjType="module" what="location">
+      <location id="18" x="-12.8859060403" y="13.744966443" />
+    </add>
+  </action>
+  <action date="2015-03-26 17:16:43" id="16" prevId="15" session="11" user="Remi">
+    <annotation id="20" key="__description__" value="Upgrade" />
+    <delete id="39" objectId="18" parentObjId="12" parentObjType="module" what="location" />
+    <delete id="40" objectId="12" parentObjId="" parentObjType="" what="module" />
+    <add id="41" objectId="13" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="13" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.3" />
+    </add>
+    <add id="42" objectId="19" parentObjId="13" parentObjType="module" what="location">
+      <location id="19" x="-12.8859060403" y="13.744966443" />
+    </add>
+  </action>
+  <actionAnnotation actionId="1" date="2015-03-26 17:09:34" id="0" key="__tag__" user="Remi" value="T1" />
+  <actionAnnotation actionId="1" date="2015-03-26 17:09:47" id="2" key="__upgrade__" user="Remi" value="2" />
+  <actionAnnotation actionId="2" date="2015-03-26 17:10:02" id="4" key="__upgrade__" user="Remi" value="3" />
+  <actionAnnotation actionId="3" date="2015-03-26 17:10:07" id="5" key="__tag__" user="Remi" value="T2" />
+  <actionAnnotation actionId="5" date="2015-03-26 17:12:10" id="7" key="__tag__" user="Remi" value="T3" />
+  <actionAnnotation actionId="5" date="2015-03-26 17:12:28" id="9" key="__upgrade__" user="Remi" value="6" />
+  <actionAnnotation actionId="6" date="2015-03-26 17:12:42" id="11" key="__upgrade__" user="Remi" value="7" />
+  <actionAnnotation actionId="9" date="2015-03-26 17:14:22" id="13" key="__upgrade__" user="Remi" value="10" />
+  <actionAnnotation actionId="10" date="2015-03-26 17:14:37" id="14" key="__tag__" user="Remi" value="T4" />
+  <actionAnnotation actionId="10" date="2015-03-26 17:15:15" id="17" key="__upgrade__" user="Remi" value="12" />
+  <actionAnnotation actionId="14" date="2015-03-26 17:16:32" id="19" key="__upgrade__" user="Remi" value="15" />
+  <actionAnnotation actionId="15" date="2015-03-26 17:16:43" id="21" key="__upgrade__" user="Remi" value="16" />
+  <actionAnnotation actionId="16" date="2015-03-26 17:16:47" id="22" key="__tag__" user="Remi" value="T5" />
+</vistrail>
diff --git a/vistrails/tests/resources/upgrades2.xml b/vistrails/tests/resources/upgrades2.xml
new file mode 100644
index 0000000..ceaff7a
--- /dev/null
+++ b/vistrails/tests/resources/upgrades2.xml
@@ -0,0 +1,133 @@
+<vistrail id="" name="" version="1.0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vistrails.org/vistrail.xsd">
+  <action date="2015-03-27 10:00:51" id="1" prevId="0" session="0" user="Remi">
+    <add id="0" objectId="0" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="0" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.1" />
+    </add>
+    <add id="1" objectId="0" parentObjId="0" parentObjType="module" what="location">
+      <location id="0" x="-4.0" y="-15.0" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:01:01" id="2" prevId="1" session="0" user="Remi">
+    <change id="2" newObjId="1" oldObjId="0" parentObjId="0" parentObjType="module" what="location">
+      <location id="1" x="-38.0" y="2.0" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:01:15" id="3" prevId="2" session="1" user="Remi">
+    <annotation id="0" key="__description__" value="Upgrade" />
+    <delete id="3" objectId="1" parentObjId="0" parentObjType="module" what="location" />
+    <delete id="4" objectId="0" parentObjId="" parentObjType="" what="module" />
+    <add id="5" objectId="1" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="1" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="6" objectId="2" parentObjId="1" parentObjType="module" what="location">
+      <location id="2" x="-38.0" y="2.0" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:01:30" id="4" prevId="3" session="1" user="Remi">
+    <change id="7" newObjId="3" oldObjId="2" parentObjId="1" parentObjType="module" what="location">
+      <location id="3" x="-75.7986577181" y="-1.43624161074" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:01:35" id="5" prevId="3" session="1" user="Remi">
+    <change id="8" newObjId="4" oldObjId="2" parentObjId="1" parentObjType="module" what="location">
+      <location id="4" x="24.711409396" y="-9.1677852349" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:01:36" id="6" prevId="5" session="1" user="Remi">
+    <change id="9" newObjId="5" oldObjId="4" parentObjId="1" parentObjType="module" what="location">
+      <location id="5" x="-43.1543624161" y="8.87248322148" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:01:57" id="7" prevId="4" session="2" user="Remi">
+    <annotation id="4" key="__description__" value="Upgrade" />
+    <delete id="10" objectId="3" parentObjId="1" parentObjType="module" what="location" />
+    <delete id="11" objectId="1" parentObjId="" parentObjType="" what="module" />
+    <add id="12" objectId="3" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="3" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.3" />
+    </add>
+    <add id="13" objectId="7" parentObjId="3" parentObjType="module" what="location">
+      <location id="7" x="-75.7986577181" y="-1.43624161074" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:03:31" id="8" prevId="0" session="3" user="Remi">
+    <add id="14" objectId="5" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="5" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.1" />
+    </add>
+    <add id="15" objectId="9" parentObjId="5" parentObjType="module" what="location">
+      <location id="9" x="-43.8120805369" y="14.6040268456" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:03:33" id="9" prevId="8" session="3" user="Remi">
+    <change id="16" newObjId="10" oldObjId="9" parentObjId="5" parentObjType="module" what="location">
+      <location id="10" x="-96.2147651007" y="6.01342281879" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:03:35" id="10" prevId="9" session="3" user="Remi">
+    <change id="17" newObjId="11" oldObjId="10" parentObjId="5" parentObjType="module" what="location">
+      <location id="11" x="-49.8255033557" y="19.7583892617" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:03:55" id="11" prevId="9" session="4" user="Remi">
+    <annotation id="7" key="__description__" value="Upgrade" />
+    <delete id="18" objectId="10" parentObjId="5" parentObjType="module" what="location" />
+    <delete id="19" objectId="5" parentObjId="" parentObjType="" what="module" />
+    <add id="20" objectId="7" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="7" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="21" objectId="13" parentObjId="7" parentObjType="module" what="location">
+      <location id="13" x="-96.2147651007" y="6.01342281879" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:04:17" id="12" prevId="0" session="5" user="Remi">
+    <add id="22" objectId="9" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="9" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.1" />
+    </add>
+    <add id="23" objectId="15" parentObjId="9" parentObjType="module" what="location">
+      <location id="15" x="4.29530201342" y="4.29530201342" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:04:19" id="13" prevId="12" session="5" user="Remi">
+    <change id="24" newObjId="16" oldObjId="15" parentObjId="9" parentObjType="module" what="location">
+      <location id="16" x="-12.0268456376" y="10.3087248322" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:04:20" id="14" prevId="13" session="5" user="Remi">
+    <change id="25" newObjId="17" oldObjId="16" parentObjId="9" parentObjType="module" what="location">
+      <location id="17" x="-0.859060402685" y="12.8859060403" />
+    </change>
+  </action>
+  <action date="2015-03-27 10:04:36" id="15" prevId="12" session="6" user="Remi">
+    <annotation id="11" key="__description__" value="Upgrade" />
+    <delete id="26" objectId="15" parentObjId="9" parentObjType="module" what="location" />
+    <delete id="27" objectId="9" parentObjId="" parentObjType="" what="module" />
+    <add id="28" objectId="11" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="11" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="29" objectId="19" parentObjId="11" parentObjType="module" what="location">
+      <location id="19" x="4.29530201342" y="4.29530201342" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:04:40" id="16" prevId="13" session="6" user="Remi">
+    <annotation id="13" key="__description__" value="Upgrade" />
+    <delete id="30" objectId="16" parentObjId="9" parentObjType="module" what="location" />
+    <delete id="31" objectId="9" parentObjId="" parentObjType="" what="module" />
+    <add id="32" objectId="12" parentObjId="" parentObjType="" what="module">
+      <module cache="1" id="12" name="Mod" namespace="" package="org.vistrails.test.upgrades_layout" version="0.2" />
+    </add>
+    <add id="33" objectId="20" parentObjId="12" parentObjType="module" what="location">
+      <location id="20" x="-12.0268456376" y="10.3087248322" />
+    </add>
+  </action>
+  <action date="2015-03-27 10:04:44" id="17" prevId="16" session="6" user="Remi">
+    <change id="34" newObjId="21" oldObjId="20" parentObjId="12" parentObjType="module" what="location">
+      <location id="21" x="-29.2080536913" y="32.644295302" />
+    </change>
+  </action>
+  <actionAnnotation actionId="2" date="2015-03-27 10:01:15" id="1" key="__upgrade__" user="Remi" value="3" />
+  <actionAnnotation actionId="3" date="2015-03-27 10:01:18" id="2" key="__tag__" user="Remi" value="T1" />
+  <actionAnnotation actionId="4" date="2015-03-27 10:01:57" id="5" key="__upgrade__" user="Remi" value="7" />
+  <actionAnnotation actionId="9" date="2015-03-27 10:03:55" id="8" key="__upgrade__" user="Remi" value="11" />
+  <actionAnnotation actionId="11" date="2015-03-27 10:03:57" id="9" key="__tag__" user="Remi" value="T2" />
+  <actionAnnotation actionId="12" date="2015-03-27 10:04:36" id="12" key="__upgrade__" user="Remi" value="15" />
+  <actionAnnotation actionId="13" date="2015-03-27 10:04:40" id="14" key="__upgrade__" user="Remi" value="16" />
+</vistrail>
diff --git a/vistrails/tests/resources/vtk.xml b/vistrails/tests/resources/vtk.xml
index 3f11dbc..212021a 100644
--- a/vistrails/tests/resources/vtk.xml
+++ b/vistrails/tests/resources/vtk.xml
@@ -1,35 +1,36 @@
 <?xml version="1.0" ?>
 <!--###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
diff --git a/vistrails/tests/run_on_mac.sh b/vistrails/tests/run_on_mac.sh
index de4deda..f2a0f88 100755
--- a/vistrails/tests/run_on_mac.sh
+++ b/vistrails/tests/run_on_mac.sh
@@ -6,20 +6,22 @@ then
     exit 65
 fi
 
+APP_PATH=$1
+shift
 THIS_DIR=`dirname $0`
 PYTHON_EXEC_PATH="Contents/MacOS/python"
 RESOURCES_PATH="Contents/Resources"
 
-if [ ! -e "$1/$RESOURCES_PATH" ]
+if [ ! -e "$APP_PATH/$RESOURCES_PATH" ]
 then
-    echo "$1/$RESOURCES_PATH does not exist"
+    echo "$APP_PATH/$RESOURCES_PATH does not exist"
     exit 66
 fi
 
-if [ ! -e "$1/$PYTHON_EXEC_PATH" ]
+if [ ! -e "$APP_PATH/$PYTHON_EXEC_PATH" ]
 then
-    echo "$1/$PYTHON_EXEC_PATH does not exist"
+    echo "$APP_PATH/$PYTHON_EXEC_PATH does not exist"
     exit 67
 fi
 
-PYTHONHOME="$1/$RESOURCES_PATH" ${1}/${PYTHON_EXEC_PATH} ${THIS_DIR}/runtestsuite.py
+PYTHONHOME="$APP_PATH/$RESOURCES_PATH" ${APP_PATH}/${PYTHON_EXEC_PATH} ${THIS_DIR}/runtestsuite.py $@
diff --git a/vistrails/tests/runtestsuite.py b/vistrails/tests/runtestsuite.py
index 8c9f055..40d8fb7 100755
--- a/vistrails/tests/runtestsuite.py
+++ b/vistrails/tests/runtestsuite.py
@@ -1,35 +1,37 @@
 #!/usr/bin/env python
+# pragma: no testimport
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -43,68 +45,146 @@ any unit tests, as a crude measure of code coverage.
 
 """
 
-# First, import unittest, replacing it with unittest2 if necessary
-import sys
-try:
-    import unittest2
-except ImportError:
-    pass
-else:
-    sys.modules['unittest'] = unittest2
-import unittest
-
 import atexit
 from distutils.version import LooseVersion
 #import doctest
+import locale
 import os
+import sys
 import traceback
-import os.path
-import optparse
 from optparse import OptionParser
 import platform
+import re
 import shutil
 import tempfile
 
-# Makes sure we can import modules as if we were running VisTrails
-# from the root directory
-_this_dir = os.path.dirname(os.path.realpath(__file__))
-root_directory = os.path.realpath(os.path.join(_this_dir,  '..'))
-sys.path.insert(0, os.path.realpath(os.path.join(root_directory, '..')))
+if 'vistrails' not in sys.modules:
+    # Makes sure we can import modules as if we were running VisTrails
+    # from the root directory
+    _this_dir = os.path.dirname(os.path.realpath(__file__))
+    _root_directory = os.path.realpath(os.path.join(_this_dir,  '..'))
+    sys.path.insert(0, os.path.realpath(os.path.join(_root_directory, '..')))
 
 # Use a different temporary directory
 test_temp_dir = tempfile.mkdtemp(prefix='vt_testsuite_')
 tempfile.tempdir = test_temp_dir
- at atexit.register
-def clean_tempdir():
-    nb_dirs = 0
-    nb_files = 0
-    for f in os.listdir(test_temp_dir):
-        if os.path.isdir(f):
-            nb_dirs += 1
-        else:
-            nb_files += 1
-    if nb_dirs > 0 or nb_files > 0:
-        sys.stdout.write("Warning: %d dirs and %d files were left behind in "
-                         "tempdir, cleaning up\n" % (nb_dirs, nb_files))
-    shutil.rmtree(test_temp_dir, ignore_errors=True)
+ at apply
+class clean_tempdir(object):
+    def __init__(self):
+        atexit.register(self.clean)
+        self.listdir = os.listdir
+        self.isdir = os.path.isdir
+        self.test_temp_dir = test_temp_dir
+        self.rmtree = shutil.rmtree
+        self.out = sys.stdout.write
+    def clean(self):
+        nb_dirs = 0
+        nb_files = 0
+        for f in self.listdir(self.test_temp_dir):
+            if self.isdir(f):
+                nb_dirs += 1
+            else:
+                nb_files += 1
+        if nb_dirs > 0 or nb_files > 0:
+            self.out("Warning: %d dirs and %d files were left behind in "
+                     "tempdir, cleaning up\n" % (nb_dirs, nb_files))
+        self.rmtree(self.test_temp_dir, ignore_errors=True)
 
+# Parse the command-line
+usage = "Usage: %prog [options] [module1 module2 ...]"
+parser = OptionParser(usage=usage)
+parser.add_option("-V", "--verbose", action="store", type="int",
+                  default=0, dest="verbose",
+                  help="set verboseness level(0--2, default=0, "
+                  "higher means more verbose)")
+parser.add_option("-v", "--vistrails-verbose", action="store", type="int",
+                  default=0, dest="debugLevel",
+                  help="set the debugLevel in VisTrails (0--2, default=0)")
+parser.add_option("-e", "--examples", action="store_true",
+                  default=False,
+                  help="run vistrails examples")
+parser.add_option("-i", "--images", action="store_true",
+                  default=False,
+                  help="perform image comparisons")
+parser.add_option("--installbundles", action='store_true',
+                  default=False,
+                  help=("Attempt to install missing Python packages "
+                        "automatically"))
+parser.add_option("-S", "--startup", action="store", type="str", default=None,
+                  dest="dotVistrails",
+                  help="Set startup file (default is temporary directory)")
+parser.add_option('-L', '--locale', action='store', type='str', default='',
+                  dest='locale',
+                  help="set locale to this string")
+parser.add_option('-D', '--debug', action='store_true',
+                  default=False,
+                  help="start interactive debugger on unexpected error")
+parser.add_option('--no-unbuffered', action='store_false', dest='unbuffered',
+                  default=True,
+                  help="Don't make output stream unbuffered")
+
+(options, test_modules) = parser.parse_args()
+# remove empty strings
+test_modules = filter(len, test_modules)
+verbose = options.verbose
+locale.setlocale(locale.LC_ALL, options.locale or '')
+test_examples = options.examples
+test_images = options.images
+installbundles = options.installbundles
+dotVistrails = options.dotVistrails
+debug_mode = options.debug
+vistrails_verbose = options.debugLevel
+
+# Makes stdout unbuffered, so python -u is not needed
+class Unbuffered(object):
+   def __init__(self, stream):
+       self.stream = stream
+   def write(self, data):
+       self.stream.write(data)
+       self.stream.flush()
+   def __getattr__(self, attr):
+       return getattr(self.stream, attr)
+
+if options.unbuffered:
+    sys.stdout = Unbuffered(sys.stdout)
+    sys.stderr = Unbuffered(sys.stderr)
+
+# Use PyQt API v2
 def setNewPyQtAPI():
     try:
         import sip
         # We now use the new PyQt API - IPython needs it
         sip.setapi('QString', 2)
         sip.setapi('QVariant', 2)
-    except:
+    except Exception:
         print "Could not set PyQt API, is PyQt4 installed?"
 setNewPyQtAPI()
 
+# Log to the console
+import vistrails.core.debug
+vistrails.core.debug.DebugPrint.getInstance().log_to_console()
+
 import vistrails.tests
 import vistrails.core
 import vistrails.core.db.io
 import vistrails.core.db.locator
+from vistrails.core import debug
 import vistrails.gui.application
 from vistrails.core.system import vistrails_root_directory, \
                                   vistrails_examples_directory
+from vistrails.core.packagemanager import get_package_manager
+
+# VisTrails does funny stuff with unittest/unittest2, be sure to load that
+# after vistrails
+import unittest
+
+# reinitializing arguments and options so VisTrails does not try parsing them
+sys.argv = sys.argv[:1]
+vistrails.gui.application.VistrailsApplicationSingleton.use_event_filter = \
+        False
+
+
+root_directory = os.path.realpath(vistrails_root_directory())
 
 ###############################################################################
 # Testing Examples
@@ -147,39 +227,12 @@ def sub_print(s, overline=False):
 
 ###############################################################################
 
-usage = "Usage: %prog [options] [module1 module2 ...]"
-parser = OptionParser(usage=usage)
-parser.add_option("-V", "--verbose", action="store", type="int",
-                  default=0, dest="verbose",
-                  help="set verboseness level(0--2, default=0, "
-                  "higher means more verbose)")
-parser.add_option("-e", "--examples", action="store_true",
-                  default=False,
-                  help="run vistrails examples")
-parser.add_option("-i", "--images", action="store_true",
-                  default=False,
-                  help="perform image comparisons")
-parser.add_option("--installbundles", action='store_true',
-                  default=False,
-                  help=("Attempt to install missing Python packages "
-                        "automatically"))
-parser.add_option("-S", "--startup", action="store", type="str", default=None,
-                  dest="dotVistrails",
-                  help="Set startup file (default is temporary directory)")
-
-(options, args) = parser.parse_args()
-# remove empty strings
-args = filter(len, args)
-verbose = options.verbose
-test_examples = options.examples
-test_images = options.images
-installbundles = options.installbundles
-dotVistrails = options.dotVistrails
-test_modules = None
-if len(args) > 0:
-    test_modules = args
+if len(test_modules) > 0:
+    test_modules = test_modules
 else:
-    test_images = True
+    test_modules = None
+    if os.path.exists(EXAMPLES_PATH):
+        test_images = True
 
 def module_filter(name):
     if test_modules is None:
@@ -190,20 +243,19 @@ def module_filter(name):
     return False
 
 ###############################################################################
-# reinitializing arguments and options so VisTrails does not try parsing them
-sys.argv = sys.argv[:1]
-
 # creates the app so that testing can happen
 
 # We need the windows so we can test events, etc.
 optionsDict = {
-        'interactiveMode': True,
-        'nologger': True,
+        'batch': False,
+        'executionLog': False,
         'singleInstance': False,
-        'fixedSpreadsheetCells': True,
         'installBundles': installbundles,
         'enablePackagesSilently': True,
         'handlerDontAsk': True,
+        'developerDebugger': debug_mode,
+        'debugLevel': vistrails_verbose,
+        'dontUnloadModules': True,
     }
 if dotVistrails:
     optionsDict['dotVistrails'] = dotVistrails
@@ -216,12 +268,17 @@ if v != 0:
         app.finishSession()
     sys.exit(v)
 
+# make sure that fixedCellSize is turned on
+spreadsheet_conf = get_package_manager().get_package_configuration("spreadsheet")
+spreadsheet_conf.fixedCellSize = True
+
 # disable first vistrail
 app = vistrails.gui.application.get_vistrails_application()
 app.builderWindow.auto_view = False
 app.builderWindow.close_all_vistrails(True)
 
 print "Test Suite for VisTrails"
+print "Locale settings: %s" % ', '.join('%s: %s' % (s, locale.setlocale(getattr(locale, s), None)) for s in ('LC_ALL', 'LC_TIME'))
 print "Running on %s" % ', '.join(platform.uname())
 print "Python is %s" % sys.version
 try:
@@ -249,6 +306,8 @@ tests_passed = True
 main_test_suite = unittest.TestSuite()
 test_loader = unittest.TestLoader()
 
+import_skip_regex = re.compile(r'(?i)# *pragma[: ]*no *testimport')
+
 if test_modules:
     sub_print("Trying to import some of the modules")
 else:
@@ -262,6 +321,7 @@ for (p, subdirs, files) in os.walk(root_directory):
         # skip files that don't look like VisTrails python modules
         if not filename.endswith('.py'):
             continue
+        module_file = os.path.join(p, filename)
         module = os.path.join("vistrails", p[len(root_directory)+1:],
                               filename[:-3])
         if (module.startswith(os.sep) or
@@ -277,15 +337,20 @@ for (p, subdirs, files) in os.walk(root_directory):
 
         if not module_filter(module):
             continue
-        if module.startswith('vistrails.tests.run'):
-            continue
         if module.startswith('vistrails.tests.resources'):
             continue
         if ('.system.' in module and not
             module.endswith('__init__')):
             continue
-
-        msg = ("%s %s |" % (" " * (40 - len(module)), module))
+        with open(module_file) as fp:
+            l = fp.readline()
+            if l.startswith('#!'): # shebang
+                l = fp.readline()
+            if import_skip_regex.match(l):
+                if verbose >= 1:
+                    print >>sys.stderr, ("Skipping %s, not an importable "
+                                         "module" % module)
+                continue
 
         m = None
         try:
@@ -293,14 +358,10 @@ for (p, subdirs, files) in os.walk(root_directory):
                 m = __import__(module, globals(), locals(), ['foo'])
             else:
                 m = __import__(module)
-        except vistrails.tests.NotModule:
-            if verbose >= 1:
-                print "Skipping %s, not an importable module" % filename
-            continue
-        except:
-            print msg, "ERROR: Could not import module!"
+        except BaseException:
+            print >>sys.stderr, "ERROR: Could not import module: %s" % module
             if verbose >= 1:
-                traceback.print_exc(file=sys.stdout)
+                traceback.print_exc(file=sys.stderr)
             continue
 
         # Load the unittest TestCases
@@ -320,9 +381,11 @@ for (p, subdirs, files) in os.walk(root_directory):
         main_test_suite.addTests(suite)
 
         if suite.countTestCases() == 0 and verbose >= 1:
-            print msg, "WARNING: %s has no tests!" % filename
+            print >>sys.stderr, "WARNING: module has no tests: %s" % module
         elif verbose >= 2:
-            print msg, "Ok: %d test cases." % suite.countTestCases()
+            print >>sys.stderr, "OK: module as %d test cases: %s" % (
+                    suite.countTestCases(),
+                    module)
 
 sub_print("Imported modules. Running %d tests%s..." % (
           main_test_suite.countTestCases(),
@@ -360,8 +423,13 @@ if compare_use_vtk:
         a = removeAlpha(prev)
         b = removeAlpha(next)
         idiff = vtk.vtkImageDifference()
-        idiff.SetInput(a)
-        idiff.SetImage(b)
+        if LooseVersion(vtk.vtkVersion().GetVTKVersion()) >= \
+           LooseVersion('6.0.0'):
+            idiff.SetInputData(a)
+            idiff.SetImageData(b)
+        else:
+            idiff.SetInput(a)
+            idiff.SetImage(b)
         idiff.Update()
         return idiff.GetThresholdedError()
 else:
@@ -407,7 +475,7 @@ def image_test_generator(vtfile, version):
                     print("   *** Error in %s:%s:%s -- %s" % err)
                     self.fail(str(err))
         except Exception, e:
-            self.fail(str(e))
+            self.fail(debug.format_exception(e))
     return test
 
 class TestVistrailImages(unittest.TestCase):
@@ -423,7 +491,15 @@ if test_images:
 
 ############## RUN TEST SUITE ####################
 
-result = unittest.TextTestRunner(verbosity=max(verbose, 1)).run(main_test_suite)
+class TestResult(unittest.TextTestResult):
+    def addSkip(self, test, reason):
+        self.stream.writeln("skipped '{0}': {1}".format(str(test), reason))
+        super(TestResult, self).addSkip(test, reason)
+
+runner = unittest.TextTestRunner(
+        verbosity=max(verbose, 1),
+        resultclass=TestResult)
+result = runner.run(main_test_suite)
 
 if not result.wasSuccessful():
     tests_passed = False
@@ -453,7 +529,7 @@ if test_examples:
                 errs = vistrails.core.console_mode.run(w_list, update_vistrail=False)
                 summary[vtfile] = errs
         except Exception, e:
-            errs.append((vtfile,"None", "None", str(e)))
+            errs.append((vtfile,"None", "None", debug.format_exception(e)))
             summary[vtfile] = errs
         nvtfiles += 1
 
diff --git a/vistrails/tests/utils.py b/vistrails/tests/utils.py
index bae8836..bc7b79b 100644
--- a/vistrails/tests/utils.py
+++ b/vistrails/tests/utils.py
@@ -1,9 +1,74 @@
+###############################################################################
+##
+## Copyright (C) 2014-2015, New York University.
+## Copyright (C) 2011-2014, NYU-Poly.
+## Copyright (C) 2006-2011, University of Utah.
+## All rights reserved.
+## Contact: contact at vistrails.org
+##
+## This file is part of VisTrails.
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are met:
+##
+##  - Redistributions of source code must retain the above copyright notice,
+##    this list of conditions and the following disclaimer.
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
+##    this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+###############################################################################
+
+from __future__ import division
+
 import contextlib
+import logging
+import sys
+
+try:
+    import cStringIO as StringIO
+except ImportError:
+    import StringIO
 
 from vistrails.core.modules.vistrails_module import Module
 
 
-def execute(modules, connections=[], add_port_specs=[], enable_pkg=True):
+def enable_package(identifier):
+    """Enables a package.
+    """
+    from vistrails.core.modules.module_registry import MissingPackage
+    from vistrails.core.packagemanager import get_package_manager
+
+    pm = get_package_manager()
+
+    try:
+        pm.get_package(identifier)
+    except MissingPackage:
+        dep_graph = pm.build_dependency_graph([identifier])
+        for pkg_id in pm.get_ordered_dependencies(dep_graph):
+            pkg = pm.identifier_is_available(pkg_id)
+            if pkg is None:
+                raise
+            pm.late_enable_package(pkg.codepath)
+
+
+def execute(modules, connections=[], add_port_specs=[],
+            enable_pkg=True, full_results=False):
     """Build a pipeline and execute it.
 
     This is useful to simply build a pipeline in a test case, and run it. When
@@ -97,10 +162,8 @@ def execute(modules, connections=[], add_port_specs=[], enable_pkg=True):
         except MissingPackage:
             if not enable_pkg:
                 raise
-            pkg = pm.identifier_is_available(identifier)
-            if pkg:
-                pm.late_enable_package(pkg.codepath)
-                pkg = pm.get_package(identifier)
+            enable_package(identifier)
+            pkg = pm.get_package(identifier)
 
         for func_name, params in functions:
             param_list = []
@@ -151,7 +214,11 @@ def execute(modules, connections=[], add_port_specs=[], enable_pkg=True):
             locator=XMLFileLocator('foo.xml'),
             current_version=1,
             view=DummyView())
-    return result.errors
+    if full_results:
+        return result
+    else:
+        # Allows to do self.assertFalse(execute(...))
+        return result.errors
 
 
 @contextlib.contextmanager
@@ -161,14 +228,14 @@ def intercept_result(module, output_name):
     It is used as a context manager, for instance:
     class MyModule(Module):
         def compute(self):
-            self.setResult('res', 42)
+            self.set_output('res', 42)
         ...
     with intercept_result(MyModule, 'res') as results:
         self.assertFalse(execute(...))
     self.assertEqual(results, [42])
     """
-    actual_setResult = module.setResult
-    old_setResult = module.__dict__.get('setResult', None)
+    actual_setResult = module.set_output
+    old_setResult = module.__dict__.get('set_output', None)
     results = []
     modules_index = {}  # Maps a Module to an index in the list, so a module
             # can change its result
@@ -180,14 +247,14 @@ def intercept_result(module, output_name):
                 modules_index[self] = len(results)
                 results.append(value)
         actual_setResult(self, name, value)
-    module.setResult = new_setResult
+    module.set_output = new_setResult
     try:
         yield results
     finally:
         if old_setResult is not None:
-            module.setResult = old_setResult
+            module.set_output = old_setResult
         else:
-            del module.setResult
+            del module.set_output
 
 
 def intercept_results(*args):
@@ -211,3 +278,71 @@ def intercept_results(*args):
         else:
             raise TypeError
     return contextlib.nested(*ctx)
+
+
+ at contextlib.contextmanager
+def capture_stream(stream):
+    lines = []
+    old = getattr(sys, stream)
+    sio = StringIO.StringIO()
+    setattr(sys, stream, sio)
+    try:
+        yield lines
+    finally:
+        setattr(sys, stream,  old)
+        lines.extend(sio.getvalue().split('\n'))
+        if lines and not lines[-1]:
+            del lines[-1]
+
+
+ at contextlib.contextmanager
+def capture_stdout():
+    with capture_stream('stdout') as lines:
+        yield lines
+
+
+ at contextlib.contextmanager
+def capture_stderr():
+    with capture_stream('stderr') as lines:
+        yield lines
+
+
+class MockLogHandler(logging.Handler):
+    """Mock logging handler to check for expected logs.
+    """
+    def __init__(self, mock_logger, *args, **kwargs):
+        self._mock_logger = mock_logger
+        self.reset()
+        logging.Handler.__init__(self, *args, **kwargs)
+
+    def emit(self, record):
+        self.messages[record.levelname.lower()].append(record.getMessage())
+
+    def reset(self):
+        self.messages = {
+            'debug': [],
+            'info': [],
+            'warning': [],
+            'error': [],
+            'critical': [],
+        }
+
+    def __enter__(self):
+        if hasattr(logging, '_acquireLock'):
+            logging._acquireLock()
+        try:
+            self._orig_handlers = self._mock_logger.handlers
+            self._mock_logger.handlers = [self]
+        finally:
+            if hasattr(logging, '_acquireLock'):
+                logging._releaseLock()
+        return self
+
+    def __exit__(self, etype, evalue, etraceback):
+        if hasattr(logging, '_acquireLock'):
+            logging._acquireLock()
+        try:
+            self._mock_logger.handlers = self._orig_handlers
+        finally:
+            if hasattr(logging, '_acquireLock'):
+                logging._releaseLock()
diff --git a/vistrails/vistrails_server.py b/vistrails/vistrails_server.py
index 76554d4..c3264ff 100644
--- a/vistrails/vistrails_server.py
+++ b/vistrails/vistrails_server.py
@@ -1,35 +1,36 @@
 #!/usr/bin/env python
 ###############################################################################
 ##
+## Copyright (C) 2014-2015, New York University.
 ## Copyright (C) 2011-2014, NYU-Poly.
-## Copyright (C) 2006-2011, University of Utah. 
+## Copyright (C) 2006-2011, University of Utah.
 ## All rights reserved.
 ## Contact: contact at vistrails.org
 ##
 ## This file is part of VisTrails.
 ##
-## "Redistribution and use in source and binary forms, with or without 
+## "Redistribution and use in source and binary forms, with or without
 ## modification, are permitted provided that the following conditions are met:
 ##
-##  - Redistributions of source code must retain the above copyright notice, 
+##  - Redistributions of source code must retain the above copyright notice,
 ##    this list of conditions and the following disclaimer.
-##  - Redistributions in binary form must reproduce the above copyright 
-##    notice, this list of conditions and the following disclaimer in the 
+##  - Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
 ##    documentation and/or other materials provided with the distribution.
-##  - Neither the name of the University of Utah nor the names of its 
-##    contributors may be used to endorse or promote products derived from 
+##  - Neither the name of the New York University nor the names of its
+##    contributors may be used to endorse or promote products derived from
 ##    this software without specific prior written permission.
 ##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
-## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
-## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ##
 ###############################################################################
@@ -75,14 +76,16 @@ if __name__ == '__main__':
             'enablePackagesSilently': False,
             'handlerDontAsk': True,
         }
-        v = vistrails.gui.application_server.start_server(optionsDict)
+        v = vistrails.gui.application_server.start_server(optionsDict,
+                                                          args=sys.argv[1:])
         app = vistrails.gui.application_server.VistrailsServer()
     except SystemExit, e:
         print str(e)
         sys.exit(e)
     except Exception, e:
-        print "Uncaught exception on initialization: %s" % e
         import traceback
+        print "Uncaught exception on initialization: %s" % (
+                traceback._format_final_exc_line(type(e).__name__, e))
         traceback.print_exc()
         sys.exit(255)
      

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/vistrails.git



More information about the debian-science-commits mailing list